Load/save user data in .ase files

This commit is contained in:
David Capello 2015-12-11 16:23:29 -03:00
parent 2fcd2b4013
commit 8a653b6de2
2 changed files with 66 additions and 18 deletions

View File

@ -174,7 +174,8 @@ Layer Chunk (0x2004)
Saturation = 13
Color = 14
Luminosity = 15
BYTE Opacity (valid if "flags" field has bit 32 set)
BYTE Opacity
Note: valid only if file header flags field has bit 1 set
BYTE[3] For future (set to zero)
STRING Layer name
@ -268,6 +269,19 @@ Palette Chunk (0x2019)
STRING Color name
User Data Chunk (0x2020)
----------------------------------------
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
+ If flags has bit 1:
STRING Text
Notes
----------------------------------------

View File

@ -34,6 +34,7 @@
#define ASE_FILE_CHUNK_PATH 0x2017
#define ASE_FILE_CHUNK_FRAME_TAGS 0x2018
#define ASE_FILE_CHUNK_PALETTE 0x2019
#define ASE_FILE_CHUNK_USER_DATA 0x2020
#define ASE_FILE_RAW_CEL 0
#define ASE_FILE_LINK_CEL 1
@ -47,6 +48,8 @@
#define ASE_PALETTE_FLAG_HAS_NAME 1
#define ASE_USER_DATA_FLAG_HAS_TEXT 1
namespace app {
using namespace base;
@ -116,6 +119,8 @@ static void ase_file_write_mask_chunk(FILE* f, ASE_FrameHeader* frame_header, Ma
#endif
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_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);
class ChunkWriter {
public:
@ -189,6 +194,7 @@ bool AseFormat::onLoad(FileOp* fop)
// Prepare variables for layer chunks
Layer* last_layer = sprite->folder();
WithUserData* last_object_with_user_data = nullptr;
int current_level = -1;
// Read frame by frame to end-of-file
@ -244,45 +250,49 @@ bool AseFormat::onLoad(FileOp* fop)
}
case ASE_FILE_CHUNK_LAYER: {
/* fop->setError("Layer chunk\n"); */
ase_file_read_layer_chunk(f, &header, sprite,
&last_layer,
&current_level);
last_object_with_user_data =
ase_file_read_layer_chunk(f, &header, sprite,
&last_layer,
&current_level);
break;
}
case ASE_FILE_CHUNK_CEL: {
/* fop->setError("Cel chunk\n"); */
ase_file_read_cel_chunk(f, sprite, frame,
sprite->pixelFormat(), fop, &header,
chunk_pos+chunk_size);
Cel* cel =
ase_file_read_cel_chunk(f, sprite, frame,
sprite->pixelFormat(), fop, &header,
chunk_pos+chunk_size);
if (cel) {
last_object_with_user_data = cel->data();
}
break;
}
case ASE_FILE_CHUNK_MASK: {
Mask* mask;
/* fop->setError("Mask chunk\n"); */
mask = ase_file_read_mask_chunk(f);
Mask* mask = ase_file_read_mask_chunk(f);
if (mask)
delete mask; // TODO add the mask in some place?
else
fop->setError("Warning: error loading a mask chunk\n");
break;
}
case ASE_FILE_CHUNK_PATH:
/* fop->setError("Path chunk\n"); */
// Ignore
break;
case ASE_FILE_CHUNK_FRAME_TAGS:
ase_file_read_frame_tags_chunk(f, &sprite->frameTags());
break;
case ASE_FILE_CHUNK_USER_DATA: {
UserData userData;
ase_file_read_user_data_chunk(f, &userData);
if (last_object_with_user_data)
last_object_with_user_data->setUserData(userData);
break;
}
default:
fop->setError("Warning: Unsupported chunk type %d (skipping)\n", chunk_type);
break;
@ -530,6 +540,8 @@ static void ase_file_write_frame_header(FILE* f, ASE_FrameHeader* frame_header)
static void ase_file_write_layers(FILE* f, ASE_FrameHeader* frame_header, const Layer* layer)
{
ase_file_write_layer_chunk(f, frame_header, layer);
if (!layer->userData().isEmpty())
ase_file_write_user_data_chunk(f, frame_header, &layer->userData());
if (layer->isFolder()) {
auto it = static_cast<const LayerFolder*>(layer)->getLayerBegin(),
@ -549,6 +561,12 @@ static void ase_file_write_cels(FILE* f, ASE_FrameHeader* frame_header, const Sp
/* frame, sprite_layer2index(sprite, layer)); */
ase_file_write_cel_chunk(f, frame_header, cel, static_cast<const LayerImage*>(layer), sprite);
if (!cel->link() &&
!cel->data()->userData().isEmpty()) {
ase_file_write_user_data_chunk(f, frame_header,
&cel->data()->userData());
}
}
}
@ -1438,4 +1456,20 @@ static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_head
}
}
static void ase_file_read_user_data_chunk(FILE* f, UserData* userData)
{
size_t flags = fgetl(f);
if (flags & ASE_USER_DATA_FLAG_HAS_TEXT) {
std::string text = ase_file_read_string(f);
userData->setText(text);
}
}
static void ase_file_write_user_data_chunk(FILE* f, ASE_FrameHeader* frame_header, const UserData* userData)
{
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_USER_DATA);
fputl(ASE_USER_DATA_FLAG_HAS_TEXT, f);
ase_file_write_string(f, userData->text().c_str());
}
} // namespace app