Krita Source Code Documentation
Loading...
Searching...
No Matches
KisOutlineGenerator Class Reference

#include <kis_outline_generator.h>

Public Member Functions

 KisOutlineGenerator (const KoColorSpace *cs, quint8 defaultOpacity)
 
QVector< QPolygon > outline (const KisPaintDevice *buffer, qint32 xOffset, qint32 yOffset, qint32 width, qint32 height)
 
QVector< QPolygon > outline (quint8 *buffer, qint32 xOffset, qint32 yOffset, qint32 width, qint32 height)
 
void setSimpleOutline (bool simple)
 

Private Types

enum  EdgeType {
  TopEdge = 1 , LeftEdge = 2 , BottomEdge = 3 , RightEdge = 0 ,
  NoEdge = 4
}
 

Private Member Functions

void appendCoordinate (QPolygon *path, int x, int y, EdgeType edge, EdgeType prevEdge)
 
template<class StorageStrategy >
bool isOutlineEdge (StorageStrategy &storage, EdgeType edge, qint32 x, qint32 y, qint32 bufWidth, qint32 bufHeight)
 
EdgeType nextEdge (EdgeType edge)
 
template<class StorageStrategy >
void nextOutlineEdge (StorageStrategy &storage, EdgeType *edge, qint32 *row, qint32 *col, qint32 width, qint32 height)
 
template<class StorageStrategy >
QVector< QPolygon > outlineImpl (typename StorageStrategy::StorageType buffer, qint32 xOffset, qint32 yOffset, qint32 width, qint32 height)
 

Private Attributes

KisRandomConstAccessorSP m_accessor
 
const KoColorSpacem_cs
 
quint8 m_defaultOpacity
 
bool m_simple
 

Detailed Description

Generates an 'outline' for a paint device. Used e.g. in for brushes and marching ants

Definition at line 26 of file kis_outline_generator.h.

Member Enumeration Documentation

◆ EdgeType

Enumerator
TopEdge 
LeftEdge 
BottomEdge 
RightEdge 
NoEdge 

Definition at line 62 of file kis_outline_generator.h.

Constructor & Destructor Documentation

◆ KisOutlineGenerator()

KisOutlineGenerator::KisOutlineGenerator ( const KoColorSpace * cs,
quint8 defaultOpacity )

Create an outline generator

Parameters
cscolorspace for the buffer passed to the generator
defaultOpacityopacity of pixels that shouldn't be included in the outline

Definition at line 84 of file kis_outline_generator.cpp.

85 : m_cs(cs), m_defaultOpacity(defaultOpacity), m_simple(false)
86{
87}
const KoColorSpace * m_cs

Member Function Documentation

◆ appendCoordinate()

void KisOutlineGenerator::appendCoordinate ( QPolygon * path,
int x,
int y,
EdgeType edge,
EdgeType prevEdge )
private

Definition at line 246 of file kis_outline_generator.cpp.

247{
248 Q_UNUSED(prevEdge);
249
250 //const QPoint origPt(x, y);
251
252 if (edge == TopEdge) {
253 x++;
254 } else if (edge == BottomEdge) {
255 y++;
256 } else if (edge == RightEdge) {
257 x++;
258 y++;
259 }
260
261 //qDebug() <<"add" << ppVar(origPt) << ppVar(edge) << ppVar(prevEdge) << "-->" << QPoint(x, y);
262
263 *path << QPoint(x, y);
264}

References BottomEdge, RightEdge, and TopEdge.

◆ isOutlineEdge()

template<class StorageStrategy >
bool KisOutlineGenerator::isOutlineEdge ( StorageStrategy & storage,
EdgeType edge,
qint32 x,
qint32 y,
qint32 bufWidth,
qint32 bufHeight )
private

Definition at line 176 of file kis_outline_generator.cpp.

