| 1 | // Aseprite Document Library |
| 2 | // Copyright (c) 2019-2020 Igara Studio S.A. |
| 3 | // Copyright (c) 2001-2016 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.h" |
| 13 | |
| 14 | #include "doc/grid.h" |
| 15 | #include "doc/image.h" |
| 16 | #include "doc/layer.h" |
| 17 | #include "doc/layer_tilemap.h" |
| 18 | #include "doc/sprite.h" |
| 19 | #include "doc/tile.h" |
| 20 | #include "gfx/rect.h" |
| 21 | |
| 22 | namespace doc { |
| 23 | |
| 24 | Cel::Cel(frame_t frame, const ImageRef& image) |
| 25 | : Object(ObjectType::Cel) |
| 26 | , m_layer(NULL) |
| 27 | , m_frame(frame) |
| 28 | , m_data(new CelData(image)) |
| 29 | { |
| 30 | } |
| 31 | |
| 32 | Cel::Cel(frame_t frame, const CelDataRef& celData) |
| 33 | : Object(ObjectType::Cel) |
| 34 | , m_layer(NULL) |
| 35 | , m_frame(frame) |
| 36 | , m_data(celData) |
| 37 | { |
| 38 | } |
| 39 | |
| 40 | // static |
| 41 | Cel* Cel::MakeCopy(const frame_t newFrame, |
| 42 | const Cel* other) |
| 43 | { |
| 44 | Cel* cel = new Cel(newFrame, |
| 45 | ImageRef(Image::createCopy(other->image()))); |
| 46 | |
| 47 | cel->setPosition(other->position()); |
| 48 | cel->setOpacity(other->opacity()); |
| 49 | return cel; |
| 50 | } |
| 51 | |
| 52 | // static |
| 53 | Cel* Cel::MakeLink(const frame_t newFrame, |
| 54 | const Cel* other) |
| 55 | { |
| 56 | return new Cel(newFrame, other->dataRef()); |
| 57 | } |
| 58 | |
| 59 | void Cel::setFrame(frame_t frame) |
| 60 | { |
| 61 | ASSERT(m_layer == NULL); |
| 62 | m_frame = frame; |
| 63 | } |
| 64 | |
| 65 | void Cel::setDataRef(const CelDataRef& celData) |
| 66 | { |
| 67 | ASSERT(celData); |
| 68 | m_data = celData; |
| 69 | } |
| 70 | |
| 71 | void Cel::setPosition(int x, int y) |
| 72 | { |
| 73 | setPosition(gfx::Point(x, y)); |
| 74 | } |
| 75 | |
| 76 | void Cel::setPosition(const gfx::Point& pos) |
| 77 | { |
| 78 | m_data->setPosition(pos); |
| 79 | } |
| 80 | |
| 81 | void Cel::setBounds(const gfx::Rect& bounds) |
| 82 | { |
| 83 | m_data->setBounds(bounds); |
| 84 | } |
| 85 | |
| 86 | void Cel::setBoundsF(const gfx::RectF& bounds) |
| 87 | { |
| 88 | m_data->setBoundsF(bounds); |
| 89 | } |
| 90 | |
| 91 | void Cel::setOpacity(int opacity) |
| 92 | { |
| 93 | m_data->setOpacity(opacity); |
| 94 | } |
| 95 | |
| 96 | Document* Cel::document() const |
| 97 | { |
| 98 | ASSERT(m_layer); |
| 99 | if (m_layer && m_layer->sprite()) |
| 100 | return m_layer->sprite()->document(); |
| 101 | else |
| 102 | return NULL; |
| 103 | } |
| 104 | |
| 105 | Sprite* Cel::sprite() const |
| 106 | { |
| 107 | ASSERT(m_layer); |
| 108 | if (m_layer) |
| 109 | return m_layer->sprite(); |
| 110 | else |
| 111 | return NULL; |
| 112 | } |
| 113 | |
| 114 | Cel* Cel::link() const |
| 115 | { |
| 116 | ASSERT(m_data); |
| 117 | if (m_data.get() == NULL) |
| 118 | return NULL; |
| 119 | |
| 120 | if (!m_data.unique()) { |
| 121 | for (frame_t fr=0; fr<m_frame; ++fr) { |
| 122 | Cel* possible = m_layer->cel(fr); |
| 123 | if (possible && possible->dataRef().get() == m_data.get()) |
| 124 | return possible; |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | return NULL; |
| 129 | } |
| 130 | |
| 131 | std::size_t Cel::links() const |
| 132 | { |
| 133 | std::size_t links = 0; |
| 134 | |
| 135 | Sprite* sprite = this->sprite(); |
| 136 | for (frame_t fr=0; fr<sprite->totalFrames(); ++fr) { |
| 137 | Cel* cel = m_layer->cel(fr); |
| 138 | if (cel && cel != this && cel->dataRef().get() == m_data.get()) |
| 139 | ++links; |
| 140 | } |
| 141 | |
| 142 | return links; |
| 143 | } |
| 144 | |
| 145 | void Cel::setParentLayer(LayerImage* layer) |
| 146 | { |
| 147 | m_layer = layer; |
| 148 | fixupImage(); |
| 149 | } |
| 150 | |
| 151 | Grid Cel::grid() const |
| 152 | { |
| 153 | if (m_layer) { |
| 154 | if (m_layer->isTilemap()) { |
| 155 | doc::Grid grid = static_cast<LayerTilemap*>(m_layer)->tileset()->grid(); |
| 156 | grid.origin(grid.origin() + position()); |
| 157 | return grid; |
| 158 | } |
| 159 | else |
| 160 | return m_layer->grid(); |
| 161 | } |
| 162 | return Grid(); |
| 163 | } |
| 164 | |
| 165 | void Cel::fixupImage() |
| 166 | { |
| 167 | // Change the mask color to the sprite mask color |
| 168 | if (m_layer && image()) { |
| 169 | image()->setMaskColor((image()->pixelFormat() == IMAGE_TILEMAP) ? |
| 170 | notile : m_layer->sprite()->transparentColor()); |
| 171 | ASSERT(m_data); |
| 172 | m_data->adjustBounds(m_layer); |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | } // namespace doc |
| 177 | |