mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-24 18:02:27 +00:00
Fix slices' user data serialization on .ase format
This commit is contained in:
parent
2c0d0d3682
commit
02b225868d
@ -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
|
layer, this user data belongs to that layer, if we've read a cel, it
|
||||||
belongs to that cel, etc.
|
belongs to that cel, etc.
|
||||||
|
|
||||||
```
|
Field | Details |
|
||||||
DWORD Flags
|
----------- | -------------------------------- |
|
||||||
1 = Has text
|
DWORD | Flags
|
||||||
2 = Has color
|
| 1 - Has text
|
||||||
+ If flags have bit 1:
|
| 2 - Has color
|
||||||
STRING Text
|
If flags have bit 1 |
|
||||||
+ If flags have bit 2:
|
STRING | Text
|
||||||
BYTE Color Red (0-255)
|
If flags have bit 2 |
|
||||||
BYTE Color Green (0-255)
|
BYTE | Color Red (0-255)
|
||||||
BYTE Color Blue (0-255)
|
BYTE | Color Green (0-255)
|
||||||
BYTE Color Alpha (0-255)
|
BYTE | Color Blue (0-255)
|
||||||
```
|
BYTE | Color Alpha (0-255)
|
||||||
|
|
||||||
### Slices Chunk (0x2021)
|
### Slice Chunk (0x2022)
|
||||||
|
|
||||||
Field | Details |
|
Field | Details |
|
||||||
----------- | -------------------------------- |
|
----------- | -------------------------------- |
|
||||||
DWORD | Number of slices
|
|
||||||
BYTE[8] | Reserved
|
|
||||||
For each slice... |
|
|
||||||
DWORD | Number of "slice keys"
|
DWORD | Number of "slice keys"
|
||||||
DWORD | Flags
|
DWORD | Flags
|
||||||
| 1 - It's a 9-patches slice
|
| 1 - It's a 9-patches slice
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "app/file/file.h"
|
#include "app/file/file.h"
|
||||||
#include "app/file/file_format.h"
|
#include "app/file/file_format.h"
|
||||||
#include "app/file/format_options.h"
|
#include "app/file/format_options.h"
|
||||||
|
#include "app/pref/preferences.h"
|
||||||
#include "base/cfile.h"
|
#include "base/cfile.h"
|
||||||
#include "base/exception.h"
|
#include "base/exception.h"
|
||||||
#include "base/file_handle.h"
|
#include "base/file_handle.h"
|
||||||
@ -39,7 +40,8 @@
|
|||||||
#define ASE_FILE_CHUNK_FRAME_TAGS 0x2018
|
#define ASE_FILE_CHUNK_FRAME_TAGS 0x2018
|
||||||
#define ASE_FILE_CHUNK_PALETTE 0x2019
|
#define ASE_FILE_CHUNK_PALETTE 0x2019
|
||||||
#define ASE_FILE_CHUNK_USER_DATA 0x2020
|
#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_IMAGE 0
|
||||||
#define ASE_FILE_LAYER_GROUP 1
|
#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_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,
|
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);
|
const frame_t fromFrame, const frame_t toFrame);
|
||||||
static void ase_file_read_slices_chunk(FILE* f, Slices* slices);
|
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 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);
|
const frame_t fromFrame, const frame_t toFrame);
|
||||||
static void ase_file_read_user_data_chunk(FILE* f, UserData* userData);
|
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);
|
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());
|
ase_file_read_frame_tags_chunk(f, &sprite->frameTags());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ASE_FILE_CHUNK_SLICES:
|
case ASE_FILE_CHUNK_SLICES: {
|
||||||
ase_file_read_slices_chunk(f, &sprite->slices());
|
ase_file_read_slices_chunk(f, sprite->slices());
|
||||||
break;
|
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: {
|
case ASE_FILE_CHUNK_USER_DATA: {
|
||||||
UserData userData;
|
UserData userData;
|
||||||
@ -468,9 +481,8 @@ bool AseFormat::onSave(FileOp* fop)
|
|||||||
fop->roi().toFrame());
|
fop->roi().toFrame());
|
||||||
|
|
||||||
// Writer slice chunks
|
// Writer slice chunks
|
||||||
if (sprite->slices().size() > 0)
|
ase_file_write_slice_chunks(f, &frame_header,
|
||||||
ase_file_write_slices_chunk(f, &frame_header,
|
sprite->slices(),
|
||||||
&sprite->slices(),
|
|
||||||
fop->roi().fromFrame(),
|
fop->roi().fromFrame(),
|
||||||
fop->roi().toFrame());
|
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
|
size_t nslices = fgetl(f); // Number of slices
|
||||||
fgetl(f); // 8 bytes reserved
|
fgetl(f); // 8 bytes reserved
|
||||||
fgetl(f);
|
fgetl(f);
|
||||||
|
|
||||||
for (size_t i=0; i<nslices; ++i) {
|
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
|
size_t nkeys = fgetl(f); // Number of keys
|
||||||
int flags = fgetl(f); // Flags
|
int flags = fgetl(f); // Flags
|
||||||
fgetl(f); // 4 bytes reserved
|
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));
|
slice->insert(frame, SliceKey(bounds, center, pivot));
|
||||||
}
|
}
|
||||||
|
|
||||||
slices->add(slice);
|
slices.add(slice);
|
||||||
slice.release();
|
return slice.release();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ase_file_write_slices_chunk(FILE* f, ASE_FrameHeader* frame_header,
|
static void ase_file_write_slice_chunks(FILE* f, ASE_FrameHeader* frame_header,
|
||||||
const Slices* slices,
|
const Slices& slices,
|
||||||
const frame_t fromFrame,
|
const frame_t fromFrame,
|
||||||
const frame_t toFrame)
|
const frame_t toFrame)
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_SLICES);
|
for (Slice* slice : slices) {
|
||||||
|
|
||||||
size_t nslices = 0;
|
|
||||||
for (Slice* slice : *slices) {
|
|
||||||
// Skip slices that are outside of the given ROI
|
// Skip slices that are outside of the given ROI
|
||||||
if (slice->range(fromFrame, toFrame).empty())
|
if (slice->range(fromFrame, toFrame).empty())
|
||||||
continue;
|
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);
|
static void ase_file_write_slice_chunk(FILE* f, ASE_FrameHeader* frame_header,
|
||||||
fputl(0, f); // 8 reserved bytes
|
Slice* slice,
|
||||||
fputl(0, f);
|
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);
|
auto range = slice->range(fromFrame, toFrame);
|
||||||
if (range.empty())
|
ASSERT(!range.empty());
|
||||||
continue;
|
|
||||||
|
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
for (auto key : range) {
|
for (auto key : range) {
|
||||||
@ -1811,11 +1840,6 @@ static void ase_file_write_slices_chunk(FILE* f, ASE_FrameHeader* frame_header,
|
|||||||
}
|
}
|
||||||
++frame;
|
++frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
--nslices;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(nslices == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ase_has_groups(LayerGroup* group)
|
static bool ase_has_groups(LayerGroup* group)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user