Refactored Layer class to include all layer_* functions as member functions.

This commit is contained in:
David Capello 2009-11-17 13:12:26 +00:00
parent 8b7f476f17
commit cbc0bf22bd
50 changed files with 1255 additions and 1203 deletions

View File

@ -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

View File

@ -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);

View File

@ -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.");

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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();

View File

@ -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());
}
//////////////////////////////////////////////////////////////////////

View File

@ -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)

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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) {

View File

@ -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) {

View File

@ -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);

View File

@ -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;
}

View File

@ -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 ||

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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) {

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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:

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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 {

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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) {

View File

@ -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 */
);
}

View File

@ -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);
}