177{
178 if (m_cs->opacityU8(storage.pickPixel(x, y)) == m_defaultOpacity)
179 return false;
180
181 switch (edge) {
182 case LeftEdge:
183 return x == 0 || m_cs->opacityU8(storage.pickPixel(x - 1, y)) == m_defaultOpacity;
184 case TopEdge:
185 return y == 0 || m_cs->opacityU8(storage.pickPixel(x, y - 1)) == m_defaultOpacity;
186 case RightEdge:
187 return x == bufWidth - 1 || m_cs->opacityU8(storage.pickPixel(x + 1, y)) == m_defaultOpacity;
188 case BottomEdge:
189 return y == bufHeight - 1 || m_cs->opacityU8(storage.pickPixel(x, y + 1)) == m_defaultOpacity;
190 case NoEdge:
191 return false;
192 }
193 return false;
194}
virtual quint8 opacityU8(const quint8 *pixel) const =0

References BottomEdge, LeftEdge, m_cs, m_defaultOpacity, NoEdge, KoColorSpace::opacityU8(), RightEdge, and TopEdge.

◆ nextEdge()

EdgeType KisOutlineGenerator::nextEdge ( EdgeType edge)
inlineprivate

Definition at line 77 of file kis_outline_generator.h.

77 {
78 return edge == NoEdge ? edge : static_cast<EdgeType>((edge + 1) % 4);
79 }

◆ nextOutlineEdge()

template<class StorageStrategy >
void KisOutlineGenerator::nextOutlineEdge ( StorageStrategy & storage,
EdgeType * edge,
qint32 * row,
qint32 * col,
qint32 width,
qint32 height )
private

Definition at line 211 of file kis_outline_generator.cpp.

212{
213 int original_row = *row;
214 int original_col = *col;
215
216 switch (*edge) {
217 case RightEdge:
218 TRY_PIXEL(-1, 0, RightEdge);
219 TRY_PIXEL(-1, 1, BottomEdge);
220 break;
221
222 case TopEdge:
223 TRY_PIXEL(0, -1, TopEdge);
224 TRY_PIXEL(-1, -1, RightEdge);
225 break;
226
227 case LeftEdge:
228 TRY_PIXEL(1, 0, LeftEdge);
229 TRY_PIXEL(1, -1, TopEdge);
230 break;
231
232 case BottomEdge:
233 TRY_PIXEL(0, 1, BottomEdge);
234 TRY_PIXEL(1, 1, LeftEdge);
235 break;
236
237 default:
238 break;
239
240 }
241
242 if (*row == original_row && *col == original_col)
243 *edge = nextEdge(*edge);
244}
EdgeType nextEdge(EdgeType edge)
#define TRY_PIXEL(deltaRow, deltaCol, test_edge)

References BottomEdge, LeftEdge, nextEdge(), RightEdge, TopEdge, and TRY_PIXEL.

◆ outline() [1/2]

QVector< QPolygon > KisOutlineGenerator::outline ( const KisPaintDevice * buffer,
qint32 xOffset,
qint32 yOffset,
qint32 width,
qint32 height )

Definition at line 170 of file kis_outline_generator.cpp.

171{
172 return outlineImpl<PaintDeviceStorage>(buffer, xOffset, yOffset, width, height);
173}

◆ outline() [2/2]

QVector< QPolygon > KisOutlineGenerator::outline ( quint8 * buffer,
qint32 xOffset,
qint32 yOffset,
qint32 width,
qint32 height )

Generates the outline.

Parameters
bufferbuffer with the data for the outline
xOffsetoffset that will be used for the x coordinate of the polygon points
yOffsetoffset that will be used for the y coordinate of the polygon points
widthwidth of the buffer
heightheight of the buffer
Returns
list of polygons around every non-transparent area

Definition at line 165 of file kis_outline_generator.cpp.

166{
167 return outlineImpl<LinearStorage>(buffer, xOffset, yOffset, width, height);
168}

◆ outlineImpl()

template<class StorageStrategy >
QVector< QPolygon > KisOutlineGenerator::outlineImpl ( typename StorageStrategy::StorageType buffer,
qint32 xOffset,
qint32 yOffset,
qint32 width,
qint32 height )
private

Definition at line 90 of file kis_outline_generator.cpp.

