Krita Source Code Documentation
Loading...
Searching...
No Matches
GridIterationTools::PaintDevicePolygonOp Struct Reference

#include <kis_grid_interpolation_tools.h>

Public Member Functions

void fastCopyArea (QPolygonF areaToCopy)
 
void fastCopyArea (QRect areaToCopy)
 
void fastCopyArea (QRect areaToCopy, bool lazy)
 
void finalize ()
 
void operator() (const QPolygonF &srcPolygon, const QPolygonF &dstPolygon)
 
void operator() (const QPolygonF &srcPolygon, const QPolygonF &dstPolygon, const QPolygonF &clipDstPolygon)
 
 PaintDevicePolygonOp (KisPaintDeviceSP srcDev, KisPaintDeviceSP dstDev)
 
void setCanMergeRects (bool newCanMergeRects)
 

Public Attributes

KisPaintDeviceSP m_dstDev
 
const qreal m_epsilon {0.1}
 
KisPaintDeviceSP m_srcDev
 

Private Attributes

bool m_canMergeRects {true}
 
QVector< QRect > m_rectsToCopy
 

Detailed Description

Definition at line 181 of file kis_grid_interpolation_tools.h.

Constructor & Destructor Documentation

◆ PaintDevicePolygonOp()

GridIterationTools::PaintDevicePolygonOp::PaintDevicePolygonOp ( KisPaintDeviceSP srcDev,
KisPaintDeviceSP dstDev )
inline

Member Function Documentation

◆ fastCopyArea() [1/3]

void GridIterationTools::PaintDevicePolygonOp::fastCopyArea ( QPolygonF areaToCopy)
inline

Definition at line 187 of file kis_grid_interpolation_tools.h.

187 {
188 QRect boundRect = areaToCopy.boundingRect().toAlignedRect();
189 if (boundRect.isEmpty()) return;
190
191 bool isItRect = KisAlgebra2D::isPolygonRect(areaToCopy, m_epsilon); // no need for lower tolerance
192
193#ifdef DEBUG_PAINTING_POLYGONS
194 isItRect = false; // force to use the code below, to not have to rewrite it for a workaround for copyAreaOptimized
195#endif
196 if (isItRect) {
197 fastCopyArea(boundRect);
198 return;
199 }
200
201 KisSequentialIterator dstIt(m_dstDev, boundRect);
202 KisSequentialIterator srcIt(m_srcDev, boundRect);
203
204 // this can possibly be optimized with scanlining the polygon
205 // (use intersectLineConvexPolygon to get a line at every height)
206 // but it doesn't matter much because in the vast majority of cases
207 // it should go straight to the rect area copying
208
209 while (dstIt.nextPixel() && srcIt.nextPixel()) {
210 if (areaToCopy.containsPoint(middlePoint(dstIt.x(), dstIt.y()), Qt::OddEvenFill)) {
211 memcpy(dstIt.rawData(), srcIt.oldRawData(), m_dstDev->pixelSize());
212#ifdef DEBUG_PAINTING_POLYGONS
213 m_dstDev->colorSpace()->fromQColor(m_debugColor, dstIt.rawData());
214#endif
215 }
216 }
217 }
quint32 pixelSize() const
const KoColorSpace * colorSpace() const
virtual void fromQColor(const QColor &color, quint8 *dst) const =0
QPointF middlePoint(int x, int y)
bool isPolygonRect(const Polygon &poly, Difference tolerance)

