Move the active mask from Sprite class to Document.

+ Removed masks and paths repositories.
+ Added Document::isMaskVisible and Document::setMaskVisible methods.
This commit is contained in:
David Capello 2011-03-23 00:06:43 -03:00
parent f412c8450b
commit 0b495085cc
36 changed files with 315 additions and 475 deletions

View File

@ -66,15 +66,15 @@ void ClearCommand::onExecute(Context* context)
{
ActiveDocumentWriter document(context);
Sprite* sprite(document->getSprite());
bool empty_mask = sprite->getMask()->is_empty();
bool visibleMask = document->isMaskVisible();
{
UndoTransaction undoTransaction(document, "Clear");
undoTransaction.clearMask(app_get_color_to_clear_layer(sprite->getCurrentLayer()));
if (!empty_mask)
if (visibleMask)
undoTransaction.deselectMask();
undoTransaction.commit();
}
if (!empty_mask)
if (visibleMask)
document->generateMaskBoundaries();
update_screen_for_document(document);
}

View File

@ -526,11 +526,10 @@ void ConfigureTools::onSetGridClick()
try {
// TODO use the same context as in ConfigureTools::onExecute
const ActiveDocumentReader document(UIContext::instance());
const Sprite* sprite(document ? document->getSprite(): 0);
if (sprite && sprite->getMask() && sprite->getMask()->bitmap) {
Rect bounds(sprite->getMask()->x, sprite->getMask()->y,
sprite->getMask()->w, sprite->getMask()->h);
if (document && document->isMaskVisible()) {
const Mask* mask(document->getMask());
Rect bounds(mask->x, mask->y, mask->w, mask->h);
UIContext::instance()->getSettings()->setGridBounds(bounds);

View File

@ -54,8 +54,7 @@ bool CopyCommand::onEnabled(Context* context)
(sprite->getCurrentLayer()) &&
(sprite->getCurrentLayer()->is_readable()) &&
(sprite->getCurrentLayer()->is_writable()) &&
(sprite->getMask()) &&
(sprite->getMask()->bitmap))
(document->isMaskVisible()))
return sprite->getCurrentImage() ? true: false;
else
return false;

View File

@ -56,26 +56,19 @@ CropSpriteCommand::CropSpriteCommand()
bool CropSpriteCommand::onEnabled(Context* context)
{
const ActiveDocumentReader document(context);
const Sprite* sprite(document ? document->getSprite(): 0);
return
sprite != NULL &&
sprite->getMask() != NULL &&
sprite->getMask()->bitmap != NULL;
return document && document->isMaskVisible();
}
void CropSpriteCommand::onExecute(Context* context)
{
ActiveDocumentWriter document(context);
Sprite* sprite(document->getSprite());
const Sprite* sprite(document->getSprite());
const Mask* mask(document->getMask());
{
UndoTransaction undoTransaction(document, "Sprite Crop");
int bgcolor = color_utils::color_for_image(app_get_colorbar()->getBgColor(), sprite->getImgType());
undoTransaction.cropSprite(sprite->getMask()->x,
sprite->getMask()->y,
sprite->getMask()->w,
sprite->getMask()->h,
bgcolor);
undoTransaction.cropSprite(mask->x, mask->y, mask->w, mask->h, bgcolor);
undoTransaction.commit();
}
document->generateMaskBoundaries();

View File

@ -54,8 +54,7 @@ bool CutCommand::onEnabled(Context* context)
(sprite->getCurrentLayer()) &&
(sprite->getCurrentLayer()->is_readable()) &&
(sprite->getCurrentLayer()->is_writable()) &&
(sprite->getMask()) &&
(sprite->getMask()->bitmap))
(document->isMaskVisible()))
return sprite->getCurrentImage() ? true: false;
else
return false;

View File

@ -49,8 +49,7 @@ DeselectMaskCommand::DeselectMaskCommand()
bool DeselectMaskCommand::onEnabled(Context* context)
{
const ActiveDocumentReader document(context);
const Sprite* sprite(document ? document->getSprite(): 0);
return sprite && !sprite->getMask()->is_empty();
return document && document->isMaskVisible();
}
void DeselectMaskCommand::onExecute(Context* context)

View File

@ -101,8 +101,9 @@ void FlipCommand::onExecute(Context* context)
image = sprite->getCurrentImage(&x, &y);
if (!image)
return;
// mask is empty?
if (sprite->getMask()->is_empty()) {
// Mask is empty?
if (!document->isMaskVisible()) {
// so we flip the entire image
x1 = 0;
y1 = 0;
@ -111,10 +112,10 @@ void FlipCommand::onExecute(Context* context)
}
else {
// apply the cel offset
x1 = sprite->getMask()->x - x;
y1 = sprite->getMask()->y - y;
x2 = sprite->getMask()->x + sprite->getMask()->w - 1 - x;
y2 = sprite->getMask()->y + sprite->getMask()->h - 1 - y;
x1 = document->getMask()->x - x;
y1 = document->getMask()->y - y;
x2 = document->getMask()->x + document->getMask()->w - 1 - x;
y2 = document->getMask()->y + document->getMask()->h - 1 - y;
// clip
x1 = MID(0, x1, image->w-1);

View File

@ -51,21 +51,22 @@ InvertMaskCommand::InvertMaskCommand()
bool InvertMaskCommand::onEnabled(Context* context)
{
const ActiveDocumentReader document(context);
return document != NULL && document->getSprite() != NULL;
return
document != NULL &&
document->getSprite() != NULL;
}
void InvertMaskCommand::onExecute(Context* context)
{
bool has_mask = false;
bool hasMask = false;
{
const ActiveDocumentReader document(context);
const Sprite* sprite(document->getSprite());
if (sprite->getMask()->bitmap)
has_mask = true;
if (document->isMaskVisible())
hasMask = true;
}
// without mask?...
if (!has_mask) {
if (!hasMask) {
// so we select all
Command* mask_all_cmd =
CommandsModule::instance()->getCommandByName(CommandId::MaskAll);
@ -80,7 +81,7 @@ void InvertMaskCommand::onExecute(Context* context)
/* undo */
if (undo->isEnabled()) {
undo->setLabel("Mask Invert");
undo->undo_set_mask(sprite);
undo->undo_set_mask(document);
}
/* create a new mask */
@ -91,23 +92,23 @@ void InvertMaskCommand::onExecute(Context* context)
/* remove in the new mask the current sprite marked region */
image_rectfill(mask->bitmap,
sprite->getMask()->x, sprite->getMask()->y,
sprite->getMask()->x + sprite->getMask()->w-1,
sprite->getMask()->y + sprite->getMask()->h-1, 0);
document->getMask()->x, document->getMask()->y,
document->getMask()->x + document->getMask()->w-1,
document->getMask()->y + document->getMask()->h-1, 0);
/* invert the current mask in the sprite */
mask_invert(sprite->getMask());
if (sprite->getMask()->bitmap) {
mask_invert(document->getMask());
if (document->getMask()->bitmap) {
/* copy the inverted region in the new mask */
image_copy(mask->bitmap, sprite->getMask()->bitmap,
sprite->getMask()->x, sprite->getMask()->y);
image_copy(mask->bitmap, document->getMask()->bitmap,
document->getMask()->x, document->getMask()->y);
}
/* we need only need the area inside the sprite */
mask_intersect(mask, 0, 0, sprite->getWidth(), sprite->getHeight());
/* set the new mask */
sprite->setMask(mask);
document->setMask(mask);
mask_free(mask);
document->generateMaskBoundaries();

View File

@ -88,10 +88,10 @@ void LoadMaskCommand::onExecute(Context* context)
// Add the mask change into the undo history.
if (undo->isEnabled()) {
undo->setLabel("Mask Load");
undo->undo_set_mask(sprite);
undo->undo_set_mask(document);
}
sprite->setMask(mask);
document->setMask(mask);
mask_free(mask);
document->generateMaskBoundaries();

View File

@ -59,14 +59,15 @@ void MaskAllCommand::onExecute(Context* context)
Sprite* sprite(document->getSprite());
UndoHistory* undo(document->getUndoHistory());
/* undo */
// Undo
if (undo->isEnabled()) {
undo->setLabel("Mask All");
undo->undo_set_mask(sprite);
undo->undo_set_mask(document);
}
/* change the selection */
mask_replace(sprite->getMask(), 0, 0, sprite->getWidth(), sprite->getHeight());
// Change the selection
mask_replace(document->getMask(), 0, 0, sprite->getWidth(), sprite->getHeight());
document->setMaskVisible(true);
document->generateMaskBoundaries();
update_screen_for_document(document);

View File

@ -53,8 +53,7 @@ bool MaskByColorCommand::onEnabled(Context* context)
void MaskByColorCommand::onExecute(Context* context)
{
ActiveDocumentWriter document(context);
dialogs_mask_color(document);
dialogs_mask_color(context->getActiveDocument());
}
//////////////////////////////////////////////////////////////////////

View File

@ -49,35 +49,30 @@ ReselectMaskCommand::ReselectMaskCommand()
bool ReselectMaskCommand::onEnabled(Context* context)
{
const ActiveDocumentReader document(context);
const Sprite* sprite(document ? document->getSprite(): 0);
return
sprite != NULL &&
sprite->requestMask("*deselected*") != NULL;
document && // The document does exist
!document->isMaskVisible() && // The mask is hidden
document->getMask() && // The mask does exist
!document->getMask()->is_empty(); // But it is not empty
}
void ReselectMaskCommand::onExecute(Context* context)
{
ActiveDocumentWriter document(context);
Sprite* sprite(document->getSprite());
UndoHistory* undo = document->getUndoHistory();
// Request *deselected* mask
Mask* mask = sprite->requestMask("*deselected*");
// TODO IMPLEMENT THIS Add an undo action in the history to reverse the change of a Document's int field
// Undo
if (undo->isEnabled()) {
undo->setLabel("Mask Reselection");
undo->undo_set_mask(sprite);
//undo->undo_set_mask(document);
}
// Set the mask.
sprite->setMask(mask);
// Remove the *deselected* mask.
sprite->removeMask(mask);
mask_free(mask);
// Make the mask visible again.
document->setMaskVisible(true);
document->generateMaskBoundaries();
update_screen_for_document(document);
}

View File

@ -124,30 +124,31 @@ protected:
}
// rotate mask
if (m_sprite->getMask()->bitmap) {
if (m_document->isMaskVisible()) {
Mask* origMask = m_document->getMask();
Mask* new_mask = mask_new();
int x = 0, y = 0;
switch (m_angle) {
case 180:
x = m_sprite->getWidth() - m_sprite->getMask()->x - m_sprite->getMask()->w;
y = m_sprite->getHeight() - m_sprite->getMask()->y - m_sprite->getMask()->h;
x = m_sprite->getWidth() - origMask->x - origMask->w;
y = m_sprite->getHeight() - origMask->y - origMask->h;
break;
case 90:
x = m_sprite->getHeight() - m_sprite->getMask()->y - m_sprite->getMask()->h;
y = m_sprite->getMask()->x;
x = m_sprite->getHeight() - origMask->y - origMask->h;
y = origMask->x;
break;
case -90:
x = m_sprite->getMask()->y;
y = m_sprite->getWidth() - m_sprite->getMask()->x - m_sprite->getMask()->w;
x = origMask->y;
y = m_sprite->getWidth() - origMask->x - origMask->w;
break;
}
// create the new rotated mask
mask_replace(new_mask, x, y,
m_angle == 180 ? m_sprite->getMask()->w: m_sprite->getMask()->h,
m_angle == 180 ? m_sprite->getMask()->h: m_sprite->getMask()->w);
image_rotate(m_sprite->getMask()->bitmap, new_mask->bitmap, m_angle);
m_angle == 180 ? origMask->w: origMask->h,
m_angle == 180 ? origMask->h: origMask->w);
image_rotate(origMask->bitmap, new_mask->bitmap, m_angle);
// copy new mask
undoTransaction.copyToCurrentMask(new_mask);

View File

@ -52,18 +52,12 @@ SaveMaskCommand::SaveMaskCommand()
bool SaveMaskCommand::onEnabled(Context* context)
{
const ActiveDocumentReader document(context);
const Sprite* sprite(document ? document->getSprite(): NULL);
if (!sprite)
return false;
else
return (sprite->getMask() &&
sprite->getMask()->bitmap) ? true: false;
return document && document->isMaskVisible();
}
void SaveMaskCommand::onExecute(Context* context)
{
const ActiveDocumentReader document(context);
const Sprite* sprite(document ? document->getSprite(): NULL);
base::string filename = "default.msk";
int ret;
@ -91,7 +85,7 @@ void SaveMaskCommand::onExecute(Context* context)
/* "no": we must back to select other file-name */
}
if (save_msk_file(sprite->getMask(), filename.c_str()) != 0)
if (save_msk_file(document->getMask(), filename.c_str()) != 0)
Alert::show("Error<<Error saving .msk file<<%s||&Close", filename.c_str());
}

View File

@ -107,18 +107,18 @@ protected:
return; // UndoTransaction destructor will undo all operations
}
// resize mask
if (m_sprite->getMask()->bitmap) {
Image* old_bitmap = image_crop(m_sprite->getMask()->bitmap, -1, -1,
m_sprite->getMask()->bitmap->w+2,
m_sprite->getMask()->bitmap->h+2, 0);
// Resize mask
if (m_document->isMaskVisible()) {
Image* old_bitmap = image_crop(m_document->getMask()->bitmap, -1, -1,
m_document->getMask()->bitmap->w+2,
m_document->getMask()->bitmap->h+2, 0);
int w = scale_x(old_bitmap->w);
int h = scale_y(old_bitmap->h);
Mask* new_mask = mask_new();
mask_replace(new_mask,
scale_x(m_sprite->getMask()->x-1),
scale_y(m_sprite->getMask()->y-1), MAX(1, w), MAX(1, h));
scale_x(m_document->getMask()->x-1),
scale_y(m_document->getMask()->y-1), MAX(1, w), MAX(1, h));
image_resize(old_bitmap, new_mask->bitmap,
m_resize_method,
m_sprite->getCurrentPalette(), // Ignored

View File

@ -102,7 +102,7 @@ void FilterManagerImpl::setTarget(int target)
void FilterManagerImpl::begin()
{
m_row = 0;
m_mask = m_sprite->getMask();
m_mask = m_document->getMask();
updateMask(m_mask, m_src);
}
@ -114,8 +114,8 @@ void FilterManagerImpl::beginForPreview()
m_preview_mask = NULL;
}
if ((m_sprite->getMask()) && (m_sprite->getMask()->bitmap))
m_preview_mask = mask_new_copy(m_sprite->getMask());
if (m_document->isMaskVisible())
m_preview_mask = mask_new_copy(m_document->getMask());
else {
m_preview_mask = mask_new();
mask_replace(m_preview_mask,
@ -340,7 +340,7 @@ void FilterManagerImpl::init(const Layer* layer, Image* image, int offset_x, int
m_offset_x = offset_x;
m_offset_y = offset_y;
if (!updateMask(m_sprite->getMask(), image))
if (!updateMask(m_document->getMask(), image))
throw InvalidAreaException();
if (m_preview_mask) {

View File

@ -23,6 +23,8 @@
#include "app/color_utils.h"
#include "base/bind.h"
#include "core/cfg.h"
#include "document.h"
#include "document_wrappers.h"
#include "gui/box.h"
#include "gui/button.h"
#include "gui/frame.h"
@ -44,14 +46,15 @@ static ColorButton* button_color;
static CheckBox* check_preview;
static Slider* slider_tolerance;
static void button_1_command(JWidget widget);
static void button_2_command(JWidget widget);
static void button_1_command(Widget* widget, const DocumentReader& document);
static void button_2_command(Widget* widget, const DocumentReader& document);
static Mask* gen_mask(const Sprite* sprite);
static void mask_preview(Document* document);
static void mask_preview(const DocumentReader& document);
void dialogs_mask_color(Document* document)
{
DocumentReader documentReader(document);
Sprite* sprite = document->getSprite();
Box* box1, *box2, *box3, *box4;
Widget* label_color;
@ -90,17 +93,14 @@ void dialogs_mask_color(Document* document)
if (get_config_bool("MaskColor", "Preview", true))
check_preview->setSelected(true);
button_1->user_data[1] = document;
button_2->user_data[1] = document;
button_1->Click.connect(Bind<void>(&button_1_command, button_1));
button_2->Click.connect(Bind<void>(&button_2_command, button_2));
button_1->Click.connect(Bind<void>(&button_1_command, button_1, Ref(documentReader)));
button_2->Click.connect(Bind<void>(&button_2_command, button_2, Ref(documentReader)));
button_ok->Click.connect(Bind<void>(&Frame::closeWindow, window.get(), button_ok));
button_cancel->Click.connect(Bind<void>(&Frame::closeWindow, window.get(), button_cancel));
button_color->Change.connect(Bind<void>(&mask_preview, document));
slider_tolerance->Change.connect(Bind<void>(&mask_preview, document));
check_preview->Click.connect(Bind<void>(&mask_preview, document));
button_color->Change.connect(Bind<void>(&mask_preview, Ref(documentReader)));
slider_tolerance->Change.connect(Bind<void>(&mask_preview, Ref(documentReader)));
check_preview->Click.connect(Bind<void>(&mask_preview, Ref(documentReader)));
jwidget_magnetic(button_ok, true);
jwidget_expansive(button_color, true);
@ -118,7 +118,7 @@ void dialogs_mask_color(Document* document)
window->center_window();
/* mask first preview */
mask_preview(document);
mask_preview(documentReader);
/* load window configuration */
load_window_pos(window, "MaskColor");
@ -127,18 +127,19 @@ void dialogs_mask_color(Document* document)
window->open_window_fg();
if (window->get_killer() == button_ok) {
DocumentWriter documentWriter(documentReader);
UndoHistory* undo = document->getUndoHistory();
Mask* mask;
/* undo */
if (undo->isEnabled()) {
undo->setLabel("Mask by Color");
undo->undo_set_mask(sprite);
undo->undo_set_mask(document);
}
/* change the mask */
mask = gen_mask(sprite);
sprite->setMask(mask);
document->setMask(mask);
mask_free(mask);
set_config_color("MaskColor", "Color", button_color->getColor());
@ -154,16 +155,16 @@ void dialogs_mask_color(Document* document)
save_window_pos(window, "MaskColor");
}
static void button_1_command(JWidget widget)
static void button_1_command(Widget* widget, const DocumentReader& document)
{
button_color->setColor(app_get_colorbar()->getFgColor());
mask_preview((Document*)widget->user_data[1]);
mask_preview(document);
}
static void button_2_command(JWidget widget)
static void button_2_command(Widget* widget, const DocumentReader& document)
{
button_color->setColor(app_get_colorbar()->getBgColor());
mask_preview((Document*)widget->user_data[1]);
mask_preview(document);
}
static Mask *gen_mask(const Sprite* sprite)
@ -182,14 +183,16 @@ static Mask *gen_mask(const Sprite* sprite)
return mask;
}
static void mask_preview(Document* document)
static void mask_preview(const DocumentReader& document)
{
if (check_preview->isSelected()) {
Mask* mask = gen_mask(document->getSprite());
document->generateMaskBoundaries(mask);
update_screen_for_document(document);
{
DocumentWriter documentWriter(document);
documentWriter->generateMaskBoundaries(mask);
}
mask_free(mask);
update_screen_for_document(document);
}
}

View File

@ -58,6 +58,10 @@ Document::Document(Sprite* sprite)
m_preferred.scroll_y = 0;
m_preferred.zoom = 0;
m_preferred.virgin = true;
// Mask
m_mask = new Mask();
m_maskVisible = true;
}
Document::~Document()
@ -70,6 +74,7 @@ Document::~Document()
delete m_mutex;
delete m_undoHistory;
delete m_sprite;
delete m_mask;
}
Document* Document::createBasicDocument(int imgtype, int width, int height, int ncolors)
@ -183,16 +188,20 @@ const _BoundSeg* Document::getBoundariesSegments() const
void Document::generateMaskBoundaries(Mask* mask)
{
// No mask specified? Use the current one in the document
if (!mask)
mask = m_sprite->getMask();
if (m_bound.seg) {
base_free(m_bound.seg);
m_bound.seg = NULL;
m_bound.nseg = 0;
}
// No mask specified? Use the current one in the document
if (!mask) {
if (!isMaskVisible()) // The mask is hidden
return; // Done, without boundaries
else
mask = getMask(); // Use the document mask
}
ASSERT(mask != NULL);
if (mask->bitmap) {
@ -252,6 +261,36 @@ Image* Document::getExtraCelImage() const
return m_extraImage;
}
//////////////////////////////////////////////////////////////////////
// Mask
Mask* Document::getMask() const
{
return m_mask;
}
void Document::setMask(const Mask* mask)
{
if (m_mask)
mask_free(m_mask);
m_mask = mask_new_copy(mask);
m_maskVisible = true;
}
bool Document::isMaskVisible() const
{
return
m_maskVisible && // The mask was not hidden by the user explicitly
m_mask && // The mask does exist
!m_mask->is_empty(); // The mask is not empty
}
void Document::setMaskVisible(bool visible)
{
m_maskVisible = visible;
}
//////////////////////////////////////////////////////////////////////
// Clonning

View File

@ -110,6 +110,28 @@ public:
Cel* getExtraCel() const;
Image* getExtraCelImage() const;
//////////////////////////////////////////////////////////////////////
// Mask
// Returns the current mask, it can be empty. The mask could be not
// empty but hidden to the user if the setMaskVisible(false) was
// used called before.
Mask* getMask() const;
// Sets the current mask. The new mask will be visible by default,
// so you don't need to call setMaskVisible(true).
void setMask(const Mask* mask);
// Returns true only when the mask is not empty, and was not yet
// hidden using setMaskVisible (e.g. when the user "deselect the
// mask").
bool isMaskVisible() const;
// Changes the visibility state of the mask (it is useful only if
// the getMask() is not empty and the user can see that the mask is
// being hidden and shown to him).
void setMaskVisible(bool visible);
//////////////////////////////////////////////////////////////////////
// Clonning
@ -172,6 +194,10 @@ private:
// Image of the extra cel.
Image* m_extraImage;
// Current mask.
Mask* m_mask;
bool m_maskVisible;
DISABLE_COPYING(Document);
};

View File

@ -19,7 +19,7 @@
#ifndef DOCUMENT_ID_H_INCLUDED
#define DOCUMENT_ID_H_INCLUDED
typedef unsigned int DocumentId;
typedef ase_uint32 DocumentId;
const DocumentId WithoutDocumentId = 0;

View File

@ -118,9 +118,7 @@ class AseFormat : public FileFormat
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_LAYERS |
FILE_SUPPORT_FRAMES |
FILE_SUPPORT_PALETTES |
FILE_SUPPORT_MASKS_REPOSITORY |
FILE_SUPPORT_PATHS_REPOSITORY;
FILE_SUPPORT_PALETTES;
}
bool onLoad(FileOp* fop);
@ -250,7 +248,7 @@ bool AseFormat::onLoad(FileOp *fop)
mask = ase_file_read_mask_chunk(f);
if (mask)
sprite->addMask(mask);
delete mask; // TODO add the mask in some place?
else
fop_error(fop, "Warning: error loading a mask chunk\n");
@ -334,11 +332,6 @@ bool AseFormat::onSave(FileOp *fop)
/* write layer chunks */
for (; it != end; ++it)
ase_file_write_layers(f, *it);
// Write all masks.
MasksList masks = sprite->getMasksRepository();
for (MasksList::iterator it = masks.begin(); it != masks.end(); ++it)
ase_file_write_mask_chunk(f, *it);
}
/* write cel chunks */

View File

@ -307,32 +307,6 @@ FileOp* fop_to_save_document(Document* document)
}
}
// Repositories.
MasksList masks = fop->document->getSprite()->getMasksRepository();
if (!masks.empty()) {
int count = 0;
for (MasksList::iterator it = masks.begin(); it != masks.end(); ++it) {
Mask* mask = *it;
// Names starting with '*' are ignored
if (mask->name && *mask->name == '*')
continue;
count++;
}
if ((count > 0) && !(fop->format->support(FILE_SUPPORT_MASKS_REPOSITORY))) {
usprintf(buf+ustrlen(buf), "<<- Mask Repository");
}
}
if (!fop->document->getSprite()->getPathsRepository().empty()) {
if (!(fop->format->support(FILE_SUPPORT_PATHS_REPOSITORY))) {
usprintf(buf+ustrlen(buf), "<<- Path Repository");
}
}
/* show the confirmation alert */
if (ugetc(buf)) {
/* interative */

View File

@ -34,9 +34,7 @@
#define FILE_SUPPORT_FRAMES 0x00000100
#define FILE_SUPPORT_PALETTES 0x00000200
#define FILE_SUPPORT_SEQUENCES 0x00000400
#define FILE_SUPPORT_MASKS_REPOSITORY 0x00000800
#define FILE_SUPPORT_PATHS_REPOSITORY 0x00001000
#define FILE_SUPPORT_GET_FORMAT_OPTIONS 0x00002000
#define FILE_SUPPORT_GET_FORMAT_OPTIONS 0x00000800
class FormatOptions;
class FileFormat;

View File

@ -18,14 +18,14 @@
#include "config.h"
#include <cstring>
#include <vector>
#include "base/memory.h"
#include "base/remove_from_container.h"
#include "file/format_options.h"
#include "raster/raster.h"
#include <cstring>
#include <vector>
#ifdef _MSC_VER
#pragma warning(disable: 4355)
#endif
@ -221,56 +221,6 @@ public:
}
}
Mask* getMask() const {
return m_mask;
}
void setMask(const Mask* mask) {
if (m_mask)
mask_free(m_mask);
m_mask = mask_new_copy(mask);
}
void addMask(Mask* mask) {
if (!mask->name) // You can't add masks to repository without name
return;
if (requestMask(mask->name)) // You can't add a mask that already exists
return;
// And add the new mask
m_repository.masks.push_back(mask);
}
void removeMask(Mask* mask) {
// Remove the mask from the repository
base::remove_from_container(m_repository.masks, mask);
}
Mask* requestMask(const char* name) const;
MasksList getMasksRepository() {
return m_repository.masks;
}
void addPath(Path* path) {
m_repository.paths.push_back(path);
}
void removePath(Path* path) {
base::remove_from_container(m_repository.paths, path);
}
void setPath(const Path* path) {
delete m_path;
m_path = new Path(*path);
}
PathsList getPathsRepository() {
return m_repository.paths;
}
void render(Image* image, int x, int y) const {
image_rectfill(image, x, y, x+m_width-1, y+m_height-1, 0);
layer_render(getFolder(), image, x, y, getCurrentFrame());
@ -290,12 +240,6 @@ private:
Stock* m_stock; // stock to get images
LayerFolder* m_folder; // main folder of layers
Layer* m_layer; // current layer
Path* m_path; // working path
Mask* m_mask; // selected mask region
struct {
PathsList paths; // paths
MasksList masks; // masks
} m_repository;
// Current rgb map
RgbMap* m_rgbMap;
@ -318,8 +262,6 @@ SpriteImpl::SpriteImpl(Sprite* sprite, int imgtype, int width, int height, int n
m_stock = new Stock(imgtype);
m_folder = new LayerFolder(m_self);
m_layer = NULL;
m_path = NULL;
m_mask = mask_new();
// Generate palette
Palette pal(0, ncolors);
@ -361,22 +303,6 @@ SpriteImpl::~SpriteImpl()
if (m_stock)
delete m_stock;
// Destroy paths
{
PathsList::iterator end = m_repository.paths.end();
PathsList::iterator it = m_repository.paths.begin();
for (; it != end; ++it)
delete *it; // path
}
// Destroy masks
{
MasksList::iterator end = m_repository.masks.end();
MasksList::iterator it = m_repository.masks.begin();
for (; it != end; ++it)
delete *it; // mask
}
// Destroy palettes
{
PalettesList::iterator end = m_palettes.end();
@ -385,8 +311,7 @@ SpriteImpl::~SpriteImpl()
delete *it; // palette
}
// Destroy undo, mask, etc.
delete m_mask;
// Destroy RGB map
delete m_rgbMap;
}
@ -431,20 +356,6 @@ void SpriteImpl::setTotalFrames(int frames)
m_frames = frames;
}
Mask *SpriteImpl::requestMask(const char *name) const
{
MasksList::const_iterator end = m_repository.masks.end();
MasksList::const_iterator it = m_repository.masks.begin();
for (; it != end; ++it) {
Mask* mask = *it;
if (strcmp(mask->name, name) == 0)
return mask;
}
return NULL;
}
int SpriteImpl::getPixel(int x, int y) const
{
int color = 0;
@ -760,83 +671,6 @@ void Sprite::remapImages(int frame_from, int frame_to, const std::vector<int>& m
m_impl->remapImages(frame_from, frame_to, mapping);
}
//////////////////////////////////////////////////////////////////////
// Mask
Mask* Sprite::getMask() const
{
return m_impl->getMask();
}
/**
* Changes the current mask (makes a copy of "mask")
*/
void Sprite::setMask(const Mask* mask)
{
m_impl->setMask(mask);
}
/**
* Adds a mask to the sprites's repository
*/
void Sprite::addMask(Mask* mask)
{
m_impl->addMask(mask);
}
/**
* Removes a mask from the sprites's repository
*/
void Sprite::removeMask(Mask* mask)
{
m_impl->removeMask(mask);
}
/**
* Returns a mask from the sprite's repository searching it by its name
*/
Mask* Sprite::requestMask(const char* name) const
{
return m_impl->requestMask(name);
}
MasksList Sprite::getMasksRepository()
{
return m_impl->getMasksRepository();
}
//////////////////////////////////////////////////////////////////////
// Path
/**
* Adds a path to the sprites's repository
*/
void Sprite::addPath(Path* path)
{
m_impl->addPath(path);
}
/**
* Removes a path from the sprites's repository
*/
void Sprite::removePath(Path* path)
{
m_impl->removePath(path);
}
/**
* Changes the current path (makes a copy of "path")
*/
void Sprite::setPath(const Path* path)
{
m_impl->setPath(path);
}
PathsList Sprite::getPathsRepository()
{
return m_impl->getPathsRepository();
}
//////////////////////////////////////////////////////////////////////
// Drawing

View File

@ -118,27 +118,6 @@ public:
void remapImages(int frame_from, int frame_to, const std::vector<int>& mapping);
////////////////////////////////////////
// Mask
Mask* getMask() const;
void setMask(const Mask* mask);
void addMask(Mask* mask);
void removeMask(Mask* mask);
Mask* requestMask(const char* name) const;
MasksList getMasksRepository();
////////////////////////////////////////
// Path
void addPath(Path* path);
void removePath(Path* path);
void setPath(const Path* path);
PathsList getPathsRepository();
////////////////////////////////////////
// Drawing

View File

@ -18,14 +18,10 @@
#include "config.h"
#include <vector>
#include <list>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <allegro/config.h>
#include "base/memory.h"
#include "context.h"
#include "document.h"
#include "documents.h"
#include "raster/cel.h"
#include "raster/dirty.h"
#include "raster/image.h"
@ -35,14 +31,22 @@
#include "raster/sprite.h"
#include "raster/stock.h"
#include "raster/undo_history.h"
#include "ui_context.h"
/* undo state */
#include <allegro/config.h>
#include <errno.h>
#include <limits.h>
#include <list>
#include <stdio.h>
#include <vector>
// Undo state
enum {
DO_UNDO,
DO_REDO,
};
// undo types
// Undo types
enum {
// group
UNDO_TYPE_OPEN,
@ -78,7 +82,7 @@ enum {
UNDO_TYPE_SET_PALETTE_COLORS,
UNDO_TYPE_REMAP_PALETTE,
/* misc */
// misc
UNDO_TYPE_SET_MASK,
UNDO_TYPE_SET_IMGTYPE,
UNDO_TYPE_SET_SIZE,
@ -135,7 +139,7 @@ struct UndoAction
static int count_undo_groups(UndoStream* undo_stream);
static bool out_of_group(UndoStream* undo_stream);
/* Undo actions */
// Undo actions
static void chunk_open_new(UndoStream* stream);
static void chunk_open_invert(UndoStream* stream, UndoChunk* chunk);
@ -197,7 +201,7 @@ static void chunk_set_palette_colors_invert(UndoStream* stream, UndoChunkSetPale
static void chunk_remap_palette_new(UndoStream* stream, Sprite* sprite, int frame_from, int frame_to, const std::vector<int>& mapping);
static void chunk_remap_palette_invert(UndoStream* stream, UndoChunkRemapPalette *chunk);
static void chunk_set_mask_new(UndoStream* stream, Sprite *sprite);
static void chunk_set_mask_new(UndoStream* stream, Document* document);
static void chunk_set_mask_invert(UndoStream* stream, UndoChunkSetMask* chunk);
static void chunk_set_imgtype_new(UndoStream* stream, Sprite *sprite);
@ -218,7 +222,7 @@ static void chunk_set_frlen_invert(UndoStream* stream, UndoChunkSetFrlen *chunk)
#define DECL_UNDO_ACTION(name) \
{ #name, (void (*)(UndoStream* , UndoChunk*))chunk_##name##_invert }
/* warning: in the same order as in UNDO_TYPEs */
// WARNING: in the same order as in UNDO_TYPEs
static UndoAction undo_actions[] = {
DECL_UNDO_ACTION(open),
DECL_UNDO_ACTION(close),
@ -248,7 +252,7 @@ static UndoAction undo_actions[] = {
DECL_UNDO_ACTION(set_frlen),
};
/* Raw data */
// Raw data
static Dirty *read_raw_dirty(ase_uint8* raw_data);
static ase_uint8* write_raw_dirty(ase_uint8* raw_data, Dirty* dirty);
@ -1643,7 +1647,7 @@ static void chunk_remap_palette_invert(UndoStream* stream, UndoChunkRemapPalette
"set_mask"
DWORD sprite ID
DWORD document ID
MASK_DATA see read/write_raw_mask
***********************************************************************/
@ -1651,37 +1655,37 @@ static void chunk_remap_palette_invert(UndoStream* stream, UndoChunkRemapPalette
struct UndoChunkSetMask
{
UndoChunk head;
ase_uint32 sprite_id;
ase_uint32 doc_id;
ase_uint8 data[0];
};
void UndoHistory::undo_set_mask(Sprite *sprite)
void UndoHistory::undo_set_mask(Document* document)
{
chunk_set_mask_new(m_undoStream, sprite);
chunk_set_mask_new(m_undoStream, document);
updateUndo();
}
static void chunk_set_mask_new(UndoStream* stream, Sprite *sprite)
static void chunk_set_mask_new(UndoStream* stream, Document* document)
{
UndoChunkSetMask* chunk = (UndoChunkSetMask* )
UndoChunkSetMask* chunk = (UndoChunkSetMask*)
undo_chunk_new(stream,
UNDO_TYPE_SET_MASK,
sizeof(UndoChunkSetMask)+get_raw_mask_size(sprite->getMask()));
sizeof(UndoChunkSetMask)+get_raw_mask_size(document->getMask()));
chunk->sprite_id = sprite->getId();
write_raw_mask(chunk->data, sprite->getMask());
chunk->doc_id = document->getId();
write_raw_mask(chunk->data, document->getMask());
}
static void chunk_set_mask_invert(UndoStream* stream, UndoChunkSetMask* chunk)
{
Sprite *sprite = (Sprite *)GfxObj::find(chunk->sprite_id);
Document* document = UIContext::instance()->getDocuments().getById(chunk->doc_id);
ASSERT(document != NULL);
if (sprite) {
if (document != NULL) {
Mask* mask = read_raw_mask(chunk->data);
chunk_set_mask_new(stream, sprite);
mask_copy(sprite->getMask(), mask);
chunk_set_mask_new(stream, document);
mask_copy(document->getMask(), mask);
mask_free(mask);
}
}

View File

@ -19,13 +19,14 @@
#ifndef RASTER_UNDO_H_INCLUDED
#define RASTER_UNDO_H_INCLUDED
#include <vector>
#include "base/exception.h"
#include "raster/gfxobj.h"
#include <vector>
class Cel;
class Dirty;
class Document;
class Image;
class Layer;
class Mask;
@ -87,7 +88,7 @@ public:
void undo_set_palette_colors(Sprite* sprite, Palette* palette, int from, int to);
void undo_remap_palette(Sprite* sprite, int frame_from, int frame_to,
const std::vector<int>& mapping);
void undo_set_mask(Sprite* sprite);
void undo_set_mask(Document* document);
void undo_set_imgtype(Sprite* sprite);
void undo_set_size(Sprite* sprite);
void undo_set_frame(Sprite* sprite);

View File

@ -33,8 +33,8 @@
addresses_define \
register int x; \
\
/* with mask */ \
if (!loop->getMask()->is_empty()) { \
/* Use mask */ \
if (loop->useMask()) { \
Point maskOrigin(loop->getMaskOrigin()); \
\
if ((y < maskOrigin.y) || (y >= maskOrigin.y+loop->getMask()->h)) \

View File

@ -260,13 +260,14 @@ public:
if (state) {
if (loop->getDocument()->getUndoHistory()->isEnabled())
loop->getDocument()->getUndoHistory()->undo_set_mask(loop->getSprite());
loop->getDocument()->getUndoHistory()->undo_set_mask(loop->getDocument());
loop->getMask()->freeze();
loop->getMask()->reserve(0, 0, loop->getSprite()->getWidth(), loop->getSprite()->getHeight());
}
else {
loop->getMask()->unfreeze();
loop->getDocument()->setMaskVisible(true);
}
}

View File

@ -251,6 +251,9 @@ public:
// Should return an image where we can write pixels
virtual Image* getDstImage() = 0;
// Returns true if we should use the mask to limit the paint area.
virtual bool useMask() = 0;
// Current mask to limit paint area
virtual Mask* getMask() = 0;

View File

@ -131,8 +131,8 @@ void UndoTransaction::cropSprite(int x, int y, int w, int h, int bgcolor)
if (background_layer)
cropLayer(background_layer, 0, 0, m_sprite->getWidth(), m_sprite->getHeight(), bgcolor);
if (!m_sprite->getMask()->is_empty())
setMaskPosition(m_sprite->getMask()->x-x, m_sprite->getMask()->y-y);
if (!m_document->getMask()->is_empty())
setMaskPosition(m_document->getMask()->x-x, m_document->getMask()->y-y);
}
void UndoTransaction::autocropSprite(int bgcolor)
@ -921,9 +921,11 @@ void UndoTransaction::clearMask(int bgcolor)
if (!image)
return;
Mask* mask = m_document->getMask();
// if the mask is empty then we have to clear the entire image
// in the cel
if (m_sprite->getMask()->is_empty()) {
if (mask->is_empty()) {
// if the layer is the background then we clear the image
if (m_sprite->getCurrentLayer()->is_background()) {
if (isEnabled())
@ -939,13 +941,13 @@ void UndoTransaction::clearMask(int bgcolor)
}
}
else {
int offset_x = m_sprite->getMask()->x-cel->x;
int offset_y = m_sprite->getMask()->y-cel->y;
int offset_x = mask->x-cel->x;
int offset_y = mask->y-cel->y;
int u, v, putx, puty;
int x1 = MAX(0, offset_x);
int y1 = MAX(0, offset_y);
int x2 = MIN(image->w-1, offset_x+m_sprite->getMask()->w-1);
int y2 = MIN(image->h-1, offset_y+m_sprite->getMask()->h-1);
int x2 = MIN(image->w-1, offset_x+mask->w-1);
int y2 = MIN(image->h-1, offset_y+mask->h-1);
// do nothing
if (x1 > x2 || y1 > y2)
@ -955,11 +957,11 @@ void UndoTransaction::clearMask(int bgcolor)
m_undoHistory->undo_image(image, x1, y1, x2-x1+1, y2-y1+1);
// clear the masked zones
for (v=0; v<m_sprite->getMask()->h; v++) {
for (v=0; v<mask->h; v++) {
div_t d = div(0, 8);
ase_uint8* address = ((ase_uint8 **)m_sprite->getMask()->bitmap->line)[v]+d.quot;
ase_uint8* address = ((ase_uint8 **)mask->bitmap->line)[v]+d.quot;
for (u=0; u<m_sprite->getMask()->w; u++) {
for (u=0; u<mask->w; u++) {
if ((*address & (1<<d.rem))) {
putx = u + offset_x;
puty = v + offset_y;
@ -1019,45 +1021,33 @@ void UndoTransaction::pasteImage(const Image* src_image, int x, int y, int opaci
void UndoTransaction::copyToCurrentMask(Mask* mask)
{
ASSERT(m_sprite->getMask());
ASSERT(m_document->getMask());
ASSERT(mask);
if (isEnabled())
m_undoHistory->undo_set_mask(m_sprite);
m_undoHistory->undo_set_mask(m_document);
mask_copy(m_sprite->getMask(), mask);
mask_copy(m_document->getMask(), mask);
}
void UndoTransaction::setMaskPosition(int x, int y)
{
ASSERT(m_sprite->getMask());
ASSERT(m_document->getMask());
if (isEnabled()) {
m_undoHistory->undo_int(m_sprite->getMask(), &m_sprite->getMask()->x);
m_undoHistory->undo_int(m_sprite->getMask(), &m_sprite->getMask()->y);
m_undoHistory->undo_int(m_document->getMask(), &m_document->getMask()->x);
m_undoHistory->undo_int(m_document->getMask(), &m_document->getMask()->y);
}
m_sprite->getMask()->x = x;
m_sprite->getMask()->y = y;
m_document->getMask()->x = x;
m_document->getMask()->y = y;
}
void UndoTransaction::deselectMask()
{
// Destroy the *deselected* mask
Mask* mask = m_sprite->requestMask("*deselected*");
if (mask) {
m_sprite->removeMask(mask);
mask_free(mask);
}
// TODO IMPLEMENT THIS (add support to save values in UndoHistory from any object)
// if (isEnabled())
// m_undoHistory->undo_int(m_document);
// Save the selection in the repository
mask = mask_new_copy(m_sprite->getMask());
mask_set_name(mask, "*deselected*");
m_sprite->addMask(mask);
if (isEnabled())
m_undoHistory->undo_set_mask(m_sprite);
/// Deselect the mask
mask_none(m_sprite->getMask());
m_document->setMaskVisible(false);
}

View File

@ -78,7 +78,7 @@ enum {
};
static void set_clipboard(Image* image, Palette* palette, bool set_system_clipboard);
static bool copy_from_sprite(const Sprite* sprite);
static bool copy_from_document(const Document* document);
static bool interactive_transform(Editor* widget, Image *dest_image, Image *image,
int x, int y, int xout[4], int yout[4]);
@ -129,14 +129,16 @@ static void set_clipboard(Image* image, Palette* palette, bool set_system_clipbo
#endif
}
static bool copy_from_sprite(const Sprite* sprite)
static bool copy_from_document(const Document* document)
{
ASSERT(sprite != NULL);
Image* image = NewImageFromMask(sprite);
ASSERT(document != NULL);
ASSERT(document->isMaskVisible());
Image* image = NewImageFromMask(document);
if (!image)
return false;
const Palette* pal = sprite->getPalette(sprite->getCurrentFrame());
const Palette* pal = document->getSprite()->getPalette(document->getSprite()->getCurrentFrame());
set_clipboard(image, pal ? new Palette(*pal): NULL, true);
return true;
}
@ -156,14 +158,14 @@ void clipboard::cut(DocumentWriter& document)
ASSERT(document->getSprite() != NULL);
ASSERT(document->getSprite()->getCurrentLayer() != NULL);
Sprite* sprite = document->getSprite();
if (!copy_from_sprite(sprite)) {
if (!copy_from_document(document)) {
Console console;
console.printf("Can't copying an image portion from the current layer\n");
}
else {
{
Sprite* sprite = document->getSprite();
UndoTransaction undoTransaction(document, "Cut");
undoTransaction.clearMask(app_get_color_to_clear_layer(sprite->getCurrentLayer()));
undoTransaction.deselectMask();
@ -178,7 +180,7 @@ void clipboard::copy(const DocumentReader& document)
{
ASSERT(document != NULL);
if (!copy_from_sprite(document->getSprite())) {
if (!copy_from_document(document)) {
Console console;
console.printf("Can't copying an image portion from the current layer\n");
}

View File

@ -36,37 +36,37 @@
#include "widgets/editor.h"
#include "widgets/statebar.h"
Image* NewImageFromMask(const Sprite* src_sprite)
Image* NewImageFromMask(const Document* srcDocument)
{
const Sprite* srcSprite = srcDocument->getSprite();
const Mask* srcMask = srcDocument->getMask();
const ase_uint8* address;
int x, y, u, v, getx, gety;
Image *dst;
const Image *src = src_sprite->getCurrentImage(&x, &y);
const Image *src = srcSprite->getCurrentImage(&x, &y);
div_t d;
ASSERT(src_sprite);
ASSERT(src_sprite->getMask());
ASSERT(src_sprite->getMask()->bitmap);
ASSERT(srcSprite);
ASSERT(srcMask);
ASSERT(srcMask->bitmap);
ASSERT(src);
dst = image_new(src_sprite->getImgType(),
src_sprite->getMask()->w,
src_sprite->getMask()->h);
dst = image_new(srcSprite->getImgType(), srcMask->w, srcMask->h);
if (!dst)
return NULL;
/* clear the new image */
// Clear the new image
image_clear(dst, 0);
/* copy the masked zones */
for (v=0; v<src_sprite->getMask()->h; v++) {
// Copy the masked zones
for (v=0; v<srcMask->h; v++) {
d = div(0, 8);
address = ((const ase_uint8 **)src_sprite->getMask()->bitmap->line)[v]+d.quot;
address = ((const ase_uint8 **)srcMask->bitmap->line)[v]+d.quot;
for (u=0; u<src_sprite->getMask()->w; u++) {
for (u=0; u<srcMask->w; u++) {
if ((*address & (1<<d.rem))) {
getx = u+src_sprite->getMask()->x-x;
gety = v+src_sprite->getMask()->y-y;
getx = u+srcMask->x-x;
gety = v+srcMask->y-y;
if ((getx >= 0) && (getx < src->w) &&
(gety >= 0) && (gety < src->h))
@ -80,8 +80,8 @@ Image* NewImageFromMask(const Sprite* src_sprite)
return dst;
}
/* Gives to the user the possibility to move the sprite's layer in the
current editor, returns true if the position was changed. */
// 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)())
{
Editor* editor = current_editor;

View File

@ -23,9 +23,9 @@
#include "widgets/editor.h" // For movement modes
class Image;
class Sprite;
class Document;
Image* NewImageFromMask(const Sprite* src);
Image* NewImageFromMask(const Document* srcDocument);
int interactive_move_layer(int mode, bool use_undo, int (*callback)());

View File

@ -617,11 +617,12 @@ void Editor::turnOnSelectionModifiers()
{
deleteDecorators();
Mask* mask = m_document->getMask();
int x1, y1, x2, y2;
editor_to_screen(m_sprite->getMask()->x, m_sprite->getMask()->y, &x1, &y1);
editor_to_screen(m_sprite->getMask()->x+m_sprite->getMask()->w-1,
m_sprite->getMask()->y+m_sprite->getMask()->h-1, &x2, &y2);
editor_to_screen(mask->x, mask->y, &x1, &y1);
editor_to_screen(mask->x+mask->w-1,
mask->y+mask->h-1, &x2, &y2);
addDecorator(new Decorator(Decorator::SELECTION_NW, Rect(x1-8, y1-8, 8, 8)));
addDecorator(new Decorator(Decorator::SELECTION_N, Rect((x1+x2)/2-4, y1-8, 8, 8)));
@ -769,7 +770,7 @@ void Editor::editor_update_statusbar_for_standby()
}
// For other tools
else {
Mask* mask = m_sprite->getMask();
Mask* mask = m_document->getMask();
app_get_statusbar()->setStatusText
(0, "Pos %d %d, Size %d %d, Frame %d",
@ -1100,9 +1101,9 @@ bool Editor::onProcessMessage(JMessage msg)
}
// Copy the mask to the extra cel image
Image* tmpImage = NewImageFromMask(m_sprite);
x = m_sprite->getMask()->x;
y = m_sprite->getMask()->y;
Image* tmpImage = NewImageFromMask(m_document);
x = m_document->getMask()->x;
y = m_document->getMask()->y;
m_pixelsMovement = new PixelsMovement(m_document, m_sprite, tmpImage, x, y, opacity);
delete tmpImage;
@ -1564,7 +1565,8 @@ void Editor::editor_setcursor(int x, int y)
// Move selection
if (m_pixelsMovement->isDragging() ||
m_sprite->getMask()->contains_point(x, y)) {
m_document->isMaskVisible() &&
m_document->getMask()->contains_point(x, y)) {
hide_drawing_cursor();
jmouse_set_cursor(JI_CURSOR_MOVE);
@ -1595,7 +1597,8 @@ void Editor::editor_setcursor(int x, int y)
screen_to_editor(jmouse_x(0), jmouse_y(0), &x, &y);
// Move pixels
if (m_sprite->getMask()->contains_point(x, y)) {
if (m_document->isMaskVisible() &&
m_document->getMask()->contains_point(x, y)) {
hide_drawing_cursor();
if (key[KEY_LCONTROL] ||
key[KEY_RCONTROL]) // TODO configurable keys
@ -1760,6 +1763,7 @@ class ToolLoopImpl : public IToolLoop
TiledMode m_tiled_mode;
Image* m_src_image;
Image* m_dst_image;
bool m_useMask;
Mask* m_mask;
Point m_maskOrigin;
int m_opacity;
@ -1779,21 +1783,20 @@ public:
Sprite* sprite,
Layer* layer,
int button, const Color& primary_color, const Color& secondary_color)
: m_editor(editor)
, m_context(context)
, m_tool(tool)
, m_document(document)
, m_sprite(sprite)
, m_layer(layer)
, m_cel(NULL)
, m_cel_image(NULL)
, m_cel_created(false)
, m_canceled(false)
, m_button(button)
, m_primary_color(color_utils::color_for_layer(primary_color, layer))
, m_secondary_color(color_utils::color_for_layer(secondary_color, layer))
{
m_editor = editor;
m_context = context;
m_tool = tool;
m_document = document;
m_sprite = sprite;
m_layer = layer;
m_cel = NULL;
m_cel_image = NULL;
m_cel_created = false;
m_canceled = false;
m_button = button;
m_primary_color = color_utils::color_for_layer(primary_color, layer);
m_secondary_color = color_utils::color_for_layer(secondary_color, layer);
// Settings
ISettings* settings = m_context->getSettings();
@ -1871,7 +1874,15 @@ public:
m_cel_image->mask_color);
m_dst_image = image_new_copy(m_src_image);
m_mask = m_sprite->getMask();
m_useMask = m_document->isMaskVisible();
// Selection ink
if (getInk()->isSelection() && !m_document->isMaskVisible()) {
Mask emptyMask;
m_document->setMask(&emptyMask);
}
m_mask = m_document->getMask();
m_maskOrigin = (!m_mask->is_empty() ? Point(m_mask->x-x1, m_mask->y-y1):
Point(0, 0));
@ -2015,6 +2026,7 @@ public:
Layer* getLayer() { return m_layer; }
Image* getSrcImage() { return m_src_image; }
Image* getDstImage() { return m_dst_image; }
bool useMask() { return m_useMask; }
Mask* getMask() { return m_mask; }
Point getMaskOrigin() { return m_maskOrigin; }
int getMouseButton() { return m_button; }

View File

@ -148,8 +148,8 @@ public:
m_undoTransaction.setMaskPosition(cel->x, cel->y);
}
else {
m_sprite->getMask()->x = cel->x;
m_sprite->getMask()->y = cel->y;
m_documentWriter->getMask()->x = cel->x;
m_documentWriter->getMask()->y = cel->y;
}
m_documentWriter->generateMaskBoundaries();