1
0
mirror of https://github.com/aseprite/aseprite.git synced 2025-01-25 09:35:25 +00:00

Fix slices' user data serialization on .ase format

This commit is contained in:
David Capello 2017-04-12 08:57:02 -03:00
parent 2c0d0d3682
commit 02b225868d
2 changed files with 150 additions and 129 deletions

@ -287,26 +287,23 @@ Insert this user data in the last read chunk. E.g. If we've read a
layer, this user data belongs to that layer, if we've read a cel, it
belongs to that cel, etc.
```
DWORD Flags
1 = Has text
2 = Has color
+ If flags have bit 1:
STRING Text
+ If flags have bit 2:
BYTE Color Red (0-255)
BYTE Color Green (0-255)
BYTE Color Blue (0-255)
BYTE Color Alpha (0-255)
```
Field | Details |
----------- | -------------------------------- |
DWORD | Flags
| 1 - Has text
| 2 - Has color
If flags have bit 1 |
STRING | Text
If flags have bit 2 |
BYTE | Color Red (0-255)
BYTE | Color Green (0-255)
BYTE | Color Blue (0-255)
BYTE | Color Alpha (0-255)
### Slices Chunk (0x2021)
### Slice Chunk (0x2022)
Field | Details |
----------- | -------------------------------- |
DWORD | Number of slices
BYTE[8] | Reserved
For each slice... |
DWORD | Number of "slice keys"
DWORD | Flags
| 1 - It's a 9-patches slice

@ -13,6 +13,7 @@
#include "app/file/file.h"
#include "app/file/file_format.h"
#include "app/file/format_options.h"
#include "app/pref/preferences.h"
#include "base/cfile.h"
#include "base/exception.h"
#include "base/file_handle.h"
@ -39,7 +40,8 @@
#define ASE_FILE_CHUNK_FRAME_TAGS 0x2018
#define ASE_FILE_CHUNK_PALETTE 0x2019
#define ASE_FILE_CHUNK_USER_DATA 0x2020
#define ASE_FILE_CHUNK_SLICES 0x2021
#define ASE_FILE_CHUNK_SLICES 0x2021 // Deprecated chunk (used on dev versions only between v1.2-beta7 and v1.2-beta8)
#define ASE_FILE_CHUNK_SLICE 0x2022
#define ASE_FILE_LAYER_IMAGE 0
#define ASE_FILE_LAYER_GROUP 1
@ -143,8 +145,11 @@ static void ase_file_write_mask_chunk(FILE* f, ASE_FrameHeader* frame_header, Ma
static void ase_file_read_frame_tags_chunk(FILE* f, FrameTags* frameTags);
static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_header, const FrameTags* frameTags,
const frame_t fromFrame, const frame_t toFrame);
static void ase_file_read_slices_chunk(FILE* f, Slices* slices);
static void ase_file_write_slices_chunk(FILE* f, ASE_FrameHeader* frame_header, const Slices* slices,
static void ase_file_read_slices_chunk(FILE* f, Slices& slices);
static Slice* ase_file_read_slice_chunk(FILE* f, Slices& slices);
static void ase_file_write_slice_chunks(FILE* f, ASE_FrameHeader* frame_header, const Slices& slices,
const frame_t fromFrame, const frame_t toFrame);
static void ase_file_write_slice_chunk(FILE* f, ASE_FrameHeader* frame_header, Slice* slice,
const frame_t fromFrame, const frame_t toFrame);
static void ase_file_read_user_data_chunk(FILE* f, UserData* userData);
static void ase_file_write_user_data_chunk(FILE* f, ASE_FrameHeader* frame_header, const UserData* userData);
@ -332,9 +337,17 @@ bool AseFormat::onLoad(FileOp* fop)
ase_file_read_frame_tags_chunk(f, &sprite->frameTags());
break;
case ASE_FILE_CHUNK_SLICES:
ase_file_read_slices_chunk(f, &sprite->slices());
case ASE_FILE_CHUNK_SLICES: {
ase_file_read_slices_chunk(f, sprite->slices());
break;
}
case ASE_FILE_CHUNK_SLICE: {
Slice* slice = ase_file_read_slice_chunk(f, sprite->slices());
if (slice)
last_object_with_user_data = slice;
break;
}
case ASE_FILE_CHUNK_USER_DATA: {
UserData userData;
@ -468,9 +481,8 @@ bool AseFormat::onSave(FileOp* fop)
fop->roi().toFrame());
// Writer slice chunks
if (sprite->slices().size() > 0)
ase_file_write_slices_chunk(f, &frame_header,
&sprite->slices(),
ase_file_write_slice_chunks(f, &frame_header,
sprite->slices(),
fop->roi().fromFrame(),
fop->roi().toFrame());
}
@ -1687,13 +1699,29 @@ static void ase_file_write_user_data_chunk(FILE* f, ASE_FrameHeader* frame_heade
}
}
static void ase_file_read_slices_chunk(FILE* f, Slices* slices)
static void ase_file_read_slices_chunk(FILE* f, Slices& slices)
{
size_t nslices = fgetl(f); // Number of slices
fgetl(f); // 8 bytes reserved
fgetl(f);
for (size_t i=0; i<nslices; ++i) {
Slice* slice = ase_file_read_slice_chunk(f, slices);
// Set the user data
if (slice) {
// Default slice color
auto color = Preferences::instance().slices.defaultColor();
slice->userData().setColor(
doc::rgba(color.getRed(),
color.getGreen(),
color.getBlue(),
color.getAlpha()));
}
}
}
static Slice* ase_file_read_slice_chunk(FILE* f, Slices& slices)
{
size_t nkeys = fgetl(f); // Number of keys
int flags = fgetl(f); // Flags
fgetl(f); // 4 bytes reserved
@ -1727,36 +1755,37 @@ static void ase_file_read_slices_chunk(FILE* f, Slices* slices)
slice->insert(frame, SliceKey(bounds, center, pivot));
}
slices->add(slice);
slice.release();
}
slices.add(slice);
return slice.release();
}
static void ase_file_write_slices_chunk(FILE* f, ASE_FrameHeader* frame_header,
const Slices* slices,
static void ase_file_write_slice_chunks(FILE* f, ASE_FrameHeader* frame_header,
const Slices& slices,
const frame_t fromFrame,
const frame_t toFrame)
{
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_SLICES);
size_t nslices = 0;
for (Slice* slice : *slices) {
for (Slice* slice : slices) {
// Skip slices that are outside of the given ROI
if (slice->range(fromFrame, toFrame).empty())
continue;
++nslices;
ase_file_write_slice_chunk(f, frame_header, slice,
fromFrame, toFrame);
if (!slice->userData().isEmpty())
ase_file_write_user_data_chunk(f, frame_header, &slice->userData());
}
}
fputl(nslices, f);
fputl(0, f); // 8 reserved bytes
fputl(0, f);
static void ase_file_write_slice_chunk(FILE* f, ASE_FrameHeader* frame_header,
Slice* slice,
const frame_t fromFrame,
const frame_t toFrame)
{
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_SLICE);
for (Slice* slice : *slices) {
// Skip slices that are outside of the given ROI
auto range = slice->range(fromFrame, toFrame);
if (range.empty())
continue;
ASSERT(!range.empty());
int flags = 0;
for (auto key : range) {
@ -1811,11 +1840,6 @@ static void ase_file_write_slices_chunk(FILE* f, ASE_FrameHeader* frame_header,
}
++frame;
}
--nslices;
}
ASSERT(nslices == 0);
}
static bool ase_has_groups(LayerGroup* group)