References KisPaintDevice::colorSpace(), fastCopyArea(), KoColorSpace::fromQColor(), KisAlgebra2D::isPolygonRect(), m_dstDev, m_epsilon, m_srcDev, GridIterationTools::middlePoint(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::oldRawData(), KisPaintDevice::pixelSize(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::x(), and KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::y().

◆ fastCopyArea() [2/3]

void GridIterationTools::PaintDevicePolygonOp::fastCopyArea ( QRect areaToCopy)
inline

◆ fastCopyArea() [3/3]

void GridIterationTools::PaintDevicePolygonOp::fastCopyArea ( QRect areaToCopy,
bool lazy )
inline

Definition at line 223 of file kis_grid_interpolation_tools.h.

223 {
224#ifdef DEBUG_PAINTING_POLYGONS
225 fastCopyArea(QPolygon(areaToCopy));
226 return;
227#endif
228 if (lazy) {
229 m_rectsToCopy.append(areaToCopy.adjusted(0, 0, -1, -1));
230 } else {
231 KisPainter::copyAreaOptimized(areaToCopy.topLeft(), m_srcDev, m_dstDev, areaToCopy);
232 }
233 }
static void copyAreaOptimized(const QPoint &dstPt, KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &originalSrcRect)

References KisPainter::copyAreaOptimized(), fastCopyArea(), m_dstDev, m_rectsToCopy, and m_srcDev.

◆ finalize()

void GridIterationTools::PaintDevicePolygonOp::finalize ( )
inline

Definition at line 323 of file kis_grid_interpolation_tools.h.

323 {
324
326
327 for (QVector<QRect>::iterator it = m_rectsToCopy.begin(); it < end; it++) {
328 QRect areaToCopy = *it;
329 fastCopyArea(areaToCopy.adjusted(0, 0, 1, 1), false);
330 }
332 }
static QVector< QRect >::iterator mergeSparseRects(QVector< QRect >::iterator beginIt, QVector< QRect >::iterator endIt)
merge a set of rectangles into a smaller set of bigger rectangles

References fastCopyArea(), m_rectsToCopy, and KisRegion::mergeSparseRects().

◆ operator()() [1/2]

void GridIterationTools::PaintDevicePolygonOp::operator() ( const QPolygonF & srcPolygon,
const QPolygonF & dstPolygon )
inline

Definition at line 235 of file kis_grid_interpolation_tools.h.

235 {
236 operator() (srcPolygon, dstPolygon, dstPolygon);
237 }
void operator()(const QPolygonF &srcPolygon, const QPolygonF &dstPolygon)

References operator()().

◆ operator()() [2/2]

void GridIterationTools::PaintDevicePolygonOp::operator() ( const QPolygonF & srcPolygon,
const QPolygonF & dstPolygon,
const QPolygonF & clipDstPolygon )
inline

We need to make sure that the destination polygon is not too small, otherwise even small rounding will send the src-accessor into infinity

Definition at line 239 of file kis_grid_interpolation_tools.h.

239 {
240 QRect boundRect = clipDstPolygon.boundingRect().toAlignedRect();
241 if (boundRect.isEmpty()) return;
242
243 bool samePolygon = (m_dstDev->colorSpace() == m_srcDev->colorSpace()) && KisAlgebra2D::fuzzyPointCompare(srcPolygon, dstPolygon, m_epsilon);
244
245 if (samePolygon) {
246 // we can use clipDstPolygon here, because it will be smaller than dstPolygon and srcPolygon, because of how IncompletePolicy works
247 // we could also calculate intersection here if we're worried whether that fact is always true
248 fastCopyArea(clipDstPolygon);
249 return;
250 }
251
252
253 KisSequentialIterator dstIt(m_dstDev, boundRect);
255
256 KisFourPointInterpolatorBackward interp(srcPolygon, dstPolygon);
257#ifdef DEBUG_PAINTING_POLYGONS
258 int pixelId = 0;
259#endif
260
266 if (interp.isValid(0.1)) {
267 int y = boundRect.top();
268 interp.setY(y);
269
270 while (dstIt.nextPixel()) {
271 int newY = dstIt.y();
272
273 if (y != newY) {
274 y = newY;
275 interp.setY(y);
276 }
277
278 QPointF srcPoint(dstIt.x(), y);
279
280 if (clipDstPolygon.containsPoint(middlePoint(srcPoint), Qt::OddEvenFill)) {
281
282 interp.setX(srcPoint.x());
283 QPointF dstPoint = interp.getValue();
284
285 // brain-blowing part:
286 //
287 // since the interpolator does the inverted
288 // transformation we read data from "dstPoint"
289 // (which is non-transformed) and write it into
290 // "srcPoint" (which is transformed position)
291
292 srcAcc->moveTo(dstPoint);
293 quint8* rawData = dstIt.rawData();
294 srcAcc->sampledOldRawData(rawData);
295#ifdef DEBUG_PAINTING_POLYGONS
296 QColor color = m_debugColor;
297 color.setHsl(m_debugColor.hslHue(), m_debugColor.hslSaturation(), qMin(m_debugColor.lightness() - 50 - pixelId, 100));
298 pixelId++;
299 m_dstDev->colorSpace()->fromQColor(color, rawData);
300#endif
301 }
302 }
303
304 } else {
305 srcAcc->moveTo(interp.fallbackSourcePoint());
306
307 while (dstIt.nextPixel()) {
308 QPointF srcPoint(dstIt.x(), dstIt.y());
309
310 if (clipDstPolygon.containsPoint(middlePoint(srcPoint), Qt::OddEvenFill)) {
311 srcAcc->sampledOldRawData(dstIt.rawData());
312#ifdef DEBUG_PAINTING_POLYGONS
313 QColor color = m_debugColor;
314 color.setHsl(m_debugColor.hslHue(), m_debugColor.hslSaturation(), m_debugColor.lightness() + 50);
315 m_dstDev->colorSpace()->fromQColor(color, dstIt.rawData());
316#endif
317 }
318 }
319 }
320
321 }
QPointF dstPoint
KisRandomSubAccessorSP createRandomSubAccessor() const
void sampledOldRawData(quint8 *dst)
void moveTo(qreal x, qreal y)
qreal interp(qreal r, qreal a, qreal b)
private functions
bool fuzzyPointCompare(const QPointF &p1, const QPointF &p2)

References KisPaintDevice::colorSpace(), KisPaintDevice::createRandomSubAccessor(), dstPoint, fastCopyArea(), KoColorSpace::fromQColor(), KisAlgebra2D::fuzzyPointCompare(), interp(), m_dstDev, m_epsilon, m_srcDev, GridIterationTools::middlePoint(), KisRandomSubAccessor::moveTo(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData(), KisRandomSubAccessor::sampledOldRawData(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::x(), and KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::y().

◆ setCanMergeRects()

void GridIterationTools::PaintDevicePolygonOp::setCanMergeRects ( bool newCanMergeRects)
inline

Definition at line 334 of file kis_grid_interpolation_tools.h.

334 {
335 m_canMergeRects = newCanMergeRects;
336 }

References m_canMergeRects.

Member Data Documentation

◆ m_canMergeRects

bool GridIterationTools::PaintDevicePolygonOp::m_canMergeRects {true}
private

Definition at line 350 of file kis_grid_interpolation_tools.h.

350{true};

◆ m_dstDev

KisPaintDeviceSP GridIterationTools::PaintDevicePolygonOp::m_dstDev

Definition at line 339 of file kis_grid_interpolation_tools.h.

◆ m_epsilon

const qreal GridIterationTools::PaintDevicePolygonOp::m_epsilon {0.1}

Definition at line 340 of file kis_grid_interpolation_tools.h.

340{0.1};

◆ m_rectsToCopy

QVector<QRect> GridIterationTools::PaintDevicePolygonOp::m_rectsToCopy
private

Definition at line 351 of file kis_grid_interpolation_tools.h.

◆ m_srcDev

KisPaintDeviceSP GridIterationTools::PaintDevicePolygonOp::m_srcDev

Definition at line 338 of file kis_grid_interpolation_tools.h.


The documentation for this struct was generated from the following file: