mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-30 06:32:42 +00:00
Separate extra cel concept from app::Document into app::ExtraCel class
This commit is contained in:
parent
b2049f7ce4
commit
a39e3710ce
@ -258,6 +258,7 @@ add_library(app-lib
|
||||
document_range.cpp
|
||||
document_range_ops.cpp
|
||||
document_undo.cpp
|
||||
extra_cel.cpp
|
||||
file/ase_format.cpp
|
||||
file/bmp_format.cpp
|
||||
file/file.cpp
|
||||
|
@ -105,7 +105,7 @@ void SetPixelFormat::setFormat(PixelFormat format)
|
||||
|
||||
// Regenerate extras
|
||||
static_cast<app::Document*>(sprite->document())
|
||||
->destroyExtraCel();
|
||||
->setExtraCel(ExtraCelRef(nullptr));
|
||||
|
||||
// Generate notification
|
||||
DocumentEvent ev(sprite->document());
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
editor->getManager()->freeMouse();
|
||||
|
||||
// Clear extras (e.g. pen preview)
|
||||
m_doc->destroyExtraCel();
|
||||
m_doc->setExtraCel(ExtraCelRef(nullptr));
|
||||
|
||||
gfx::Rect vp = view->getViewportBounds();
|
||||
gfx::Point scroll = view->getViewScroll();
|
||||
|
@ -122,7 +122,7 @@ void UndoCommand::onExecute(Context* context)
|
||||
}
|
||||
|
||||
document->generateMaskBoundaries();
|
||||
document->destroyExtraCel(); // Regenerate extras
|
||||
document->setExtraCel(ExtraCelRef(nullptr));
|
||||
|
||||
update_screen_for_document(document);
|
||||
set_current_palette(writer.palette(), false);
|
||||
|
@ -51,12 +51,6 @@ Document::Document(Sprite* sprite)
|
||||
, m_read_locks(0)
|
||||
// Information about the file format used to load/save this document
|
||||
, m_format_options(NULL)
|
||||
// Extra cel
|
||||
, m_extraCel(nullptr)
|
||||
, m_extraImage(nullptr)
|
||||
, m_extraImageBuffer(nullptr)
|
||||
, m_extraCelBlendMode(BlendMode::NORMAL)
|
||||
, m_extraCelType(render::ExtraType::NONE)
|
||||
// Mask
|
||||
, m_mask(new Mask())
|
||||
, m_maskVisible(true)
|
||||
@ -75,8 +69,6 @@ Document::~Document()
|
||||
// which could result in serious problems for observers expecting a
|
||||
// fully created app::Document.
|
||||
ASSERT(context() == NULL);
|
||||
|
||||
destroyExtraCel();
|
||||
}
|
||||
|
||||
DocumentApi Document::getApi(Transaction& transaction)
|
||||
@ -232,55 +224,6 @@ void Document::generateMaskBoundaries(const Mask* mask)
|
||||
notifySelectionChanged();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Extra Cel (it is used to draw pen preview, pixels in movement, etc.)
|
||||
|
||||
void Document::destroyExtraCel()
|
||||
{
|
||||
delete m_extraCel;
|
||||
|
||||
m_extraCel = nullptr;
|
||||
m_extraImage.reset(nullptr);
|
||||
m_extraCelType = render::ExtraType::NONE;
|
||||
}
|
||||
|
||||
void Document::prepareExtraCel(const gfx::Rect& bounds, frame_t frame, int opacity)
|
||||
{
|
||||
ASSERT(sprite() != NULL);
|
||||
|
||||
if (!m_extraImage ||
|
||||
m_extraImage->pixelFormat() != sprite()->pixelFormat() ||
|
||||
m_extraImage->width() != bounds.w ||
|
||||
m_extraImage->height() != bounds.h) {
|
||||
if (!m_extraImageBuffer)
|
||||
m_extraImageBuffer.reset(new ImageBuffer(1));
|
||||
Image* newImage = Image::create(sprite()->pixelFormat(), bounds.w, bounds.h, m_extraImageBuffer);
|
||||
m_extraImage.reset(newImage);
|
||||
}
|
||||
|
||||
if (!m_extraCel)
|
||||
m_extraCel = new Cel(frame_t(0), ImageRef(NULL)); // Ignored fields for this cel (frame, and image index)
|
||||
|
||||
m_extraCel->setPosition(bounds.getOrigin());
|
||||
m_extraCel->setOpacity(opacity);
|
||||
m_extraCel->setFrame(frame);
|
||||
}
|
||||
|
||||
void Document::setExtraCelType(render::ExtraType type)
|
||||
{
|
||||
m_extraCelType = type;
|
||||
}
|
||||
|
||||
Cel* Document::getExtraCel() const
|
||||
{
|
||||
return m_extraCel;
|
||||
}
|
||||
|
||||
Image* Document::getExtraCelImage() const
|
||||
{
|
||||
return m_extraImage.get();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Mask
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define APP_DOCUMENT_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/extra_cel.h"
|
||||
#include "app/file/format_options.h"
|
||||
#include "base/disable_copying.h"
|
||||
#include "base/mutex.h"
|
||||
@ -19,12 +20,9 @@
|
||||
#include "doc/color.h"
|
||||
#include "doc/document.h"
|
||||
#include "doc/frame.h"
|
||||
#include "doc/image_ref.h"
|
||||
#include "doc/image_buffer.h"
|
||||
#include "doc/pixel_format.h"
|
||||
#include "gfx/rect.h"
|
||||
#include "gfx/transformation.h"
|
||||
#include "render/extra_type.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -123,14 +121,8 @@ namespace app {
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Extra Cel (it is used to draw pen preview, pixels in movement, etc.)
|
||||
|
||||
void prepareExtraCel(const gfx::Rect& bounds, frame_t frame, int opacity);
|
||||
void setExtraCelType(render::ExtraType type);
|
||||
void destroyExtraCel();
|
||||
Cel* getExtraCel() const;
|
||||
Image* getExtraCelImage() const;
|
||||
render::ExtraType getExtraCelType() const { return m_extraCelType; }
|
||||
BlendMode getExtraCelBlendMode() const { return m_extraCelBlendMode; }
|
||||
void setExtraCelBlendMode(BlendMode mode) { m_extraCelBlendMode = mode; }
|
||||
ExtraCelRef extraCel() const { return m_extraCel; }
|
||||
void setExtraCel(const ExtraCelRef& extraCel) { m_extraCel = extraCel; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Mask
|
||||
@ -210,13 +202,7 @@ namespace app {
|
||||
base::SharedPtr<FormatOptions> m_format_options;
|
||||
|
||||
// Extra cel used to draw extra stuff (e.g. editor's pen preview, pixels in movement, etc.)
|
||||
Cel* m_extraCel;
|
||||
|
||||
// Image of the extra cel.
|
||||
ImageRef m_extraImage;
|
||||
ImageBufferPtr m_extraImageBuffer;
|
||||
BlendMode m_extraCelBlendMode;
|
||||
render::ExtraType m_extraCelType;
|
||||
ExtraCelRef m_extraCel;
|
||||
|
||||
// Current mask.
|
||||
base::UniquePtr<Mask> m_mask;
|
||||
|
53
src/app/extra_cel.cpp
Normal file
53
src/app/extra_cel.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/extra_cel.h"
|
||||
|
||||
#include "doc/sprite.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
ExtraCel::ExtraCel()
|
||||
: m_type(render::ExtraType::NONE)
|
||||
, m_blendMode(doc::BlendMode::NORMAL)
|
||||
{
|
||||
}
|
||||
|
||||
void ExtraCel::create(doc::Sprite* sprite,
|
||||
const gfx::Rect& bounds,
|
||||
doc::frame_t frame,
|
||||
int opacity)
|
||||
{
|
||||
ASSERT(sprite);
|
||||
|
||||
if (!m_image ||
|
||||
m_image->pixelFormat() != sprite->pixelFormat() ||
|
||||
m_image->width() != bounds.w ||
|
||||
m_image->height() != bounds.h) {
|
||||
if (!m_imageBuffer)
|
||||
m_imageBuffer.reset(new doc::ImageBuffer(1));
|
||||
doc::Image* newImage = doc::Image::create(sprite->pixelFormat(),
|
||||
bounds.w, bounds.h,
|
||||
m_imageBuffer);
|
||||
m_image.reset(newImage);
|
||||
}
|
||||
|
||||
if (!m_cel) {
|
||||
// Ignored fields for this cel (frame, and image index)
|
||||
m_cel.reset(new doc::Cel(doc::frame_t(0), doc::ImageRef(nullptr)));
|
||||
}
|
||||
|
||||
m_cel->setPosition(bounds.getOrigin());
|
||||
m_cel->setOpacity(opacity);
|
||||
m_cel->setFrame(frame);
|
||||
}
|
||||
|
||||
} // namespace app
|
58
src/app/extra_cel.h
Normal file
58
src/app/extra_cel.h
Normal file
@ -0,0 +1,58 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_EXTRA_CEL_H_INCLUDED
|
||||
#define APP_EXTRA_CEL_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "base/disable_copying.h"
|
||||
#include "base/unique_ptr.h"
|
||||
#include "doc/blend_mode.h"
|
||||
#include "doc/cel.h"
|
||||
#include "doc/frame.h"
|
||||
#include "doc/image_buffer.h"
|
||||
#include "doc/image_ref.h"
|
||||
#include "gfx/rect.h"
|
||||
#include "render/extra_type.h"
|
||||
|
||||
namespace doc {
|
||||
class Sprite;
|
||||
}
|
||||
|
||||
namespace app {
|
||||
|
||||
class ExtraCel {
|
||||
public:
|
||||
ExtraCel();
|
||||
|
||||
void create(doc::Sprite* sprite, const gfx::Rect& bounds, doc::frame_t frame, int opacity);
|
||||
void destroy();
|
||||
|
||||
render::ExtraType type() const { return m_type; }
|
||||
void setType(render::ExtraType type) { m_type = type; }
|
||||
|
||||
doc::Cel* cel() const { return m_cel.get(); }
|
||||
doc::Image* image() const { return m_image.get(); }
|
||||
|
||||
doc::BlendMode blendMode() const { return m_blendMode; }
|
||||
void setBlendMode(doc::BlendMode mode) { m_blendMode = mode; }
|
||||
|
||||
private:
|
||||
render::ExtraType m_type;
|
||||
base::UniquePtr<doc::Cel> m_cel;
|
||||
doc::ImageRef m_image;
|
||||
doc::ImageBufferPtr m_imageBuffer;
|
||||
doc::BlendMode m_blendMode;
|
||||
|
||||
DISABLE_COPYING(ExtraCel);
|
||||
};
|
||||
|
||||
typedef base::SharedPtr<ExtraCel> ExtraCelRef;
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -155,13 +155,17 @@ void BrushPreview::show(const gfx::Point& screenPos)
|
||||
if (cel) opacity = MUL_UN8(opacity, cel->opacity(), t);
|
||||
if (layer) opacity = MUL_UN8(opacity, static_cast<LayerImage*>(layer)->opacity(), t);
|
||||
|
||||
document->prepareExtraCel(brushBounds, site.frame(), opacity);
|
||||
document->setExtraCelType(render::ExtraType::NONE);
|
||||
document->setExtraCelBlendMode(
|
||||
if (!m_extraCel)
|
||||
m_extraCel.reset(new ExtraCel);
|
||||
m_extraCel->create(document->sprite(), brushBounds, site.frame(), opacity);
|
||||
m_extraCel->setType(render::ExtraType::NONE);
|
||||
m_extraCel->setBlendMode(
|
||||
(layer ? static_cast<LayerImage*>(layer)->blendMode():
|
||||
BlendMode::NORMAL));
|
||||
|
||||
Image* extraImage = document->getExtraCelImage();
|
||||
document->setExtraCel(m_extraCel);
|
||||
|
||||
Image* extraImage = m_extraCel->image();
|
||||
extraImage->setMaskColor(mask_index);
|
||||
clear_image(extraImage,
|
||||
(extraImage->pixelFormat() == IMAGE_INDEXED ? mask_index: 0));
|
||||
@ -173,7 +177,7 @@ void BrushPreview::show(const gfx::Point& screenPos)
|
||||
BlendMode::SRC);
|
||||
|
||||
// This extra cel is a patch for the current layer/frame
|
||||
document->setExtraCelType(render::ExtraType::PATCH);
|
||||
m_extraCel->setType(render::ExtraType::PATCH);
|
||||
}
|
||||
|
||||
tools::ToolLoop* loop = create_tool_loop_preview(
|
||||
@ -247,7 +251,7 @@ void BrushPreview::hide()
|
||||
|
||||
// Clean pixel/brush preview
|
||||
if (m_withRealPreview) {
|
||||
document->destroyExtraCel();
|
||||
document->setExtraCel(ExtraCelRef(nullptr));
|
||||
document->notifySpritePixelsModified(
|
||||
sprite, gfx::Region(m_lastBounds), m_lastFrame);
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define APP_UI_EDITOR_BRUSH_PREVIEW_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/extra_cel.h"
|
||||
#include "base/shared_ptr.h"
|
||||
#include "doc/color.h"
|
||||
#include "doc/frame.h"
|
||||
@ -106,6 +107,8 @@ namespace app {
|
||||
// brush preview in the exact same place.
|
||||
gfx::Rect m_lastBounds;
|
||||
doc::frame_t m_lastFrame;
|
||||
|
||||
ExtraCelRef m_extraCel;
|
||||
};
|
||||
|
||||
class HideBrushPreview {
|
||||
|
@ -479,14 +479,13 @@ void Editor::drawOneSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& sprite
|
||||
}
|
||||
}
|
||||
|
||||
if (m_document->getExtraCelType() != render::ExtraType::NONE) {
|
||||
ASSERT(m_document->getExtraCel());
|
||||
|
||||
ExtraCelRef extraCel = m_document->extraCel();
|
||||
if (extraCel && extraCel->type() != render::ExtraType::NONE) {
|
||||
m_renderEngine.setExtraImage(
|
||||
m_document->getExtraCelType(),
|
||||
m_document->getExtraCel(),
|
||||
m_document->getExtraCelImage(),
|
||||
m_document->getExtraCelBlendMode(),
|
||||
extraCel->type(),
|
||||
extraCel->cel(),
|
||||
extraCel->image(),
|
||||
extraCel->blendMode(),
|
||||
m_layer, m_frame);
|
||||
}
|
||||
|
||||
@ -794,22 +793,24 @@ void Editor::flashCurrentLayer()
|
||||
if (src_image) {
|
||||
m_renderEngine.removePreviewImage();
|
||||
|
||||
m_document->prepareExtraCel(m_sprite->bounds(), m_frame, 255);
|
||||
m_document->setExtraCelType(render::ExtraType::COMPOSITE);
|
||||
|
||||
Image* flash_image = m_document->getExtraCelImage();
|
||||
ExtraCelRef extraCel(new ExtraCel);
|
||||
extraCel->create(m_sprite, m_sprite->bounds(), m_frame, 255);
|
||||
extraCel->setType(render::ExtraType::COMPOSITE);
|
||||
extraCel->setBlendMode(BlendMode::NEG_BW);
|
||||
|
||||
Image* flash_image = extraCel->image();
|
||||
clear_image(flash_image, flash_image->maskColor());
|
||||
copy_image(flash_image, src_image, x, y);
|
||||
m_document->setExtraCelBlendMode(BlendMode::NEG_BW);
|
||||
|
||||
drawSpriteClipped(gfx::Region(
|
||||
gfx::Rect(0, 0, m_sprite->width(), m_sprite->height())));
|
||||
{
|
||||
ExtraCelRef oldExtraCel = m_document->extraCel();
|
||||
m_document->setExtraCel(extraCel);
|
||||
drawSpriteClipped(gfx::Region(
|
||||
gfx::Rect(0, 0, m_sprite->width(), m_sprite->height())));
|
||||
getManager()->flipDisplay();
|
||||
m_document->setExtraCel(oldExtraCel);
|
||||
}
|
||||
|
||||
getManager()->flipDisplay();
|
||||
|
||||
m_document->setExtraCelBlendMode(BlendMode::NORMAL);
|
||||
m_document->destroyExtraCel();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ PixelsMovement::PixelsMovement(
|
||||
// The extra cel must be null, because if it's not null, it means
|
||||
// that someone else is using it (e.g. the editor brush preview),
|
||||
// and its owner could destroy our new "extra cel".
|
||||
ASSERT(!m_document->getExtraCel());
|
||||
ASSERT(!m_document->extraCel());
|
||||
redrawExtraImage();
|
||||
redrawCurrentMask();
|
||||
|
||||
@ -491,8 +491,8 @@ void PixelsMovement::getDraggedImageCopy(base::UniquePtr<Image>& outputImage,
|
||||
|
||||
void PixelsMovement::stampImage()
|
||||
{
|
||||
const Cel* cel = m_document->getExtraCel();
|
||||
const Image* image = m_document->getExtraCelImage();
|
||||
const Cel* cel = m_extraCel->cel();
|
||||
const Image* image = m_extraCel->image();
|
||||
|
||||
ASSERT(cel && image);
|
||||
|
||||
@ -583,7 +583,7 @@ void PixelsMovement::dropImage()
|
||||
// Destroy the extra cel (this cel will be used by the drawing
|
||||
// cursor surely).
|
||||
ContextWriter writer(m_reader, 1000);
|
||||
m_document->destroyExtraCel();
|
||||
m_document->setExtraCel(ExtraCelRef(nullptr));
|
||||
}
|
||||
|
||||
void PixelsMovement::discardImage(bool commit)
|
||||
@ -599,7 +599,7 @@ void PixelsMovement::discardImage(bool commit)
|
||||
// Destroy the extra cel and regenerate the mask boundaries (we've
|
||||
// just deselect the mask).
|
||||
ContextWriter writer(m_reader, 1000);
|
||||
m_document->destroyExtraCel();
|
||||
m_document->setExtraCel(ExtraCelRef(nullptr));
|
||||
m_document->generateMaskBoundaries();
|
||||
}
|
||||
|
||||
@ -610,8 +610,8 @@ bool PixelsMovement::isDragging() const
|
||||
|
||||
gfx::Rect PixelsMovement::getImageBounds()
|
||||
{
|
||||
const Cel* cel = m_document->getExtraCel();
|
||||
const Image* image = m_document->getExtraCelImage();
|
||||
const Cel* cel = m_extraCel->cel();
|
||||
const Image* image = m_extraCel->image();
|
||||
|
||||
ASSERT(cel != NULL);
|
||||
ASSERT(image != NULL);
|
||||
@ -641,14 +641,16 @@ void PixelsMovement::redrawExtraImage()
|
||||
if (cel) opacity = MUL_UN8(opacity, cel->opacity(), t);
|
||||
|
||||
gfx::Rect bounds = m_currentData.transformedBounds();
|
||||
m_document->prepareExtraCel(bounds, m_site.frame(), opacity);
|
||||
m_document->setExtraCelType(render::ExtraType::PATCH);
|
||||
m_document->setExtraCelBlendMode(
|
||||
static_cast<LayerImage*>(m_layer)->blendMode());
|
||||
|
||||
m_extraCel.reset(new ExtraCel);
|
||||
m_extraCel->create(m_document->sprite(), bounds, m_site.frame(), opacity);
|
||||
m_extraCel->setType(render::ExtraType::PATCH);
|
||||
m_extraCel->setBlendMode(static_cast<LayerImage*>(m_layer)->blendMode());
|
||||
m_document->setExtraCel(m_extraCel);
|
||||
|
||||
// Draw the transformed pixels in the extra-cel which is the chunk
|
||||
// of pixels that the user is moving.
|
||||
drawImage(m_document->getExtraCelImage(), bounds.getOrigin(), true);
|
||||
drawImage(m_extraCel->image(), bounds.getOrigin(), true);
|
||||
}
|
||||
|
||||
void PixelsMovement::redrawCurrentMask()
|
||||
|
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "app/context_access.h"
|
||||
#include "app/extra_cel.h"
|
||||
#include "app/transaction.h"
|
||||
#include "app/ui/editor/handle_type.h"
|
||||
#include "base/connection.h"
|
||||
@ -125,6 +126,7 @@ namespace app {
|
||||
ScopedConnection m_pivotVisConn;
|
||||
ScopedConnection m_pivotPosConn;
|
||||
ScopedConnection m_rotAlgoConn;
|
||||
ExtraCelRef m_extraCel;
|
||||
};
|
||||
|
||||
inline PixelsMovement::MoveModifier& operator|=(PixelsMovement::MoveModifier& a,
|
||||
|
Loading…
x
Reference in New Issue
Block a user