Replace Brush::m_scanline with doc::CompressedImage

This commit is contained in:
David Capello 2015-04-25 20:01:03 -03:00
parent 4a05436252
commit 8382d1ca8f
9 changed files with 111 additions and 41 deletions

View File

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

View File

@ -33,29 +33,34 @@ public:
};
class BrushPointShape : public PointShape {
Brush* m_brush;
base::SharedPtr<CompressedImage> m_compressedImage;
public:
void transformPoint(ToolLoop* loop, int x, int y)
{
Brush* brush = loop->getBrush();
std::vector<BrushScanline>::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; v<h; ++v) {
if (scanline->state)
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 {

View File

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

View File

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

View File

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

View File

@ -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; y<m_image->height(); y++) {
m_scanline[y].state = false;
for (int x=0; x<m_image->width(); x++) {
if (get_pixel(m_image.get(), x, y)) {
m_scanline[y].x1 = x;
for (; x<m_image->width(); 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());

View File

@ -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<BrushScanline>& 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<BrushScanline> m_scanline;
gfx::Rect m_bounds;
};

View File

@ -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; y<image->height(); ++y) {
Scanline scanline(y);
for (int x=0; x<image->width(); ++x) {
scanline.color = get_pixel(image, x, y);
if (scanline.color != mask) {
scanline.x = x;
for (; x<image->width(); ++x)
if (!get_pixel(image, x, y))
break;
scanline.w = x - scanline.x;
m_scanlines.push_back(scanline);
}
}
}
}
} // namespace doc

View File

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