mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-04 05:50:15 +00:00
Avoid problems regenerating brush boundaries when the brush image ptr addresses are the same
This commit is contained in:
parent
12e28960e4
commit
15fb45f3a1
@ -55,10 +55,10 @@ using namespace ui;
|
|||||||
static struct {
|
static struct {
|
||||||
int nseg;
|
int nseg;
|
||||||
BoundSeg* seg;
|
BoundSeg* seg;
|
||||||
Image* brush_image;
|
int brush_gen;
|
||||||
int brush_width;
|
int brush_width;
|
||||||
int brush_height;
|
int brush_height;
|
||||||
} cursor_bound = { 0, nullptr, nullptr, 0, 0 };
|
} cursor_bound = { 0, nullptr, 0, 0, 0 };
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CURSOR_THINCROSS = 1,
|
CURSOR_THINCROSS = 1,
|
||||||
@ -79,7 +79,7 @@ static gfx::Region old_clipping_region;
|
|||||||
|
|
||||||
static gfx::Rect lastBrushBounds;
|
static gfx::Rect lastBrushBounds;
|
||||||
|
|
||||||
static void generate_cursor_boundaries(Editor* editor);
|
static void generate_cursor_boundaries();
|
||||||
|
|
||||||
static void trace_thincross_pixels(ui::Graphics* g, Editor* editor, const gfx::Point& pt, gfx::Color color, Editor::PixelDelegate pixel);
|
static void trace_thincross_pixels(ui::Graphics* g, Editor* editor, const gfx::Point& pt, gfx::Color color, Editor::PixelDelegate pixel);
|
||||||
static void trace_thickcross_pixels(ui::Graphics* g, Editor* editor, const gfx::Point& pt, gfx::Color color, int thickness, Editor::PixelDelegate pixel);
|
static void trace_thickcross_pixels(ui::Graphics* g, Editor* editor, const gfx::Point& pt, gfx::Color color, int thickness, Editor::PixelDelegate pixel);
|
||||||
@ -172,7 +172,7 @@ void Editor::drawBrushPreview(const gfx::Point& pos)
|
|||||||
|
|
||||||
// For cursor type 'bounds' we have to generate cursor boundaries
|
// For cursor type 'bounds' we have to generate cursor boundaries
|
||||||
if (cursor_type & CURSOR_BRUSHBOUNDS)
|
if (cursor_type & CURSOR_BRUSHBOUNDS)
|
||||||
generate_cursor_boundaries(this);
|
generate_cursor_boundaries();
|
||||||
|
|
||||||
// Draw pixel/brush preview
|
// Draw pixel/brush preview
|
||||||
if (cursor_type & CURSOR_THINCROSS && m_state->requireBrushPreview()) {
|
if (cursor_type & CURSOR_THINCROSS && m_state->requireBrushPreview()) {
|
||||||
@ -292,41 +292,40 @@ bool Editor::doesBrushPreviewNeedSubpixel()
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void generate_cursor_boundaries(Editor* editor)
|
static void generate_cursor_boundaries()
|
||||||
{
|
{
|
||||||
Brush* brush = get_current_brush();
|
Brush* brush = get_current_brush();
|
||||||
|
|
||||||
if (!cursor_bound.seg || cursor_bound.brush_image != brush->image()) {
|
if (cursor_bound.seg &&
|
||||||
Image* brush_image = brush->image();
|
cursor_bound.brush_gen == brush->gen())
|
||||||
int w = brush_image->width();
|
return;
|
||||||
int h = brush_image->height();
|
|
||||||
|
|
||||||
cursor_bound.brush_image = brush_image;
|
Image* brush_image = brush->image();
|
||||||
cursor_bound.brush_width = w;
|
int w = brush_image->width();
|
||||||
cursor_bound.brush_height = h;
|
int h = brush_image->height();
|
||||||
|
|
||||||
if (cursor_bound.seg)
|
cursor_bound.brush_gen = brush->gen();
|
||||||
base_free(cursor_bound.seg);
|
cursor_bound.brush_width = w;
|
||||||
|
cursor_bound.brush_height = h;
|
||||||
|
|
||||||
ImageRef mask;
|
ImageRef mask;
|
||||||
if (brush_image->pixelFormat() != IMAGE_BITMAP) {
|
if (brush_image->pixelFormat() != IMAGE_BITMAP) {
|
||||||
mask.reset(Image::create(IMAGE_BITMAP, w, h));
|
mask.reset(Image::create(IMAGE_BITMAP, w, h));
|
||||||
|
|
||||||
LockImageBits<BitmapTraits> bits(mask.get());
|
LockImageBits<BitmapTraits> bits(mask.get());
|
||||||
auto pos = bits.begin();
|
auto pos = bits.begin();
|
||||||
for (int v=0; v<h; ++v) {
|
for (int v=0; v<h; ++v) {
|
||||||
for (int u=0; u<w; ++u) {
|
for (int u=0; u<w; ++u) {
|
||||||
*pos = get_pixel(brush_image, u, v);
|
*pos = get_pixel(brush_image, u, v);
|
||||||
++pos;
|
++pos;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor_bound.seg = find_mask_boundary(
|
|
||||||
(mask ? mask.get(): brush_image),
|
|
||||||
&cursor_bound.nseg,
|
|
||||||
IgnoreBounds, 0, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cursor_bound.seg = find_mask_boundary(
|
||||||
|
(mask ? mask.get(): brush_image),
|
||||||
|
&cursor_bound.nseg,
|
||||||
|
IgnoreBounds, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::forEachBrushPixel(
|
void Editor::forEachBrushPixel(
|
||||||
|
@ -19,12 +19,15 @@
|
|||||||
|
|
||||||
namespace doc {
|
namespace doc {
|
||||||
|
|
||||||
|
static int generation = 0;
|
||||||
|
|
||||||
Brush::Brush()
|
Brush::Brush()
|
||||||
{
|
{
|
||||||
m_type = kCircleBrushType;
|
m_type = kCircleBrushType;
|
||||||
m_size = 1;
|
m_size = 1;
|
||||||
m_angle = 0;
|
m_angle = 0;
|
||||||
m_pattern = BrushPattern::DEFAULT;
|
m_pattern = BrushPattern::DEFAULT;
|
||||||
|
m_gen = 0;
|
||||||
|
|
||||||
regenerate();
|
regenerate();
|
||||||
}
|
}
|
||||||
@ -35,6 +38,7 @@ Brush::Brush(BrushType type, int size, int angle)
|
|||||||
m_size = size;
|
m_size = size;
|
||||||
m_angle = angle;
|
m_angle = angle;
|
||||||
m_pattern = BrushPattern::DEFAULT;
|
m_pattern = BrushPattern::DEFAULT;
|
||||||
|
m_gen = 0;
|
||||||
|
|
||||||
regenerate();
|
regenerate();
|
||||||
}
|
}
|
||||||
@ -47,6 +51,7 @@ Brush::Brush(const Brush& brush)
|
|||||||
m_image = brush.m_image;
|
m_image = brush.m_image;
|
||||||
m_pattern = brush.m_pattern;
|
m_pattern = brush.m_pattern;
|
||||||
m_patternOrigin = brush.m_patternOrigin;
|
m_patternOrigin = brush.m_patternOrigin;
|
||||||
|
m_gen = 0;
|
||||||
|
|
||||||
regenerate();
|
regenerate();
|
||||||
}
|
}
|
||||||
@ -89,6 +94,7 @@ void Brush::setImage(const Image* image)
|
|||||||
// Cleans the brush's data (image and region).
|
// Cleans the brush's data (image and region).
|
||||||
void Brush::clean()
|
void Brush::clean()
|
||||||
{
|
{
|
||||||
|
m_gen = ++generation;
|
||||||
m_image.reset();
|
m_image.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ namespace doc {
|
|||||||
int size() const { return m_size; }
|
int size() const { return m_size; }
|
||||||
int angle() const { return m_angle; }
|
int angle() const { return m_angle; }
|
||||||
Image* image() const { return m_image.get(); }
|
Image* image() const { return m_image.get(); }
|
||||||
|
int gen() const { return m_gen; }
|
||||||
|
|
||||||
BrushPattern pattern() const { return m_pattern; }
|
BrushPattern pattern() const { return m_pattern; }
|
||||||
gfx::Point patternOrigin() const { return m_patternOrigin; }
|
gfx::Point patternOrigin() const { return m_patternOrigin; }
|
||||||
@ -60,6 +61,7 @@ namespace doc {
|
|||||||
gfx::Rect m_bounds;
|
gfx::Rect m_bounds;
|
||||||
BrushPattern m_pattern; // How the image should be replicated
|
BrushPattern m_pattern; // How the image should be replicated
|
||||||
gfx::Point m_patternOrigin; // From what position the brush was taken
|
gfx::Point m_patternOrigin; // From what position the brush was taken
|
||||||
|
int m_gen;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef base::SharedPtr<Brush> BrushRef;
|
typedef base::SharedPtr<Brush> BrushRef;
|
||||||
|
Loading…
Reference in New Issue
Block a user