30 m_marks.reset(
new quint8[width * height]);
31 memset(
m_marks.data(), 0, width * height);
85 : m_cs(cs), m_defaultOpacity(defaultOpacity), m_simple(false)
89template <
class StorageStrategy>
91 qint32 xOffset, qint32 yOffset,
92 qint32 width, qint32 height)
97 StorageStrategy storage(buffer, width, height,
m_cs->
pixelSize());
99 for (qint32 y = 0; y < height; y++) {
100 for (qint32 x = 0; x < width; x++) {
108 while (startEdge !=
NoEdge &&
109 (*storage.pickMark(x, y) & (1 << startEdge) ||
113 if (startEdge == initialEdge)
117 if (startEdge !=
NoEdge) {
119 const bool clockwise = startEdge ==
BottomEdge;
121 qint32 row = y, col = x;
126 appendCoordinate(&path, col + xOffset, row + yOffset, currentEdge, lastEdge);
133 *storage.pickMark(col, row) |= 1 << currentEdge;
137 if (lastEdge != currentEdge) {
138 appendCoordinate(&path, col + xOffset, row + yOffset, currentEdge, lastEdge);
139 lastEdge = currentEdge;
142 if (row == y && col == x && currentEdge == startEdge) {
152 paths.push_back(path);
158 catch(
const std::bad_alloc&) {
159 warnKrita <<
"KisOutlineGenerator::outline ran out of memory allocating " << width <<
"*" << height <<
"marks";
167 return outlineImpl<LinearStorage>(buffer, xOffset, yOffset, width, height);
172 return outlineImpl<PaintDeviceStorage>(buffer, xOffset, yOffset, width, height);
175template <
class StorageStrategy>
196#define TRY_PIXEL(deltaRow, deltaCol, test_edge) \
198 int test_row = *row + deltaRow; \
199 int test_col = *col + deltaCol; \
200 if ( (0 <= (test_row) && (test_row) < height && 0 <= (test_col) && (test_col) < width) && \
201 isOutlineEdge (storage, test_edge, test_col, test_row, width, height)) \
210template <
class StorageStrategy>
213 int original_row = *row;
214 int original_col = *col;
242 if (*row == original_row && *col == original_col)
263 *path << QPoint(x, y);
virtual quint8 * rawData()=0
virtual const quint8 * rawDataConst() const =0
bool isOutlineEdge(StorageStrategy &storage, EdgeType edge, qint32 x, qint32 y, qint32 bufWidth, qint32 bufHeight)
void setSimpleOutline(bool simple)
void nextOutlineEdge(StorageStrategy &storage, EdgeType *edge, qint32 *row, qint32 *col, qint32 width, qint32 height)
QVector< QPolygon > outline(quint8 *buffer, qint32 xOffset, qint32 yOffset, qint32 width, qint32 height)
void appendCoordinate(QPolygon *path, int x, int y, EdgeType edge, EdgeType prevEdge)
const KoColorSpace * m_cs
QVector< QPolygon > outlineImpl(typename StorageStrategy::StorageType buffer, qint32 xOffset, qint32 yOffset, qint32 width, qint32 height)
KisOutlineGenerator(const KoColorSpace *cs, quint8 defaultOpacity)
EdgeType nextEdge(EdgeType edge)
KisRandomConstAccessorSP createRandomConstAccessorNG() const
KisRandomAccessorSP createRandomAccessorNG()
virtual void moveTo(qint32 x, qint32 y)=0
virtual quint32 pixelSize() const =0
virtual quint8 opacityU8(const quint8 *pixel) const =0
quint8 * pickPixel(int x, int y)
QScopedArrayPointer< quint8 > m_marks
LinearStorage(quint8 *buffer, int width, int height, int pixelSize)
quint8 * pickMark(int x, int y)
KisRandomConstAccessorSP m_deviceIt
const KisPaintDevice * StorageType
quint8 * pickMark(int x, int y)
const KisPaintDevice * m_device
const quint8 * pickPixel(int x, int y)
KisRandomAccessorSP m_marksIt
PaintDeviceStorage(const KisPaintDevice *device, int, int, int)
#define TRY_PIXEL(deltaRow, deltaCol, test_edge)
static KoColorSpaceRegistry * instance()
const KoColorSpace * alpha8()