From 8382d1ca8f13b88704ec142f22276537c4a7039b Mon Sep 17 00:00:00 2001 From: David Capello Date: Sat, 25 Apr 2015 20:01:03 -0300 Subject: [PATCH] Replace Brush::m_scanline with doc::CompressedImage --- src/app/tools/point_shape.h | 1 + src/app/tools/point_shapes.h | 35 ++++++++++++---------- src/app/tools/tool_box.cpp | 1 + src/app/tools/tool_loop_manager.cpp | 1 + src/doc/CMakeLists.txt | 1 + src/doc/brush.cpp | 20 ------------- src/doc/brush.h | 6 ---- src/doc/compressed_image.cpp | 42 +++++++++++++++++++++++++++ src/doc/compressed_image.h | 45 +++++++++++++++++++++++++++++ 9 files changed, 111 insertions(+), 41 deletions(-) create mode 100644 src/doc/compressed_image.cpp create mode 100644 src/doc/compressed_image.h diff --git a/src/app/tools/point_shape.h b/src/app/tools/point_shape.h index dc45caf9a..137c0dcd3 100644 --- a/src/app/tools/point_shape.h +++ b/src/app/tools/point_shape.h @@ -21,6 +21,7 @@ namespace app { virtual ~PointShape() { } virtual bool isFloodFill() { return false; } virtual bool isSpray() { return false; } + virtual void preparePointShape(ToolLoop* loop) { } virtual void transformPoint(ToolLoop* loop, int x, int y) = 0; virtual void getModifiedArea(ToolLoop* loop, int x, int y, gfx::Rect& area) = 0; diff --git a/src/app/tools/point_shapes.h b/src/app/tools/point_shapes.h index 54926cee5..32f12689e 100644 --- a/src/app/tools/point_shapes.h +++ b/src/app/tools/point_shapes.h @@ -33,29 +33,34 @@ public: }; class BrushPointShape : public PointShape { + Brush* m_brush; + base::SharedPtr m_compressedImage; + public: - void transformPoint(ToolLoop* loop, int x, int y) - { - Brush* brush = loop->getBrush(); - std::vector::const_iterator scanline = brush->scanline().begin(); - int v, h = brush->bounds().h; - x += brush->bounds().x; - y += brush->bounds().y; + void preparePointShape(ToolLoop* loop) override { + m_brush = loop->getBrush(); + m_compressedImage.reset(new CompressedImage(m_brush->image())); + } - for (v=0; vstate) - doInkHline(x+scanline->x1, y+v, x+scanline->x2, loop); - ++scanline; + void transformPoint(ToolLoop* loop, int x, int y) override { + int h = m_brush->bounds().h; + + x += m_brush->bounds().x; + y += m_brush->bounds().y; + + for (auto scanline : *m_compressedImage) { + int u = x+scanline.x; + doInkHline(u, y+scanline.y, u+scanline.w, loop); } } - void getModifiedArea(ToolLoop* loop, int x, int y, Rect& area) - { - Brush* brush = loop->getBrush(); - area = brush->bounds(); + + void getModifiedArea(ToolLoop* loop, int x, int y, Rect& area) override { + area = m_brush->bounds(); area.x += x; area.y += y; } + }; class FloodFillPointShape : public PointShape { diff --git a/src/app/tools/tool_box.cpp b/src/app/tools/tool_box.cpp index c3e365262..6d21f4070 100644 --- a/src/app/tools/tool_box.cpp +++ b/src/app/tools/tool_box.cpp @@ -23,6 +23,7 @@ #include "doc/algorithm/floodfill.h" #include "doc/algorithm/polygon.h" #include "doc/brush.h" +#include "doc/compressed_image.h" #include "doc/image.h" #include "doc/mask.h" #include "fixmath/fixmath.h" diff --git a/src/app/tools/tool_loop_manager.cpp b/src/app/tools/tool_loop_manager.cpp index 18a631d31..78dc51ee5 100644 --- a/src/app/tools/tool_loop_manager.cpp +++ b/src/app/tools/tool_loop_manager.cpp @@ -55,6 +55,7 @@ void ToolLoopManager::prepareLoop(const Pointer& pointer) m_toolLoop->getInk()->prepareInk(m_toolLoop); m_toolLoop->getIntertwine()->prepareIntertwine(); m_toolLoop->getController()->prepareController(); + m_toolLoop->getPointShape()->preparePointShape(m_toolLoop); // Prepare preview image (the destination image will be our preview // in the tool-loop time, so we can see what we are drawing) diff --git a/src/doc/CMakeLists.txt b/src/doc/CMakeLists.txt index 502825b1c..a7bb783c2 100644 --- a/src/doc/CMakeLists.txt +++ b/src/doc/CMakeLists.txt @@ -18,6 +18,7 @@ add_library(doc-lib cel_io.cpp cels_range.cpp color_scales.cpp + compressed_image.cpp context.cpp conversion_she.cpp document.cpp diff --git a/src/doc/brush.cpp b/src/doc/brush.cpp index 6b99fdf9d..419e9a203 100644 --- a/src/doc/brush.cpp +++ b/src/doc/brush.cpp @@ -73,7 +73,6 @@ void Brush::setAngle(int angle) void Brush::clean() { m_image.reset(); - m_scanline.clear(); } static void algo_hline(int x1, int y, int x2, void *data) @@ -144,25 +143,6 @@ void Brush::regenerate() } } - m_scanline.resize(m_image->height()); - for (int y=0; yheight(); y++) { - m_scanline[y].state = false; - - for (int x=0; xwidth(); x++) { - if (get_pixel(m_image.get(), x, y)) { - m_scanline[y].x1 = x; - - for (; xwidth(); x++) - if (!get_pixel(m_image.get(), x, y)) - break; - - m_scanline[y].x2 = x-1; - m_scanline[y].state = true; - break; - } - } - } - m_bounds = gfx::Rect( -m_image->width()/2, -m_image->height()/2, m_image->width(), m_image->height()); diff --git a/src/doc/brush.h b/src/doc/brush.h index 25b6cc30b..54b4c033d 100644 --- a/src/doc/brush.h +++ b/src/doc/brush.h @@ -17,10 +17,6 @@ namespace doc { - struct BrushScanline { - int state, x1, x2; - }; - class Brush { public: static const int kMinBrushSize = 1; @@ -35,7 +31,6 @@ namespace doc { int size() const { return m_size; } int angle() const { return m_angle; } Image* image() { return m_image.get(); } - const std::vector& scanline() const { return m_scanline; } const gfx::Rect& bounds() const { return m_bounds; } @@ -51,7 +46,6 @@ namespace doc { int m_size; // Size (diameter) int m_angle; // Angle in degrees 0-360 ImageRef m_image; // Image of the brush - std::vector m_scanline; gfx::Rect m_bounds; }; diff --git a/src/doc/compressed_image.cpp b/src/doc/compressed_image.cpp new file mode 100644 index 000000000..dd8194e19 --- /dev/null +++ b/src/doc/compressed_image.cpp @@ -0,0 +1,42 @@ +// Aseprite Document Library +// Copyright (c) 2001-2015 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "doc/compressed_image.h" + +#include "doc/primitives.h" + +namespace doc { + +CompressedImage::CompressedImage(const Image* image) + : m_image(image) +{ + color_t mask = image->maskColor(); + + for (int y=0; yheight(); ++y) { + Scanline scanline(y); + + for (int x=0; xwidth(); ++x) { + scanline.color = get_pixel(image, x, y); + + if (scanline.color != mask) { + scanline.x = x; + + for (; xwidth(); ++x) + if (!get_pixel(image, x, y)) + break; + + scanline.w = x - scanline.x; + m_scanlines.push_back(scanline); + } + } + } +} + +} // namespace doc diff --git a/src/doc/compressed_image.h b/src/doc/compressed_image.h new file mode 100644 index 000000000..46b550665 --- /dev/null +++ b/src/doc/compressed_image.h @@ -0,0 +1,45 @@ +// Aseprite Document Library +// Copyright (c) 2001-2015 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef DOC_COMPRESSED_IMAGE_H_INCLUDED +#define DOC_COMPRESSED_IMAGE_H_INCLUDED +#pragma once + +#include "doc/color.h" +#include "doc/image.h" + +#include + +namespace doc { + + class CompressedImage { + public: + struct Scanline { + int x, y, w; + color_t color; + Scanline(int y) : x(0), y(y), w(0), color(0) { } + }; + + typedef std::vector Scanlines; + typedef Scanlines::const_iterator const_iterator; + + CompressedImage(const Image* image); + + const_iterator begin() const { return m_scanlines.begin(); } + const_iterator end() const { return m_scanlines.end(); } + + PixelFormat pixelFormat() const { return m_image->pixelFormat(); } + int width() const { return m_image->width(); } + int height() const { return m_image->height(); } + + private: + const Image* m_image; + Scanlines m_scanlines; + }; + +} // namespace doc + +#endif