mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-03 05:22:23 +00:00
Refactored Layer class to include all layer_* functions as member functions.
This commit is contained in:
parent
8b7f476f17
commit
cbc0bf22bd
@ -1,3 +1,8 @@
|
||||
2009-11-17 David Capello <davidcapello@gmail.com>
|
||||
|
||||
* src/raster/layer.h (Layer, LayerImage, LayerFolder): Converted
|
||||
layer to a class with member functions.
|
||||
|
||||
2009-10-17 David Capello <davidcapello@gmail.com>
|
||||
|
||||
* src/commands/cmd_configure_screen.cpp: Fixed issue #2874422
|
||||
|
@ -51,9 +51,9 @@ bool BackgroundFromLayerCommand::enabled(Context* context)
|
||||
sprite != NULL &&
|
||||
sprite->layer != NULL &&
|
||||
sprite_get_background_layer(sprite) == NULL &&
|
||||
layer_is_image(sprite->layer) &&
|
||||
layer_is_readable(sprite->layer) &&
|
||||
layer_is_writable(sprite->layer);
|
||||
sprite->layer->is_image() &&
|
||||
sprite->layer->is_readable() &&
|
||||
sprite->layer->is_writable();
|
||||
}
|
||||
|
||||
void BackgroundFromLayerCommand::execute(Context* context)
|
||||
@ -67,7 +67,7 @@ void BackgroundFromLayerCommand::execute(Context* context)
|
||||
|
||||
{
|
||||
Undoable undoable(sprite, "Background from Layer");
|
||||
undoable.background_from_layer(sprite->layer, bgcolor);
|
||||
undoable.background_from_layer(static_cast<LayerImage*>(sprite->layer), bgcolor);
|
||||
undoable.commit();
|
||||
}
|
||||
update_screen_for_sprite(sprite);
|
||||
|
@ -55,30 +55,26 @@ CelPropertiesCommand::CelPropertiesCommand()
|
||||
bool CelPropertiesCommand::enabled(Context* context)
|
||||
{
|
||||
const CurrentSpriteReader sprite(context);
|
||||
return sprite && sprite->layer;
|
||||
return
|
||||
sprite &&
|
||||
sprite->layer &&
|
||||
sprite->layer->is_image();
|
||||
}
|
||||
|
||||
void CelPropertiesCommand::execute(Context* context)
|
||||
{
|
||||
JWidget label_frame, label_pos, label_size;
|
||||
JWidget slider_opacity, button_ok;
|
||||
Layer *layer;
|
||||
Cel *cel;
|
||||
Layer* layer;
|
||||
Cel* cel;
|
||||
char buf[1024];
|
||||
int memsize;
|
||||
|
||||
/* get current sprite */
|
||||
const CurrentSpriteReader sprite(context);
|
||||
if (!sprite)
|
||||
return;
|
||||
|
||||
/* get selected layer */
|
||||
layer = sprite->layer;
|
||||
if (!layer)
|
||||
return;
|
||||
|
||||
/* get current cel (can be NULL) */
|
||||
cel = layer_get_cel(layer, sprite->frame);
|
||||
cel = static_cast<LayerImage*>(layer)->get_cel(sprite->frame);
|
||||
|
||||
JWidgetPtr window(load_widget("celprop.jid", "cel_properties"));
|
||||
get_widgets(window,
|
||||
@ -89,7 +85,7 @@ void CelPropertiesCommand::execute(Context* context)
|
||||
"ok", &button_ok, NULL);
|
||||
|
||||
/* if the layer isn't writable */
|
||||
if (!layer_is_writable(layer)) {
|
||||
if (!layer->is_writable()) {
|
||||
jwidget_set_text(button_ok, _("Locked"));
|
||||
jwidget_disable(button_ok);
|
||||
}
|
||||
@ -120,7 +116,7 @@ void CelPropertiesCommand::execute(Context* context)
|
||||
|
||||
/* opacity */
|
||||
jslider_set_value(slider_opacity, cel->opacity);
|
||||
if (layer_is_background(layer)) {
|
||||
if (layer->is_background()) {
|
||||
jwidget_disable(slider_opacity);
|
||||
jwidget_add_tooltip_text(slider_opacity, "The `Background' layer is opaque,\n"
|
||||
"you can't change its opacity.");
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
protected:
|
||||
void load_params(Params* params);
|
||||
bool enabled(Context* context);
|
||||
bool checked(Context* context);
|
||||
void execute(Context* context);
|
||||
};
|
||||
|
||||
@ -71,8 +72,27 @@ void ChangeImageTypeCommand::load_params(Params* params)
|
||||
bool ChangeImageTypeCommand::enabled(Context* context)
|
||||
{
|
||||
const CurrentSpriteReader sprite(context);
|
||||
|
||||
if (sprite != NULL) {
|
||||
if (sprite->imgtype == IMAGE_INDEXED && m_imgtype == IMAGE_INDEXED && m_dithering == DITHERING_NONE)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChangeImageTypeCommand::checked(Context* context)
|
||||
{
|
||||
const CurrentSpriteReader sprite(context);
|
||||
|
||||
if (sprite != NULL) {
|
||||
if (sprite->imgtype == IMAGE_INDEXED && m_imgtype == IMAGE_INDEXED && m_dithering == DITHERING_NONE)
|
||||
return false;
|
||||
}
|
||||
|
||||
return
|
||||
sprite != NULL;
|
||||
sprite != NULL &&
|
||||
sprite->imgtype == m_imgtype;
|
||||
}
|
||||
|
||||
void ChangeImageTypeCommand::execute(Context* context)
|
||||
|
@ -55,9 +55,9 @@ bool ClearCommand::enabled(Context* context)
|
||||
return
|
||||
sprite != NULL &&
|
||||
sprite->layer != NULL &&
|
||||
layer_is_image(sprite->layer) &&
|
||||
layer_is_readable(sprite->layer) &&
|
||||
layer_is_writable(sprite->layer);
|
||||
sprite->layer->is_image() &&
|
||||
sprite->layer->is_readable() &&
|
||||
sprite->layer->is_writable();
|
||||
}
|
||||
|
||||
void ClearCommand::execute(Context* context)
|
||||
|
@ -50,15 +50,15 @@ bool CopyCommand::enabled(Context* context)
|
||||
{
|
||||
const CurrentSpriteReader sprite(context);
|
||||
|
||||
if ((!sprite) ||
|
||||
(!sprite->layer) ||
|
||||
(!layer_is_readable(sprite->layer)) ||
|
||||
(!layer_is_writable(sprite->layer)) ||
|
||||
(!sprite->mask) ||
|
||||
(!sprite->mask->bitmap))
|
||||
return false;
|
||||
else
|
||||
if ((sprite) &&
|
||||
(sprite->layer) &&
|
||||
(sprite->layer->is_readable()) &&
|
||||
(sprite->layer->is_writable()) &&
|
||||
(sprite->mask) &&
|
||||
(sprite->mask->bitmap))
|
||||
return GetImage(sprite) ? true: false;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void CopyCommand::execute(Context* context)
|
||||
|
@ -49,15 +49,15 @@ CutCommand::CutCommand()
|
||||
bool CutCommand::enabled(Context* context)
|
||||
{
|
||||
const CurrentSpriteReader sprite(context);
|
||||
if ((!sprite) ||
|
||||
(!sprite->layer) ||
|
||||
(!layer_is_readable(sprite->layer)) ||
|
||||
(!layer_is_writable(sprite->layer)) ||
|
||||
(!sprite->mask) ||
|
||||
(!sprite->mask->bitmap))
|
||||
return false;
|
||||
else
|
||||
if ((sprite) &&
|
||||
(sprite->layer) &&
|
||||
(sprite->layer->is_readable()) &&
|
||||
(sprite->layer->is_writable()) &&
|
||||
(sprite->mask) &&
|
||||
(sprite->mask->bitmap))
|
||||
return GetImage(sprite) ? true: false;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void CutCommand::execute(Context* context)
|
||||
|
@ -65,21 +65,15 @@ void DuplicateLayerCommand::execute(Context* context)
|
||||
update_screen_for_sprite(sprite);
|
||||
}
|
||||
|
||||
static Layer *duplicate_layer(Sprite* sprite)
|
||||
static Layer* duplicate_layer(Sprite* sprite)
|
||||
{
|
||||
Layer *layer_copy;
|
||||
char buf[1024];
|
||||
|
||||
if (!sprite || !sprite->layer)
|
||||
return NULL;
|
||||
|
||||
/* open undo */
|
||||
if (undo_is_enabled(sprite->undo)) {
|
||||
undo_set_label(sprite->undo, "Layer Duplication");
|
||||
undo_open(sprite->undo);
|
||||
}
|
||||
|
||||
layer_copy = layer_new_copy(sprite, sprite->layer);
|
||||
Layer* layer_copy = sprite->layer->duplicate_for(sprite);
|
||||
if (!layer_copy) {
|
||||
if (undo_is_enabled(sprite->undo))
|
||||
undo_close(sprite->undo);
|
||||
@ -89,16 +83,15 @@ static Layer *duplicate_layer(Sprite* sprite)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
layer_copy->flags &= ~(LAYER_IS_LOCKMOVE | LAYER_IS_BACKGROUND);
|
||||
|
||||
sprintf(buf, "%s %s", layer_copy->name, _("Copy"));
|
||||
layer_set_name(layer_copy, buf);
|
||||
layer_copy->set_background(false);
|
||||
layer_copy->set_moveable(true);
|
||||
layer_copy->set_name(layer_copy->get_name() + " " + _("Copy"));
|
||||
|
||||
/* add the new layer in the sprite */
|
||||
if (undo_is_enabled(sprite->undo))
|
||||
undo_add_layer(sprite->undo, sprite->layer->parent_layer, layer_copy);
|
||||
undo_add_layer(sprite->undo, sprite->layer->get_parent(), layer_copy);
|
||||
|
||||
layer_add_layer(sprite->layer->parent_layer, layer_copy);
|
||||
sprite->layer->get_parent()->add_layer(layer_copy);
|
||||
|
||||
if (undo_is_enabled(sprite->undo)) {
|
||||
undo_move_layer(sprite->undo, layer_copy);
|
||||
@ -106,7 +99,7 @@ static Layer *duplicate_layer(Sprite* sprite)
|
||||
undo_close(sprite->undo);
|
||||
}
|
||||
|
||||
layer_move_layer(sprite->layer->parent_layer, layer_copy, sprite->layer);
|
||||
sprite->layer->get_parent()->move_layer(layer_copy, sprite->layer);
|
||||
sprite_set_layer(sprite, layer_copy);
|
||||
|
||||
return layer_copy;
|
||||
|
@ -129,13 +129,12 @@ void FlipCommand::execute(Context* context)
|
||||
}
|
||||
else {
|
||||
// get all sprite cels
|
||||
JList cels = jlist_new();
|
||||
CelList cels;
|
||||
sprite_get_cels(sprite, cels);
|
||||
|
||||
// for each cel...
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(cels, link) {
|
||||
Cel* cel = (Cel*)link->data;
|
||||
for (CelIterator it = cels.begin(); it != cels.end(); ++it) {
|
||||
Cel* cel = *it;
|
||||
Image* image = stock_get_image(sprite->stock, cel->image);
|
||||
|
||||
undoable.set_cel_position(cel,
|
||||
@ -145,7 +144,6 @@ void FlipCommand::execute(Context* context)
|
||||
undoable.flip_image(image, 0, 0, image->w-1, image->h-1,
|
||||
m_flip_horizontal, m_flip_vertical);
|
||||
}
|
||||
jlist_free(cels);
|
||||
}
|
||||
|
||||
undoable.commit();
|
||||
|
@ -73,7 +73,7 @@ void GotoPreviousLayerCommand::execute(Context* context)
|
||||
|
||||
statusbar_show_tip(app_get_statusbar(), 1000,
|
||||
_("Layer `%s' selected"),
|
||||
sprite->layer->name);
|
||||
sprite->layer->get_name().c_str());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -121,7 +121,7 @@ void GotoNextLayerCommand::execute(Context* context)
|
||||
|
||||
statusbar_show_tip(app_get_statusbar(), 1000,
|
||||
_("Layer `%s' selected"),
|
||||
sprite->layer->name);
|
||||
sprite->layer->get_name().c_str());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -51,12 +51,12 @@ bool LayerFromBackgroundCommand::enabled(Context* context)
|
||||
{
|
||||
const CurrentSpriteReader sprite(context);
|
||||
return
|
||||
sprite != NULL &&
|
||||
sprite->layer != NULL &&
|
||||
layer_is_image(sprite->layer) &&
|
||||
layer_is_readable(sprite->layer) &&
|
||||
layer_is_writable(sprite->layer) &&
|
||||
layer_is_background(sprite->layer);
|
||||
sprite &&
|
||||
sprite->layer &&
|
||||
sprite->layer->is_image() &&
|
||||
sprite->layer->is_readable() &&
|
||||
sprite->layer->is_writable() &&
|
||||
sprite->layer->is_background();
|
||||
}
|
||||
|
||||
void LayerFromBackgroundCommand::execute(Context* context)
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "commands/command.h"
|
||||
#include "core/app.h"
|
||||
#include "modules/gui.h"
|
||||
#include "raster/image.h"
|
||||
#include "raster/layer.h"
|
||||
#include "raster/sprite.h"
|
||||
#include "sprite_wrappers.h"
|
||||
@ -61,18 +62,19 @@ void LayerPropertiesCommand::execute(Context* context)
|
||||
JWidget box1, box2, box3, label_name, entry_name;
|
||||
JWidget button_ok, button_cancel, label_bm, view_bm, list_bm;
|
||||
CurrentSpriteWriter sprite(context);
|
||||
Layer *layer = sprite->layer;
|
||||
Layer* layer = sprite->layer;
|
||||
bool with_blend_modes = (layer->is_image() && sprite->imgtype != IMAGE_INDEXED);
|
||||
|
||||
JWidgetPtr window(jwindow_new(_("Layer Properties")));
|
||||
box1 = jbox_new(JI_VERTICAL);
|
||||
box2 = jbox_new(JI_HORIZONTAL);
|
||||
box3 = jbox_new(JI_HORIZONTAL + JI_HOMOGENEOUS);
|
||||
label_name = jlabel_new(_("Name:"));
|
||||
entry_name = jentry_new(256, layer->name);
|
||||
entry_name = jentry_new(256, layer->get_name().c_str());
|
||||
button_ok = jbutton_new(_("&OK"));
|
||||
button_cancel = jbutton_new(_("&Cancel"));
|
||||
|
||||
if (layer->type == GFXOBJ_LAYER_IMAGE) {
|
||||
if (with_blend_modes) {
|
||||
label_bm = jlabel_new(_("Blend mode:"));
|
||||
view_bm = jview_new();
|
||||
list_bm = jlistbox_new();
|
||||
@ -95,19 +97,20 @@ void LayerPropertiesCommand::execute(Context* context)
|
||||
jwidget_add_child(list_bm, jlistitem_new(_("Color")));
|
||||
jwidget_add_child(list_bm, jlistitem_new(_("Luminosity")));
|
||||
|
||||
jlistbox_select_index(list_bm, layer->blend_mode);
|
||||
jlistbox_select_index(list_bm, static_cast<LayerImage*>(layer)->get_blend_mode());
|
||||
|
||||
jview_attach(view_bm, list_bm);
|
||||
jwidget_set_min_size(view_bm, 128*guiscale(), 64*guiscale());
|
||||
jwidget_expansive(view_bm, TRUE);
|
||||
}
|
||||
|
||||
jwidget_expansive(entry_name, TRUE);
|
||||
jwidget_set_min_size(entry_name, 128, 0);
|
||||
jwidget_expansive(entry_name, true);
|
||||
|
||||
jwidget_add_child(box2, label_name);
|
||||
jwidget_add_child(box2, entry_name);
|
||||
jwidget_add_child(box1, box2);
|
||||
if (layer->type == GFXOBJ_LAYER_IMAGE) {
|
||||
if (with_blend_modes) {
|
||||
jwidget_add_child(box1, label_bm);
|
||||
jwidget_add_child(box1, view_bm);
|
||||
}
|
||||
@ -116,14 +119,16 @@ void LayerPropertiesCommand::execute(Context* context)
|
||||
jwidget_add_child(box1, box3);
|
||||
jwidget_add_child(window, box1);
|
||||
|
||||
jwidget_magnetic(button_ok, TRUE);
|
||||
jwidget_magnetic(entry_name, true);
|
||||
jwidget_magnetic(button_ok, true);
|
||||
|
||||
jwindow_open_fg(window);
|
||||
|
||||
if (jwindow_get_killer(window) == button_ok) {
|
||||
layer_set_name(layer, jwidget_get_text(entry_name));
|
||||
if (layer->type == GFXOBJ_LAYER_IMAGE)
|
||||
layer_set_blend_mode(layer, jlistbox_get_selected_index(list_bm));
|
||||
layer->set_name(jwidget_get_text(entry_name));
|
||||
|
||||
if (with_blend_modes)
|
||||
static_cast<LayerImage*>(layer)->set_blend_mode(jlistbox_get_selected_index(list_bm));
|
||||
|
||||
update_screen_for_sprite(sprite);
|
||||
}
|
||||
|
@ -59,14 +59,14 @@ bool MergeDownLayerCommand::enabled(Context* context)
|
||||
return false;
|
||||
|
||||
Layer *src_layer = sprite->layer;
|
||||
if (!src_layer || !layer_is_image(src_layer))
|
||||
if (!src_layer || !src_layer->is_image())
|
||||
return false;
|
||||
|
||||
Layer* dst_layer = layer_get_prev(sprite->layer);
|
||||
if (!dst_layer || !layer_is_image(dst_layer))
|
||||
Layer* dst_layer = sprite->layer->get_prev();
|
||||
if (!dst_layer || !dst_layer->is_image())
|
||||
return false;
|
||||
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MergeDownLayerCommand::execute(Context* context)
|
||||
@ -78,7 +78,7 @@ void MergeDownLayerCommand::execute(Context* context)
|
||||
int frpos, index;
|
||||
|
||||
src_layer = sprite->layer;
|
||||
dst_layer = layer_get_prev(sprite->layer);
|
||||
dst_layer = sprite->layer->get_prev();
|
||||
|
||||
if (undo_is_enabled(sprite->undo)) {
|
||||
undo_set_label(sprite->undo, "Merge Down Layer");
|
||||
@ -87,8 +87,8 @@ void MergeDownLayerCommand::execute(Context* context)
|
||||
|
||||
for (frpos=0; frpos<sprite->frames; ++frpos) {
|
||||
/* get frames */
|
||||
src_cel = layer_get_cel(src_layer, frpos);
|
||||
dst_cel = layer_get_cel(dst_layer, frpos);
|
||||
src_cel = static_cast<LayerImage*>(src_layer)->get_cel(frpos);
|
||||
dst_cel = static_cast<LayerImage*>(dst_layer)->get_cel(frpos);
|
||||
|
||||
/* get images */
|
||||
if (src_cel != NULL)
|
||||
@ -122,7 +122,8 @@ void MergeDownLayerCommand::execute(Context* context)
|
||||
|
||||
if (undo_is_enabled(sprite->undo))
|
||||
undo_add_cel(sprite->undo, dst_layer, dst_cel);
|
||||
layer_add_cel(dst_layer, dst_cel);
|
||||
|
||||
static_cast<LayerImage*>(dst_layer)->add_cel(dst_cel);
|
||||
}
|
||||
/* with destination */
|
||||
else {
|
||||
@ -130,7 +131,7 @@ void MergeDownLayerCommand::execute(Context* context)
|
||||
Image *new_image;
|
||||
|
||||
/* merge down in the background layer */
|
||||
if (layer_is_background(dst_layer)) {
|
||||
if (dst_layer->is_background()) {
|
||||
x1 = 0;
|
||||
y1 = 0;
|
||||
x2 = sprite->w;
|
||||
@ -156,7 +157,7 @@ void MergeDownLayerCommand::execute(Context* context)
|
||||
src_cel->x-x1,
|
||||
src_cel->y-y1,
|
||||
src_cel->opacity,
|
||||
src_layer->blend_mode);
|
||||
static_cast<LayerImage*>(src_layer)->get_blend_mode());
|
||||
|
||||
if (undo_is_enabled(sprite->undo)) {
|
||||
undo_int(sprite->undo, (GfxObj *)dst_cel, &dst_cel->x);
|
||||
@ -181,10 +182,9 @@ void MergeDownLayerCommand::execute(Context* context)
|
||||
}
|
||||
|
||||
sprite_set_layer(sprite, dst_layer);
|
||||
layer_remove_layer(src_layer->parent_layer, src_layer);
|
||||
src_layer->get_parent()->remove_layer(src_layer);
|
||||
|
||||
layer_free_images(src_layer);
|
||||
layer_free(src_layer);
|
||||
delete src_layer;
|
||||
|
||||
update_screen_for_sprite(sprite);
|
||||
}
|
||||
|
@ -158,9 +158,10 @@ void NewFileCommand::execute(Context* context)
|
||||
/* if the background color isn't transparent, we have to
|
||||
convert the `Layer 1' in a `Background' */
|
||||
if (color_type(color) != COLOR_TYPE_MASK) {
|
||||
layer_configure_as_background(sprite->layer);
|
||||
image_clear(GetImage(sprite),
|
||||
get_color_for_image(imgtype, color));
|
||||
assert(sprite->layer && sprite->layer->is_image());
|
||||
|
||||
static_cast<LayerImage*>(sprite->layer)->configure_as_background();
|
||||
image_clear(GetImage(sprite), get_color_for_image(imgtype, color));
|
||||
}
|
||||
|
||||
/* show the sprite to the user */
|
||||
|
@ -63,9 +63,9 @@ bool NewFrameCommand::enabled(Context* context)
|
||||
return
|
||||
sprite != NULL &&
|
||||
sprite->layer != NULL &&
|
||||
layer_is_readable(sprite->layer) &&
|
||||
layer_is_writable(sprite->layer) &&
|
||||
layer_is_image(sprite->layer);
|
||||
sprite->layer->is_readable() &&
|
||||
sprite->layer->is_writable() &&
|
||||
sprite->layer->is_image();
|
||||
}
|
||||
|
||||
void NewFrameCommand::execute(Context* context)
|
||||
|
@ -82,7 +82,7 @@ void NewLayerCommand::execute(Context* context)
|
||||
layer = undoable.new_layer();
|
||||
undoable.commit();
|
||||
}
|
||||
layer_set_name(layer, name);
|
||||
layer->set_name(name);
|
||||
update_screen_for_sprite(sprite);
|
||||
}
|
||||
}
|
||||
@ -91,7 +91,7 @@ static char* get_unique_layer_name(Sprite* sprite)
|
||||
{
|
||||
if (sprite != NULL) {
|
||||
char buf[1024];
|
||||
sprintf(buf, "Layer %d", get_max_layer_num(sprite->set)+1);
|
||||
sprintf(buf, "Layer %d", get_max_layer_num(sprite->get_folder())+1);
|
||||
return jstrdup(buf);
|
||||
}
|
||||
else
|
||||
@ -102,13 +102,15 @@ static int get_max_layer_num(Layer* layer)
|
||||
{
|
||||
int max = 0;
|
||||
|
||||
if (strncmp(layer->name, "Layer ", 6) == 0)
|
||||
max = strtol(layer->name+6, NULL, 10);
|
||||
if (strncmp(layer->get_name().c_str(), "Layer ", 6) == 0)
|
||||
max = strtol(layer->get_name().c_str()+6, NULL, 10);
|
||||
|
||||
if (layer_is_set(layer)) {
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->layers, link) {
|
||||
int tmp = get_max_layer_num(reinterpret_cast<Layer*>(link->data));
|
||||
if (layer->is_folder()) {
|
||||
LayerIterator it = static_cast<LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerIterator end = static_cast<LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
int tmp = get_max_layer_num(*it);
|
||||
max = MAX(tmp, max);
|
||||
}
|
||||
}
|
||||
|
@ -66,10 +66,10 @@ void NewLayerSetCommand::execute(Context* context)
|
||||
|
||||
if (jwindow_get_killer(window) == jwidget_find_name(window, "ok")) {
|
||||
const char *name = jwidget_get_text(jwidget_find_name(window, "name"));
|
||||
Layer *layer = layer_set_new(sprite);
|
||||
Layer* layer = new LayerFolder(sprite);
|
||||
|
||||
layer_set_name(layer, name);
|
||||
layer_add_layer(sprite->set, layer);
|
||||
layer->set_name(name);
|
||||
sprite->get_folder()->add_layer(layer);
|
||||
sprite_set_layer(sprite, layer);
|
||||
|
||||
update_screen_for_sprite(sprite);
|
||||
|
@ -51,21 +51,21 @@ bool RemoveCelCommand::enabled(Context* context)
|
||||
{
|
||||
const CurrentSpriteReader sprite(context);
|
||||
return
|
||||
sprite != NULL &&
|
||||
sprite->layer != NULL &&
|
||||
layer_is_readable(sprite->layer) &&
|
||||
layer_is_writable(sprite->layer) &&
|
||||
layer_is_image(sprite->layer) &&
|
||||
layer_get_cel(sprite->layer, sprite->frame);
|
||||
sprite &&
|
||||
sprite->layer &&
|
||||
sprite->layer->is_readable() &&
|
||||
sprite->layer->is_writable() &&
|
||||
sprite->layer->is_image() &&
|
||||
static_cast<LayerImage*>(sprite->layer)->get_cel(sprite->frame);
|
||||
}
|
||||
|
||||
void RemoveCelCommand::execute(Context* context)
|
||||
{
|
||||
CurrentSpriteWriter sprite(context);
|
||||
Cel* cel = layer_get_cel(sprite->layer, sprite->frame);
|
||||
Cel* cel = static_cast<LayerImage*>(sprite->layer)->get_cel(sprite->frame);
|
||||
{
|
||||
Undoable undoable(sprite, "Remove Cel");
|
||||
undoable.remove_cel(sprite->layer, cel);
|
||||
undoable.remove_cel(static_cast<LayerImage*>(sprite->layer), cel);
|
||||
undoable.commit();
|
||||
}
|
||||
update_screen_for_sprite(sprite);
|
||||
|
@ -77,13 +77,12 @@ protected:
|
||||
Undoable undoable(m_sprite, "Rotate Canvas");
|
||||
|
||||
// get all sprite cels
|
||||
JList cels = jlist_new();
|
||||
CelList cels;
|
||||
sprite_get_cels(m_sprite, cels);
|
||||
|
||||
// for each cel...
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(cels, link) {
|
||||
Cel* cel = (Cel*)link->data;
|
||||
for (CelIterator it = cels.begin(); it != cels.end(); ++it) {
|
||||
Cel* cel = *it;
|
||||
Image* image = stock_get_image(m_sprite->stock, cel->image);
|
||||
|
||||
// change it location
|
||||
@ -101,7 +100,6 @@ protected:
|
||||
break;
|
||||
}
|
||||
}
|
||||
jlist_free(cels);
|
||||
|
||||
// for each stock's image
|
||||
for (int i=0; i<m_sprite->stock->nimage; ++i) {
|
||||
|
@ -69,18 +69,16 @@ protected:
|
||||
Undoable undoable(m_sprite, "Sprite Size");
|
||||
|
||||
// get all sprite cels
|
||||
JList cels = jlist_new();
|
||||
CelList cels;
|
||||
sprite_get_cels(m_sprite, cels);
|
||||
|
||||
// for each cel...
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(cels, link) {
|
||||
Cel* cel = (Cel*)link->data;
|
||||
for (CelIterator it = cels.begin(); it != cels.end(); ++it) {
|
||||
Cel* cel = *it;
|
||||
|
||||
// change it location
|
||||
undoable.set_cel_position(cel, scale_x(cel->x), scale_y(cel->y));
|
||||
}
|
||||
jlist_free(cels);
|
||||
|
||||
// for each stock's image
|
||||
for (int i=0; i<m_sprite->stock->nimage; ++i) {
|
||||
|
@ -552,7 +552,7 @@ int app_get_color_to_clear_layer(Layer *layer)
|
||||
color_t color = color_mask();
|
||||
|
||||
/* the `Background' is erased with the `Background Color' */
|
||||
if (layer != NULL && layer_is_background(layer))
|
||||
if (layer != NULL && layer->is_background())
|
||||
color = colorbar_get_bg_color(colorbar);
|
||||
|
||||
return get_color_for_layer(layer, color);
|
||||
|
@ -640,14 +640,14 @@ int get_color_for_layer(Layer *layer, color_t color)
|
||||
{
|
||||
return
|
||||
fixup_color_for_layer(layer,
|
||||
get_color_for_image(layer->sprite->imgtype,
|
||||
get_color_for_image(layer->get_sprite()->imgtype,
|
||||
color));
|
||||
}
|
||||
|
||||
int fixup_color_for_layer(Layer *layer, int color)
|
||||
{
|
||||
if (layer_is_background(layer))
|
||||
return fixup_color_for_background(layer->sprite->imgtype, color);
|
||||
if (layer->is_background())
|
||||
return fixup_color_for_background(layer->get_sprite()->imgtype, color);
|
||||
else
|
||||
return color;
|
||||
}
|
||||
|
@ -580,7 +580,7 @@ static bool anieditor_msg_proc(JWidget widget, JMessage msg)
|
||||
anieditor->hot_layer < anieditor->nlayers &&
|
||||
anieditor->hot_layer != anieditor->clk_layer &&
|
||||
anieditor->hot_layer != anieditor->clk_layer+1) {
|
||||
if (!layer_is_background(anieditor->layers[anieditor->clk_layer])) {
|
||||
if (!anieditor->layers[anieditor->clk_layer]->is_background()) {
|
||||
// move the clicked-layer after the hot-layer
|
||||
try {
|
||||
const SpriteReader sprite((Sprite*)anieditor->sprite);
|
||||
@ -611,9 +611,9 @@ static bool anieditor_msg_proc(JWidget widget, JMessage msg)
|
||||
if (anieditor->hot_layer == anieditor->clk_layer &&
|
||||
anieditor->hot_layer >= 0 &&
|
||||
anieditor->hot_layer < anieditor->nlayers) {
|
||||
Layer *layer = anieditor->layers[anieditor->clk_layer];
|
||||
Layer* layer = anieditor->layers[anieditor->clk_layer];
|
||||
assert(layer != NULL);
|
||||
layer->flags ^= LAYER_IS_READABLE;
|
||||
layer->set_readable(!layer->is_readable());
|
||||
}
|
||||
break;
|
||||
case PART_LAYER_LOCK_ICON:
|
||||
@ -621,9 +621,9 @@ static bool anieditor_msg_proc(JWidget widget, JMessage msg)
|
||||
if (anieditor->hot_layer == anieditor->clk_layer &&
|
||||
anieditor->hot_layer >= 0 &&
|
||||
anieditor->hot_layer < anieditor->nlayers) {
|
||||
Layer *layer = anieditor->layers[anieditor->clk_layer];
|
||||
Layer* layer = anieditor->layers[anieditor->clk_layer];
|
||||
assert(layer != NULL);
|
||||
layer->flags ^= LAYER_IS_WRITABLE;
|
||||
layer->set_writable(!layer->is_writable());
|
||||
}
|
||||
break;
|
||||
case PART_CEL: {
|
||||
@ -843,7 +843,7 @@ static void anieditor_setcursor(JWidget widget, int x, int y)
|
||||
anieditor->clk_part == PART_LAYER &&
|
||||
anieditor->hot_part == PART_LAYER &&
|
||||
anieditor->clk_layer != anieditor->hot_layer) {
|
||||
if (layer_is_background(anieditor->layers[anieditor->clk_layer]))
|
||||
if (anieditor->layers[anieditor->clk_layer]->is_background())
|
||||
jmouse_set_cursor(JI_CURSOR_FORBIDDEN);
|
||||
else
|
||||
jmouse_set_cursor(JI_CURSOR_MOVE);
|
||||
@ -1025,8 +1025,8 @@ static void anieditor_draw_layer(JWidget widget, JRect clip, int layer_index)
|
||||
{
|
||||
AniEditor* anieditor = anieditor_data(widget);
|
||||
Layer *layer = anieditor->layers[layer_index];
|
||||
BITMAP *icon1 = get_gfx(layer_is_readable(layer) ? GFX_BOX_SHOW: GFX_BOX_HIDE);
|
||||
BITMAP *icon2 = get_gfx(layer_is_writable(layer) ? GFX_BOX_UNLOCK: GFX_BOX_LOCK);
|
||||
BITMAP *icon1 = get_gfx(layer->is_readable() ? GFX_BOX_SHOW: GFX_BOX_HIDE);
|
||||
BITMAP *icon2 = get_gfx(layer->is_writable() ? GFX_BOX_UNLOCK: GFX_BOX_LOCK);
|
||||
bool selected_layer = (layer == anieditor->sprite->layer);
|
||||
bool is_hot = (anieditor->hot_part == PART_LAYER && anieditor->hot_layer == layer_index);
|
||||
bool is_clk = (anieditor->clk_part == PART_LAYER && anieditor->clk_layer == layer_index);
|
||||
@ -1102,16 +1102,16 @@ static void anieditor_draw_layer(JWidget widget, JRect clip, int layer_index)
|
||||
u += ICONBORDER+icon2->w+ICONBORDER+ICONSEP;
|
||||
|
||||
/* draw the layer's name */
|
||||
jdraw_text(widget->font(), layer->name,
|
||||
jdraw_text(widget->font(), layer->get_name().c_str(),
|
||||
u, y_mid - ji_font_get_size(widget->font())/2,
|
||||
fg, bg, TRUE);
|
||||
|
||||
/* the background should be underlined */
|
||||
if (layer_is_background(layer)) {
|
||||
if (layer->is_background()) {
|
||||
hline(ji_screen,
|
||||
u,
|
||||
y_mid - ji_font_get_size(widget->font())/2 + ji_font_get_size(widget->font()) + 1,
|
||||
u + text_length(widget->font(), layer->name),
|
||||
u + text_length(widget->font(), layer->get_name().c_str()),
|
||||
fg);
|
||||
}
|
||||
|
||||
@ -1199,7 +1199,7 @@ static void anieditor_draw_cel(JWidget widget, JRect clip, int layer_index, int
|
||||
hline(ji_screen, x1, y2, x2, ji_color_foreground());
|
||||
|
||||
/* get the cel of this layer in this frame */
|
||||
cel = layer_get_cel(layer, frame);
|
||||
cel = layer->is_image() ? static_cast<LayerImage*>(layer)->get_cel(frame): NULL;
|
||||
|
||||
/* empty cel? */
|
||||
if (cel == NULL ||
|
||||
|
@ -142,7 +142,7 @@ void effect_set_target(Effect *effect, int target)
|
||||
|
||||
/* the alpha channel of the background layer can't be modified */
|
||||
if (effect->sprite->layer &&
|
||||
layer_is_background(effect->sprite->layer))
|
||||
effect->sprite->layer->is_background())
|
||||
effect->target &= ~TARGET_ALPHA_CHANNEL;
|
||||
}
|
||||
|
||||
@ -382,7 +382,7 @@ static void effect_init(Effect *effect, Layer *layer, Image *image,
|
||||
effect->target = effect->_target;
|
||||
|
||||
/* the alpha channel of the background layer can't be modified */
|
||||
if (layer_is_background(layer))
|
||||
if (layer->is_background())
|
||||
effect->target &= ~TARGET_ALPHA_CHANNEL;
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ static ImageRef* images_ref_get_from_layer(Sprite* sprite, Layer* layer, int tar
|
||||
|
||||
ImageRef* images_ref_get_from_sprite(Sprite* sprite, int target, bool write)
|
||||
{
|
||||
Layer* layer = target & TARGET_ALL_LAYERS ? sprite->set:
|
||||
Layer* layer = target & TARGET_ALL_LAYERS ? sprite->get_folder():
|
||||
sprite->layer;
|
||||
|
||||
return images_ref_get_from_layer(sprite, layer, target, write);
|
||||
@ -72,7 +72,7 @@ static ImageRef* images_ref_get_from_layer(Sprite* sprite, Layer* layer, int tar
|
||||
{ \
|
||||
ImageRef* image_ref = jnew(ImageRef, 1); \
|
||||
\
|
||||
image_ref->image = layer->sprite->stock->image[cel->image]; \
|
||||
image_ref->image = layer->get_sprite()->stock->image[cel->image]; \
|
||||
image_ref->layer = layer; \
|
||||
image_ref->cel = cel; \
|
||||
image_ref->next = NULL; \
|
||||
@ -84,10 +84,10 @@ static ImageRef* images_ref_get_from_layer(Sprite* sprite, Layer* layer, int tar
|
||||
ImageRef* last_image = NULL;
|
||||
int frame = sprite->frame;
|
||||
|
||||
if (!layer_is_readable(layer))
|
||||
if (!layer->is_readable())
|
||||
return NULL;
|
||||
|
||||
if (write && !layer_is_writable(layer))
|
||||
if (write && !layer->is_writable())
|
||||
return NULL;
|
||||
|
||||
switch (layer->type) {
|
||||
@ -95,27 +95,26 @@ static ImageRef* images_ref_get_from_layer(Sprite* sprite, Layer* layer, int tar
|
||||
case GFXOBJ_LAYER_IMAGE: {
|
||||
if (target & TARGET_ALL_FRAMES) {
|
||||
for (frame=0; frame<sprite->frames; frame++) {
|
||||
Cel* cel = layer_get_cel(layer, frame);
|
||||
Cel* cel = static_cast<LayerImage*>(layer)->get_cel(frame);
|
||||
if (cel != NULL)
|
||||
NEW_IMAGE(layer, cel);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Cel* cel = layer_get_cel(layer, frame);
|
||||
Cel* cel = static_cast<LayerImage*>(layer)->get_cel(frame);
|
||||
if (cel != NULL)
|
||||
NEW_IMAGE(layer, cel);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GFXOBJ_LAYER_SET: {
|
||||
case GFXOBJ_LAYER_FOLDER: {
|
||||
ImageRef* sub_images;
|
||||
JLink link;
|
||||
|
||||
JI_LIST_FOR_EACH(layer->layers, link) {
|
||||
sub_images = images_ref_get_from_layer
|
||||
(sprite, reinterpret_cast<Layer*>(link->data), target, write);
|
||||
LayerIterator it = static_cast<LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerIterator end = static_cast<LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
sub_images = images_ref_get_from_layer(sprite, *it, target, write);
|
||||
if (sub_images != NULL)
|
||||
ADD_IMAGES(sub_images);
|
||||
}
|
||||
|
@ -85,8 +85,8 @@ static void ase_file_write_cels(FILE *f, Sprite *sprite, Layer *layer, int frame
|
||||
|
||||
static void ase_file_read_padding(FILE *f, int bytes);
|
||||
static void ase_file_write_padding(FILE *f, int bytes);
|
||||
static char *ase_file_read_string(FILE *f);
|
||||
static void ase_file_write_string(FILE *f, const char *string);
|
||||
static std::string ase_file_read_string(FILE *f);
|
||||
static void ase_file_write_string(FILE *f, const std::string& string);
|
||||
|
||||
static void ase_file_write_start_chunk(FILE *f, int type);
|
||||
static void ase_file_write_close_chunk(FILE *f);
|
||||
@ -97,7 +97,7 @@ static void ase_file_write_color2_chunk(FILE *f, Palette *pal);
|
||||
static Layer *ase_file_read_layer_chunk(FILE *f, Sprite *sprite, Layer **previous_layer, int *current_level);
|
||||
static void ase_file_write_layer_chunk(FILE *f, Layer *layer);
|
||||
static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frame, int imgtype, FileOp *fop, ASE_Header *header);
|
||||
static void ase_file_write_cel_chunk(FILE *f, Cel *cel, Layer *layer, Sprite *sprite);
|
||||
static void ase_file_write_cel_chunk(FILE *f, Cel *cel, LayerImage *layer, Sprite *sprite);
|
||||
static Mask *ase_file_read_mask_chunk(FILE *f);
|
||||
static void ase_file_write_mask_chunk(FILE *f, Mask *mask);
|
||||
|
||||
@ -125,7 +125,6 @@ static bool load_ASE(FileOp *fop)
|
||||
Sprite *sprite = NULL;
|
||||
ASE_Header header;
|
||||
ASE_FrameHeader frame_header;
|
||||
Layer *last_layer;
|
||||
int current_level;
|
||||
int frame_pos;
|
||||
int chunk_pos;
|
||||
@ -159,7 +158,7 @@ static bool load_ASE(FileOp *fop)
|
||||
sprite_set_speed(sprite, header.speed);
|
||||
|
||||
/* prepare variables for layer chunks */
|
||||
last_layer = sprite->set;
|
||||
Layer* last_layer = sprite->get_folder();
|
||||
current_level = -1;
|
||||
|
||||
/* read frame by frame to end-of-file */
|
||||
@ -315,9 +314,12 @@ static bool save_ASE(FileOp *fop)
|
||||
|
||||
/* write extra chunks in the first frame */
|
||||
if (frame == 0) {
|
||||
LayerIterator it = sprite->get_folder()->get_layer_begin();
|
||||
LayerIterator end = sprite->get_folder()->get_layer_end();
|
||||
|
||||
/* write layer chunks */
|
||||
JI_LIST_FOR_EACH(sprite->set->layers, link)
|
||||
ase_file_write_layers(f, reinterpret_cast<Layer*>(link->data));
|
||||
for (; it != end; ++it)
|
||||
ase_file_write_layers(f, *it);
|
||||
|
||||
/* write masks */
|
||||
JI_LIST_FOR_EACH(sprite->repository.masks, link)
|
||||
@ -325,7 +327,7 @@ static bool save_ASE(FileOp *fop)
|
||||
}
|
||||
|
||||
/* write cel chunks */
|
||||
ase_file_write_cels(f, sprite, sprite->set, frame);
|
||||
ase_file_write_cels(f, sprite, sprite->get_folder(), frame);
|
||||
|
||||
/* write the frame header */
|
||||
ase_file_write_frame_header(f, &frame_header);
|
||||
@ -460,77 +462,69 @@ static void ase_file_write_layers(FILE *f, Layer *layer)
|
||||
{
|
||||
ase_file_write_layer_chunk(f, layer);
|
||||
|
||||
if (layer_is_set(layer)) {
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->layers, link)
|
||||
ase_file_write_layers(f, reinterpret_cast<Layer*>(link->data));
|
||||
if (layer->is_folder()) {
|
||||
LayerIterator it = static_cast<LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerIterator end = static_cast<LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
ase_file_write_layers(f, *it);
|
||||
}
|
||||
}
|
||||
|
||||
static void ase_file_write_cels(FILE *f, Sprite *sprite, Layer *layer, int frame)
|
||||
{
|
||||
if (layer_is_image(layer)) {
|
||||
Cel *cel = layer_get_cel(layer, frame);
|
||||
|
||||
if (layer->is_image()) {
|
||||
Cel* cel = static_cast<LayerImage*>(layer)->get_cel(frame);
|
||||
if (cel) {
|
||||
/* fop_error(fop, "New cel in frame %d, in layer %d\n", */
|
||||
/* frame, sprite_layer2index(sprite, layer)); */
|
||||
|
||||
ase_file_write_cel_chunk(f, cel, layer, sprite);
|
||||
ase_file_write_cel_chunk(f, cel, static_cast<LayerImage*>(layer), sprite);
|
||||
}
|
||||
}
|
||||
|
||||
if (layer_is_set(layer)) {
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->layers, link)
|
||||
ase_file_write_cels(f, sprite, reinterpret_cast<Layer*>(link->data), frame);
|
||||
if (layer->is_folder()) {
|
||||
LayerIterator it = static_cast<LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerIterator end = static_cast<LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
ase_file_write_cels(f, sprite, *it, frame);
|
||||
}
|
||||
}
|
||||
|
||||
static void ase_file_read_padding(FILE *f, int bytes)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c=0; c<bytes; c++)
|
||||
for (int c=0; c<bytes; c++)
|
||||
fgetc(f);
|
||||
}
|
||||
|
||||
static void ase_file_write_padding(FILE *f, int bytes)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c=0; c<bytes; c++)
|
||||
for (int c=0; c<bytes; c++)
|
||||
fputc(0, f);
|
||||
}
|
||||
|
||||
static char *ase_file_read_string(FILE *f)
|
||||
static std::string ase_file_read_string(FILE *f)
|
||||
{
|
||||
char *string;
|
||||
int c, length;
|
||||
|
||||
length = fgetw(f);
|
||||
int length = fgetw(f);
|
||||
if (length == EOF)
|
||||
return NULL;
|
||||
return "";
|
||||
|
||||
string = (char*)jmalloc(length+1);
|
||||
if (!string)
|
||||
return NULL;
|
||||
std::string string;
|
||||
string.reserve(length+1);
|
||||
|
||||
for (c=0; c<length; c++)
|
||||
string[c] = fgetc(f);
|
||||
string[c] = 0;
|
||||
for (int c=0; c<length; c++)
|
||||
string.push_back(fgetc(f));
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
static void ase_file_write_string(FILE *f, const char *string)
|
||||
static void ase_file_write_string(FILE *f, const std::string& string)
|
||||
{
|
||||
const char *p;
|
||||
fputw(string.size(), f);
|
||||
|
||||
fputw(strlen(string), f);
|
||||
|
||||
for (p=string; *p; p++)
|
||||
fputc(*p, f);
|
||||
for (size_t c=0; c<string.size(); ++c)
|
||||
fputc(string[c], f);
|
||||
}
|
||||
|
||||
static void ase_file_write_start_chunk(FILE *f, int type)
|
||||
@ -632,7 +626,7 @@ static void ase_file_write_color2_chunk(FILE *f, Palette *pal)
|
||||
|
||||
static Layer *ase_file_read_layer_chunk(FILE *f, Sprite *sprite, Layer **previous_layer, int *current_level)
|
||||
{
|
||||
char *name;
|
||||
std::string name;
|
||||
Layer *layer = NULL;
|
||||
/* read chunk data */
|
||||
int flags;
|
||||
@ -652,33 +646,28 @@ static Layer *ase_file_read_layer_chunk(FILE *f, Sprite *sprite, Layer **previou
|
||||
|
||||
/* image layer */
|
||||
if (layer_type == 0) {
|
||||
layer = layer_new(sprite);
|
||||
if (layer)
|
||||
layer_set_blend_mode(layer, blend_mode);
|
||||
layer = new LayerImage(sprite);
|
||||
static_cast<LayerImage*>(layer)->set_blend_mode(blend_mode);
|
||||
}
|
||||
/* layer set */
|
||||
else if (layer_type == 1) {
|
||||
layer = layer_set_new(sprite);
|
||||
layer = new LayerFolder(sprite);
|
||||
}
|
||||
|
||||
if (layer) {
|
||||
/* flags */
|
||||
layer->flags = flags;
|
||||
// flags
|
||||
*layer->flags_addr() = flags;
|
||||
|
||||
/* name */
|
||||
if (name) {
|
||||
layer_set_name(layer, name);
|
||||
jfree(name);
|
||||
}
|
||||
|
||||
/* child level... */
|
||||
// name
|
||||
layer->set_name(name.c_str());
|
||||
|
||||
// child level...
|
||||
if (child_level == *current_level)
|
||||
layer_add_layer((*previous_layer)->parent_layer, layer);
|
||||
(*previous_layer)->get_parent()->add_layer(layer);
|
||||
else if (child_level > *current_level)
|
||||
layer_add_layer((*previous_layer), layer);
|
||||
static_cast<LayerFolder*>(*previous_layer)->add_layer(layer);
|
||||
else if (child_level < *current_level)
|
||||
layer_add_layer((*previous_layer)->parent_layer->parent_layer, layer);
|
||||
(*previous_layer)->get_parent()->get_parent()->add_layer(layer);
|
||||
|
||||
*previous_layer = layer;
|
||||
*current_level = child_level;
|
||||
@ -689,37 +678,33 @@ static Layer *ase_file_read_layer_chunk(FILE *f, Sprite *sprite, Layer **previou
|
||||
|
||||
static void ase_file_write_layer_chunk(FILE *f, Layer *layer)
|
||||
{
|
||||
Layer *parent;
|
||||
int child_level;
|
||||
|
||||
ase_file_write_start_chunk(f, ASE_FILE_CHUNK_LAYER);
|
||||
|
||||
/* flags */
|
||||
fputw(layer->flags, f);
|
||||
fputw(*layer->flags_addr(), f);
|
||||
|
||||
/* layer type */
|
||||
fputw(layer_is_image(layer) ? 0:
|
||||
layer_is_set(layer) ? 1: -1, f);
|
||||
fputw(layer->is_image() ? 0: (layer->is_folder() ? 1: -1), f);
|
||||
|
||||
/* layer child level */
|
||||
child_level = -1;
|
||||
parent = layer->parent_layer;
|
||||
LayerFolder* parent = layer->get_parent();
|
||||
int child_level = -1;
|
||||
while (parent != NULL) {
|
||||
child_level++;
|
||||
parent = parent->parent_layer;
|
||||
parent = parent->get_parent();
|
||||
}
|
||||
fputw(child_level, f);
|
||||
|
||||
/* width, height and blend mode */
|
||||
fputw(0, f);
|
||||
fputw(0, f);
|
||||
fputw(layer_is_image(layer) ? layer->blend_mode: 0, f);
|
||||
fputw(layer->is_image() ? static_cast<LayerImage*>(layer)->get_blend_mode(): 0, f);
|
||||
|
||||
/* padding */
|
||||
ase_file_write_padding(f, 4);
|
||||
|
||||
/* layer name */
|
||||
ase_file_write_string(f, layer->name);
|
||||
ase_file_write_string(f, layer->get_name());
|
||||
|
||||
ase_file_write_close_chunk(f);
|
||||
|
||||
@ -735,7 +720,7 @@ static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frame, int imgt
|
||||
int y = ((short)fgetw(f));
|
||||
int opacity = fgetc(f);
|
||||
int cel_type = fgetw(f);
|
||||
Layer *layer;
|
||||
Layer* layer;
|
||||
|
||||
ase_file_read_padding(f, 7);
|
||||
|
||||
@ -745,6 +730,11 @@ static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frame, int imgt
|
||||
frame, layer_index);
|
||||
return NULL;
|
||||
}
|
||||
if (!layer->is_image()) {
|
||||
fop_error(fop, _("Invalid ASE file (frame %d in layer %d which does not contain images\n"),
|
||||
frame, layer_index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create the new frame */
|
||||
cel = cel_new(frame, 0);
|
||||
@ -813,31 +803,31 @@ static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frame, int imgt
|
||||
case ASE_FILE_LINK_CEL: {
|
||||
/* read link position */
|
||||
int link_frame = fgetw(f);
|
||||
Cel *link = layer_get_cel(layer, link_frame);
|
||||
Cel* link = static_cast<LayerImage*>(layer)->get_cel(link_frame);
|
||||
|
||||
if (link) {
|
||||
/* create a copy of the linked cel (avoid using links cel) */
|
||||
Image *image = image_new_copy(stock_get_image(sprite->stock, link->image));
|
||||
// create a copy of the linked cel (avoid using links cel)
|
||||
Image* image = image_new_copy(stock_get_image(sprite->stock, link->image));
|
||||
cel->image = stock_add_image(sprite->stock, image);
|
||||
}
|
||||
else {
|
||||
cel_free(cel);
|
||||
/* linked cel doesn't found */
|
||||
// linked cel doesn't found
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ASE_FILE_RLE_COMPRESSED_CEL:
|
||||
/* TODO */
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
|
||||
layer_add_cel(layer, cel);
|
||||
static_cast<LayerImage*>(layer)->add_cel(cel);
|
||||
return cel;
|
||||
}
|
||||
|
||||
static void ase_file_write_cel_chunk(FILE *f, Cel *cel, Layer *layer, Sprite *sprite)
|
||||
static void ase_file_write_cel_chunk(FILE *f, Cel *cel, LayerImage *layer, Sprite *sprite)
|
||||
{
|
||||
int layer_index = sprite_layer2index(sprite, layer);
|
||||
Cel *link = cel_is_link(cel, layer);
|
||||
@ -926,19 +916,15 @@ static Mask *ase_file_read_mask_chunk(FILE *f)
|
||||
int y = fgetw(f);
|
||||
int w = fgetw(f);
|
||||
int h = fgetw(f);
|
||||
char *name;
|
||||
|
||||
ase_file_read_padding(f, 8);
|
||||
name = ase_file_read_string(f);
|
||||
std::string name = ase_file_read_string(f);
|
||||
|
||||
mask = mask_new();
|
||||
if (!mask)
|
||||
return NULL;
|
||||
|
||||
if (name) {
|
||||
mask_set_name(mask, name);
|
||||
jfree(name);
|
||||
}
|
||||
|
||||
mask_set_name(mask, name.c_str());
|
||||
mask_replace(mask, x, y, w, h);
|
||||
|
||||
/* read image data */
|
||||
|
@ -306,15 +306,15 @@ FileOp *fop_to_save_sprite(Sprite *sprite)
|
||||
break;
|
||||
}
|
||||
|
||||
/* check frames support */
|
||||
// check frames support
|
||||
if (!(fop->format->flags & (FILE_SUPPORT_FRAMES |
|
||||
FILE_SUPPORT_SEQUENCES))) {
|
||||
if (fop->sprite->frames > 1)
|
||||
usprintf(buf+ustrlen(buf), "<<- %s", _("Frames"));
|
||||
}
|
||||
|
||||
/* layers support */
|
||||
if (jlist_length(fop->sprite->set->layers) > 1) {
|
||||
// layers support
|
||||
if (fop->sprite->get_folder()->get_layers_count() > 1) {
|
||||
if (!(fop->format->flags & FILE_SUPPORT_LAYERS)) {
|
||||
usprintf(buf+ustrlen(buf), "<<- %s", _("Layers"));
|
||||
}
|
||||
@ -470,8 +470,7 @@ void fop_operate(FileOp *fop)
|
||||
fop->seq.image); \
|
||||
\
|
||||
fop->seq.last_cel->image = image_index; \
|
||||
\
|
||||
layer_add_cel(fop->seq.layer, fop->seq.last_cel); \
|
||||
fop->seq.layer->add_cel(fop->seq.last_cel); \
|
||||
\
|
||||
if (palette_count_diff(sprite_get_palette(fop->sprite, frame), \
|
||||
fop->seq.palette, NULL, NULL) > 0) { \
|
||||
@ -561,7 +560,7 @@ void fop_operate(FileOp *fop)
|
||||
if (fop->sprite != NULL) {
|
||||
/* configure the layer as the `Background' */
|
||||
if (!fop->seq.has_alpha)
|
||||
layer_configure_as_background(fop->seq.layer);
|
||||
fop->seq.layer->configure_as_background();
|
||||
|
||||
/* set the frames range */
|
||||
sprite_set_frames(fop->sprite, frame);
|
||||
@ -581,8 +580,10 @@ void fop_operate(FileOp *fop)
|
||||
|
||||
if (fop->sprite != NULL) {
|
||||
/* select the last layer */
|
||||
Layer* last_layer = reinterpret_cast<Layer*>(jlist_last_data(fop->sprite->set->layers));
|
||||
sprite_set_layer(fop->sprite, last_layer);
|
||||
if (fop->sprite->get_folder()->get_layers_count() > 0) {
|
||||
LayerIterator last_layer = --fop->sprite->get_folder()->get_layer_end();
|
||||
sprite_set_layer(fop->sprite, *last_layer);
|
||||
}
|
||||
|
||||
/* set the filename */
|
||||
if (fop->seq.filename_list)
|
||||
@ -736,28 +737,25 @@ void fop_sequence_get_color(FileOp *fop, int index, int *r, int *g, int *b)
|
||||
|
||||
Image *fop_sequence_image(FileOp *fop, int imgtype, int w, int h)
|
||||
{
|
||||
Sprite *sprite;
|
||||
Image *image;
|
||||
Layer *layer;
|
||||
Sprite* sprite;
|
||||
|
||||
/* create the image */
|
||||
if (!fop->sprite) {
|
||||
sprite = sprite_new(imgtype, w, h);
|
||||
if (!sprite)
|
||||
return NULL;
|
||||
try {
|
||||
LayerImage* layer = new LayerImage(sprite);
|
||||
|
||||
layer = layer_new(sprite);
|
||||
if (!layer) {
|
||||
delete sprite;
|
||||
return NULL;
|
||||
/* add the layer */
|
||||
sprite->get_folder()->add_layer(layer);
|
||||
|
||||
/* done */
|
||||
fop->sprite = sprite;
|
||||
fop->seq.layer = layer;
|
||||
}
|
||||
catch (...) {
|
||||
delete sprite;
|
||||
throw;
|
||||
}
|
||||
|
||||
/* add the layer */
|
||||
layer_add_layer(sprite->set, layer);
|
||||
|
||||
/* done */
|
||||
fop->sprite = sprite;
|
||||
fop->seq.layer = layer;
|
||||
}
|
||||
else {
|
||||
sprite = fop->sprite;
|
||||
@ -773,7 +771,7 @@ Image *fop_sequence_image(FileOp *fop, int imgtype, int w, int h)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image = image_new(imgtype, w, h);
|
||||
Image* image = image_new(imgtype, w, h);
|
||||
if (!image) {
|
||||
fop_error(fop, _("Not enough memory to allocate a bitmap.\n"));
|
||||
return NULL;
|
||||
|
@ -42,6 +42,7 @@
|
||||
class Cel;
|
||||
class Image;
|
||||
class Layer;
|
||||
class LayerImage;
|
||||
class Palette;
|
||||
class Sprite;
|
||||
|
||||
@ -98,7 +99,7 @@ struct FileOp
|
||||
/* to load sequences */
|
||||
int frame;
|
||||
bool has_alpha;
|
||||
Layer* layer;
|
||||
LayerImage* layer;
|
||||
Cel* last_cel;
|
||||
FormatOptions* format_options;
|
||||
} seq;
|
||||
|
@ -62,7 +62,7 @@ static bool load_FLI(FileOp *fop)
|
||||
s_fli_header fli_header;
|
||||
Image *bmp, *old, *image;
|
||||
Sprite *sprite;
|
||||
Layer *layer;
|
||||
LayerImage *layer;
|
||||
Palette *pal;
|
||||
int c, w, h;
|
||||
int frpos_in;
|
||||
@ -104,9 +104,9 @@ static bool load_FLI(FileOp *fop)
|
||||
|
||||
/* create the image */
|
||||
sprite = sprite_new(IMAGE_INDEXED, w, h);
|
||||
layer = layer_new(sprite);
|
||||
layer_add_layer(sprite->set, layer);
|
||||
layer_configure_as_background(layer);
|
||||
layer = new LayerImage(sprite);
|
||||
sprite->get_folder()->add_layer(layer);
|
||||
layer->configure_as_background();
|
||||
|
||||
/* set frames and speed */
|
||||
sprite_set_frames(sprite, fli_header.frames);
|
||||
@ -151,7 +151,7 @@ static bool load_FLI(FileOp *fop)
|
||||
fop_error(fop, _("Not enough memory\n"));
|
||||
break;
|
||||
}
|
||||
layer_add_cel(layer, cel);
|
||||
layer->add_cel(cel);
|
||||
|
||||
/* first frame or the palette changes */
|
||||
if ((frpos_in == 0) || (memcmp(omap, cmap, 768) != 0))
|
||||
@ -272,7 +272,7 @@ static bool save_FLI(FileOp *fop)
|
||||
|
||||
/* render the frame in the bitmap */
|
||||
image_clear(bmp, 0);
|
||||
layer_render(sprite->set, bmp, 0, 0, frpos);
|
||||
layer_render(sprite->get_folder(), bmp, 0, 0, frpos);
|
||||
|
||||
/* how many times this frame should be written to get the same
|
||||
time that it has in the sprite */
|
||||
|
@ -77,7 +77,7 @@ static bool load_GIF(FileOp *fop)
|
||||
{
|
||||
GIF_ANIMATION *gif = NULL;
|
||||
Sprite *sprite = NULL;
|
||||
Layer *layer = NULL;
|
||||
LayerImage *layer = NULL;
|
||||
Cel *cel = NULL;
|
||||
Image *image = NULL;
|
||||
Image *current_image_old = NULL;
|
||||
@ -111,14 +111,14 @@ static bool load_GIF(FileOp *fop)
|
||||
|
||||
sprite_set_frames(sprite, gif->frames_count);
|
||||
|
||||
layer = layer_new(sprite);
|
||||
layer = new LayerImage(sprite);
|
||||
if (!layer) {
|
||||
fop_error(fop, _("Error creating main layer.\n"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
layer_add_layer(sprite->set, layer);
|
||||
layer_configure_as_background(layer);
|
||||
sprite->get_folder()->add_layer(layer);
|
||||
layer->configure_as_background();
|
||||
|
||||
image_clear(current_image, gif->background_index);
|
||||
image_clear(current_image_old, gif->background_index);
|
||||
@ -196,7 +196,7 @@ static bool load_GIF(FileOp *fop)
|
||||
#endif
|
||||
);
|
||||
cel->image = stock_add_image(sprite->stock, image);
|
||||
layer_add_cel(layer, cel);
|
||||
layer->add_cel(cel);
|
||||
|
||||
#ifdef LOAD_GIF_STRUCTURE
|
||||
/* when load the GIF structure, the disposal method is ever
|
||||
@ -330,7 +330,7 @@ static bool save_GIF(FileOp *fop)
|
||||
|
||||
/* render the frame in the bitmap */
|
||||
image_clear(bmp, 0);
|
||||
layer_render(sprite->set, bmp, 0, 0, i);
|
||||
layer_render(sprite->get_folder(), bmp, 0, 0, i);
|
||||
|
||||
/* first frame */
|
||||
if (i == 0) {
|
||||
|
@ -94,7 +94,7 @@ static bool save_ICO(FileOp *fop)
|
||||
|
||||
for (n=0; n<num; ++n) {
|
||||
image_clear(bmp, 0);
|
||||
layer_render(fop->sprite->set, bmp, 0, 0, n);
|
||||
layer_render(fop->sprite->get_folder(), bmp, 0, 0, n);
|
||||
|
||||
depth = 8; /* bitmap_color_depth(bmp); */
|
||||
bpp = (depth == 8) ? 8 : 24;
|
||||
|
@ -850,7 +850,7 @@ void control_tool(JWidget widget, Tool *tool,
|
||||
jwidget_flush_redraw(jwidget_get_manager(widget));
|
||||
|
||||
/* error, the active layer is not visible */
|
||||
if (!layer_is_readable(sprite->layer)) {
|
||||
if (!sprite->layer->is_readable()) {
|
||||
jalert(_(PACKAGE
|
||||
"<<The current layer is hidden,"
|
||||
"<<make it visible and try again"
|
||||
@ -858,7 +858,7 @@ void control_tool(JWidget widget, Tool *tool,
|
||||
return;
|
||||
}
|
||||
/* error, the active layer is locked */
|
||||
else if (!layer_is_writable(sprite->layer)) {
|
||||
else if (!sprite->layer->is_writable()) {
|
||||
jalert(_(PACKAGE
|
||||
"<<The current layer is locked,"
|
||||
"<<unlock it and try again"
|
||||
@ -871,9 +871,8 @@ void control_tool(JWidget widget, Tool *tool,
|
||||
|
||||
if (sprite != NULL &&
|
||||
sprite->layer != NULL &&
|
||||
layer_is_image(sprite->layer)) {
|
||||
cel = layer_get_cel(sprite->layer,
|
||||
sprite->frame);
|
||||
sprite->layer->is_image()) {
|
||||
cel = ((LayerImage*)sprite->layer)->get_cel(sprite->frame);
|
||||
if (cel != NULL)
|
||||
cel_image = sprite->stock->image[cel->image];
|
||||
}
|
||||
@ -885,7 +884,7 @@ void control_tool(JWidget widget, Tool *tool,
|
||||
|
||||
/* create the cel */
|
||||
cel = cel_new(sprite->frame, 0);
|
||||
layer_add_cel(sprite->layer, cel);
|
||||
((LayerImage*)sprite->layer)->add_cel(cel);
|
||||
|
||||
cel_created = TRUE;
|
||||
}
|
||||
@ -1482,7 +1481,7 @@ next_pts:;
|
||||
/* is the undo enabled? */
|
||||
if (undo_is_enabled(sprite->undo)) {
|
||||
/* we can temporary remove the cel */
|
||||
layer_remove_cel(sprite->layer, cel);
|
||||
static_cast<LayerImage*>(sprite->layer)->remove_cel(cel);
|
||||
|
||||
/* we create the undo information (for the new cel_image
|
||||
in the stock and the new cel in the layer)... */
|
||||
@ -1492,7 +1491,7 @@ next_pts:;
|
||||
undo_close(sprite->undo);
|
||||
|
||||
/* and finally we add the cel again in the layer */
|
||||
layer_add_cel(sprite->layer, cel);
|
||||
static_cast<LayerImage*>(sprite->layer)->add_cel(cel);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -1557,7 +1556,7 @@ next_pts:;
|
||||
cel->y = old_cel_y;
|
||||
|
||||
if (cel_created) {
|
||||
layer_remove_cel(sprite->layer, cel);
|
||||
static_cast<LayerImage*>(sprite->layer)->remove_cel(cel);
|
||||
cel_free(cel);
|
||||
image_free(cel_image);
|
||||
}
|
||||
|
@ -69,13 +69,13 @@ void cel_free(Cel* cel)
|
||||
delete cel;
|
||||
}
|
||||
|
||||
Cel* cel_is_link(Cel* cel, Layer *layer)
|
||||
Cel* cel_is_link(Cel* cel, LayerImage* layer)
|
||||
{
|
||||
Cel* link;
|
||||
int frame;
|
||||
|
||||
for (frame=0; frame<cel->frame; frame++) {
|
||||
link = layer_get_cel(layer, frame);
|
||||
link = layer->get_cel(frame);
|
||||
if (link && link->image == cel->image)
|
||||
return link;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#include "raster/gfxobj.h"
|
||||
|
||||
class Layer;
|
||||
class LayerImage;
|
||||
|
||||
class Cel : public GfxObj
|
||||
{
|
||||
@ -40,7 +40,7 @@ Cel* cel_new(int frame, int image);
|
||||
Cel* cel_new_copy(const Cel* cel);
|
||||
void cel_free(Cel* cel);
|
||||
|
||||
Cel* cel_is_link(Cel* cel, Layer* layer);
|
||||
Cel* cel_is_link(Cel* cel, LayerImage* layer);
|
||||
|
||||
void cel_set_frame(Cel* cel, int frame);
|
||||
void cel_set_image(Cel* cel, int image);
|
||||
|
@ -20,12 +20,13 @@
|
||||
#define RASTER_GFXOBJ_H_INCLUDED
|
||||
|
||||
#include "jinete/jbase.h"
|
||||
#include <list>
|
||||
|
||||
enum {
|
||||
GFXOBJ_CEL,
|
||||
GFXOBJ_IMAGE,
|
||||
GFXOBJ_LAYER_IMAGE,
|
||||
GFXOBJ_LAYER_SET,
|
||||
GFXOBJ_LAYER_FOLDER,
|
||||
GFXOBJ_MASK,
|
||||
GFXOBJ_PALETTE,
|
||||
GFXOBJ_PATH,
|
||||
@ -36,6 +37,17 @@ enum {
|
||||
|
||||
typedef unsigned int gfxobj_id;
|
||||
|
||||
class Cel;
|
||||
class Layer;
|
||||
|
||||
typedef std::list<Cel*> CelList;
|
||||
typedef std::list<Cel*>::iterator CelIterator;
|
||||
typedef std::list<Cel*>::const_iterator CelConstIterator;
|
||||
|
||||
typedef std::list<Layer*> LayerList;
|
||||
typedef std::list<Layer*>::iterator LayerIterator;
|
||||
typedef std::list<Layer*>::const_iterator LayerConstIterator;
|
||||
|
||||
class GfxObj
|
||||
{
|
||||
public:
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <allegro/unicode.h>
|
||||
@ -33,162 +34,330 @@
|
||||
#include "raster/undo.h"
|
||||
|
||||
static bool has_cels(const Layer* layer, int frame);
|
||||
static void layer_set_parent(Layer* layer, Layer* parent_set);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Layer class
|
||||
|
||||
Layer::Layer(int type, Sprite* sprite)
|
||||
: GfxObj(type)
|
||||
{
|
||||
assert(type == GFXOBJ_LAYER_IMAGE || type == GFXOBJ_LAYER_SET);
|
||||
assert(type == GFXOBJ_LAYER_IMAGE || type == GFXOBJ_LAYER_FOLDER);
|
||||
|
||||
layer_set_name(this, "");
|
||||
set_name("Layer");
|
||||
|
||||
this->sprite = sprite;
|
||||
this->parent_layer = NULL;
|
||||
this->flags =
|
||||
m_sprite = sprite;
|
||||
m_parent = NULL;
|
||||
m_flags =
|
||||
LAYER_IS_READABLE |
|
||||
LAYER_IS_WRITABLE;
|
||||
|
||||
this->blend_mode = 0;
|
||||
this->cels = NULL;
|
||||
}
|
||||
|
||||
this->layers = NULL;
|
||||
Layer::Layer(Layer* src_layer, Sprite* dst_sprite)
|
||||
: GfxObj(src_layer->type)
|
||||
{
|
||||
m_sprite = dst_sprite;
|
||||
m_parent = NULL;
|
||||
m_flags =
|
||||
LAYER_IS_READABLE |
|
||||
LAYER_IS_WRITABLE;
|
||||
|
||||
set_name(src_layer->get_name());
|
||||
m_flags = src_layer->m_flags;
|
||||
}
|
||||
|
||||
Layer::~Layer()
|
||||
{
|
||||
switch (this->type) {
|
||||
}
|
||||
|
||||
case GFXOBJ_LAYER_IMAGE: {
|
||||
JLink link;
|
||||
/**
|
||||
* Gets the previous layer of "layer" that are in the parent set.
|
||||
*/
|
||||
Layer* Layer::get_prev() const
|
||||
{
|
||||
if (m_parent != NULL) {
|
||||
LayerConstIterator it =
|
||||
std::find(m_parent->get_layer_begin(),
|
||||
m_parent->get_layer_end(), this);
|
||||
|
||||
/* remove cels */
|
||||
JI_LIST_FOR_EACH(this->cels, link)
|
||||
cel_free(reinterpret_cast<Cel*>(link->data));
|
||||
|
||||
jlist_free(this->cels);
|
||||
break;
|
||||
}
|
||||
|
||||
case GFXOBJ_LAYER_SET: {
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(this->layers, link)
|
||||
layer_free(reinterpret_cast<Layer*>(link->data));
|
||||
jlist_free(this->layers);
|
||||
break;
|
||||
if (it != m_parent->get_layer_end() &&
|
||||
it != m_parent->get_layer_begin()) {
|
||||
it--;
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Layer* Layer::get_next() const
|
||||
{
|
||||
if (m_parent != NULL) {
|
||||
LayerConstIterator it =
|
||||
std::find(m_parent->get_layer_begin(),
|
||||
m_parent->get_layer_end(), this);
|
||||
|
||||
if (it != m_parent->get_layer_end()) {
|
||||
it++;
|
||||
if (it != m_parent->get_layer_end())
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// LayerImage class
|
||||
|
||||
LayerImage::LayerImage(Sprite* sprite)
|
||||
: Layer(GFXOBJ_LAYER_IMAGE, sprite)
|
||||
{
|
||||
m_blend_mode = BLEND_MODE_NORMAL;
|
||||
}
|
||||
|
||||
LayerImage::LayerImage(LayerImage* src_layer, Sprite* dst_sprite)
|
||||
: Layer(src_layer, dst_sprite)
|
||||
{
|
||||
set_blend_mode(src_layer->get_blend_mode());
|
||||
|
||||
try {
|
||||
// copy cels
|
||||
CelIterator it = static_cast<LayerImage*>(src_layer)->get_cel_begin();
|
||||
CelIterator end = static_cast<LayerImage*>(src_layer)->get_cel_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
Cel* cel = *it;
|
||||
Cel* cel_copy = cel_new_copy(cel);
|
||||
|
||||
assert((cel->image >= 0) &&
|
||||
(cel->image < src_layer->get_sprite()->stock->nimage));
|
||||
|
||||
Image* image = src_layer->get_sprite()->stock->image[cel->image];
|
||||
assert(image != NULL);
|
||||
|
||||
Image* image_copy = image_new_copy(image);
|
||||
|
||||
cel_copy->image = stock_add_image(dst_sprite->stock, image_copy);
|
||||
if (undo_is_enabled(dst_sprite->undo))
|
||||
undo_add_image(dst_sprite->undo, dst_sprite->stock, cel_copy->image);
|
||||
|
||||
add_cel(cel_copy);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
destroy_all_cels();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
LayerImage::~LayerImage()
|
||||
{
|
||||
destroy_all_cels();
|
||||
}
|
||||
|
||||
void LayerImage::destroy_all_cels()
|
||||
{
|
||||
CelIterator it = get_cel_begin();
|
||||
CelIterator end = get_cel_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
Cel* cel = *it;
|
||||
|
||||
if (!cel_is_link(cel, this)) {
|
||||
Image* image = get_sprite()->stock->image[cel->image];
|
||||
|
||||
assert(image != NULL);
|
||||
|
||||
stock_remove_image(get_sprite()->stock, image);
|
||||
image_free(image);
|
||||
}
|
||||
|
||||
cel_free(cel);
|
||||
}
|
||||
}
|
||||
|
||||
void LayerImage::set_blend_mode(int blend_mode)
|
||||
{
|
||||
m_blend_mode = blend_mode;
|
||||
}
|
||||
|
||||
void LayerImage::get_cels(CelList& cels)
|
||||
{
|
||||
CelIterator it = m_cels.begin();
|
||||
CelIterator end = m_cels.begin();
|
||||
|
||||
for (; it != end; ++it)
|
||||
cels.push_back(*it);
|
||||
}
|
||||
|
||||
void LayerImage::add_cel(Cel *cel)
|
||||
{
|
||||
CelIterator it = get_cel_begin();
|
||||
CelIterator end = get_cel_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
if ((*it)->frame > cel->frame)
|
||||
break;
|
||||
}
|
||||
|
||||
m_cels.insert(it, cel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new empty (without frames) normal (image) layer.
|
||||
* Removes the cel from the layer.
|
||||
*
|
||||
* It doesn't destroy the cel, you have to delete it after calling
|
||||
* this routine.
|
||||
*/
|
||||
Layer* layer_new(Sprite* sprite)
|
||||
void LayerImage::remove_cel(Cel *cel)
|
||||
{
|
||||
Layer* layer = new Layer(GFXOBJ_LAYER_IMAGE, sprite);
|
||||
CelIterator it = std::find(m_cels.begin(), m_cels.end(), cel);
|
||||
|
||||
layer_set_name(layer, "Layer");
|
||||
assert(it != m_cels.end());
|
||||
|
||||
layer->blend_mode = BLEND_MODE_NORMAL;
|
||||
layer->cels = jlist_new();
|
||||
|
||||
return layer;
|
||||
m_cels.erase(it);
|
||||
}
|
||||
|
||||
Layer* layer_set_new(Sprite *sprite)
|
||||
const Cel* LayerImage::get_cel(int frame) const
|
||||
{
|
||||
Layer* layer = new Layer(GFXOBJ_LAYER_SET, sprite);
|
||||
|
||||
layer_set_name(layer, "Layer Set");
|
||||
|
||||
layer->layers = jlist_new();
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
Layer* layer_new_copy(Sprite *dst_sprite, const Layer* src_layer)
|
||||
{
|
||||
Layer* layer_copy = NULL;
|
||||
|
||||
assert(dst_sprite != NULL);
|
||||
|
||||
switch (src_layer->type) {
|
||||
|
||||
case GFXOBJ_LAYER_IMAGE: {
|
||||
Cel* cel_copy, *cel;
|
||||
Image* image_copy, *image;
|
||||
JLink link;
|
||||
|
||||
layer_copy = layer_new(dst_sprite);
|
||||
if (!layer_copy)
|
||||
break;
|
||||
|
||||
layer_set_blend_mode(layer_copy, src_layer->blend_mode);
|
||||
|
||||
/* copy cels */
|
||||
JI_LIST_FOR_EACH(src_layer->cels, link) {
|
||||
cel = (Cel* )link->data;
|
||||
cel_copy = cel_new_copy(cel);
|
||||
if (!cel_copy) {
|
||||
layer_free(layer_copy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert((cel->image >= 0) &&
|
||||
(cel->image < src_layer->sprite->stock->nimage));
|
||||
|
||||
image = src_layer->sprite->stock->image[cel->image];
|
||||
assert(image != NULL);
|
||||
|
||||
image_copy = image_new_copy(image);
|
||||
|
||||
cel_copy->image = stock_add_image(dst_sprite->stock, image_copy);
|
||||
if (undo_is_enabled(dst_sprite->undo))
|
||||
undo_add_image(dst_sprite->undo, dst_sprite->stock, cel_copy->image);
|
||||
|
||||
layer_add_cel(layer_copy, cel_copy);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GFXOBJ_LAYER_SET: {
|
||||
Layer* child_copy;
|
||||
JLink link;
|
||||
|
||||
layer_copy = layer_set_new(dst_sprite);
|
||||
if (!layer_copy)
|
||||
break;
|
||||
|
||||
JI_LIST_FOR_EACH(src_layer->layers, link) {
|
||||
/* copy the child */
|
||||
child_copy = layer_new_copy(dst_sprite,
|
||||
reinterpret_cast<Layer*>(link->data));
|
||||
/* not enough memory? */
|
||||
if (!child_copy) {
|
||||
layer_free(layer_copy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* add the new child in the layer copy */
|
||||
layer_add_layer(layer_copy, child_copy);
|
||||
}
|
||||
break;
|
||||
}
|
||||
CelConstIterator it = get_cel_begin();
|
||||
CelConstIterator end = get_cel_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
const Cel* cel = *it;
|
||||
if (cel->frame == frame)
|
||||
return cel;
|
||||
}
|
||||
|
||||
/* copy general properties */
|
||||
if (layer_copy != NULL) {
|
||||
layer_set_name(layer_copy, src_layer->name);
|
||||
layer_copy->flags = src_layer->flags;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Cel* LayerImage::get_cel(int frame)
|
||||
{
|
||||
CelIterator it = get_cel_begin();
|
||||
CelIterator end = get_cel_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
Cel* cel = *it;
|
||||
if (cel->frame == frame)
|
||||
return cel;
|
||||
}
|
||||
|
||||
return layer_copy;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures some properties of the specified layer to make it as the
|
||||
* "Background" of the sprite.
|
||||
*
|
||||
* You can't use this routine if the sprite already has a background
|
||||
* layer.
|
||||
*/
|
||||
void LayerImage::configure_as_background()
|
||||
{
|
||||
assert(get_sprite() != NULL);
|
||||
assert(sprite_get_background_layer(get_sprite()) == NULL);
|
||||
|
||||
*flags_addr() |= LAYER_IS_LOCKMOVE | LAYER_IS_BACKGROUND;
|
||||
set_name("Background");
|
||||
|
||||
get_sprite()->get_folder()->move_layer(this, NULL);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// LayerFolder class
|
||||
|
||||
LayerFolder::LayerFolder(Sprite* sprite)
|
||||
: Layer(GFXOBJ_LAYER_FOLDER, sprite)
|
||||
{
|
||||
set_name("Layer Set");
|
||||
}
|
||||
|
||||
LayerFolder::LayerFolder(LayerFolder* src_layer, Sprite* dst_sprite)
|
||||
: Layer(src_layer, dst_sprite)
|
||||
{
|
||||
try {
|
||||
LayerIterator it = static_cast<LayerFolder*>(src_layer)->get_layer_begin();
|
||||
LayerIterator end = static_cast<LayerFolder*>(src_layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
// duplicate the child
|
||||
Layer* child_copy = (*it)->duplicate_for(dst_sprite);
|
||||
|
||||
// add the new child in the layer copy
|
||||
add_layer(child_copy);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
destroy_all_layers();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
LayerFolder::~LayerFolder()
|
||||
{
|
||||
destroy_all_layers();
|
||||
}
|
||||
|
||||
void LayerFolder::destroy_all_layers()
|
||||
{
|
||||
LayerIterator it = get_layer_begin();
|
||||
LayerIterator end = get_layer_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
Layer* layer = *it;
|
||||
delete layer;
|
||||
}
|
||||
}
|
||||
|
||||
void LayerFolder::get_cels(CelList& cels)
|
||||
{
|
||||
LayerIterator it = get_layer_begin();
|
||||
LayerIterator end = get_layer_end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
(*it)->get_cels(cels);
|
||||
}
|
||||
|
||||
void LayerFolder::add_layer(Layer* layer)
|
||||
{
|
||||
m_layers.push_back(layer);
|
||||
layer->set_parent(this);
|
||||
}
|
||||
|
||||
void LayerFolder::remove_layer(Layer* layer)
|
||||
{
|
||||
LayerIterator it = std::find(m_layers.begin(), m_layers.end(), layer);
|
||||
assert(it != m_layers.end());
|
||||
m_layers.erase(it);
|
||||
|
||||
layer->set_parent(NULL);
|
||||
}
|
||||
|
||||
void LayerFolder::move_layer(Layer* layer, Layer* after)
|
||||
{
|
||||
LayerIterator it = std::find(m_layers.begin(), m_layers.end(), layer);
|
||||
assert(it != m_layers.end());
|
||||
m_layers.erase(it);
|
||||
|
||||
if (after) {
|
||||
LayerIterator after_it = std::find(m_layers.begin(), m_layers.end(), after);
|
||||
assert(after_it != m_layers.end());
|
||||
after_it++;
|
||||
m_layers.insert(after_it, layer);
|
||||
}
|
||||
else
|
||||
m_layers.push_front(layer);
|
||||
|
||||
// TODO
|
||||
// if (after) {
|
||||
// JLink before = jlist_find(m_layers, after)->next;
|
||||
// jlist_insert_before(m_layers, before, layer);
|
||||
// }
|
||||
// else
|
||||
// jlist_prepend(m_layers, layer);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Returns a new layer (flat_layer) with all "layer" rendered frame by
|
||||
* frame from "frmin" to "frmax" (inclusive). "layer" can be a set of
|
||||
@ -198,303 +367,78 @@ Layer* layer_new_copy(Sprite *dst_sprite, const Layer* src_layer)
|
||||
* @param dst_sprite The sprite where to put the new flattened layer.
|
||||
* @param src_layer Generally a set of layers to be flattened.
|
||||
*/
|
||||
Layer* layer_new_flatten_copy(Sprite *dst_sprite, const Layer* src_layer,
|
||||
Layer* layer_new_flatten_copy(Sprite* dst_sprite, const Layer* src_layer,
|
||||
int x, int y, int w, int h, int frmin, int frmax)
|
||||
{
|
||||
Layer* flat_layer;
|
||||
Image* image;
|
||||
Cel* cel;
|
||||
int frame;
|
||||
LayerImage* flat_layer = new LayerImage(dst_sprite);
|
||||
|
||||
flat_layer = layer_new(dst_sprite);
|
||||
if (!flat_layer)
|
||||
return NULL;
|
||||
try {
|
||||
for (int frame=frmin; frame<=frmax; frame++) {
|
||||
/* does this frame have cels to render? */
|
||||
if (has_cels(src_layer, frame)) {
|
||||
/* create a new image */
|
||||
Image* image = image_new(flat_layer->get_sprite()->imgtype, w, h);
|
||||
|
||||
for (frame=frmin; frame<=frmax; frame++) {
|
||||
/* does this frame have cels to render? */
|
||||
if (has_cels(src_layer, frame)) {
|
||||
/* create a new image */
|
||||
image = image_new(flat_layer->sprite->imgtype, w, h);
|
||||
if (!image) {
|
||||
layer_free(flat_layer);
|
||||
return NULL;
|
||||
try {
|
||||
/* create the new cel for the output layer (add the image to
|
||||
stock too) */
|
||||
Cel* cel = cel_new(frame, stock_add_image(flat_layer->get_sprite()->stock, image));
|
||||
cel_set_position(cel, x, y);
|
||||
|
||||
/* clear the image and render this frame */
|
||||
image_clear(image, 0);
|
||||
layer_render(src_layer, image, -x, -y, frame);
|
||||
flat_layer->add_cel(cel);
|
||||
}
|
||||
catch (...) {
|
||||
delete image;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/* create the new cel for the output layer (add the image to
|
||||
stock too) */
|
||||
cel = cel_new(frame, stock_add_image(flat_layer->sprite->stock, image));
|
||||
cel_set_position(cel, x, y);
|
||||
if (!cel) {
|
||||
layer_free(flat_layer);
|
||||
image_free(image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* clear the image and render this frame */
|
||||
image_clear(image, 0);
|
||||
layer_render(src_layer, image, -x, -y, frame);
|
||||
layer_add_cel(flat_layer, cel);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
delete flat_layer;
|
||||
throw;
|
||||
}
|
||||
|
||||
return flat_layer;
|
||||
}
|
||||
|
||||
void layer_free(Layer* layer)
|
||||
{
|
||||
assert(layer);
|
||||
delete layer;
|
||||
}
|
||||
|
||||
|
||||
void layer_free_images(Layer* layer)
|
||||
{
|
||||
JLink link;
|
||||
|
||||
switch (layer->type) {
|
||||
|
||||
case GFXOBJ_LAYER_IMAGE:
|
||||
JI_LIST_FOR_EACH(layer->cels, link) {
|
||||
Cel* cel = reinterpret_cast<Cel*>(link->data);
|
||||
|
||||
if (!cel_is_link(cel, layer)) {
|
||||
Image* image = layer->sprite->stock->image[cel->image];
|
||||
|
||||
assert(image != NULL);
|
||||
|
||||
stock_remove_image(layer->sprite->stock, image);
|
||||
image_free(image);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GFXOBJ_LAYER_SET: {
|
||||
JI_LIST_FOR_EACH(layer->layers, link)
|
||||
layer_free_images(reinterpret_cast<Layer*>(link->data));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures some properties of the specified layer to make it as the
|
||||
* "Background" of the sprite.
|
||||
*
|
||||
* You can't use this routine if the sprite already has a background
|
||||
* layer.
|
||||
*/
|
||||
void layer_configure_as_background(Layer* layer)
|
||||
{
|
||||
assert(layer != NULL);
|
||||
assert(layer->sprite != NULL);
|
||||
assert(sprite_get_background_layer(layer->sprite) == NULL);
|
||||
|
||||
layer->flags |= LAYER_IS_LOCKMOVE | LAYER_IS_BACKGROUND;
|
||||
layer_set_name(layer, "Background");
|
||||
|
||||
layer_move_layer(layer->sprite->set, layer, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if "layer" is a normal layer type (an image layer)
|
||||
*/
|
||||
bool layer_is_image(const Layer* layer)
|
||||
{
|
||||
return (layer->type == GFXOBJ_LAYER_IMAGE) ? true: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if "layer" is a set of layers
|
||||
*/
|
||||
bool layer_is_set(const Layer* layer)
|
||||
{
|
||||
return (layer->type == GFXOBJ_LAYER_SET) ? true: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the layer is readable/viewable.
|
||||
*/
|
||||
bool layer_is_readable(const Layer* layer)
|
||||
{
|
||||
return (layer->flags & LAYER_IS_READABLE) == LAYER_IS_READABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the layer is writable/editable.
|
||||
*/
|
||||
bool layer_is_writable(const Layer* layer)
|
||||
{
|
||||
return (layer->flags & LAYER_IS_WRITABLE) == LAYER_IS_WRITABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the layer is moveable.
|
||||
*/
|
||||
bool layer_is_moveable(const Layer* layer)
|
||||
{
|
||||
return (layer->flags & LAYER_IS_LOCKMOVE) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the layer is the background.
|
||||
*/
|
||||
bool layer_is_background(const Layer* layer)
|
||||
{
|
||||
return (layer->flags & LAYER_IS_BACKGROUND) == LAYER_IS_BACKGROUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the previous layer of "layer" that are in the parent set.
|
||||
*/
|
||||
Layer* layer_get_prev(Layer* layer)
|
||||
{
|
||||
if (layer->parent_layer != NULL) {
|
||||
JList list = layer->parent_layer->layers;
|
||||
JLink link = jlist_find(list, layer);
|
||||
if (link != list->end && link->prev != list->end)
|
||||
return reinterpret_cast<Layer*>(link->prev->data);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Layer* layer_get_next(Layer* layer)
|
||||
{
|
||||
if (layer->parent_layer != NULL) {
|
||||
JList list = layer->parent_layer->layers;
|
||||
JLink link = jlist_find(list, layer);
|
||||
if (link != list->end && link->next != list->end)
|
||||
return reinterpret_cast<Layer*>(link->next->data);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void layer_set_name(Layer* layer, const char *name)
|
||||
{
|
||||
ustrzcpy(layer->name, LAYER_NAME_SIZE, name);
|
||||
}
|
||||
|
||||
void layer_set_blend_mode(Layer* layer, int blend_mode)
|
||||
{
|
||||
if (layer_is_image(layer))
|
||||
layer->blend_mode = blend_mode;
|
||||
}
|
||||
|
||||
void layer_get_cels(const Layer* layer, JList cels)
|
||||
{
|
||||
JLink link;
|
||||
|
||||
if (layer_is_image(layer)) {
|
||||
JI_LIST_FOR_EACH(layer->cels, link)
|
||||
jlist_append(cels, link->data);
|
||||
}
|
||||
else if (layer_is_set(layer)) {
|
||||
JI_LIST_FOR_EACH(layer->layers, link)
|
||||
layer_get_cels((const Layer*)link->data, cels);
|
||||
}
|
||||
}
|
||||
|
||||
void layer_add_cel(Layer* layer, Cel* cel)
|
||||
{
|
||||
if (layer_is_image(layer)) {
|
||||
JLink link;
|
||||
|
||||
JI_LIST_FOR_EACH(layer->cels, link)
|
||||
if (((Cel* )link->data)->frame >= cel->frame)
|
||||
break;
|
||||
|
||||
jlist_insert_before(layer->cels, link, cel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the cel from the layer.
|
||||
*
|
||||
* It doesn't destroy the cel, you have to delete it after calling
|
||||
* this routine.
|
||||
*/
|
||||
void layer_remove_cel(Layer* layer, Cel* cel)
|
||||
{
|
||||
assert(layer_is_image(layer));
|
||||
jlist_remove(layer->cels, cel);
|
||||
}
|
||||
|
||||
Cel* layer_get_cel(const Layer* layer, int frame)
|
||||
{
|
||||
if (layer_is_image(layer)) {
|
||||
Cel* cel;
|
||||
JLink link;
|
||||
|
||||
JI_LIST_FOR_EACH(layer->cels, link) {
|
||||
cel = reinterpret_cast<Cel*>(link->data);
|
||||
if (cel->frame == frame)
|
||||
return cel;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void layer_add_layer(Layer* set, Layer* layer)
|
||||
{
|
||||
assert(set != NULL && layer_is_set(set));
|
||||
|
||||
jlist_append(set->layers, layer);
|
||||
layer_set_parent(layer, set);
|
||||
}
|
||||
|
||||
void layer_remove_layer(Layer* set, Layer* layer)
|
||||
{
|
||||
assert(set != NULL && layer_is_set(set));
|
||||
|
||||
jlist_remove(set->layers, layer);
|
||||
layer_set_parent(layer, NULL);
|
||||
}
|
||||
|
||||
void layer_move_layer(Layer* set, Layer* layer, Layer* after)
|
||||
{
|
||||
assert(set != NULL && layer_is_set(set));
|
||||
|
||||
jlist_remove(set->layers, layer);
|
||||
|
||||
if (after) {
|
||||
JLink before = jlist_find(set->layers, after)->next;
|
||||
jlist_insert_before(set->layers, before, layer);
|
||||
}
|
||||
else
|
||||
jlist_prepend(set->layers, layer);
|
||||
}
|
||||
|
||||
void layer_render(const Layer* layer, Image* image, int x, int y, int frame)
|
||||
{
|
||||
if (!layer_is_readable(layer))
|
||||
if (!layer->is_readable())
|
||||
return;
|
||||
|
||||
switch (layer->type) {
|
||||
|
||||
case GFXOBJ_LAYER_IMAGE: {
|
||||
Cel* cel = layer_get_cel(layer, frame);
|
||||
const Cel* cel = static_cast<const LayerImage*>(layer)->get_cel(frame);
|
||||
Image* src_image;
|
||||
|
||||
if (cel) {
|
||||
assert((cel->image >= 0) &&
|
||||
(cel->image < layer->sprite->stock->nimage));
|
||||
(cel->image < layer->get_sprite()->stock->nimage));
|
||||
|
||||
src_image = layer->sprite->stock->image[cel->image];
|
||||
src_image = layer->get_sprite()->stock->image[cel->image];
|
||||
assert(src_image != NULL);
|
||||
|
||||
image_merge(image, src_image,
|
||||
cel->x + x,
|
||||
cel->y + y,
|
||||
MID (0, cel->opacity, 255),
|
||||
layer->blend_mode);
|
||||
static_cast<const LayerImage*>(layer)->get_blend_mode());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GFXOBJ_LAYER_SET: {
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->layers, link)
|
||||
layer_render(reinterpret_cast<Layer*>(link->data), image, x, y, frame);
|
||||
case GFXOBJ_LAYER_FOLDER: {
|
||||
LayerConstIterator it = static_cast<const LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerConstIterator end = static_cast<const LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
layer_render(*it, image, x, y, frame);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -502,36 +446,31 @@ void layer_render(const Layer* layer, Image* image, int x, int y, int frame)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the "layer" (or him childs) has cels to render in
|
||||
* Returns true if the "layer" (or him childs) has cels to render in
|
||||
* frame.
|
||||
*/
|
||||
static bool has_cels(const Layer* layer, int frame)
|
||||
{
|
||||
if (!layer_is_readable(layer))
|
||||
return FALSE;
|
||||
if (!layer->is_readable())
|
||||
return false;
|
||||
|
||||
switch (layer->type) {
|
||||
|
||||
case GFXOBJ_LAYER_IMAGE:
|
||||
return layer_get_cel(layer, frame) ? true: false;
|
||||
return static_cast<const LayerImage*>(layer)->get_cel(frame) ? true: false;
|
||||
|
||||
case GFXOBJ_LAYER_SET: {
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->layers, link) {
|
||||
if (has_cels(reinterpret_cast<const Layer*>(link->data), frame))
|
||||
return TRUE;
|
||||
case GFXOBJ_LAYER_FOLDER: {
|
||||
LayerConstIterator it = static_cast<const LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerConstIterator end = static_cast<const LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
if (has_cels(*it, frame))
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void layer_set_parent(Layer* layer, Layer* parent_set)
|
||||
{
|
||||
assert(parent_set == NULL || layer_is_set(parent_set));
|
||||
|
||||
layer->parent_layer = parent_set;
|
||||
return false;
|
||||
}
|
||||
|
@ -19,72 +19,139 @@
|
||||
#ifndef RASTER_LAYER_H_INCLUDED
|
||||
#define RASTER_LAYER_H_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include "jinete/jbase.h"
|
||||
#include "raster/gfxobj.h"
|
||||
|
||||
class Cel;
|
||||
class Image;
|
||||
class Sprite;
|
||||
|
||||
#define LAYER_NAME_SIZE 256
|
||||
class Layer;
|
||||
class LayerImage;
|
||||
class LayerFolder;
|
||||
|
||||
#define LAYER_IS_READABLE 0x0001
|
||||
#define LAYER_IS_WRITABLE 0x0002
|
||||
#define LAYER_IS_LOCKMOVE 0x0004
|
||||
#define LAYER_IS_BACKGROUND 0x0008
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Layer class
|
||||
|
||||
class Layer : public GfxObj
|
||||
{
|
||||
public:
|
||||
char name[LAYER_NAME_SIZE]; /* layer name */
|
||||
Sprite* sprite; /* owner of the layer */
|
||||
Layer* parent_layer; /* parent layer */
|
||||
unsigned short flags;
|
||||
|
||||
/* for GFXOBJ_LAYER_IMAGE */
|
||||
int blend_mode; /* constant blend mode */
|
||||
JList cels; /* list of cels */
|
||||
|
||||
/* for GFXOBJ_LAYER_SET */
|
||||
JList layers;
|
||||
std::string m_name; // layer name
|
||||
Sprite* m_sprite; // owner of the layer
|
||||
LayerFolder* m_parent; // parent layer
|
||||
unsigned short m_flags;
|
||||
|
||||
protected:
|
||||
Layer(int type, Sprite* sprite);
|
||||
Layer(Sprite* sprite);
|
||||
Layer(Layer* src_layer, Sprite* dst_sprite);
|
||||
|
||||
public:
|
||||
virtual ~Layer();
|
||||
|
||||
std::string get_name() const { return m_name; }
|
||||
void set_name(const std::string& name) { m_name = name; }
|
||||
|
||||
Sprite* get_sprite() const { return m_sprite; }
|
||||
LayerFolder* get_parent() const { return m_parent; }
|
||||
void set_parent(LayerFolder* folder) { m_parent = folder; }
|
||||
Layer* get_prev() const;
|
||||
Layer* get_next() const;
|
||||
|
||||
bool is_image() const { return type == GFXOBJ_LAYER_IMAGE; }
|
||||
bool is_folder() const { return type == GFXOBJ_LAYER_FOLDER; }
|
||||
bool is_background() const { return (m_flags & LAYER_IS_BACKGROUND) == LAYER_IS_BACKGROUND; }
|
||||
bool is_moveable() const { return (m_flags & LAYER_IS_LOCKMOVE) == 0; }
|
||||
bool is_readable() const { return (m_flags & LAYER_IS_READABLE) == LAYER_IS_READABLE; }
|
||||
bool is_writable() const { return (m_flags & LAYER_IS_WRITABLE) == LAYER_IS_WRITABLE; }
|
||||
|
||||
void set_background(bool b) { if (b) m_flags |= LAYER_IS_BACKGROUND; else m_flags &= ~LAYER_IS_BACKGROUND; }
|
||||
void set_moveable(bool b) { if (b) m_flags &= ~LAYER_IS_LOCKMOVE; else m_flags |= LAYER_IS_LOCKMOVE; }
|
||||
void set_readable(bool b) { if (b) m_flags |= LAYER_IS_READABLE; else m_flags &= ~LAYER_IS_READABLE; }
|
||||
void set_writable(bool b) { if (b) m_flags |= LAYER_IS_WRITABLE; else m_flags &= ~LAYER_IS_WRITABLE; }
|
||||
|
||||
virtual void get_cels(CelList& cels) = 0;
|
||||
virtual Layer* duplicate_for(Sprite* sprite) = 0;
|
||||
|
||||
// TODO remove these methods (from C backward-compatibility)
|
||||
unsigned short* flags_addr() { return &m_flags; }
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// LayerImage class
|
||||
|
||||
class LayerImage : public Layer
|
||||
{
|
||||
int m_blend_mode; // constant blend mode
|
||||
CelList m_cels; // list of cels
|
||||
|
||||
public:
|
||||
LayerImage(Sprite* sprite);
|
||||
LayerImage(LayerImage* copy, Sprite* sprite);
|
||||
virtual ~LayerImage();
|
||||
|
||||
int get_blend_mode() const { return m_blend_mode; }
|
||||
void set_blend_mode(int blend_mode);
|
||||
|
||||
void add_cel(Cel *cel);
|
||||
void remove_cel(Cel *cel);
|
||||
const Cel* get_cel(int frame) const;
|
||||
Cel* get_cel(int frame);
|
||||
|
||||
void get_cels(CelList& cels);
|
||||
|
||||
void configure_as_background();
|
||||
|
||||
CelIterator get_cel_begin() { return m_cels.begin(); }
|
||||
CelIterator get_cel_end() { return m_cels.end(); }
|
||||
CelConstIterator get_cel_begin() const { return m_cels.begin(); }
|
||||
CelConstIterator get_cel_end() const { return m_cels.end(); }
|
||||
int get_cels_count() const { return m_cels.size(); }
|
||||
|
||||
LayerImage* duplicate_for(Sprite* sprite) { return new LayerImage(this, sprite); }
|
||||
|
||||
private:
|
||||
void destroy_all_cels();
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// LayerFolder class
|
||||
|
||||
class LayerFolder : public Layer
|
||||
{
|
||||
LayerList m_layers;
|
||||
|
||||
public:
|
||||
LayerFolder(Sprite* sprite);
|
||||
LayerFolder(LayerFolder* copy, Sprite* sprite);
|
||||
virtual ~LayerFolder();
|
||||
|
||||
LayerList get_layers_list() { return m_layers; }
|
||||
LayerIterator get_layer_begin() { return m_layers.begin(); }
|
||||
LayerIterator get_layer_end() { return m_layers.end(); }
|
||||
LayerConstIterator get_layer_begin() const { return m_layers.begin(); }
|
||||
LayerConstIterator get_layer_end() const { return m_layers.end(); }
|
||||
int get_layers_count() const { return m_layers.size(); }
|
||||
|
||||
void add_layer(Layer* layer);
|
||||
void remove_layer(Layer* layer);
|
||||
void move_layer(Layer* layer, Layer* after);
|
||||
|
||||
void get_cels(CelList& cels);
|
||||
|
||||
LayerFolder* duplicate_for(Sprite* sprite) { return new LayerFolder(this, sprite); }
|
||||
|
||||
private:
|
||||
void destroy_all_layers();
|
||||
};
|
||||
|
||||
Layer* layer_new(Sprite* sprite);
|
||||
Layer* layer_set_new(Sprite* sprite);
|
||||
Layer* layer_new_copy(Sprite* dst_sprite, const Layer* src_layer);
|
||||
Layer* layer_new_flatten_copy(Sprite* dst_sprite, const Layer* src_layer,
|
||||
int x, int y, int w, int h, int frmin, int frmax);
|
||||
void layer_free(Layer* layer);
|
||||
void layer_free_images(Layer* layer);
|
||||
|
||||
void layer_configure_as_background(Layer* layer);
|
||||
|
||||
bool layer_is_image(const Layer* layer);
|
||||
bool layer_is_set(const Layer* layer);
|
||||
bool layer_is_background(const Layer* layer);
|
||||
bool layer_is_moveable(const Layer* layer);
|
||||
bool layer_is_readable(const Layer* layer);
|
||||
bool layer_is_writable(const Layer* layer);
|
||||
|
||||
Layer* layer_get_prev(Layer* layer);
|
||||
Layer* layer_get_next(Layer* layer);
|
||||
|
||||
void layer_set_name(Layer* layer, const char *name);
|
||||
void layer_set_blend_mode(Layer* layer, int blend_mode);
|
||||
void layer_get_cels(const Layer* layer, JList cels);
|
||||
|
||||
/* for LAYER_IMAGE */
|
||||
void layer_add_cel(Layer* layer, Cel *cel);
|
||||
void layer_remove_cel(Layer* layer, Cel *cel);
|
||||
Cel *layer_get_cel(const Layer* layer, int frame);
|
||||
|
||||
/* for LAYER_SET */
|
||||
void layer_add_layer(Layer* set, Layer* layer);
|
||||
void layer_remove_layer(Layer* set, Layer* layer);
|
||||
void layer_move_layer(Layer* set, Layer* layer, Layer* after);
|
||||
|
||||
void layer_render(const Layer* layer, Image *image, int x, int y, int frame);
|
||||
|
||||
|
@ -53,7 +53,7 @@ Sprite::Sprite(int imgtype, int w, int h)
|
||||
this->frame = 0;
|
||||
this->palettes = jlist_new();
|
||||
this->stock = stock_new(imgtype);
|
||||
this->set = layer_set_new(this);
|
||||
this->m_folder = new LayerFolder(this);
|
||||
this->layer = NULL;
|
||||
this->path = NULL;
|
||||
this->mask = mask_new();
|
||||
@ -106,9 +106,10 @@ Sprite::~Sprite()
|
||||
{
|
||||
JLink link;
|
||||
|
||||
// assert(m_locked == 1);
|
||||
// destroy layers
|
||||
delete m_folder; // destroy layers
|
||||
|
||||
/* destroy images' stock */
|
||||
// destroy images' stock
|
||||
if (this->stock)
|
||||
stock_free(this->stock);
|
||||
|
||||
@ -140,7 +141,6 @@ Sprite::~Sprite()
|
||||
if (this->frlens) jfree(this->frlens);
|
||||
if (this->undo) undo_free(this->undo);
|
||||
if (this->mask) mask_free(this->mask);
|
||||
if (this->set) layer_free(this->set);
|
||||
if (this->bound.seg) jfree(this->bound.seg);
|
||||
|
||||
/* destroy mutex */
|
||||
@ -167,18 +167,18 @@ Sprite* sprite_new_copy(const Sprite* src_sprite)
|
||||
return NULL;
|
||||
|
||||
/* copy layers */
|
||||
if (dst_sprite->set) {
|
||||
layer_free(dst_sprite->set);
|
||||
dst_sprite->set = NULL;
|
||||
if (dst_sprite->m_folder) {
|
||||
delete dst_sprite->m_folder; // delete
|
||||
dst_sprite->m_folder = NULL;
|
||||
}
|
||||
|
||||
assert(src_sprite->set != NULL);
|
||||
assert(src_sprite->get_folder() != NULL);
|
||||
|
||||
undo_disable(dst_sprite->undo);
|
||||
dst_sprite->set = layer_new_copy(dst_sprite, src_sprite->set);
|
||||
dst_sprite->m_folder = src_sprite->get_folder()->duplicate_for(dst_sprite);
|
||||
undo_enable(dst_sprite->undo);
|
||||
|
||||
if (dst_sprite->set == NULL) {
|
||||
if (dst_sprite->m_folder == NULL) {
|
||||
delete dst_sprite;
|
||||
return NULL;
|
||||
}
|
||||
@ -205,10 +205,10 @@ Sprite* sprite_new_flatten_copy(const Sprite* src_sprite)
|
||||
return NULL;
|
||||
|
||||
/* flatten layers */
|
||||
assert(src_sprite->set != NULL);
|
||||
assert(src_sprite->get_folder() != NULL);
|
||||
|
||||
flat_layer = layer_new_flatten_copy(dst_sprite,
|
||||
src_sprite->set,
|
||||
src_sprite->get_folder(),
|
||||
0, 0, src_sprite->w, src_sprite->h,
|
||||
0, src_sprite->frames-1);
|
||||
if (flat_layer == NULL) {
|
||||
@ -217,7 +217,7 @@ Sprite* sprite_new_flatten_copy(const Sprite* src_sprite)
|
||||
}
|
||||
|
||||
/* add and select the new flat layer */
|
||||
layer_add_layer(dst_sprite->set, flat_layer);
|
||||
dst_sprite->get_folder()->add_layer(flat_layer);
|
||||
dst_sprite->layer = flat_layer;
|
||||
|
||||
return dst_sprite;
|
||||
@ -225,55 +225,46 @@ Sprite* sprite_new_flatten_copy(const Sprite* src_sprite)
|
||||
|
||||
Sprite* sprite_new_with_layer(int imgtype, int w, int h)
|
||||
{
|
||||
Sprite* sprite;
|
||||
Layer *layer;
|
||||
Cel *cel;
|
||||
Image *image;
|
||||
int index;
|
||||
Sprite* sprite = NULL;
|
||||
LayerImage *layer = NULL;
|
||||
Image *image = NULL;
|
||||
Cel *cel = NULL;
|
||||
|
||||
sprite = sprite_new(imgtype, w, h);
|
||||
if (!sprite)
|
||||
return NULL;
|
||||
try {
|
||||
sprite = sprite_new(imgtype, w, h);
|
||||
image = image_new(imgtype, w, h);
|
||||
layer = new LayerImage(sprite);
|
||||
|
||||
/* new image */
|
||||
image = image_new(imgtype, w, h);
|
||||
if (!image) {
|
||||
delete sprite;
|
||||
return NULL;
|
||||
/* clear with mask color */
|
||||
image_clear(image, 0);
|
||||
|
||||
/* configure the first transparent layer */
|
||||
layer->set_name("Layer 1");
|
||||
layer->set_blend_mode(BLEND_MODE_NORMAL);
|
||||
|
||||
/* add image in the layer stock */
|
||||
int index = stock_add_image(sprite->stock, image);
|
||||
|
||||
/* create the cel */
|
||||
cel = cel_new(0, index);
|
||||
cel_set_position(cel, 0, 0);
|
||||
|
||||
/* add the cel in the layer */
|
||||
layer->add_cel(cel);
|
||||
|
||||
/* add the layer in the sprite */
|
||||
sprite->get_folder()->add_layer(layer);
|
||||
|
||||
sprite_set_frames(sprite, 1);
|
||||
sprite_set_filename(sprite, "Sprite");
|
||||
sprite_set_layer(sprite, layer);
|
||||
}
|
||||
|
||||
/* new layer */
|
||||
layer = layer_new(sprite);
|
||||
if (!layer) {
|
||||
image_free(image);
|
||||
catch (...) {
|
||||
delete sprite;
|
||||
return NULL;
|
||||
delete image;
|
||||
throw;
|
||||
}
|
||||
|
||||
/* clear with mask color */
|
||||
image_clear(image, 0);
|
||||
|
||||
/* configure the first transparent layer */
|
||||
layer_set_name(layer, "Layer 1");
|
||||
layer_set_blend_mode(layer, BLEND_MODE_NORMAL);
|
||||
|
||||
/* add image in the layer stock */
|
||||
index = stock_add_image(sprite->stock, image);
|
||||
|
||||
/* create the cel */
|
||||
cel = cel_new(0, index);
|
||||
cel_set_position(cel, 0, 0);
|
||||
|
||||
/* add the cel in the layer */
|
||||
layer_add_cel(layer, cel);
|
||||
|
||||
/* add the layer in the sprite */
|
||||
layer_add_layer(sprite->set, layer);
|
||||
|
||||
sprite_set_frames(sprite, 1);
|
||||
sprite_set_filename(sprite, "Sprite");
|
||||
sprite_set_layer(sprite, layer);
|
||||
|
||||
return sprite;
|
||||
}
|
||||
|
||||
@ -574,15 +565,15 @@ void sprite_set_frame(Sprite* sprite, int frame)
|
||||
sprite->frame = frame;
|
||||
}
|
||||
|
||||
Layer *sprite_get_background_layer(const Sprite* sprite)
|
||||
LayerImage* sprite_get_background_layer(const Sprite* sprite)
|
||||
{
|
||||
assert(sprite != NULL);
|
||||
|
||||
if (jlist_length(sprite->set->layers) > 0) {
|
||||
Layer *bglayer = reinterpret_cast<Layer*>(jlist_first_data(sprite->set->layers));
|
||||
if (sprite->get_folder()->get_layers_count() > 0) {
|
||||
Layer* bglayer = *sprite->get_folder()->get_layer_begin();
|
||||
|
||||
if (layer_is_background(bglayer))
|
||||
return bglayer;
|
||||
if (bglayer->is_background())
|
||||
return static_cast<LayerImage*>(bglayer);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -650,7 +641,7 @@ Mask *sprite_request_mask(const Sprite* sprite, const char *name)
|
||||
void sprite_render(const Sprite* sprite, Image *image, int x, int y)
|
||||
{
|
||||
image_rectfill(image, x, y, x+sprite->w-1, y+sprite->h-1, 0);
|
||||
layer_render(sprite->set, image, x, y, sprite->frame);
|
||||
layer_render(sprite->get_folder(), image, x, y, sprite->frame);
|
||||
}
|
||||
|
||||
void sprite_generate_mask_boundaries(Sprite* sprite)
|
||||
@ -681,7 +672,7 @@ Layer* sprite_index2layer(const Sprite* sprite, int index)
|
||||
int index_count = -1;
|
||||
assert(sprite != NULL);
|
||||
|
||||
return index2layer(sprite->set, index, &index_count);
|
||||
return index2layer(sprite->get_folder(), index, &index_count);
|
||||
}
|
||||
|
||||
int sprite_layer2index(const Sprite* sprite, const Layer *layer)
|
||||
@ -689,18 +680,18 @@ int sprite_layer2index(const Sprite* sprite, const Layer *layer)
|
||||
int index_count = -1;
|
||||
assert(sprite != NULL);
|
||||
|
||||
return layer2index(sprite->set, layer, &index_count);
|
||||
return layer2index(sprite->get_folder(), layer, &index_count);
|
||||
}
|
||||
|
||||
int sprite_count_layers(const Sprite* sprite)
|
||||
{
|
||||
assert(sprite != NULL);
|
||||
return layer_count_layers(sprite->set)-1;
|
||||
return sprite->get_folder()->get_layers_count();
|
||||
}
|
||||
|
||||
void sprite_get_cels(const Sprite* sprite, JList cels)
|
||||
void sprite_get_cels(const Sprite* sprite, CelList& cels)
|
||||
{
|
||||
return layer_get_cels(sprite->set, cels);
|
||||
sprite->get_folder()->get_cels(cels);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -746,12 +737,14 @@ static Layer *index2layer(const Layer *layer, int index, int *index_count)
|
||||
else {
|
||||
(*index_count)++;
|
||||
|
||||
if (layer_is_set (layer)) {
|
||||
if (layer->is_folder()) {
|
||||
Layer *found;
|
||||
JLink link;
|
||||
|
||||
JI_LIST_FOR_EACH(layer->layers, link) {
|
||||
if ((found = index2layer(reinterpret_cast<Layer*>(link->data), index, index_count)))
|
||||
LayerConstIterator it = static_cast<const LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerConstIterator end = static_cast<const LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
if ((found = index2layer(*it, index, index_count)))
|
||||
return found;
|
||||
}
|
||||
}
|
||||
@ -767,13 +760,14 @@ static int layer2index(const Layer *layer, const Layer *find_layer, int *index_c
|
||||
else {
|
||||
(*index_count)++;
|
||||
|
||||
if (layer_is_set(layer)) {
|
||||
JLink link;
|
||||
if (layer->is_folder()) {
|
||||
int found;
|
||||
|
||||
JI_LIST_FOR_EACH(layer->layers, link) {
|
||||
if ((found = layer2index(reinterpret_cast<Layer*>(link->data),
|
||||
find_layer, index_count)) >= 0)
|
||||
LayerConstIterator it = static_cast<const LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerConstIterator end = static_cast<const LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
if ((found = layer2index(*it, find_layer, index_count)) >= 0)
|
||||
return found;
|
||||
}
|
||||
}
|
||||
@ -782,15 +776,16 @@ static int layer2index(const Layer *layer, const Layer *find_layer, int *index_c
|
||||
}
|
||||
}
|
||||
|
||||
static int layer_count_layers(const Layer *layer)
|
||||
static int layer_count_layers(const Layer* layer)
|
||||
{
|
||||
int count = 1;
|
||||
|
||||
if (layer_is_set(layer)) {
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->layers, link) {
|
||||
count += layer_count_layers(reinterpret_cast<Layer*>(link->data));
|
||||
}
|
||||
if (layer->is_folder()) {
|
||||
LayerConstIterator it = static_cast<const LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerConstIterator end = static_cast<const LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
count += layer_count_layers(*it);
|
||||
}
|
||||
|
||||
return count;
|
||||
|
@ -25,17 +25,24 @@
|
||||
struct FormatOptions;
|
||||
class Image;
|
||||
class Layer;
|
||||
class LayerFolder;
|
||||
class LayerImage;
|
||||
class Mask;
|
||||
class Palette;
|
||||
class Path;
|
||||
class Stock;
|
||||
class Undo;
|
||||
class Sprite;
|
||||
|
||||
Sprite* sprite_new_copy(const Sprite* src_sprite);
|
||||
|
||||
/**
|
||||
* The main structure used in the whole program to handle a sprite.
|
||||
*/
|
||||
class Sprite : public GfxObj
|
||||
{
|
||||
friend Sprite* sprite_new_copy(const Sprite* src_sprite);
|
||||
|
||||
public:
|
||||
char filename[512]; /* sprite's file name */
|
||||
bool associated_to_file; /* true if this sprite is associated
|
||||
@ -47,7 +54,9 @@ public:
|
||||
int frame; /* current frame, range [0,frames) */
|
||||
JList palettes; /* list of palettes */
|
||||
Stock *stock; /* stock to get images */
|
||||
Layer *set; /* layer list */
|
||||
private:
|
||||
LayerFolder *m_folder; /* main folder of layers */
|
||||
public:
|
||||
Layer *layer; /* current layer */
|
||||
Path *path; /* working path */
|
||||
Mask *mask; /* selected mask region */
|
||||
@ -101,10 +110,11 @@ public:
|
||||
bool lock_to_write();
|
||||
void unlock_to_read();
|
||||
void unlock();
|
||||
|
||||
LayerFolder* get_folder() const { return m_folder; }
|
||||
};
|
||||
|
||||
Sprite* sprite_new(int imgtype, int w, int h);
|
||||
Sprite* sprite_new_copy(const Sprite* src_sprite);
|
||||
Sprite* sprite_new_flatten_copy(const Sprite* src_sprite);
|
||||
Sprite* sprite_new_with_layer(int imgtype, int w, int h);
|
||||
|
||||
@ -131,7 +141,7 @@ void sprite_set_mask(Sprite* sprite, const Mask* mask);
|
||||
void sprite_set_layer(Sprite* sprite, Layer* layer);
|
||||
void sprite_set_frame(Sprite* sprite, int frame);
|
||||
|
||||
Layer* sprite_get_background_layer(const Sprite* sprite);
|
||||
LayerImage* sprite_get_background_layer(const Sprite* sprite);
|
||||
|
||||
void sprite_add_path(Sprite* sprite, Path* path);
|
||||
void sprite_remove_path(Sprite* sprite, Path* path);
|
||||
@ -146,7 +156,7 @@ void sprite_generate_mask_boundaries(Sprite* sprite);
|
||||
Layer* sprite_index2layer(const Sprite* sprite, int index);
|
||||
int sprite_layer2index(const Sprite* sprite, const Layer* layer);
|
||||
int sprite_count_layers(const Sprite* sprite);
|
||||
void sprite_get_cels(const Sprite* sprite, JList cels);
|
||||
void sprite_get_cels(const Sprite* sprite, CelList& cels);
|
||||
|
||||
int sprite_getpixel(const Sprite* sprite, int x, int y);
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
@ -66,6 +67,7 @@ enum {
|
||||
UNDO_TYPE_REMOVE_CEL,
|
||||
|
||||
// layer management
|
||||
UNDO_TYPE_SET_LAYER_NAME,
|
||||
UNDO_TYPE_ADD_LAYER,
|
||||
UNDO_TYPE_REMOVE_LAYER,
|
||||
UNDO_TYPE_MOVE_LAYER,
|
||||
@ -81,44 +83,45 @@ enum {
|
||||
UNDO_TYPE_SET_FRLEN,
|
||||
};
|
||||
|
||||
typedef struct UndoChunkData UndoChunkData;
|
||||
typedef struct UndoChunkImage UndoChunkImage;
|
||||
typedef struct UndoChunkFlip UndoChunkFlip;
|
||||
typedef struct UndoChunkDirty UndoChunkDirty;
|
||||
typedef struct UndoChunkAddImage UndoChunkAddImage;
|
||||
typedef struct UndoChunkRemoveImage UndoChunkRemoveImage;
|
||||
typedef struct UndoChunkReplaceImage UndoChunkReplaceImage;
|
||||
typedef struct UndoChunkAddCel UndoChunkAddCel;
|
||||
typedef struct UndoChunkRemoveCel UndoChunkRemoveCel;
|
||||
typedef struct UndoChunkAddLayer UndoChunkAddLayer;
|
||||
typedef struct UndoChunkRemoveLayer UndoChunkRemoveLayer;
|
||||
typedef struct UndoChunkMoveLayer UndoChunkMoveLayer;
|
||||
typedef struct UndoChunkSetLayer UndoChunkSetLayer;
|
||||
typedef struct UndoChunkAddPalette UndoChunkAddPalette;
|
||||
typedef struct UndoChunkRemovePalette UndoChunkRemovePalette;
|
||||
typedef struct UndoChunkSetMask UndoChunkSetMask;
|
||||
typedef struct UndoChunkSetFrames UndoChunkSetFrames;
|
||||
typedef struct UndoChunkSetFrlen UndoChunkSetFrlen;
|
||||
struct UndoChunkData;
|
||||
struct UndoChunkImage;
|
||||
struct UndoChunkFlip;
|
||||
struct UndoChunkDirty;
|
||||
struct UndoChunkAddImage;
|
||||
struct UndoChunkRemoveImage;
|
||||
struct UndoChunkReplaceImage;
|
||||
struct UndoChunkAddCel;
|
||||
struct UndoChunkRemoveCel;
|
||||
struct UndoChunkSetLayerName;
|
||||
struct UndoChunkAddLayer;
|
||||
struct UndoChunkRemoveLayer;
|
||||
struct UndoChunkMoveLayer;
|
||||
struct UndoChunkSetLayer;
|
||||
struct UndoChunkAddPalette;
|
||||
struct UndoChunkRemovePalette;
|
||||
struct UndoChunkSetMask;
|
||||
struct UndoChunkSetFrames;
|
||||
struct UndoChunkSetFrlen;
|
||||
|
||||
typedef struct UndoChunk
|
||||
struct UndoChunk
|
||||
{
|
||||
int type;
|
||||
int size;
|
||||
const char *label;
|
||||
} UndoChunk;
|
||||
};
|
||||
|
||||
typedef struct UndoStream
|
||||
struct UndoStream
|
||||
{
|
||||
Undo* undo;
|
||||
JList chunks;
|
||||
int size;
|
||||
} UndoStream;
|
||||
};
|
||||
|
||||
typedef struct UndoAction
|
||||
struct UndoAction
|
||||
{
|
||||
const char *name;
|
||||
void (*invert)(UndoStream* stream, UndoChunk* chunk, int state);
|
||||
} UndoAction;
|
||||
};
|
||||
|
||||
static void run_undo(Undo* undo, int state);
|
||||
static void discard_undo_tail(Undo* undo);
|
||||
@ -161,6 +164,9 @@ static void chunk_add_cel_invert(UndoStream* stream, UndoChunkAddCel* chunk, int
|
||||
static void chunk_remove_cel_new(UndoStream* stream, Layer* layer, Cel* cel);
|
||||
static void chunk_remove_cel_invert(UndoStream* stream, UndoChunkRemoveCel* chunk, int state);
|
||||
|
||||
static void chunk_set_layer_name_new(UndoStream* stream, Layer *layer);
|
||||
static void chunk_set_layer_name_invert(UndoStream* stream, UndoChunkSetLayerName* chunk, int state);
|
||||
|
||||
static void chunk_add_layer_new(UndoStream* stream, Layer* set, Layer* layer);
|
||||
static void chunk_add_layer_invert(UndoStream* stream, UndoChunkAddLayer* chunk, int state);
|
||||
|
||||
@ -204,6 +210,7 @@ static UndoAction undo_actions[] = {
|
||||
DECL_UNDO_ACTION(replace_image),
|
||||
DECL_UNDO_ACTION(add_cel),
|
||||
DECL_UNDO_ACTION(remove_cel),
|
||||
DECL_UNDO_ACTION(set_layer_name),
|
||||
DECL_UNDO_ACTION(add_layer),
|
||||
DECL_UNDO_ACTION(remove_layer),
|
||||
DECL_UNDO_ACTION(move_layer),
|
||||
@ -1029,13 +1036,13 @@ static void chunk_add_cel_new(UndoStream* stream, Layer* layer, Cel* cel)
|
||||
|
||||
static void chunk_add_cel_invert(UndoStream* stream, UndoChunkAddCel* chunk, int state)
|
||||
{
|
||||
Layer* layer = (Layer* )gfxobj_find(chunk->layer_id);
|
||||
Cel* cel = (Cel* )gfxobj_find(chunk->cel_id);
|
||||
LayerImage* layer = (LayerImage*)gfxobj_find(chunk->layer_id);
|
||||
Cel* cel = (Cel*)gfxobj_find(chunk->cel_id);
|
||||
|
||||
if (layer && cel) {
|
||||
chunk_remove_cel_new(stream, layer, cel);
|
||||
|
||||
layer_remove_cel(layer, cel);
|
||||
layer->remove_cel(cel);
|
||||
cel_free(cel);
|
||||
}
|
||||
}
|
||||
@ -1064,7 +1071,7 @@ void undo_remove_cel(Undo* undo, Layer* layer, Cel* cel)
|
||||
|
||||
static void chunk_remove_cel_new(UndoStream* stream, Layer* layer, Cel* cel)
|
||||
{
|
||||
UndoChunkRemoveCel* chunk = (UndoChunkRemoveCel* )
|
||||
UndoChunkRemoveCel* chunk = (UndoChunkRemoveCel*)
|
||||
undo_chunk_new(stream,
|
||||
UNDO_TYPE_REMOVE_CEL,
|
||||
sizeof(UndoChunkRemoveCel)+get_raw_cel_size(cel));
|
||||
@ -1076,7 +1083,7 @@ static void chunk_remove_cel_new(UndoStream* stream, Layer* layer, Cel* cel)
|
||||
static void chunk_remove_cel_invert(UndoStream* stream, UndoChunkRemoveCel* chunk, int state)
|
||||
{
|
||||
unsigned int layer_id = chunk->layer_id;
|
||||
Layer* layer = (Layer* )gfxobj_find(layer_id);
|
||||
LayerImage* layer = (LayerImage*)gfxobj_find(layer_id);
|
||||
|
||||
if (layer) {
|
||||
Cel* cel = read_raw_cel(chunk->data);
|
||||
@ -1084,7 +1091,64 @@ static void chunk_remove_cel_invert(UndoStream* stream, UndoChunkRemoveCel* chun
|
||||
/* assert(cel != NULL); */
|
||||
|
||||
chunk_add_cel_new(stream, layer, cel);
|
||||
layer_add_cel(layer, cel);
|
||||
layer->add_cel(cel);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
"set_layer_name"
|
||||
|
||||
DWORD layer ID
|
||||
DWORD name length
|
||||
BYTES[length] name text
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
struct UndoChunkSetLayerName
|
||||
{
|
||||
UndoChunk head;
|
||||
ase_uint32 layer_id;
|
||||
ase_uint16 name_length;
|
||||
ase_uint8 name_text[0];
|
||||
};
|
||||
|
||||
void undo_set_layer_name(Undo* undo, Layer* layer)
|
||||
{
|
||||
chunk_set_layer_name_new(undo->undo_stream, layer);
|
||||
update_undo(undo);
|
||||
}
|
||||
|
||||
static void chunk_set_layer_name_new(UndoStream* stream, Layer *layer)
|
||||
{
|
||||
std::string layer_name = layer->get_name();
|
||||
|
||||
UndoChunkSetLayerName* chunk = (UndoChunkSetLayerName*)
|
||||
undo_chunk_new(stream,
|
||||
UNDO_TYPE_SET_LAYER_NAME,
|
||||
sizeof(UndoChunkSetLayerName) + layer_name.size());
|
||||
|
||||
chunk->layer_id = layer->id;
|
||||
chunk->name_length = layer_name.size();
|
||||
|
||||
for (int c=0; c<chunk->name_length; c++)
|
||||
chunk->name_text[c] = layer_name[c];
|
||||
}
|
||||
|
||||
static void chunk_set_layer_name_invert(UndoStream* stream, UndoChunkSetLayerName* chunk, int state)
|
||||
{
|
||||
Layer* layer = (Layer*)gfxobj_find(chunk->layer_id);
|
||||
|
||||
if (layer) {
|
||||
chunk_set_layer_name_new(stream, layer);
|
||||
|
||||
std::string layer_name;
|
||||
layer_name.reserve(chunk->name_length);
|
||||
|
||||
for (int c=0; c<chunk->name_length; c++)
|
||||
layer_name.push_back(chunk->name_text[c]);
|
||||
|
||||
layer->set_name(layer_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1100,38 +1164,37 @@ static void chunk_remove_cel_invert(UndoStream* stream, UndoChunkRemoveCel* chun
|
||||
struct UndoChunkAddLayer
|
||||
{
|
||||
UndoChunk head;
|
||||
ase_uint32 set_id;
|
||||
ase_uint32 folder_id;
|
||||
ase_uint32 layer_id;
|
||||
};
|
||||
|
||||
void undo_add_layer(Undo* undo, Layer* set, Layer* layer)
|
||||
void undo_add_layer(Undo* undo, Layer* folder, Layer* layer)
|
||||
{
|
||||
chunk_add_layer_new(undo->undo_stream, set, layer);
|
||||
chunk_add_layer_new(undo->undo_stream, folder, layer);
|
||||
update_undo(undo);
|
||||
}
|
||||
|
||||
static void chunk_add_layer_new(UndoStream* stream, Layer* set, Layer* layer)
|
||||
static void chunk_add_layer_new(UndoStream* stream, Layer* folder, Layer* layer)
|
||||
{
|
||||
UndoChunkAddLayer* chunk = (UndoChunkAddLayer* )
|
||||
undo_chunk_new(stream,
|
||||
UNDO_TYPE_ADD_LAYER,
|
||||
sizeof(UndoChunkAddLayer));
|
||||
|
||||
chunk->set_id = set->id;
|
||||
chunk->folder_id = folder->id;
|
||||
chunk->layer_id = layer->id;
|
||||
}
|
||||
|
||||
static void chunk_add_layer_invert(UndoStream* stream, UndoChunkAddLayer* chunk, int state)
|
||||
{
|
||||
Layer* set = (Layer* )gfxobj_find(chunk->set_id);
|
||||
Layer* layer = (Layer* )gfxobj_find(chunk->layer_id);
|
||||
LayerFolder* folder = (LayerFolder*)gfxobj_find(chunk->folder_id);
|
||||
Layer* layer = (Layer*)gfxobj_find(chunk->layer_id);
|
||||
|
||||
if (set && layer) {
|
||||
if (folder && layer) {
|
||||
chunk_remove_layer_new(stream, layer);
|
||||
|
||||
layer_remove_layer(set, layer);
|
||||
layer_free_images(layer);
|
||||
layer_free(layer);
|
||||
folder->remove_layer(layer);
|
||||
delete layer;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1139,7 +1202,7 @@ static void chunk_add_layer_invert(UndoStream* stream, UndoChunkAddLayer* chunk,
|
||||
|
||||
"remove_layer"
|
||||
|
||||
DWORD parent layer set ID
|
||||
DWORD parent layer folder ID
|
||||
DWORD after layer ID
|
||||
LAYER_DATA see read/write_raw_layer
|
||||
|
||||
@ -1148,7 +1211,7 @@ static void chunk_add_layer_invert(UndoStream* stream, UndoChunkAddLayer* chunk,
|
||||
struct UndoChunkRemoveLayer
|
||||
{
|
||||
UndoChunk head;
|
||||
ase_uint32 set_id;
|
||||
ase_uint32 folder_id;
|
||||
ase_uint32 after_id;
|
||||
ase_uint8 data[0];
|
||||
};
|
||||
@ -1161,14 +1224,14 @@ void undo_remove_layer(Undo* undo, Layer* layer)
|
||||
|
||||
static void chunk_remove_layer_new(UndoStream* stream, Layer* layer)
|
||||
{
|
||||
UndoChunkRemoveLayer* chunk = (UndoChunkRemoveLayer* )
|
||||
UndoChunkRemoveLayer* chunk = (UndoChunkRemoveLayer*)
|
||||
undo_chunk_new(stream,
|
||||
UNDO_TYPE_REMOVE_LAYER,
|
||||
sizeof(UndoChunkRemoveLayer)+get_raw_layer_size(layer));
|
||||
Layer* set = layer->parent_layer;
|
||||
Layer* after = layer_get_prev(layer);
|
||||
LayerFolder* folder = layer->get_parent();
|
||||
Layer* after = layer->get_prev();
|
||||
|
||||
chunk->set_id = set->id;
|
||||
chunk->folder_id = folder->id;
|
||||
chunk->after_id = after != NULL ? after->id: 0;
|
||||
|
||||
write_raw_layer(chunk->data, layer);
|
||||
@ -1176,17 +1239,17 @@ static void chunk_remove_layer_new(UndoStream* stream, Layer* layer)
|
||||
|
||||
static void chunk_remove_layer_invert(UndoStream* stream, UndoChunkRemoveLayer* chunk, int state)
|
||||
{
|
||||
Layer* set = (Layer* )gfxobj_find(chunk->set_id);
|
||||
Layer* after = (Layer* )gfxobj_find(chunk->after_id);
|
||||
LayerFolder* folder = (LayerFolder*)gfxobj_find(chunk->folder_id);
|
||||
Layer* after = (Layer*)gfxobj_find(chunk->after_id);
|
||||
|
||||
if (set != NULL) {
|
||||
if (folder) {
|
||||
Layer* layer = read_raw_layer(chunk->data);
|
||||
|
||||
/* assert(layer != NULL); */
|
||||
|
||||
chunk_add_layer_new(stream, set, layer);
|
||||
layer_add_layer(set, layer);
|
||||
layer_move_layer(set, layer, after);
|
||||
chunk_add_layer_new(stream, folder, layer);
|
||||
folder->add_layer(layer);
|
||||
folder->move_layer(layer, after);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1194,7 +1257,7 @@ static void chunk_remove_layer_invert(UndoStream* stream, UndoChunkRemoveLayer*
|
||||
|
||||
"move_layer"
|
||||
|
||||
DWORD parent layer set ID
|
||||
DWORD parent layer folder ID
|
||||
DWORD layer ID
|
||||
DWORD after layer ID
|
||||
|
||||
@ -1203,7 +1266,7 @@ static void chunk_remove_layer_invert(UndoStream* stream, UndoChunkRemoveLayer*
|
||||
struct UndoChunkMoveLayer
|
||||
{
|
||||
UndoChunk head;
|
||||
ase_uint32 set_id;
|
||||
ase_uint32 folder_id;
|
||||
ase_uint32 layer_id;
|
||||
ase_uint32 after_id;
|
||||
};
|
||||
@ -1220,25 +1283,25 @@ static void chunk_move_layer_new(UndoStream* stream, Layer* layer)
|
||||
undo_chunk_new(stream,
|
||||
UNDO_TYPE_MOVE_LAYER,
|
||||
sizeof(UndoChunkMoveLayer));
|
||||
Layer* set = layer->parent_layer;
|
||||
Layer* after = layer_get_prev(layer);
|
||||
LayerFolder* folder = layer->get_parent();
|
||||
Layer* after = layer->get_prev();
|
||||
|
||||
chunk->set_id = set->id;
|
||||
chunk->folder_id = folder->id;
|
||||
chunk->layer_id = layer->id;
|
||||
chunk->after_id = after ? after->id: 0;
|
||||
}
|
||||
|
||||
static void chunk_move_layer_invert(UndoStream* stream, UndoChunkMoveLayer* chunk, int state)
|
||||
{
|
||||
Layer* set = (Layer* )gfxobj_find(chunk->set_id);
|
||||
Layer* layer = (Layer* )gfxobj_find(chunk->layer_id);
|
||||
Layer* after = (Layer* )gfxobj_find(chunk->after_id);
|
||||
LayerFolder* folder = (LayerFolder*)gfxobj_find(chunk->folder_id);
|
||||
Layer* layer = (Layer*)gfxobj_find(chunk->layer_id);
|
||||
Layer* after = (Layer*)gfxobj_find(chunk->after_id);
|
||||
|
||||
if (set == NULL || layer == NULL)
|
||||
if (folder == NULL || layer == NULL)
|
||||
throw undo_exception("chunk_move_layer_invert");
|
||||
|
||||
chunk_move_layer_new(stream, layer);
|
||||
layer_move_layer(set, layer, after);
|
||||
folder->move_layer(layer, after);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@ -1265,7 +1328,7 @@ void undo_set_layer(Undo* undo, Sprite *sprite)
|
||||
|
||||
static void chunk_set_layer_new(UndoStream* stream, Sprite *sprite)
|
||||
{
|
||||
UndoChunkSetLayer* chunk = (UndoChunkSetLayer* )
|
||||
UndoChunkSetLayer* chunk = (UndoChunkSetLayer*)
|
||||
undo_chunk_new(stream,
|
||||
UNDO_TYPE_SET_LAYER,
|
||||
sizeof(UndoChunkSetLayer));
|
||||
@ -1877,18 +1940,27 @@ static Layer* read_raw_layer(ase_uint8* raw_data)
|
||||
ase_uint32 dword;
|
||||
ase_uint16 word;
|
||||
gfxobj_id layer_id, sprite_id;
|
||||
char name[LAYER_NAME_SIZE];
|
||||
int flags, layer_type;
|
||||
std::vector<char> name(1);
|
||||
int name_length, flags, layer_type;
|
||||
Layer* layer = NULL;
|
||||
Sprite *sprite;
|
||||
|
||||
read_raw_uint32(layer_id); /* ID */
|
||||
read_raw_data(name, LAYER_NAME_SIZE); /* name */
|
||||
|
||||
read_raw_uint16(name_length); /* name length */
|
||||
name.resize(name_length+1);
|
||||
if (name_length > 0) {
|
||||
read_raw_data(&name[0], name_length); /* name */
|
||||
name[name_length] = 0;
|
||||
}
|
||||
else
|
||||
name[0] = 0;
|
||||
|
||||
read_raw_uint8(flags); /* flags */
|
||||
read_raw_uint16(layer_type); /* type */
|
||||
read_raw_uint32(sprite_id); /* sprite */
|
||||
|
||||
sprite = (Sprite *)gfxobj_find(sprite_id);
|
||||
sprite = (Sprite*)gfxobj_find(sprite_id);
|
||||
|
||||
switch (layer_type) {
|
||||
|
||||
@ -1899,10 +1971,10 @@ static Layer* read_raw_layer(ase_uint8* raw_data)
|
||||
read_raw_uint16(cels); /* cels */
|
||||
|
||||
/* create layer */
|
||||
layer = layer_new(sprite);
|
||||
layer = new LayerImage(sprite);
|
||||
|
||||
/* set blend mode */
|
||||
layer_set_blend_mode(layer, blend_mode);
|
||||
static_cast<LayerImage*>(layer)->set_blend_mode(blend_mode);
|
||||
|
||||
/* read cels */
|
||||
for (c=0; c<cels; c++) {
|
||||
@ -1914,7 +1986,7 @@ static Layer* read_raw_layer(ase_uint8* raw_data)
|
||||
raw_data += get_raw_cel_size(cel);
|
||||
|
||||
/* add the cel in the layer */
|
||||
layer_add_cel(layer, cel);
|
||||
static_cast<LayerImage*>(layer)->add_cel(cel);
|
||||
|
||||
/* read the image */
|
||||
read_raw_uint8(has_image);
|
||||
@ -1922,17 +1994,17 @@ static Layer* read_raw_layer(ase_uint8* raw_data)
|
||||
Image* image = read_raw_image(raw_data);
|
||||
raw_data += get_raw_image_size(image);
|
||||
|
||||
stock_replace_image(layer->sprite->stock, cel->image, image);
|
||||
stock_replace_image(layer->get_sprite()->stock, cel->image, image);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GFXOBJ_LAYER_SET: {
|
||||
case GFXOBJ_LAYER_FOLDER: {
|
||||
int c, layers;
|
||||
|
||||
/* create the layer set */
|
||||
layer = layer_set_new(sprite);
|
||||
layer = new LayerFolder(sprite);
|
||||
|
||||
/* read how many sub-layers */
|
||||
read_raw_uint16(layers);
|
||||
@ -1940,7 +2012,7 @@ static Layer* read_raw_layer(ase_uint8* raw_data)
|
||||
for (c=0; c<layers; c++) {
|
||||
Layer* child = read_raw_layer(raw_data);
|
||||
if (child) {
|
||||
layer_add_layer(layer, child);
|
||||
static_cast<LayerFolder*>(layer)->add_layer(child);
|
||||
raw_data += get_raw_layer_size(child);
|
||||
}
|
||||
else
|
||||
@ -1952,10 +2024,10 @@ static Layer* read_raw_layer(ase_uint8* raw_data)
|
||||
}
|
||||
|
||||
if (layer != NULL) {
|
||||
layer_set_name(layer, name);
|
||||
layer->flags = flags;
|
||||
layer->set_name(&name[0]);
|
||||
*layer->flags_addr() = flags;
|
||||
|
||||
_gfxobj_set_id((GfxObj *)layer, layer_id);
|
||||
_gfxobj_set_id((GfxObj*)layer, layer_id);
|
||||
}
|
||||
|
||||
return layer;
|
||||
@ -1965,30 +2037,39 @@ static ase_uint8* write_raw_layer(ase_uint8* raw_data, Layer* layer)
|
||||
{
|
||||
ase_uint32 dword;
|
||||
ase_uint16 word;
|
||||
JLink link;
|
||||
std::string name = layer->get_name();
|
||||
|
||||
write_raw_uint32(layer->id); /* ID */
|
||||
write_raw_data(layer->name, LAYER_NAME_SIZE); /* name */
|
||||
write_raw_uint8(layer->flags); /* flags */
|
||||
|
||||
write_raw_uint16(name.size()); /* name length */
|
||||
if (!name.empty())
|
||||
write_raw_data(name.c_str(), name.size()); /* name */
|
||||
|
||||
write_raw_uint8(*layer->flags_addr()); /* flags */
|
||||
write_raw_uint16(layer->type); /* type */
|
||||
write_raw_uint32(layer->sprite->id); /* sprite */
|
||||
write_raw_uint32(layer->get_sprite()->id); /* sprite */
|
||||
|
||||
switch (layer->type) {
|
||||
|
||||
case GFXOBJ_LAYER_IMAGE:
|
||||
/* blend mode */
|
||||
write_raw_uint8(layer->blend_mode);
|
||||
/* cels */
|
||||
write_raw_uint16(jlist_length(layer->cels));
|
||||
JI_LIST_FOR_EACH(layer->cels, link) {
|
||||
Cel* cel = reinterpret_cast<Cel*>(link->data);
|
||||
case GFXOBJ_LAYER_IMAGE: {
|
||||
// blend mode
|
||||
write_raw_uint8(static_cast<LayerImage*>(layer)->get_blend_mode());
|
||||
|
||||
// cels
|
||||
write_raw_uint16(static_cast<LayerImage*>(layer)->get_cels_count());
|
||||
|
||||
CelIterator it = static_cast<LayerImage*>(layer)->get_cel_begin();
|
||||
CelIterator end = static_cast<LayerImage*>(layer)->get_cel_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
Cel* cel = *it;
|
||||
raw_data = write_raw_cel(raw_data, cel);
|
||||
|
||||
if (cel_is_link(cel, layer)) {
|
||||
if (cel_is_link(cel, static_cast<LayerImage*>(layer))) {
|
||||
write_raw_uint8(0);
|
||||
}
|
||||
else {
|
||||
Image* image = layer->sprite->stock->image[cel->image];
|
||||
Image* image = layer->get_sprite()->stock->image[cel->image];
|
||||
assert(image != NULL);
|
||||
|
||||
write_raw_uint8(1);
|
||||
@ -1996,13 +2077,19 @@ static ase_uint8* write_raw_layer(ase_uint8* raw_data, Layer* layer)
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GFXOBJ_LAYER_SET:
|
||||
write_raw_uint16(jlist_length(layer->layers)); /* how many sub-layers */
|
||||
JI_LIST_FOR_EACH(layer->layers, link) {
|
||||
raw_data = write_raw_layer(raw_data, reinterpret_cast<Layer*>(link->data));
|
||||
}
|
||||
case GFXOBJ_LAYER_FOLDER: {
|
||||
LayerIterator it = static_cast<LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerIterator end = static_cast<LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
// how many sub-layers
|
||||
write_raw_uint16(static_cast<LayerFolder*>(layer)->get_layers_count());
|
||||
|
||||
for (; it != end; ++it)
|
||||
raw_data = write_raw_layer(raw_data, *it);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2011,31 +2098,39 @@ static ase_uint8* write_raw_layer(ase_uint8* raw_data, Layer* layer)
|
||||
|
||||
static int get_raw_layer_size(Layer* layer)
|
||||
{
|
||||
JLink link;
|
||||
int size = 4+LAYER_NAME_SIZE+1+2+4;
|
||||
int size = 4+2+layer->get_name().size()+1+2+4;
|
||||
|
||||
switch (layer->type) {
|
||||
|
||||
case GFXOBJ_LAYER_IMAGE:
|
||||
size += 1; /* blend mode */
|
||||
size += 2; /* num of cels */
|
||||
JI_LIST_FOR_EACH(layer->cels, link) {
|
||||
Cel* cel = reinterpret_cast<Cel*>(link->data);
|
||||
case GFXOBJ_LAYER_IMAGE: {
|
||||
size += 1; // blend mode
|
||||
size += 2; // num of cels
|
||||
|
||||
CelIterator it = static_cast<LayerImage*>(layer)->get_cel_begin();
|
||||
CelIterator end = static_cast<LayerImage*>(layer)->get_cel_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
Cel* cel = *it;
|
||||
size += get_raw_cel_size(cel);
|
||||
size++; /* has image? */
|
||||
if (!cel_is_link(cel, layer)) {
|
||||
Image* image = layer->sprite->stock->image[cel->image];
|
||||
size++; // has image?
|
||||
if (!cel_is_link(cel, static_cast<LayerImage*>(layer))) {
|
||||
Image* image = layer->get_sprite()->stock->image[cel->image];
|
||||
size += get_raw_image_size(image);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GFXOBJ_LAYER_SET:
|
||||
size += 2; /* how many sub-layers */
|
||||
JI_LIST_FOR_EACH(layer->layers, link) {
|
||||
size += get_raw_layer_size(reinterpret_cast<Layer*>(link->data));
|
||||
}
|
||||
case GFXOBJ_LAYER_FOLDER: {
|
||||
size += 2; // how many sub-layers
|
||||
|
||||
LayerIterator it = static_cast<LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerIterator end = static_cast<LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
size += get_raw_layer_size(*it);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,7 @@ void undo_dirty(Undo* undo, Dirty *dirty);
|
||||
void undo_add_image(Undo* undo, Stock *stock, int image_index);
|
||||
void undo_remove_image(Undo* undo, Stock *stock, int image_index);
|
||||
void undo_replace_image(Undo* undo, Stock *stock, int image_index);
|
||||
void undo_set_layer_name(Undo* undo, Layer *layer);
|
||||
void undo_add_cel(Undo* undo, Layer *layer, Cel *cel);
|
||||
void undo_remove_cel(Undo* undo, Layer *layer, Cel *cel);
|
||||
void undo_add_layer(Undo* undo, Layer *set, Layer *layer);
|
||||
|
228
src/undoable.cpp
228
src/undoable.cpp
@ -139,7 +139,7 @@ void Undoable::crop_sprite(int x, int y, int w, int h, int bgcolor)
|
||||
{
|
||||
set_sprite_size(w, h);
|
||||
|
||||
displace_layers(m_sprite->set, -x, -y);
|
||||
displace_layers(m_sprite->get_folder(), -x, -y);
|
||||
|
||||
Layer *background_layer = sprite_get_background_layer(m_sprite);
|
||||
if (background_layer)
|
||||
@ -316,15 +316,16 @@ void Undoable::replace_stock_image(int image_index, Image* new_image)
|
||||
Layer* Undoable::new_layer()
|
||||
{
|
||||
// new layer
|
||||
Layer* layer = layer_new(m_sprite);
|
||||
LayerImage* layer = new LayerImage(m_sprite);
|
||||
|
||||
// configure layer name and blend mode
|
||||
layer_set_blend_mode(layer, BLEND_MODE_NORMAL);
|
||||
layer->set_blend_mode(BLEND_MODE_NORMAL);
|
||||
|
||||
// add the layer in the sprite set
|
||||
if (is_enabled())
|
||||
undo_add_layer(m_sprite->undo, m_sprite->set, layer);
|
||||
layer_add_layer(m_sprite->set, layer);
|
||||
undo_add_layer(m_sprite->undo, m_sprite->get_folder(), layer);
|
||||
|
||||
m_sprite->get_folder()->add_layer(layer);
|
||||
|
||||
// select the new layer
|
||||
set_current_layer(layer);
|
||||
@ -339,7 +340,7 @@ void Undoable::remove_layer(Layer* layer)
|
||||
{
|
||||
assert(layer);
|
||||
|
||||
Layer* parent = layer->parent_layer;
|
||||
LayerFolder* parent = layer->get_parent();
|
||||
|
||||
// if the layer to be removed is the selected layer
|
||||
if (layer == m_sprite->layer) {
|
||||
@ -347,11 +348,11 @@ void Undoable::remove_layer(Layer* layer)
|
||||
|
||||
// select: previous layer, or next layer, or parent(if it is not the
|
||||
// main layer of sprite set)
|
||||
if (layer_get_prev(layer))
|
||||
layer_select = layer_get_prev(layer);
|
||||
else if (layer_get_next(layer))
|
||||
layer_select = layer_get_next(layer);
|
||||
else if (parent != m_sprite->set)
|
||||
if (layer->get_prev())
|
||||
layer_select = layer->get_prev();
|
||||
else if (layer->get_next())
|
||||
layer_select = layer->get_next();
|
||||
else if (parent != m_sprite->get_folder())
|
||||
layer_select = parent;
|
||||
|
||||
// select other layer
|
||||
@ -362,11 +363,10 @@ void Undoable::remove_layer(Layer* layer)
|
||||
if (is_enabled())
|
||||
undo_remove_layer(m_sprite->undo, layer);
|
||||
|
||||
layer_remove_layer(parent, layer);
|
||||
parent->remove_layer(layer);
|
||||
|
||||
// destroy the layer
|
||||
layer_free_images(layer);
|
||||
layer_free(layer);
|
||||
delete layer;
|
||||
}
|
||||
|
||||
void Undoable::move_layer_after(Layer* layer, Layer* after_this)
|
||||
@ -374,20 +374,21 @@ void Undoable::move_layer_after(Layer* layer, Layer* after_this)
|
||||
if (is_enabled())
|
||||
undo_move_layer(m_sprite->undo, layer);
|
||||
|
||||
layer_move_layer(layer->parent_layer, layer, after_this);
|
||||
layer->get_parent()->move_layer(layer, after_this);
|
||||
}
|
||||
|
||||
void Undoable::crop_layer(Layer* layer, int x, int y, int w, int h, int bgcolor)
|
||||
{
|
||||
JLink link;
|
||||
if (!layer->is_image())
|
||||
return;
|
||||
|
||||
if (!layer_is_background(layer))
|
||||
if (!layer->is_background())
|
||||
bgcolor = 0;
|
||||
|
||||
JI_LIST_FOR_EACH(layer->cels, link) {
|
||||
Cel* cel = reinterpret_cast<Cel*>(link->data);
|
||||
crop_cel(cel, x, y, w, h, bgcolor);
|
||||
}
|
||||
CelIterator it = ((LayerImage*)layer)->get_cel_begin();
|
||||
CelIterator end = ((LayerImage*)layer)->get_cel_end();
|
||||
for (; it != end; ++it)
|
||||
crop_cel(*it, x, y, w, h, bgcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -398,33 +399,33 @@ void Undoable::displace_layers(Layer* layer, int dx, int dy)
|
||||
switch (layer->type) {
|
||||
|
||||
case GFXOBJ_LAYER_IMAGE: {
|
||||
Cel* cel;
|
||||
JLink link;
|
||||
|
||||
JI_LIST_FOR_EACH(layer->cels, link) {
|
||||
cel = reinterpret_cast<Cel*>(link->data);
|
||||
CelIterator it = ((LayerImage*)layer)->get_cel_begin();
|
||||
CelIterator end = ((LayerImage*)layer)->get_cel_end();
|
||||
for (; it != end; ++it) {
|
||||
Cel* cel = *it;
|
||||
set_cel_position(cel, cel->x+dx, cel->y+dy);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GFXOBJ_LAYER_SET: {
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->layers, link)
|
||||
displace_layers(reinterpret_cast<Layer*>(link->data), dx, dy);
|
||||
case GFXOBJ_LAYER_FOLDER: {
|
||||
LayerIterator it = ((LayerFolder*)layer)->get_layer_begin();
|
||||
LayerIterator end = ((LayerFolder*)layer)->get_layer_end();
|
||||
for (; it != end; ++it)
|
||||
displace_layers(*it, dx, dy);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Undoable::background_from_layer(Layer* layer, int bgcolor)
|
||||
void Undoable::background_from_layer(LayerImage* layer, int bgcolor)
|
||||
{
|
||||
assert(layer);
|
||||
assert(layer_is_image(layer));
|
||||
assert(layer_is_readable(layer));
|
||||
assert(layer_is_writable(layer));
|
||||
assert(layer->sprite == m_sprite);
|
||||
assert(layer->is_image());
|
||||
assert(layer->is_readable());
|
||||
assert(layer->is_writable());
|
||||
assert(layer->get_sprite() == m_sprite);
|
||||
assert(sprite_get_background_layer(m_sprite) == NULL);
|
||||
|
||||
// create a temporary image to draw each frame of the new
|
||||
@ -432,9 +433,11 @@ void Undoable::background_from_layer(Layer* layer, int bgcolor)
|
||||
std::auto_ptr<Image> bg_image_wrap(image_new(m_sprite->imgtype, m_sprite->w, m_sprite->h));
|
||||
Image* bg_image = bg_image_wrap.get();
|
||||
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->cels, link) {
|
||||
Cel* cel = reinterpret_cast<Cel*>(link->data);
|
||||
CelIterator it = layer->get_cel_begin();
|
||||
CelIterator end = layer->get_cel_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
Cel* cel = *it;
|
||||
assert((cel->image > 0) &&
|
||||
(cel->image < m_sprite->stock->nimage));
|
||||
|
||||
@ -447,7 +450,7 @@ void Undoable::background_from_layer(Layer* layer, int bgcolor)
|
||||
cel->x,
|
||||
cel->y,
|
||||
MID(0, cel->opacity, 255),
|
||||
layer->blend_mode);
|
||||
layer->get_blend_mode());
|
||||
|
||||
// now we have to copy the new image (bg_image) to the cel...
|
||||
set_cel_position(cel, 0, 0);
|
||||
@ -472,33 +475,29 @@ void Undoable::layer_from_background()
|
||||
{
|
||||
assert(sprite_get_background_layer(m_sprite) != NULL);
|
||||
assert(m_sprite->layer != NULL);
|
||||
assert(layer_is_image(m_sprite->layer));
|
||||
assert(layer_is_readable(m_sprite->layer));
|
||||
assert(layer_is_writable(m_sprite->layer));
|
||||
assert(layer_is_background(m_sprite->layer));
|
||||
assert(m_sprite->layer->is_image());
|
||||
assert(m_sprite->layer->is_readable());
|
||||
assert(m_sprite->layer->is_writable());
|
||||
assert(m_sprite->layer->is_background());
|
||||
|
||||
if (is_enabled()) {
|
||||
undo_data(m_sprite->undo,
|
||||
m_sprite->layer,
|
||||
&m_sprite->layer->flags,
|
||||
sizeof(m_sprite->layer->flags));
|
||||
m_sprite->layer->flags_addr(),
|
||||
sizeof(*m_sprite->layer->flags_addr()));
|
||||
|
||||
undo_data(m_sprite->undo,
|
||||
m_sprite->layer,
|
||||
&m_sprite->layer->name,
|
||||
LAYER_NAME_SIZE);
|
||||
undo_set_layer_name(m_sprite->undo, m_sprite->layer);
|
||||
}
|
||||
|
||||
m_sprite->layer->flags &= ~(LAYER_IS_LOCKMOVE | LAYER_IS_BACKGROUND);
|
||||
layer_set_name(m_sprite->layer, "Layer 0");
|
||||
m_sprite->layer->set_background(false);
|
||||
m_sprite->layer->set_moveable(true);
|
||||
m_sprite->layer->set_name("Layer 0");
|
||||
}
|
||||
|
||||
void Undoable::flatten_layers(int bgcolor)
|
||||
{
|
||||
JLink link, next;
|
||||
Layer *background;
|
||||
Image *cel_image;
|
||||
Cel *cel;
|
||||
Image* cel_image;
|
||||
Cel* cel;
|
||||
int frame;
|
||||
|
||||
// create a temporary image
|
||||
@ -506,29 +505,29 @@ void Undoable::flatten_layers(int bgcolor)
|
||||
Image* image = image_wrap.get();
|
||||
|
||||
/* get the background layer from the sprite */
|
||||
background = sprite_get_background_layer(m_sprite);
|
||||
LayerImage* background = sprite_get_background_layer(m_sprite);
|
||||
if (!background) {
|
||||
/* if there aren't a background layer we must to create the background */
|
||||
background = layer_new(m_sprite);
|
||||
background = new LayerImage(m_sprite);
|
||||
|
||||
if (is_enabled())
|
||||
undo_add_layer(m_sprite->undo, m_sprite->set, background);
|
||||
undo_add_layer(m_sprite->undo, m_sprite->get_folder(), background);
|
||||
|
||||
layer_add_layer(m_sprite->set, background);
|
||||
m_sprite->get_folder()->add_layer(background);
|
||||
|
||||
if (is_enabled())
|
||||
undo_move_layer(m_sprite->undo, background);
|
||||
|
||||
layer_configure_as_background(background);
|
||||
background->configure_as_background();
|
||||
}
|
||||
|
||||
/* copy all frames to the background */
|
||||
for (frame=0; frame<m_sprite->frames; frame++) {
|
||||
/* clear the image and render this frame */
|
||||
image_clear(image, bgcolor);
|
||||
layer_render(m_sprite->set, image, 0, 0, frame);
|
||||
layer_render(m_sprite->get_folder(), image, 0, 0, frame);
|
||||
|
||||
cel = layer_get_cel(background, frame);
|
||||
cel = background->get_cel(frame);
|
||||
if (cel) {
|
||||
cel_image = m_sprite->stock->image[cel->image];
|
||||
assert(cel_image != NULL);
|
||||
@ -551,7 +550,7 @@ void Undoable::flatten_layers(int bgcolor)
|
||||
/* TODO error handling: if (!cel) { ... } */
|
||||
|
||||
/* and finally we add the cel in the background */
|
||||
layer_add_cel(background, cel);
|
||||
background->add_cel(cel);
|
||||
}
|
||||
|
||||
image_copy(cel_image, image, 0, 0);
|
||||
@ -566,38 +565,41 @@ void Undoable::flatten_layers(int bgcolor)
|
||||
}
|
||||
|
||||
/* remove old layers */
|
||||
JI_LIST_FOR_EACH_SAFE(m_sprite->set->layers, link, next) {
|
||||
if (link->data != background) {
|
||||
Layer* old_layer = reinterpret_cast<Layer*>(link->data);
|
||||
LayerList layers = m_sprite->get_folder()->get_layers_list();
|
||||
LayerIterator it = layers.begin();
|
||||
LayerIterator end = layers.end();
|
||||
|
||||
/* remove the layer */
|
||||
for (; it != end; ++it) {
|
||||
if (*it != background) {
|
||||
Layer* old_layer = *it;
|
||||
|
||||
// remove the layer
|
||||
if (is_enabled())
|
||||
undo_remove_layer(m_sprite->undo, old_layer);
|
||||
|
||||
layer_remove_layer(m_sprite->set, old_layer);
|
||||
m_sprite->get_folder()->remove_layer(old_layer);
|
||||
|
||||
/* destroy the layer */
|
||||
layer_free_images(old_layer);
|
||||
layer_free(old_layer);
|
||||
// destroy the layer
|
||||
delete old_layer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Undoable::configure_layer_as_background(Layer* layer)
|
||||
void Undoable::configure_layer_as_background(LayerImage* layer)
|
||||
{
|
||||
if (is_enabled()) {
|
||||
undo_data(m_sprite->undo, (GfxObj *)layer, &layer->flags, sizeof(layer->flags));
|
||||
undo_data(m_sprite->undo, (GfxObj *)layer, &layer->name, LAYER_NAME_SIZE);
|
||||
undo_data(m_sprite->undo, layer, layer->flags_addr(), sizeof(*layer->flags_addr()));
|
||||
undo_set_layer_name(m_sprite->undo, layer);
|
||||
undo_move_layer(m_sprite->undo, layer);
|
||||
}
|
||||
|
||||
layer_configure_as_background(layer);
|
||||
layer->configure_as_background();
|
||||
}
|
||||
|
||||
void Undoable::new_frame()
|
||||
{
|
||||
// add a new cel to every layer
|
||||
new_frame_for_layer(m_sprite->set,
|
||||
new_frame_for_layer(m_sprite->get_folder(),
|
||||
m_sprite->frame+1);
|
||||
|
||||
// increment frames counter in the sprite
|
||||
@ -617,7 +619,7 @@ void Undoable::new_frame_for_layer(Layer* layer, int frame)
|
||||
case GFXOBJ_LAYER_IMAGE:
|
||||
// displace all cels in '>=frame' to the next frame
|
||||
for (int c=m_sprite->frames-1; c>=frame; --c) {
|
||||
Cel* cel = layer_get_cel(layer, c);
|
||||
Cel* cel = static_cast<LayerImage*>(layer)->get_cel(c);
|
||||
if (cel)
|
||||
set_cel_frame_position(cel, cel->frame+1);
|
||||
}
|
||||
@ -625,10 +627,12 @@ void Undoable::new_frame_for_layer(Layer* layer, int frame)
|
||||
copy_previous_frame(layer, frame);
|
||||
break;
|
||||
|
||||
case GFXOBJ_LAYER_SET: {
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->layers, link)
|
||||
new_frame_for_layer(reinterpret_cast<Layer*>(link->data), frame);
|
||||
case GFXOBJ_LAYER_FOLDER: {
|
||||
LayerIterator it = static_cast<LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerIterator end = static_cast<LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
new_frame_for_layer(*it, frame);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -641,7 +645,7 @@ void Undoable::remove_frame(int frame)
|
||||
|
||||
// remove cels from this frame (and displace one position backward
|
||||
// all next frames)
|
||||
remove_frame_of_layer(m_sprite->set, frame);
|
||||
remove_frame_of_layer(m_sprite->get_folder(), frame);
|
||||
|
||||
/* decrement frames counter in the sprite */
|
||||
if (is_enabled())
|
||||
@ -666,18 +670,20 @@ void Undoable::remove_frame_of_layer(Layer* layer, int frame)
|
||||
switch (layer->type) {
|
||||
|
||||
case GFXOBJ_LAYER_IMAGE:
|
||||
if (Cel* cel = layer_get_cel(layer, frame))
|
||||
remove_cel(layer, cel);
|
||||
if (Cel* cel = static_cast<LayerImage*>(layer)->get_cel(frame))
|
||||
remove_cel(static_cast<LayerImage*>(layer), cel);
|
||||
|
||||
for (++frame; frame<m_sprite->frames; ++frame)
|
||||
if (Cel* cel = layer_get_cel(layer, frame))
|
||||
if (Cel* cel = static_cast<LayerImage*>(layer)->get_cel(frame))
|
||||
set_cel_frame_position(cel, cel->frame-1);
|
||||
break;
|
||||
|
||||
case GFXOBJ_LAYER_SET: {
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->layers, link)
|
||||
remove_frame_of_layer(reinterpret_cast<Layer*>(link->data), frame);
|
||||
case GFXOBJ_LAYER_FOLDER: {
|
||||
LayerIterator it = static_cast<LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerIterator end = static_cast<LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
remove_frame_of_layer(*it, frame);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -693,7 +699,7 @@ void Undoable::copy_previous_frame(Layer* layer, int frame)
|
||||
assert(frame > 0);
|
||||
|
||||
// create a copy of the previous cel
|
||||
Cel* src_cel = layer_get_cel(layer, frame-1);
|
||||
Cel* src_cel = static_cast<LayerImage*>(layer)->get_cel(frame-1);
|
||||
Image* src_image = src_cel ? stock_get_image(m_sprite->stock,
|
||||
src_cel->image):
|
||||
NULL;
|
||||
@ -714,32 +720,30 @@ void Undoable::copy_previous_frame(Layer* layer, int frame)
|
||||
}
|
||||
|
||||
// add the cel in the layer
|
||||
add_cel(layer, dst_cel);
|
||||
static_cast<LayerImage*>(layer)->add_cel(dst_cel);
|
||||
}
|
||||
|
||||
void Undoable::add_cel(Layer* layer, Cel* cel)
|
||||
void Undoable::add_cel(LayerImage* layer, Cel* cel)
|
||||
{
|
||||
assert(layer);
|
||||
assert(cel);
|
||||
assert(layer_is_image(layer));
|
||||
|
||||
if (is_enabled())
|
||||
undo_add_cel(m_sprite->undo, layer, cel);
|
||||
|
||||
layer_add_cel(layer, cel);
|
||||
layer->add_cel(cel);
|
||||
}
|
||||
|
||||
void Undoable::remove_cel(Layer* layer, Cel* cel)
|
||||
void Undoable::remove_cel(LayerImage* layer, Cel* cel)
|
||||
{
|
||||
assert(layer);
|
||||
assert(cel);
|
||||
assert(layer_is_image(layer));
|
||||
|
||||
// find if the image that use the cel to remove, is used by
|
||||
// another cels
|
||||
bool used = false;
|
||||
for (int frame=0; frame<m_sprite->frames; ++frame) {
|
||||
Cel* it = layer_get_cel(layer, frame);
|
||||
Cel* it = layer->get_cel(frame);
|
||||
if (it && it != cel && it->image == cel->image) {
|
||||
used = true;
|
||||
break;
|
||||
@ -755,7 +759,7 @@ void Undoable::remove_cel(Layer* layer, Cel* cel)
|
||||
undo_remove_cel(m_sprite->undo, layer, cel);
|
||||
|
||||
// remove the cel from the layer
|
||||
layer_remove_cel(layer, cel);
|
||||
layer->remove_cel(cel);
|
||||
|
||||
// and here we destroy the cel
|
||||
cel_free(cel);
|
||||
@ -834,7 +838,7 @@ void Undoable::move_frame_before(int frame, int before_frame)
|
||||
}
|
||||
|
||||
// change the cels of position...
|
||||
move_frame_before_layer(m_sprite->set, frame, before_frame);
|
||||
move_frame_before_layer(m_sprite->get_folder(), frame, before_frame);
|
||||
}
|
||||
}
|
||||
|
||||
@ -845,9 +849,11 @@ void Undoable::move_frame_before_layer(Layer* layer, int frame, int before_frame
|
||||
switch (layer->type) {
|
||||
|
||||
case GFXOBJ_LAYER_IMAGE: {
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->cels, link) {
|
||||
Cel* cel = reinterpret_cast<Cel*>(link->data);
|
||||
CelIterator it = ((LayerImage*)layer)->get_cel_begin();
|
||||
CelIterator end = ((LayerImage*)layer)->get_cel_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
Cel* cel = *it;
|
||||
int new_frame = cel->frame;
|
||||
|
||||
// moving the frame to the future
|
||||
@ -877,10 +883,12 @@ void Undoable::move_frame_before_layer(Layer* layer, int frame, int before_frame
|
||||
break;
|
||||
}
|
||||
|
||||
case GFXOBJ_LAYER_SET: {
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->layers, link)
|
||||
move_frame_before_layer(reinterpret_cast<Layer*>(link->data), frame, before_frame);
|
||||
case GFXOBJ_LAYER_FOLDER: {
|
||||
LayerIterator it = static_cast<LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerIterator end = static_cast<LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
move_frame_before_layer(*it, frame, before_frame);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -889,8 +897,8 @@ void Undoable::move_frame_before_layer(Layer* layer, int frame, int before_frame
|
||||
|
||||
Cel* Undoable::get_current_cel()
|
||||
{
|
||||
if (m_sprite->layer && layer_is_image(m_sprite->layer))
|
||||
return layer_get_cel(m_sprite->layer, m_sprite->frame);
|
||||
if (m_sprite->layer && m_sprite->layer->is_image())
|
||||
return static_cast<LayerImage*>(m_sprite->layer)->get_cel(m_sprite->frame);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@ -933,7 +941,7 @@ void Undoable::clear_mask(int bgcolor)
|
||||
// in the cel
|
||||
if (mask_is_empty(m_sprite->mask)) {
|
||||
// if the layer is the background then we clear the image
|
||||
if (layer_is_background(m_sprite->layer)) {
|
||||
if (m_sprite->layer->is_background()) {
|
||||
if (is_enabled())
|
||||
undo_image(m_sprite->undo, image, 0, 0, image->w, image->h);
|
||||
|
||||
@ -943,7 +951,7 @@ void Undoable::clear_mask(int bgcolor)
|
||||
// if the layer is transparent we can remove the cel (and its
|
||||
// associated image)
|
||||
else {
|
||||
remove_cel(m_sprite->layer, cel);
|
||||
static_cast<LayerImage*>(m_sprite->layer)->remove_cel(cel);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -22,6 +22,7 @@
|
||||
class Cel;
|
||||
class Mask;
|
||||
class Layer;
|
||||
class LayerImage;
|
||||
class Sprite;
|
||||
class SpriteWriter;
|
||||
|
||||
@ -66,11 +67,11 @@ public:
|
||||
void move_layer_after(Layer *layer, Layer *after_this);
|
||||
void crop_layer(Layer* layer, int x, int y, int w, int h, int bgcolor);
|
||||
void displace_layers(Layer* layer, int dx, int dy);
|
||||
void background_from_layer(Layer* layer, int bgcolor);
|
||||
void background_from_layer(LayerImage* layer, int bgcolor);
|
||||
void layer_from_background();
|
||||
void flatten_layers(int bgcolor);
|
||||
private:
|
||||
void configure_layer_as_background(Layer* layer);
|
||||
void configure_layer_as_background(LayerImage* layer);
|
||||
|
||||
public:
|
||||
// for frames
|
||||
@ -85,8 +86,8 @@ public:
|
||||
void move_frame_before_layer(Layer* layer, int frame, int before_frame);
|
||||
|
||||
// for cels
|
||||
void add_cel(Layer* layer, Cel* cel);
|
||||
void remove_cel(Layer* layer, Cel* cel);
|
||||
void add_cel(LayerImage* layer, Cel* cel);
|
||||
void remove_cel(LayerImage* layer, Cel* cel);
|
||||
void set_cel_frame_position(Cel* cel, int frame);
|
||||
void set_cel_position(Cel* cel, int x, int y);
|
||||
Cel* get_current_cel();
|
||||
|
@ -38,12 +38,12 @@
|
||||
|
||||
/* these variables indicate what cel to move (and the sprite's
|
||||
frame indicates where to move it) */
|
||||
static Layer *src_layer = NULL; /* TODO warning not thread safe */
|
||||
static Layer *dst_layer = NULL;
|
||||
static Layer* src_layer = NULL; // TODO warning not thread safe
|
||||
static Layer* dst_layer = NULL;
|
||||
static int src_frame = 0;
|
||||
static int dst_frame = 0;
|
||||
|
||||
static void remove_cel(Sprite* sprite, Layer *layer, Cel *cel);
|
||||
static void remove_cel(Sprite* sprite, LayerImage* layer, Cel* cel);
|
||||
|
||||
void set_frame_to_handle(Layer *_src_layer, int _src_frame,
|
||||
Layer *_dst_layer, int _dst_frame)
|
||||
@ -63,13 +63,13 @@ void move_cel(SpriteWriter& sprite)
|
||||
assert(src_frame >= 0 && src_frame < sprite->frames);
|
||||
assert(dst_frame >= 0 && dst_frame < sprite->frames);
|
||||
|
||||
if (layer_is_background(src_layer)) {
|
||||
if (src_layer->is_background()) {
|
||||
copy_cel(sprite);
|
||||
return;
|
||||
}
|
||||
|
||||
src_cel = layer_get_cel(src_layer, src_frame);
|
||||
dst_cel = layer_get_cel(dst_layer, dst_frame);
|
||||
src_cel = static_cast<LayerImage*>(src_layer)->get_cel(src_frame);
|
||||
dst_cel = static_cast<LayerImage*>(dst_layer)->get_cel(dst_frame);
|
||||
|
||||
if (undo_is_enabled(sprite->undo)) {
|
||||
undo_set_label(sprite->undo, "Move Cel");
|
||||
@ -84,8 +84,8 @@ void move_cel(SpriteWriter& sprite)
|
||||
|
||||
/* remove the 'dst_cel' (if it exists) because it must be
|
||||
replaced with 'src_cel' */
|
||||
if ((dst_cel != NULL) && (!layer_is_background(dst_layer) || src_cel != NULL))
|
||||
remove_cel(sprite, dst_layer, dst_cel);
|
||||
if ((dst_cel != NULL) && (!dst_layer->is_background() || src_cel != NULL))
|
||||
remove_cel(sprite, static_cast<LayerImage*>(dst_layer), dst_cel);
|
||||
|
||||
/* move the cel in the same layer */
|
||||
if (src_cel != NULL) {
|
||||
@ -99,15 +99,15 @@ void move_cel(SpriteWriter& sprite)
|
||||
else {
|
||||
if (undo_is_enabled(sprite->undo))
|
||||
undo_remove_cel(sprite->undo, src_layer, src_cel);
|
||||
layer_remove_cel(src_layer, src_cel);
|
||||
static_cast<LayerImage*>(src_layer)->remove_cel(src_cel);
|
||||
|
||||
src_cel->frame = dst_frame;
|
||||
|
||||
/* if we are moving a cel from a transparent layer to the
|
||||
background layer, we have to clear the background of the
|
||||
image */
|
||||
if (!layer_is_background(src_layer) &&
|
||||
layer_is_background(dst_layer)) {
|
||||
if (!src_layer->is_background() &&
|
||||
dst_layer->is_background()) {
|
||||
Image *src_image = stock_get_image(sprite->stock, src_cel->image);
|
||||
Image *dst_image = image_crop(src_image,
|
||||
-src_cel->x,
|
||||
@ -135,7 +135,8 @@ void move_cel(SpriteWriter& sprite)
|
||||
|
||||
if (undo_is_enabled(sprite->undo))
|
||||
undo_add_cel(sprite->undo, dst_layer, src_cel);
|
||||
layer_add_cel(dst_layer, src_cel);
|
||||
|
||||
static_cast<LayerImage*>(dst_layer)->add_cel(src_cel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,8 +155,8 @@ void copy_cel(SpriteWriter& sprite)
|
||||
assert(src_frame >= 0 && src_frame < sprite->frames);
|
||||
assert(dst_frame >= 0 && dst_frame < sprite->frames);
|
||||
|
||||
src_cel = layer_get_cel(src_layer, src_frame);
|
||||
dst_cel = layer_get_cel(dst_layer, dst_frame);
|
||||
src_cel = static_cast<LayerImage*>(src_layer)->get_cel(src_frame);
|
||||
dst_cel = static_cast<LayerImage*>(dst_layer)->get_cel(dst_frame);
|
||||
|
||||
if (undo_is_enabled(sprite->undo)) {
|
||||
undo_set_label(sprite->undo, "Move Cel");
|
||||
@ -170,8 +171,8 @@ void copy_cel(SpriteWriter& sprite)
|
||||
|
||||
/* remove the 'dst_cel' (if it exists) because it must be
|
||||
replaced with 'src_cel' */
|
||||
if ((dst_cel != NULL) && (!layer_is_background(dst_layer) || src_cel != NULL))
|
||||
remove_cel(sprite, dst_layer, dst_cel);
|
||||
if ((dst_cel != NULL) && (!dst_layer->is_background() || src_cel != NULL))
|
||||
remove_cel(sprite, static_cast<LayerImage*>(dst_layer), dst_cel);
|
||||
|
||||
/* move the cel in the same layer */
|
||||
if (src_cel != NULL) {
|
||||
@ -185,8 +186,8 @@ void copy_cel(SpriteWriter& sprite)
|
||||
/* if we are moving a cel from a transparent layer to the
|
||||
background layer, we have to clear the background of the
|
||||
image */
|
||||
if (!layer_is_background(src_layer) &&
|
||||
layer_is_background(dst_layer)) {
|
||||
if (!src_layer->is_background() &&
|
||||
dst_layer->is_background()) {
|
||||
dst_image = image_crop(src_image,
|
||||
-src_cel->x,
|
||||
-src_cel->y,
|
||||
@ -219,7 +220,8 @@ void copy_cel(SpriteWriter& sprite)
|
||||
|
||||
if (undo_is_enabled(sprite->undo))
|
||||
undo_add_cel(sprite->undo, dst_layer, dst_cel);
|
||||
layer_add_cel(dst_layer, dst_cel);
|
||||
|
||||
static_cast<LayerImage*>(dst_layer)->add_cel(dst_cel);
|
||||
}
|
||||
|
||||
if (undo_is_enabled(sprite->undo))
|
||||
@ -228,19 +230,19 @@ void copy_cel(SpriteWriter& sprite)
|
||||
set_frame_to_handle(NULL, 0, NULL, 0);
|
||||
}
|
||||
|
||||
static void remove_cel(Sprite* sprite, Layer *layer, Cel *cel)
|
||||
static void remove_cel(Sprite* sprite, LayerImage *layer, Cel *cel)
|
||||
{
|
||||
Image *image;
|
||||
Cel *it;
|
||||
int frame;
|
||||
bool used;
|
||||
|
||||
if (sprite != NULL && layer_is_image(layer) && cel != NULL) {
|
||||
if (sprite != NULL && layer->is_image() && cel != NULL) {
|
||||
/* find if the image that use the cel to remove, is used by
|
||||
another cels */
|
||||
used = FALSE;
|
||||
for (frame=0; frame<sprite->frames; ++frame) {
|
||||
it = layer_get_cel(layer, frame);
|
||||
it = layer->get_cel(frame);
|
||||
if (it != NULL && it != cel && it->image == cel->image) {
|
||||
used = TRUE;
|
||||
break;
|
||||
@ -268,7 +270,7 @@ static void remove_cel(Sprite* sprite, Layer *layer, Cel *cel)
|
||||
}
|
||||
|
||||
/* remove the cel */
|
||||
layer_remove_cel(layer, cel);
|
||||
layer->remove_cel(cel);
|
||||
cel_free(cel);
|
||||
}
|
||||
}
|
||||
|
@ -43,13 +43,13 @@ Image *GetImage(const Sprite *sprite)
|
||||
{
|
||||
Image *image = NULL;
|
||||
|
||||
if (sprite && sprite->layer && layer_is_image(sprite->layer)) {
|
||||
Cel *cel = layer_get_cel(sprite->layer, sprite->frame);
|
||||
|
||||
if (sprite && sprite->layer && sprite->layer->is_image()) {
|
||||
Cel *cel = static_cast<LayerImage*>(sprite->layer)->get_cel(sprite->frame);
|
||||
if (cel) {
|
||||
if ((cel->image >= 0) &&
|
||||
(cel->image < sprite->stock->nimage))
|
||||
image = sprite->stock->image[cel->image];
|
||||
assert((cel->image >= 0) &&
|
||||
(cel->image < sprite->stock->nimage));
|
||||
|
||||
image = sprite->stock->image[cel->image];
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,13 +62,13 @@ Image* GetImage2(const Sprite* sprite, int* x, int* y, int* opacity)
|
||||
|
||||
if (sprite != NULL &&
|
||||
sprite->layer != NULL &&
|
||||
layer_is_image(sprite->layer)) {
|
||||
Cel *cel = layer_get_cel(sprite->layer, sprite->frame);
|
||||
|
||||
sprite->layer->is_image()) {
|
||||
Cel* cel = static_cast<LayerImage*>(sprite->layer)->get_cel(sprite->frame);
|
||||
if (cel) {
|
||||
if ((cel->image >= 0) &&
|
||||
(cel->image < sprite->stock->nimage))
|
||||
image = sprite->stock->image[cel->image];
|
||||
assert((cel->image >= 0) &&
|
||||
(cel->image < sprite->stock->nimage));
|
||||
|
||||
image = sprite->stock->image[cel->image];
|
||||
|
||||
if (x) *x = cel->x;
|
||||
if (y) *y = cel->y;
|
||||
@ -113,64 +113,6 @@ void LoadPalette(Sprite* sprite, const char *filename)
|
||||
dirs_free(dirs);
|
||||
}
|
||||
|
||||
/* returns a new layer created from the current mask in the current
|
||||
sprite, the layer isn't added to the sprite */
|
||||
Layer *NewLayerFromMask(const Sprite *src_sprite, Sprite *dst_sprite)
|
||||
{
|
||||
ase_uint8 *address;
|
||||
int x, y, u, v, getx, gety;
|
||||
Image *dst, *src = GetImage2(src_sprite, &x, &y, NULL);
|
||||
Layer *layer;
|
||||
Cel *cel;
|
||||
div_t d;
|
||||
|
||||
if (!src_sprite || !src_sprite->mask || !src_sprite->mask->bitmap || !src)
|
||||
return NULL;
|
||||
|
||||
dst = image_new(dst_sprite->imgtype,
|
||||
src_sprite->mask->w,
|
||||
src_sprite->mask->h);
|
||||
if (!dst)
|
||||
return NULL;
|
||||
|
||||
/* clear the new image */
|
||||
image_clear(dst, 0);
|
||||
|
||||
/* copy the masked zones */
|
||||
for (v=0; v<src_sprite->mask->h; v++) {
|
||||
d = div(0, 8);
|
||||
address = ((ase_uint8 **)src_sprite->mask->bitmap->line)[v]+d.quot;
|
||||
|
||||
for (u=0; u<src_sprite->mask->w; u++) {
|
||||
if ((*address & (1<<d.rem))) {
|
||||
getx = u+src_sprite->mask->x-x;
|
||||
gety = v+src_sprite->mask->y-y;
|
||||
|
||||
if ((getx >= 0) && (getx < src->w) &&
|
||||
(gety >= 0) && (gety < src->h))
|
||||
dst->putpixel(u, v, src->getpixel(getx, gety));
|
||||
}
|
||||
|
||||
_image_bitmap_next_bit(d, address);
|
||||
}
|
||||
}
|
||||
|
||||
layer = layer_new(dst_sprite);
|
||||
if (!layer) {
|
||||
image_free(dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
layer_set_blend_mode(layer, BLEND_MODE_NORMAL);
|
||||
|
||||
cel = cel_new(dst_sprite->frame, stock_add_image(dst_sprite->stock, dst));
|
||||
cel_set_position(cel, dst_sprite->mask->x, dst_sprite->mask->y);
|
||||
|
||||
layer_add_cel(layer, cel);
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
Image* NewImageFromMask(const Sprite* src_sprite)
|
||||
{
|
||||
ase_uint8 *address;
|
||||
@ -214,34 +156,17 @@ Image* NewImageFromMask(const Sprite* src_sprite)
|
||||
return dst;
|
||||
}
|
||||
|
||||
Image *GetLayerImage(Layer *layer, int *x, int *y, int frame)
|
||||
{
|
||||
Image *image = NULL;
|
||||
|
||||
if (layer_is_image (layer)) {
|
||||
Cel *cel = layer_get_cel(layer, frame);
|
||||
|
||||
if (cel) {
|
||||
if ((cel->image >= 0) &&
|
||||
(cel->image < layer->sprite->stock->nimage))
|
||||
image = layer->sprite->stock->image[cel->image];
|
||||
|
||||
if (x) *x = cel->x;
|
||||
if (y) *y = cel->y;
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/* Gives to the user the possibility to move the sprite's layer in the
|
||||
current editor, returns TRUE if the position was changed. */
|
||||
int interactive_move_layer(int mode, bool use_undo, int (*callback)())
|
||||
{
|
||||
JWidget editor = current_editor;
|
||||
Sprite *sprite = editor_get_sprite (editor);
|
||||
Layer *layer = sprite->layer;
|
||||
Cel *cel = layer_get_cel(layer, sprite->frame);
|
||||
Sprite *sprite = editor_get_sprite(editor);
|
||||
|
||||
assert(sprite->layer->is_image());
|
||||
|
||||
LayerImage* layer = static_cast<LayerImage*>(sprite->layer);
|
||||
Cel *cel = layer->get_cel(sprite->frame);
|
||||
int start_x, new_x;
|
||||
int start_y, new_y;
|
||||
int start_b;
|
||||
|
@ -33,11 +33,8 @@ Image* GetImage2(const Sprite* sprite, int *x, int *y, int *opacity);
|
||||
|
||||
void LoadPalette(Sprite* sprite, const char* filename);
|
||||
|
||||
Layer* NewLayerFromMask(const Sprite* src, Sprite* dst);
|
||||
Image* NewImageFromMask(const Sprite* src);
|
||||
|
||||
Image* GetLayerImage(Layer* layer, int *x, int *y, int frame);
|
||||
|
||||
int interactive_move_layer(int mode, bool use_undo, int (*callback)());
|
||||
|
||||
#endif
|
||||
|
@ -282,8 +282,8 @@ Image *render_sprite(Sprite *sprite,
|
||||
int frame, int zoom)
|
||||
{
|
||||
void (*zoomed_func)(Image *, Image *, int, int, int, int, int);
|
||||
Layer *background = sprite_get_background_layer(sprite);
|
||||
bool need_grid = (background != NULL ? !layer_is_readable(background): true);
|
||||
LayerImage* background = sprite_get_background_layer(sprite);
|
||||
bool need_grid = (background != NULL ? !background->is_readable(): true);
|
||||
int depth;
|
||||
Image *image;
|
||||
|
||||
@ -375,26 +375,26 @@ Image *render_sprite(Sprite *sprite,
|
||||
color_map = NULL;
|
||||
global_opacity = 255;
|
||||
|
||||
render_layer(sprite, sprite->set, image, source_x, source_y,
|
||||
render_layer(sprite, sprite->get_folder(), image, source_x, source_y,
|
||||
frame, zoom, zoomed_func, TRUE, FALSE);
|
||||
|
||||
/* draw transparent layers of the previous frame with opacity=128 */
|
||||
color_map = orig_trans_map;
|
||||
global_opacity = 128;
|
||||
|
||||
render_layer(sprite, sprite->set, image, source_x, source_y,
|
||||
render_layer(sprite, sprite->get_folder(), image, source_x, source_y,
|
||||
frame-1, zoom, zoomed_func, FALSE, TRUE);
|
||||
|
||||
/* draw transparent layers of the current frame with opacity=255 */
|
||||
color_map = NULL;
|
||||
global_opacity = 255;
|
||||
|
||||
render_layer(sprite, sprite->set, image, source_x, source_y,
|
||||
render_layer(sprite, sprite->get_folder(), image, source_x, source_y,
|
||||
frame, zoom, zoomed_func, FALSE, TRUE);
|
||||
}
|
||||
/* just draw the current frame */
|
||||
// just draw the current frame
|
||||
else {
|
||||
render_layer(sprite, sprite->set, image, source_x, source_y,
|
||||
render_layer(sprite, sprite->get_folder(), image, source_x, source_y,
|
||||
frame, zoom, zoomed_func, TRUE, TRUE);
|
||||
}
|
||||
|
||||
@ -408,22 +408,21 @@ static void render_layer(Sprite *sprite, Layer *layer, Image *image,
|
||||
bool render_background,
|
||||
bool render_transparent)
|
||||
{
|
||||
/* we can't read from this layer */
|
||||
if (!layer_is_readable(layer))
|
||||
// we can't read from this layer
|
||||
if (!layer->is_readable())
|
||||
return;
|
||||
|
||||
switch (layer->type) {
|
||||
|
||||
case GFXOBJ_LAYER_IMAGE: {
|
||||
Image *src_image;
|
||||
Cel *cel;
|
||||
|
||||
if ((!render_background && layer_is_background(layer)) ||
|
||||
(!render_transparent && !layer_is_background(layer)))
|
||||
if ((!render_background && layer->is_background()) ||
|
||||
(!render_transparent && !layer->is_background()))
|
||||
break;
|
||||
|
||||
cel = layer_get_cel(layer, frame);
|
||||
Cel* cel = static_cast<LayerImage*>(layer)->get_cel(frame);
|
||||
if (cel != NULL) {
|
||||
Image *src_image;
|
||||
|
||||
/* is the 'rastering_image' setted to be used with this layer? */
|
||||
if ((frame == sprite->frame) &&
|
||||
(selected_layer == layer) &&
|
||||
@ -432,8 +431,8 @@ static void render_layer(Sprite *sprite, Layer *layer, Image *image,
|
||||
}
|
||||
/* if not, we use the original cel-image from the images' stock */
|
||||
else if ((cel->image >= 0) &&
|
||||
(cel->image < layer->sprite->stock->nimage))
|
||||
src_image = layer->sprite->stock->image[cel->image];
|
||||
(cel->image < layer->get_sprite()->stock->nimage))
|
||||
src_image = layer->get_sprite()->stock->image[cel->image];
|
||||
else
|
||||
src_image = NULL;
|
||||
|
||||
@ -448,27 +447,30 @@ static void render_layer(Sprite *sprite, Layer *layer, Image *image,
|
||||
image_merge(image, src_image,
|
||||
cel->x - source_x,
|
||||
cel->y - source_y,
|
||||
output_opacity, layer->blend_mode);
|
||||
output_opacity, static_cast<LayerImage*>(layer)->get_blend_mode());
|
||||
}
|
||||
else {
|
||||
(*zoomed_func)(image, src_image,
|
||||
(cel->x << zoom) - source_x,
|
||||
(cel->y << zoom) - source_y,
|
||||
output_opacity, layer->blend_mode, zoom);
|
||||
output_opacity, static_cast<LayerImage*>(layer)->get_blend_mode(), zoom);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GFXOBJ_LAYER_SET: {
|
||||
JLink link;
|
||||
JI_LIST_FOR_EACH(layer->layers, link)
|
||||
render_layer(sprite, reinterpret_cast<Layer*>(link->data), image,
|
||||
case GFXOBJ_LAYER_FOLDER: {
|
||||
LayerIterator it = static_cast<LayerFolder*>(layer)->get_layer_begin();
|
||||
LayerIterator end = static_cast<LayerFolder*>(layer)->get_layer_end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
render_layer(sprite, *it, image,
|
||||
source_x, source_y,
|
||||
frame, zoom, zoomed_func,
|
||||
render_background,
|
||||
render_transparent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ BITMAP* generate_thumbnail(const Layer* layer, const Cel* cel, const Sprite *spr
|
||||
|
||||
thumbnail_render(bmp,
|
||||
stock_get_image(sprite->stock, cel->image),
|
||||
!layer_is_background(layer));
|
||||
!layer->is_background());
|
||||
|
||||
thumbnail = thumbnail_new(cel, bmp);
|
||||
if (!thumbnail) {
|
||||
|
@ -1045,12 +1045,12 @@ static bool editor_msg_proc(JWidget widget, JMessage msg)
|
||||
if ((editor->sprite->layer) &&
|
||||
(editor->sprite->layer->type == GFXOBJ_LAYER_IMAGE)) {
|
||||
/* TODO you can move the `Background' with tiled mode */
|
||||
if (layer_is_background(editor->sprite->layer)) {
|
||||
if (editor->sprite->layer->is_background()) {
|
||||
jalert(_(PACKAGE
|
||||
"<<You can't move the `Background' layer."
|
||||
"||&Close"));
|
||||
}
|
||||
else if (!layer_is_moveable(editor->sprite->layer)) {
|
||||
else if (!editor->sprite->layer->is_moveable()) {
|
||||
jalert(_(PACKAGE
|
||||
"<<The layer movement is locked."
|
||||
"||&Close"));
|
||||
@ -1403,9 +1403,9 @@ static void editor_update_candraw(JWidget widget)
|
||||
editor->cursor_candraw =
|
||||
(editor->sprite != NULL &&
|
||||
editor->sprite->layer != NULL &&
|
||||
layer_is_image(editor->sprite->layer) &&
|
||||
layer_is_readable(editor->sprite->layer) &&
|
||||
layer_is_writable(editor->sprite->layer) /* && */
|
||||
editor->sprite->layer->is_image() &&
|
||||
editor->sprite->layer->is_readable() &&
|
||||
editor->sprite->layer->is_writable() /* && */
|
||||
/* layer_get_cel(editor->sprite->layer, editor->sprite->frame) != NULL */
|
||||
);
|
||||
}
|
||||
|
@ -394,9 +394,8 @@ static bool slider_change_hook(JWidget widget, void *data)
|
||||
CurrentSpriteWriter sprite(UIContext::instance());
|
||||
if (sprite) {
|
||||
if ((sprite->layer) &&
|
||||
(sprite->layer->type == GFXOBJ_LAYER_IMAGE)) {
|
||||
Cel *cel = layer_get_cel(sprite->layer, sprite->frame);
|
||||
|
||||
(sprite->layer->is_image())) {
|
||||
Cel* cel = ((LayerImage*)sprite->layer)->get_cel(sprite->frame);
|
||||
if (cel) {
|
||||
// update the opacity
|
||||
cel->opacity = jslider_get_value(widget);
|
||||
@ -439,7 +438,7 @@ static void update_from_layer(StatusBar *statusbar)
|
||||
/* layer button */
|
||||
if (sprite && sprite->layer) {
|
||||
char buf[512];
|
||||
usprintf(buf, "[%d] %s", sprite->frame, sprite->layer->name);
|
||||
usprintf(buf, "[%d] %s", sprite->frame, sprite->layer->get_name().c_str());
|
||||
jwidget_set_text(statusbar->b_layer, buf);
|
||||
jwidget_enable(statusbar->b_layer);
|
||||
}
|
||||
@ -451,9 +450,9 @@ static void update_from_layer(StatusBar *statusbar)
|
||||
/* opacity layer */
|
||||
if (sprite &&
|
||||
sprite->layer &&
|
||||
layer_is_image(sprite->layer) &&
|
||||
!layer_is_background(sprite->layer) &&
|
||||
(cel = layer_get_cel(sprite->layer, sprite->frame))) {
|
||||
sprite->layer->is_image() &&
|
||||
!sprite->layer->is_background() &&
|
||||
(cel = ((LayerImage*)sprite->layer)->get_cel(sprite->frame))) {
|
||||
jslider_set_value(statusbar->slider, MID(0, cel->opacity, 255));
|
||||
jwidget_enable(statusbar->slider);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user