mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-01 01:20:25 +00:00
Changes: - Merged app::cmd::ObjectIO into doc::SubObjectsIO - Changed app::cmd::SetCelImage with app::cmd::SetCelData - Added Cel::createCopy/Link() to avoid confunsion with Cel copy ctor - Renamed Sprite::getImage() -> getImageRef() - Added Sprite::getDataCelRef() - Added doc::CelsRange helper to iterate cels - Added Sprite::cels()/uniqueCels() member functions (removed Sprite::getCels()) - Added DocumentRange::convertToCels()
183 lines
4.4 KiB
C++
183 lines
4.4 KiB
C++
// Aseprite Document Library
|
|
// Copyright (c) 2001-2014 David Capello
|
|
//
|
|
// This file is released under the terms of the MIT license.
|
|
// Read LICENSE.txt for more information.
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "doc/layer_io.h"
|
|
|
|
#include "base/serialization.h"
|
|
#include "base/unique_ptr.h"
|
|
#include "doc/cel.h"
|
|
#include "doc/cel_data.h"
|
|
#include "doc/cel_data_io.h"
|
|
#include "doc/cel_io.h"
|
|
#include "doc/image_io.h"
|
|
#include "doc/layer.h"
|
|
#include "doc/layer_io.h"
|
|
#include "doc/sprite.h"
|
|
#include "doc/subobjects_io.h"
|
|
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
namespace doc {
|
|
|
|
using namespace base::serialization;
|
|
using namespace base::serialization::little_endian;
|
|
|
|
// Serialized Layer data:
|
|
|
|
void write_layer(std::ostream& os, Layer* layer)
|
|
{
|
|
std::string name = layer->name();
|
|
|
|
write32(os, layer->id());
|
|
|
|
write16(os, name.size()); // Name length
|
|
if (!name.empty())
|
|
os.write(name.c_str(), name.size()); // Name
|
|
|
|
write32(os, static_cast<int>(layer->flags())); // Flags
|
|
write16(os, static_cast<int>(layer->type())); // Type
|
|
|
|
switch (layer->type()) {
|
|
|
|
case ObjectType::LayerImage: {
|
|
CelIterator it, begin = static_cast<LayerImage*>(layer)->getCelBegin();
|
|
CelIterator end = static_cast<LayerImage*>(layer)->getCelEnd();
|
|
|
|
// Images
|
|
int images = 0;
|
|
int celdatas = 0;
|
|
for (it=begin; it != end; ++it) {
|
|
Cel* cel = *it;
|
|
if (!cel->link()) {
|
|
++images;
|
|
++celdatas;
|
|
}
|
|
}
|
|
|
|
write16(os, images);
|
|
for (it=begin; it != end; ++it) {
|
|
Cel* cel = *it;
|
|
if (!cel->link())
|
|
write_image(os, cel->image());
|
|
}
|
|
|
|
write16(os, celdatas);
|
|
for (it=begin; it != end; ++it) {
|
|
Cel* cel = *it;
|
|
if (!cel->link())
|
|
write_celdata(os, cel->dataRef());
|
|
}
|
|
|
|
// Cels
|
|
write16(os, static_cast<LayerImage*>(layer)->getCelsCount());
|
|
for (it=begin; it != end; ++it) {
|
|
Cel* cel = *it;
|
|
write_cel(os, cel);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ObjectType::LayerFolder: {
|
|
LayerIterator it = static_cast<LayerFolder*>(layer)->getLayerBegin();
|
|
LayerIterator end = static_cast<LayerFolder*>(layer)->getLayerEnd();
|
|
|
|
// Number of sub-layers
|
|
write16(os, static_cast<LayerFolder*>(layer)->getLayersCount());
|
|
|
|
for (; it != end; ++it)
|
|
write_layer(os, *it);
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
Layer* read_layer(std::istream& is, SubObjectsIO* subObjects)
|
|
{
|
|
ObjectId id = read32(is);
|
|
uint16_t name_length = read16(is); // Name length
|
|
std::vector<char> name(name_length+1);
|
|
if (name_length > 0) {
|
|
is.read(&name[0], name_length); // Name
|
|
name[name_length] = 0;
|
|
}
|
|
else
|
|
name[0] = 0;
|
|
|
|
uint32_t flags = read32(is); // Flags
|
|
uint16_t layer_type = read16(is); // Type
|
|
|
|
base::UniquePtr<Layer> layer;
|
|
|
|
switch (static_cast<ObjectType>(layer_type)) {
|
|
|
|
case ObjectType::LayerImage: {
|
|
// Create layer
|
|
layer.reset(new LayerImage(subObjects->sprite()));
|
|
|
|
// Read images
|
|
int images = read16(is); // Number of images
|
|
for (int c=0; c<images; ++c) {
|
|
ImageRef image(read_image(is));
|
|
subObjects->addImageRef(image);
|
|
}
|
|
|
|
// Read celdatas
|
|
int celdatas = read16(is);
|
|
for (int c=0; c<celdatas; ++c) {
|
|
CelDataRef celdata(read_celdata(is, subObjects));
|
|
subObjects->addCelDataRef(celdata);
|
|
}
|
|
|
|
// Read cels
|
|
int cels = read16(is); // Number of cels
|
|
for (int c=0; c<cels; ++c) {
|
|
// Read the cel
|
|
Cel* cel = read_cel(is, subObjects);
|
|
|
|
// Add the cel in the layer
|
|
static_cast<LayerImage*>(layer.get())->addCel(cel);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ObjectType::LayerFolder: {
|
|
// Create the layer set
|
|
layer.reset(new LayerFolder(subObjects->sprite()));
|
|
|
|
// Number of sub-layers
|
|
int layers = read16(is);
|
|
for (int c=0; c<layers; c++) {
|
|
Layer* child = read_layer(is, subObjects);
|
|
if (child)
|
|
static_cast<LayerFolder*>(layer.get())->addLayer(child);
|
|
else
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
throw InvalidLayerType("Invalid layer type found in stream");
|
|
|
|
}
|
|
|
|
if (layer) {
|
|
layer->setName(&name[0]);
|
|
layer->setFlags(static_cast<LayerFlags>(flags));
|
|
layer->setId(id);
|
|
}
|
|
|
|
return layer.release();
|
|
}
|
|
|
|
}
|