93{
95
96 try {
97 StorageStrategy storage(buffer, width, height, m_cs->pixelSize());
98
99 for (qint32 y = 0; y < height; y++) {
100 for (qint32 x = 0; x < width; x++) {
101
102 if (m_cs->opacityU8(storage.pickPixel(x, y)) == m_defaultOpacity)
103 continue;
104
105 const EdgeType initialEdge = TopEdge;
106
107 EdgeType startEdge = initialEdge;
108 while (startEdge != NoEdge &&
109 (*storage.pickMark(x, y) & (1 << startEdge) ||
110 !isOutlineEdge(storage, startEdge, x, y, width, height))) {
111
112 startEdge = nextEdge(startEdge);
113 if (startEdge == initialEdge)
114 startEdge = NoEdge;
115 }
116
117 if (startEdge != NoEdge) {
118 QPolygon path;
119 const bool clockwise = startEdge == BottomEdge;
120
121 qint32 row = y, col = x;
122 EdgeType currentEdge = startEdge;
123 EdgeType lastEdge = NoEdge;
124
125 if (currentEdge == BottomEdge) {
126 appendCoordinate(&path, col + xOffset, row + yOffset, currentEdge, lastEdge);
127 lastEdge = BottomEdge;
128 }
129
130 forever {
131 //qDebug() << "visit" << xOffset + col << yOffset + row << ppVar(currentEdge) << ppVar(lastEdge);
132
133 *storage.pickMark(col, row) |= 1 << currentEdge;
134 nextOutlineEdge(storage, &currentEdge, &row, &col, width, height);
135
136 //While following a straight line no points need to be added
137 if (lastEdge != currentEdge) {
138 appendCoordinate(&path, col + xOffset, row + yOffset, currentEdge, lastEdge);
139 lastEdge = currentEdge;
140 }
141
142 if (row == y && col == x && currentEdge == startEdge) {
143 if (startEdge != BottomEdge) {
144 // add last point of the polygon
145 appendCoordinate(&path, col + xOffset, row + yOffset, NoEdge, NoEdge);
146 }
147 break;
148 }
149 }
150
151 if(!m_simple || !clockwise) {
152 paths.push_back(path);
153 }
154 }
155 }
156 }
157 }
158 catch(const std::bad_alloc&) {
159 warnKrita << "KisOutlineGenerator::outline ran out of memory allocating " << width << "*" << height << "marks";
160 }
161
162 return paths;
163}
bool isOutlineEdge(StorageStrategy &storage, EdgeType edge, qint32 x, qint32 y, qint32 bufWidth, qint32 bufHeight)
void nextOutlineEdge(StorageStrategy &storage, EdgeType *edge, qint32 *row, qint32 *col, qint32 width, qint32 height)
void appendCoordinate(QPolygon *path, int x, int y, EdgeType edge, EdgeType prevEdge)
virtual quint32 pixelSize() const =0
#define warnKrita
Definition kis_debug.h:87

References appendCoordinate(), BottomEdge, isOutlineEdge(), m_cs, m_defaultOpacity, m_simple, nextEdge(), nextOutlineEdge(), NoEdge, KoColorSpace::opacityU8(), KoColorSpace::pixelSize(), TopEdge, and warnKrita.

◆ setSimpleOutline()

void KisOutlineGenerator::setSimpleOutline ( bool simple)

Set the generator to produce simpile outline, skipping outline that are fully enclosed

Parameters
simpleset simple mode, if true enclosed outline will be skipped

Definition at line 266 of file kis_outline_generator.cpp.

267{
268 m_simple = simple;
269}

References m_simple.

Member Data Documentation

◆ m_accessor

KisRandomConstAccessorSP KisOutlineGenerator::m_accessor
private

Definition at line 89 of file kis_outline_generator.h.

◆ m_cs

const KoColorSpace* KisOutlineGenerator::m_cs
private

Definition at line 85 of file kis_outline_generator.h.

◆ m_defaultOpacity

quint8 KisOutlineGenerator::m_defaultOpacity
private

Definition at line 86 of file kis_outline_generator.h.

◆ m_simple

bool KisOutlineGenerator::m_simple
private

Definition at line 87 of file kis_outline_generator.h.


The documentation for this class was generated from the following files: