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

#include <kis_grid_interpolation_tools.h>

Public Member Functions

void copyPreviousRects ()
 
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)
 
 ~PaintDevicePolygonOp ()
 

Public Attributes

KisPaintDeviceSP m_dstDev
 
const qreal m_epsilon {0.001}
 
KisPaintDeviceSP m_srcDev
 

Private Attributes

bool m_canMergeRects {false}
 
QVector< QRect > m_rectsToCopy
 

Detailed Description

Definition at line 169 of file kis_grid_interpolation_tools.h.

Constructor & Destructor Documentation

◆ PaintDevicePolygonOp()

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

◆ ~PaintDevicePolygonOp()

GridIterationTools::PaintDevicePolygonOp::~PaintDevicePolygonOp ( )
inline

When setCanMergeRects() is set to true, the caller should call finalize() to process all the postponed rects, which would clear the vector

Definition at line 174 of file kis_grid_interpolation_tools.h.

175 {
182 }
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130

References KIS_SAFE_ASSERT_RECOVER_NOOP, and m_rectsToCopy.

Member Function Documentation

◆ copyPreviousRects()

void GridIterationTools::PaintDevicePolygonOp::copyPreviousRects ( )
inline

Definition at line 313 of file kis_grid_interpolation_tools.h.

313 {
315
316 for (QVector<QRect>::iterator it = m_rectsToCopy.begin(); it < end; it++) {
317 QRect areaToCopy = *it;
318 fastCopyArea(areaToCopy.adjusted(0, 0, 1, 1), false);
319 }
321 }
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().

◆ fastCopyArea() [1/2]

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

◆ fastCopyArea() [2/2]

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

Definition at line 188 of file kis_grid_interpolation_tools.h.

188 {
189#ifdef DEBUG_PAINTING_POLYGONS
190
191 QRect boundRect = areaToCopy;
192 KisSequentialIterator dstIt(m_dstDev, boundRect);
193 KisSequentialIterator srcIt(m_srcDev, boundRect);
194
195 // this can possibly be optimized with scanlining the polygon
196 // (use intersectLineConvexPolygon to get a line at every height)
197 // but it doesn't matter much because in the vast majority of cases
198 // it should go straight to the rect area copying
199
200 while (dstIt.nextPixel() && srcIt.nextPixel()) {
201 memcpy(dstIt.rawData(), srcIt.oldRawData(), m_dstDev->pixelSize());
202 QColor color = m_debugColor;
203 color.setHsl(KisAlgebra2D::wrapValue(m_debugColor.hslHue() + 20, 0, 360), m_debugColor.hslSaturation(), m_debugColor.lightness());
204 m_dstDev->colorSpace()->fromQColor(color, dstIt.rawData());
205 }
206 return;
207#endif
208 if (lazy) {
209 m_rectsToCopy.append(areaToCopy.adjusted(0, 0, -1, -1));
210 } else {
211 KisPainter::copyAreaOptimized(areaToCopy.topLeft(), m_srcDev, m_dstDev, areaToCopy);
212 }
213 }
quint32 pixelSize() const
const KoColorSpace * colorSpace() const
static void copyAreaOptimized(const QPoint &dstPt, KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &originalSrcRect)
virtual void fromQColor(const QColor &color, quint8 *dst) const =0
T wrapValue(T value, T wrapBounds)

