| 1 | // Aseprite Document Library |
| 2 | // Copyright (c) 2022 Igara Studio S.A. |
| 3 | // Copyright (c) 2001-2018 David Capello |
| 4 | // |
| 5 | // This file is released under the terms of the MIT license. |
| 6 | // Read LICENSE.txt for more information. |
| 7 | |
| 8 | #ifdef HAVE_CONFIG_H |
| 9 | #include "config.h" |
| 10 | #endif |
| 11 | |
| 12 | #include "doc/cel_data_io.h" |
| 13 | |
| 14 | #include "base/serialization.h" |
| 15 | #include "doc/cel_data.h" |
| 16 | #include "doc/subobjects_io.h" |
| 17 | #include "doc/user_data_io.h" |
| 18 | #include "fixmath/fixmath.h" |
| 19 | |
| 20 | #include <iostream> |
| 21 | #include <memory> |
| 22 | |
| 23 | namespace doc { |
| 24 | |
| 25 | #define HAS_BOUNDS_F 1 |
| 26 | |
| 27 | using namespace base::serialization; |
| 28 | using namespace base::serialization::little_endian; |
| 29 | |
| 30 | void write_celdata(std::ostream& os, const CelData* celdata) |
| 31 | { |
| 32 | write32(os, celdata->id()); |
| 33 | write32(os, celdata->bounds().x); |
| 34 | write32(os, celdata->bounds().y); |
| 35 | write32(os, celdata->bounds().w); |
| 36 | write32(os, celdata->bounds().h); |
| 37 | write8(os, celdata->opacity()); |
| 38 | write32(os, celdata->image()->id()); |
| 39 | write_user_data(os, celdata->userData()); |
| 40 | |
| 41 | if (celdata->hasBoundsF()) { // Reference layer |
| 42 | write32(os, HAS_BOUNDS_F); |
| 43 | write32(os, fixmath::ftofix(celdata->boundsF().x)); |
| 44 | write32(os, fixmath::ftofix(celdata->boundsF().y)); |
| 45 | write32(os, fixmath::ftofix(celdata->boundsF().w)); |
| 46 | write32(os, fixmath::ftofix(celdata->boundsF().h)); |
| 47 | } |
| 48 | else { |
| 49 | write32(os, 0); |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | CelData* read_celdata(std::istream& is, SubObjectsIO* subObjects, bool setId) |
| 54 | { |
| 55 | ObjectId id = read32(is); |
| 56 | int x = read32(is); |
| 57 | int y = read32(is); |
| 58 | int w = read32(is); |
| 59 | int h = read32(is); |
| 60 | int opacity = read8(is); |
| 61 | ObjectId imageId = read32(is); |
| 62 | UserData userData = read_user_data(is); |
| 63 | gfx::RectF boundsF; |
| 64 | |
| 65 | // Extra fields |
| 66 | int flags = read32(is); |
| 67 | if (flags & HAS_BOUNDS_F) { |
| 68 | fixmath::fixed x = read32(is); |
| 69 | fixmath::fixed y = read32(is); |
| 70 | fixmath::fixed w = read32(is); |
| 71 | fixmath::fixed h = read32(is); |
| 72 | if (w && h) { |
| 73 | boundsF = gfx::RectF(fixmath::fixtof(x), |
| 74 | fixmath::fixtof(y), |
| 75 | fixmath::fixtof(w), |
| 76 | fixmath::fixtof(h)); |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | ImageRef image(subObjects->getImageRef(imageId)); |
| 81 | if (!image) |
| 82 | return nullptr; |
| 83 | |
| 84 | std::unique_ptr<CelData> celdata(new CelData(image)); |
| 85 | celdata->setBounds(gfx::Rect(x, y, w, h)); |
| 86 | celdata->setOpacity(opacity); |
| 87 | celdata->setUserData(userData); |
| 88 | if (setId) |
| 89 | celdata->setId(id); |
| 90 | if (!boundsF.isEmpty()) |
| 91 | celdata->setBoundsF(boundsF); |
| 92 | return celdata.release(); |
| 93 | } |
| 94 | |
| 95 | } |
| 96 | |