References KisPaintDevice::colorSpace(), KisPainter::copyAreaOptimized(), KoColorSpace::fromQColor(), m_dstDev, m_rectsToCopy, m_srcDev, KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::oldRawData(), KisPaintDevice::pixelSize(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData(), and KisAlgebra2D::wrapValue().

◆ finalize()

void GridIterationTools::PaintDevicePolygonOp::finalize ( )
inline

◆ operator()() [1/2]

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

Definition at line 215 of file kis_grid_interpolation_tools.h.

215 {
216 operator() (srcPolygon, dstPolygon, dstPolygon);
217 }
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 219 of file kis_grid_interpolation_tools.h.

219 {
220#ifdef DEBUG_PAINTING_POLYGONS
221 //m_rectId++;
222#endif
223 QRect boundRect = clipDstPolygon.boundingRect().toAlignedRect();
224 if (boundRect.isEmpty()) return;
225
226 bool samePolygon = (m_dstDev->colorSpace() == m_srcDev->colorSpace())
227 && KisAlgebra2D::fuzzyPointCompare(srcPolygon, dstPolygon, m_epsilon)
228 && KisAlgebra2D::fuzzyPointCompare(srcPolygon, clipDstPolygon, m_epsilon);
229
230 if (samePolygon && KisAlgebra2D::isPolygonPixelAlignedRect(dstPolygon, m_epsilon)) {
231 QRect boundRect = dstPolygon.boundingRect().toAlignedRect();
232 fastCopyArea(boundRect);
233 return;
234 }
235
236
237 // provess previous rects so they are all processed
238 // in the same order as without any performance improvements
239 // (according to the grid processing order)
241
242
243 KisSequentialIterator dstIt(m_dstDev, boundRect);
245
246 KisFourPointInterpolatorBackward interp(srcPolygon, dstPolygon);
247#ifdef DEBUG_PAINTING_POLYGONS
248 int pixelId = 0;
249#endif
250
256 if (interp.isValid(0.1)) {
257 int y = boundRect.top();
258 interp.setY(y);
259
260 while (dstIt.nextPixel()) {
261 int newY = dstIt.y();
262
263 if (y != newY) {
264 y = newY;
265 interp.setY(y);
266 }
267
268 QPointF srcPoint(dstIt.x(), y);
269
270 if (clipDstPolygon.containsPoint(srcPoint, Qt::OddEvenFill)) {
271
272 interp.setX(srcPoint.x());
273 QPointF dstPoint = interp.getValue();
274
275 // brain-blowing part:
276 //
277 // since the interpolator does the inverted
278 // transformation we read data from "dstPoint"
279 // (which is non-transformed) and write it into
280 // "srcPoint" (which is transformed position)
281
282 srcAcc->moveTo(dstPoint);
283 quint8* rawData = dstIt.rawData();
284 srcAcc->sampledOldRawData(rawData);
285#ifdef DEBUG_PAINTING_POLYGONS
286 QColor color = m_debugColor;
287 color.setHsl(KisAlgebra2D::wrapValue(m_debugColor.hslHue() + m_rectId, 0, 360), m_debugColor.hslSaturation(), qBound(0, m_debugColor.lightness() - 50 - pixelId, 100));
288 pixelId++;
289 m_dstDev->colorSpace()->fromQColor(color, rawData);
290#endif
291 }
292 }
293
294 } else {
295 srcAcc->moveTo(interp.fallbackSourcePoint());
296
297 while (dstIt.nextPixel()) {
298 QPointF srcPoint(dstIt.x(), dstIt.y());
299
300 if (clipDstPolygon.containsPoint(srcPoint, Qt::OddEvenFill)) {
301 srcAcc->sampledOldRawData(dstIt.rawData());
302#ifdef DEBUG_PAINTING_POLYGONS
303 QColor color = m_debugColor;
304 color.setHsl(KisAlgebra2D::wrapValue(m_debugColor.hslHue() + m_rectId, 0, 360), m_debugColor.hslSaturation(), qBound(0, m_debugColor.lightness() + 50, 100));
305 m_dstDev->colorSpace()->fromQColor(color, dstIt.rawData());
306#endif
307 }
308 }
309 }
310
311 }
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 isPolygonPixelAlignedRect(const Polygon &poly, Difference tolerance)
bool fuzzyPointCompare(const QPointF &p1, const QPointF &p2)

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

◆ setCanMergeRects()

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

IMPORTANT: When setCanMergeRects() is set to true, the caller should calls finalize() in the end of the processing action to actually copy all the lazily postponed rects.

Definition at line 333 of file kis_grid_interpolation_tools.h.

333 {
334 m_canMergeRects = newCanMergeRects;
335 }

References m_canMergeRects.

Member Data Documentation

◆ m_canMergeRects

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

Definition at line 350 of file kis_grid_interpolation_tools.h.

350{false};

◆ m_dstDev

KisPaintDeviceSP GridIterationTools::PaintDevicePolygonOp::m_dstDev

Definition at line 338 of file kis_grid_interpolation_tools.h.

◆ m_epsilon

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

Definition at line 339 of file kis_grid_interpolation_tools.h.

339{0.001};

◆ 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 337 of file kis_grid_interpolation_tools.h.


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