Krita Source Code Documentation
Loading...
Searching...
No Matches
KritaUtils Namespace Reference

Classes

struct  ExportFileJob
 
struct  is_appendable_container
 
struct  is_container
 

Enumerations

enum  BackgroudSavingStartResult { Success = 0 , Failure = 1 , AnotherSavingInProgress = 2 , ImageLockFailure = 3 }
 
enum  DeviceCopyMode { CopySnapshot = 0 , CopyAllFrames }
 
enum  SaveFlag { SaveNone = 0 , SaveShowWarnings = 0x1 , SaveIsExporting = 0x2 , SaveInAutosaveMode = 0x4 }
 
enum  ThresholdMode { ThresholdNone = 0 , ThresholdFloor , ThresholdCeil , ThresholdMaxOut }
 

Functions

template<typename Func , typename Job >
void addJobBarrier (QVector< Job * > &jobs, Func func)
 
template<typename Func , typename Job >
void addJobBarrier (QVector< Job * > &jobs, int lod, Func func)
 
template<typename Func , typename Job >
void addJobBarrierExclusive (QVector< Job * > &jobs, Func func)
 
template<typename Func , typename Job >
void addJobBarrierExclusiveNoCancel (QVector< Job * > &jobs, Func func)
 
template<typename Func , typename Job >
void addJobBarrierNoCancel (QVector< Job * > &jobs, Func func)
 
template<typename Func , typename Job >
void addJobConcurrent (QVector< Job * > &jobs, Func func)
 
template<typename Func , typename Job >
void addJobConcurrent (QVector< Job * > &jobs, int lod, Func func)
 
template<typename Func , typename Job >
void addJobConcurrentNoCancel (QVector< Job * > &jobs, Func func)
 
template<typename Func , typename Job >
void addJobSequential (QVector< Job * > &jobs, Func func)
 
template<typename Func , typename Job >
void addJobSequential (QVector< Job * > &jobs, int lod, Func func)
 
template<typename Func , typename Job >
void addJobSequentialExclusive (QVector< Job * > &jobs, Func func)
 
template<typename Func , typename Job >
void addJobSequentialExclusive (QVector< Job * > &jobs, int lod, Func func)
 
template<typename Func , typename Job >
void addJobSequentialExclusiveNoCancel (QVector< Job * > &jobs, Func func)
 
template<typename Func , typename Job >
void addJobSequentialNoCancel (QVector< Job * > &jobs, Func func)
 
template<typename Func , typename Job >
void addJobUniquelyConcurrent (QVector< Job * > &jobs, Func func)
 
template<typename Func , typename Job >
void addJobUniquelyConcurrent (QVector< Job * > &jobs, int lod, Func func)
 
template<typename Func , typename Job >
void addJobUniquelyConcurrentNoCancel (QVector< Job * > &jobs, Func func)
 
void applyToAlpha8Device (KisPaintDeviceSP dev, const QRect &rc, std::function< void(quint8)> func)
 
bool checkInTriangle (const QRectF &rect, const QPolygonF &triangle)
 
bool compareChannelFlags (QBitArray f1, QBitArray f2)
 
template<class T >
bool compareListsUnordered (const QList< T > &a, const QList< T > &b)
 
QImage convertQImageToGrayA (const QImage &image)
 
qreal estimatePortionOfTransparentPixels (KisPaintDeviceSP dev, const QRect &rect, qreal samplePortion)
 
boost::optional< QPointF > fetchControlPoint (KoPathPoint *pt, bool takeFirst)
 
void filterAlpha8Device (KisPaintDeviceSP dev, const QRect &rc, std::function< quint8(quint8)> func)
 
template<class C , typename KeepIfFunction >
auto filterContainer (C &container, KeepIfFunction keepIf) -> decltype(bool(keepIf(container[0])), void())
 
template<class C >
void makeContainerUnique (C &container)
 
void makeSymmetric (KoPathPoint *pt, bool copyFromFirst)
 
qreal KRITAIMAGE_EXPORT maxDimensionPortion (const QRectF &bounds, qreal portion, qreal minValue)
 
QBitArray mergeChannelFlags (const QBitArray &childFlags, const QBitArray &parentFlags)
 
qreal mergeOpacityF (qreal opacity, qreal parentOpacity)
 
quint8 mergeOpacityU8 (quint8 opacity, quint8 parentOpacity)
 
void mirrorDab (Qt::Orientation dir, const QPoint &center, KisRenderedDab *dab, bool skipMirrorPixels)
 
void mirrorDab (Qt::Orientation dir, const QPointF &center, KisRenderedDab *dab, bool skipMirrorPixels)
 
void mirrorPoint (Qt::Orientation dir, const QPoint &center, QPointF *pt)
 
void mirrorPoint (Qt::Orientation dir, const QPointF &center, QPointF *pt)
 
void mirrorRect (Qt::Orientation dir, const QPoint &center, QRect *rc)
 
void mirrorRect (Qt::Orientation dir, const QPointF &center, QRect *rc)
 
KisNodeSP nearestNodeAfterRemoval (KisNodeSP node)
 
QSize optimalPatchSize ()
 
QTransform pathShapeBooleanSpaceWorkaround (KisImageSP image)
 
QString KRITAIMAGE_EXPORT prettyFormatReal (qreal value)
 
template<class PixelProcessor >
void processTwoDevices (const QRect &rc, KisRandomConstAccessorSP srcIt, KisRandomAccessorSP dstIt, const int srcPixelSize, const int dstPixelSize, PixelProcessor pixelProcessor)
 
template<class PixelProcessor >
void processTwoDevicesWithStrides (const QRect &rc, KisRandomConstAccessorSP srcIt, KisRandomAccessorSP dstIt, PixelProcessor pixelProcessor)
 
QVector< QPoint > rasterizeHLine (const QPoint &startPoint, const QPoint &endPoint)
 
template<typename Visitor >
void rasterizeHLine (const QPoint &startPoint, const QPoint &endPoint, Visitor visitor)
 
QVector< QPoint > rasterizeLineDDA (const QPoint &startPoint, const QPoint &endPoint)
 
template<typename Visitor >
void rasterizeLineDDA (const QPoint &startPoint, const QPoint &endPoint, Visitor visitor)
 
QVector< QPoint > rasterizePolygonDDA (const QVector< QPoint > &polygonPoints)
 
template<typename Visitor >
void rasterizePolygonDDA (const QVector< QPoint > &polygonPoints, Visitor visitor)
 
QVector< QPoint > rasterizePolylineDDA (const QVector< QPoint > &polylinePoints)
 
template<typename Visitor >
void rasterizePolylineDDA (const QVector< QPoint > &polylinePoints, Visitor visitor)
 
QVector< QPoint > rasterizeVLine (const QPoint &startPoint, const QPoint &endPoint)
 
template<typename Visitor >
void rasterizeVLine (const QPoint &startPoint, const QPoint &endPoint, Visitor visitor)
 
void renderExactRect (QPainter *p, const QRect &rc)
 
void renderExactRect (QPainter *p, const QRect &rc, const QPen &pen)
 
QString resolveAbsoluteFilePath (const QString &baseDir, const QString &filePath)
 Resolve absolute file path from a file path and base dir.
 
void restoreControlPoint (KoPathPoint *pt, bool restoreFirst, boost::optional< QPointF > savedPoint)
 
QList< QPainterPath > splitDisjointPaths (const QPainterPath &path)
 
KisRegion splitPath (const QPainterPath &path)
 
QVector< QRect > splitRectIntoPatches (const QRect &rc, const QSize &patchSize)
 
QVector< QRect > splitRectIntoPatchesTight (const QRect &rc, const QSize &patchSize)
 
QVector< QRect > splitRegionIntoPatches (const KisRegion &region, const QSize &patchSize)
 
QVector< QRect > KRITAIMAGE_EXPORT splitRegionIntoPatches (const QRegion &region, const QSize &patchSize)
 
KisRegion splitTriangles (const QPointF &center, const QVector< QPointF > &points)
 
void thresholdOpacity (KisPaintDeviceSP device, const QRect &rect, ThresholdMode mode)
 
void thresholdOpacityAlpha8 (KisPaintDeviceSP device, const QRect &rect, ThresholdMode mode)
 
QString KRITAIMAGE_EXPORT toLocalizedOnOff (bool value)
 
QPainterPath tryCloseTornSubpathsAfterIntersection (QPainterPath path)
 
bool tryMergePoints (QPainterPath &path, const QPointF &startPoint, const QPointF &endPoint, qreal &distance, qreal distanceThreshold, bool lastSegment)
 
QPainterPath trySimplifyPath (const QPainterPath &path, qreal lengthThreshold)
 
KisImportExportErrorCode workaroundUnsuitableImageColorSpace (KisImageSP image, KisImportUserFeedbackInterface *feedbackInterface, KisImageBarrierLock &lock)
 

Enumeration Type Documentation

◆ BackgroudSavingStartResult

Enumerator
Success 
Failure 
AnotherSavingInProgress 
ImageLockFailure 

Definition at line 31 of file KisImportExportUtils.h.

31 {
32 Success = 0,
33 Failure = 1,
36};

◆ DeviceCopyMode

Enumerator
CopySnapshot 
CopyAllFrames 

Definition at line 51 of file kis_paint_device.h.

◆ SaveFlag

Enumerator
SaveNone 
SaveShowWarnings 
SaveIsExporting 
SaveInAutosaveMode 

Definition at line 24 of file KisImportExportUtils.h.

◆ ThresholdMode

Enumerator
ThresholdNone 
ThresholdFloor 
ThresholdCeil 
ThresholdMaxOut 

Definition at line 131 of file krita_utils.h.

131 {
132 ThresholdNone = 0,
136 };

Function Documentation

◆ addJobBarrier() [1/2]

template<typename Func , typename Job >
void KritaUtils::addJobBarrier ( QVector< Job * > & jobs,
Func func )

◆ addJobBarrier() [2/2]

template<typename Func , typename Job >
void KritaUtils::addJobBarrier ( QVector< Job * > & jobs,
int lod,
Func func )

Definition at line 71 of file KisRunnableStrokeJobUtils.h.

71 {
73 data->setLevelOfDetailOverride(lod);
74 jobs.append(data);
75}

References KisStrokeJobData::BARRIER.

◆ addJobBarrierExclusive()

template<typename Func , typename Job >
void KritaUtils::addJobBarrierExclusive ( QVector< Job * > & jobs,
Func func )

◆ addJobBarrierExclusiveNoCancel()

template<typename Func , typename Job >
void KritaUtils::addJobBarrierExclusiveNoCancel ( QVector< Job * > & jobs,
Func func )

Definition at line 115 of file KisRunnableStrokeJobUtils.h.

115 {
117 data->setCancellable(false);
118 jobs.append(data);
119}

References KisStrokeJobData::BARRIER, and KisStrokeJobData::EXCLUSIVE.

◆ addJobBarrierNoCancel()

template<typename Func , typename Job >
void KritaUtils::addJobBarrierNoCancel ( QVector< Job * > & jobs,
Func func )

Definition at line 108 of file KisRunnableStrokeJobUtils.h.

108 {
110 data->setCancellable(false);
111 jobs.append(data);
112}

References KisStrokeJobData::BARRIER.

◆ addJobConcurrent() [1/2]

template<typename Func , typename Job >
void KritaUtils::addJobConcurrent ( QVector< Job * > & jobs,
Func func )

◆ addJobConcurrent() [2/2]

template<typename Func , typename Job >
void KritaUtils::addJobConcurrent ( QVector< Job * > & jobs,
int lod,
Func func )

Definition at line 64 of file KisRunnableStrokeJobUtils.h.

64 {
66 data->setLevelOfDetailOverride(lod);
67 jobs.append(data);
68}

References KisStrokeJobData::CONCURRENT.

◆ addJobConcurrentNoCancel()

template<typename Func , typename Job >
void KritaUtils::addJobConcurrentNoCancel ( QVector< Job * > & jobs,
Func func )

Definition at line 101 of file KisRunnableStrokeJobUtils.h.

101 {
103 data->setCancellable(false);
104 jobs.append(data);
105}

References KisStrokeJobData::CONCURRENT.

◆ addJobSequential() [1/2]

template<typename Func , typename Job >
void KritaUtils::addJobSequential ( QVector< Job * > & jobs,
Func func )

◆ addJobSequential() [2/2]

template<typename Func , typename Job >
void KritaUtils::addJobSequential ( QVector< Job * > & jobs,
int lod,
Func func )

Definition at line 50 of file KisRunnableStrokeJobUtils.h.

50 {
52 data->setLevelOfDetailOverride(lod);
53 jobs.append(data);
54}

References KisStrokeJobData::SEQUENTIAL.

◆ addJobSequentialExclusive() [1/2]

template<typename Func , typename Job >
void KritaUtils::addJobSequentialExclusive ( QVector< Job * > & jobs,
Func func )

◆ addJobSequentialExclusive() [2/2]

template<typename Func , typename Job >
void KritaUtils::addJobSequentialExclusive ( QVector< Job * > & jobs,
int lod,
Func func )

Definition at line 57 of file KisRunnableStrokeJobUtils.h.

57 {
59 data->setLevelOfDetailOverride(lod);
60 jobs.append(data);
61}

References KisStrokeJobData::EXCLUSIVE, and KisStrokeJobData::SEQUENTIAL.

◆ addJobSequentialExclusiveNoCancel()

template<typename Func , typename Job >
void KritaUtils::addJobSequentialExclusiveNoCancel ( QVector< Job * > & jobs,
Func func )

Definition at line 93 of file KisRunnableStrokeJobUtils.h.

93 {
95 data->setCancellable(false);
96 jobs.append(data);
97}

References KisStrokeJobData::EXCLUSIVE, and KisStrokeJobData::SEQUENTIAL.

◆ addJobSequentialNoCancel()

template<typename Func , typename Job >
void KritaUtils::addJobSequentialNoCancel ( QVector< Job * > & jobs,
Func func )

Definition at line 86 of file KisRunnableStrokeJobUtils.h.

86 {
88 data->setCancellable(false);
89 jobs.append(data);
90}

References KisStrokeJobData::SEQUENTIAL.

◆ addJobUniquelyConcurrent() [1/2]

template<typename Func , typename Job >
void KritaUtils::addJobUniquelyConcurrent ( QVector< Job * > & jobs,
Func func )

◆ addJobUniquelyConcurrent() [2/2]

template<typename Func , typename Job >
void KritaUtils::addJobUniquelyConcurrent ( QVector< Job * > & jobs,
int lod,
Func func )

Definition at line 78 of file KisRunnableStrokeJobUtils.h.

78 {
80 data->setLevelOfDetailOverride(lod);
81 jobs.append(data);
82}

References KisStrokeJobData::UNIQUELY_CONCURRENT.

◆ addJobUniquelyConcurrentNoCancel()

template<typename Func , typename Job >
void KritaUtils::addJobUniquelyConcurrentNoCancel ( QVector< Job * > & jobs,
Func func )

Definition at line 122 of file KisRunnableStrokeJobUtils.h.

122 {
124 data->setCancellable(false);
125 jobs.append(data);
126}

References KisStrokeJobData::UNIQUELY_CONCURRENT.

◆ applyToAlpha8Device()

void KRITAIMAGE_EXPORT KritaUtils::applyToAlpha8Device ( KisPaintDeviceSP dev,
const QRect & rc,
std::function< void(quint8)> func )

Definition at line 407 of file krita_utils.cpp.

407 {
408 KisSequentialConstIterator dstIt(dev, rc);
409 while (dstIt.nextPixel()) {
410 const quint8 *dstPtr = dstIt.rawDataConst();
411 func(*dstPtr);
412 }
413 }

References KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), and KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawDataConst().

◆ checkInTriangle()

bool KritaUtils::checkInTriangle ( const QRectF & rect,
const QPolygonF & triangle )

Definition at line 97 of file krita_utils.cpp.

99 {
100 return triangle.intersected(rect).boundingRect().isValid();
101 }

◆ compareChannelFlags()

bool KRITAIMAGE_EXPORT KritaUtils::compareChannelFlags ( QBitArray f1,
QBitArray f2 )

Definition at line 343 of file krita_utils.cpp.

344 {
345 if (f1.isNull() && f2.isNull()) return true;
346
347 if (f1.isNull()) {
348 f1.fill(true, f2.size());
349 }
350
351 if (f2.isNull()) {
352 f2.fill(true, f1.size());
353 }
354
355 return f1 == f2;
356 }

◆ compareListsUnordered()

template<class T >
bool KritaUtils::compareListsUnordered ( const QList< T > & a,
const QList< T > & b )

Definition at line 17 of file krita_container_utils.h.

17 {
18 if (a.size() != b.size()) return false;
19
20 Q_FOREACH(const T &t, a) {
21 if (!b.contains(t)) return false;
22 }
23
24 return true;
25}

◆ convertQImageToGrayA()

QImage KRITAIMAGE_EXPORT KritaUtils::convertQImageToGrayA ( const QImage & image)

Definition at line 390 of file krita_utils.cpp.

391 {
392 QImage dstImage(image.size(), QImage::Format_ARGB32);
393
394 // TODO: if someone feel bored, a more optimized version of this would be welcome
395 const QSize size = image.size();
396 for(int y = 0; y < size.height(); ++y) {
397 for(int x = 0; x < size.width(); ++x) {
398 const QRgb pixel = image.pixel(x,y);
399 const int gray = qGray(pixel);
400 dstImage.setPixel(x, y, qRgba(gray, gray, gray, qAlpha(pixel)));
401 }
402 }
403
404 return dstImage;
405 }
unsigned int QRgb

◆ estimatePortionOfTransparentPixels()

qreal KRITAIMAGE_EXPORT KritaUtils::estimatePortionOfTransparentPixels ( KisPaintDeviceSP dev,
const QRect & rect,
qreal samplePortion )

Definition at line 423 of file krita_utils.cpp.

423 {
424 const KoColorSpace *cs = dev->colorSpace();
425
426 const qreal linearPortion = std::sqrt(samplePortion);
427 const qreal ratio = qreal(rect.width()) / rect.height();
428 const int xStep = qMax(1, qRound(1.0 / linearPortion * ratio));
429 const int yStep = qMax(1, qRound(1.0 / linearPortion / ratio));
430
431 int numTransparentPixels = 0;
432 int numPixels = 0;
433
435 for (int y = rect.y(); y <= rect.bottom(); y += yStep) {
436 for (int x = rect.x(); x <= rect.right(); x += xStep) {
437 it->moveTo(x, y);
438 const quint8 alpha = cs->opacityU8(it->rawDataConst());
439
440 if (alpha != OPACITY_OPAQUE_U8) {
441 numTransparentPixels++;
442 }
443
444 numPixels++;
445 }
446 }
447
448 if (numPixels == 0) {
449 return 0; // avoid dividing by 0
450 }
451 return qreal(numTransparentPixels) / numPixels;
452 }
const quint8 OPACITY_OPAQUE_U8
virtual const quint8 * rawDataConst() const =0
KisRandomConstAccessorSP createRandomConstAccessorNG() const
const KoColorSpace * colorSpace() const
virtual void moveTo(qint32 x, qint32 y)=0
virtual quint8 opacityU8(const quint8 *pixel) const =0

References KisPaintDevice::colorSpace(), KisPaintDevice::createRandomConstAccessorNG(), KisRandomConstAccessorNG::moveTo(), OPACITY_OPAQUE_U8, KoColorSpace::opacityU8(), and KisBaseConstAccessor::rawDataConst().

◆ fetchControlPoint()

boost::optional< QPointF > KritaUtils::fetchControlPoint ( KoPathPoint * pt,
bool takeFirst )

Definition at line 11 of file KoPathMergeUtils.cpp.

12{
13 boost::optional<QPointF> result;
14
15 if (takeFirst) {
16 if (pt->activeControlPoint1()) {
17 result = pt->controlPoint1();
18 }
19 } else {
20 if (pt->activeControlPoint2()) {
21 result = pt->controlPoint2();
22 }
23 }
24
25 return result;
26}
QPointF controlPoint1
bool activeControlPoint1
bool activeControlPoint2
QPointF controlPoint2

References KoPathPoint::activeControlPoint1, KoPathPoint::activeControlPoint2, KoPathPoint::controlPoint1, and KoPathPoint::controlPoint2.

◆ filterAlpha8Device()

void KRITAIMAGE_EXPORT KritaUtils::filterAlpha8Device ( KisPaintDeviceSP dev,
const QRect & rc,
std::function< quint8(quint8)> func )

Definition at line 415 of file krita_utils.cpp.

415 {
416 KisSequentialIterator dstIt(dev, rc);
417 while (dstIt.nextPixel()) {
418 quint8 *dstPtr = dstIt.rawData();
419 *dstPtr = func(*dstPtr);
420 }
421 }

References KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), and KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData().

◆ filterContainer()

template<class C , typename KeepIfFunction >
auto KritaUtils::filterContainer ( C & container,
KeepIfFunction keepIf ) -> decltype(bool(keepIf(container[0])), void())

Definition at line 39 of file krita_container_utils.h.

40 {
41
42 auto newEnd = std::remove_if(container.begin(), container.end(), [keepIf] (typename C::reference p) { return !keepIf(p); });
43 while (newEnd != container.end()) {
44 newEnd = container.erase(newEnd);
45 }
46}
const Params2D p

References p.

◆ makeContainerUnique()

template<class C >
void KritaUtils::makeContainerUnique ( C & container)

Definition at line 28 of file krita_container_utils.h.

28 {
29 std::sort(container.begin(), container.end());
30 auto newEnd = std::unique(container.begin(), container.end());
31
32 while (newEnd != container.end()) {
33 newEnd = container.erase(newEnd);
34 }
35}

◆ makeSymmetric()

void KritaUtils::makeSymmetric ( KoPathPoint * pt,
bool copyFromFirst )

Definition at line 28 of file KoPathMergeUtils.cpp.

29{
30 if (copyFromFirst) {
31 if (pt->activeControlPoint1()) {
32 pt->setControlPoint2(2.0 * pt->point() - pt->controlPoint1());
33 }
34 } else {
35 if (pt->activeControlPoint2()) {
36 pt->setControlPoint1(2.0 * pt->point() - pt->controlPoint2());
37 }
38 }
39
41}
void setControlPoint1(const QPointF &point)
Set the control point 1.
QPointF point
void setProperty(PointProperty property)
Sets a single property of a point.
void setControlPoint2(const QPointF &point)
Set the control point 2.
@ IsSymmetric
it is symmetric, like smooth but control points have same distance to point
Definition KoPathPoint.h:42

References KoPathPoint::activeControlPoint1, KoPathPoint::activeControlPoint2, KoPathPoint::controlPoint1, KoPathPoint::controlPoint2, KoPathPoint::IsSymmetric, KoPathPoint::point, KoPathPoint::setControlPoint1(), KoPathPoint::setControlPoint2(), and KoPathPoint::setProperty().

◆ maxDimensionPortion()

qreal KRITAIMAGE_EXPORT KritaUtils::maxDimensionPortion ( const QRectF & bounds,
qreal portion,
qreal minValue )

Definition at line 190 of file krita_utils.cpp.

191 {
192 qreal maxDimension = qMax(bounds.width(), bounds.height());
193 return qMax(portion * maxDimension, minValue);
194 }
#define bounds(x, a, b)

References bounds.

◆ mergeChannelFlags()

QBitArray KRITAIMAGE_EXPORT KritaUtils::mergeChannelFlags ( const QBitArray & childFlags,
const QBitArray & parentFlags )

Definition at line 326 of file krita_utils.cpp.

327 {
328 QBitArray flags = childFlags;
329
330 if (!flags.isEmpty() &&
331 !parentFlags.isEmpty() &&
332 flags.size() == parentFlags.size()) {
333
334 flags &= parentFlags;
335
336 } else if (!parentFlags.isEmpty()) {
337 flags = parentFlags;
338 }
339
340 return flags;
341 }

◆ mergeOpacityF()

qreal KRITAIMAGE_EXPORT KritaUtils::mergeOpacityF ( qreal opacity,
qreal parentOpacity )

Definition at line 318 of file krita_utils.cpp.

319 {
320 if (!qFuzzyCompare(parentOpacity, OPACITY_OPAQUE_F)) {
321 opacity *= parentOpacity;
322 }
323 return opacity;
324 }
const qreal OPACITY_OPAQUE_F
static bool qFuzzyCompare(half p1, half p2)

References OPACITY_OPAQUE_F, and qFuzzyCompare().

◆ mergeOpacityU8()

quint8 KRITAIMAGE_EXPORT KritaUtils::mergeOpacityU8 ( quint8 opacity,
quint8 parentOpacity )

Definition at line 310 of file krita_utils.cpp.

311 {
312 if (parentOpacity != OPACITY_OPAQUE_U8) {
313 opacity = (int(opacity) * parentOpacity) / OPACITY_OPAQUE_U8;
314 }
315 return opacity;
316 }

References OPACITY_OPAQUE_U8.

◆ mirrorDab() [1/2]

void KRITAIMAGE_EXPORT KritaUtils::mirrorDab ( Qt::Orientation dir,
const QPoint & center,
KisRenderedDab * dab,
bool skipMirrorPixels )

Definition at line 454 of file krita_utils.cpp.

455 {
456 const QRect rc = dab->realBounds();
457
458 if (dir == Qt::Horizontal) {
459 const int mirrorX = -((rc.x() + rc.width()) - center.x()) + center.x();
460
461 if (!skipMirrorPixels) {
462 dab->device->mirror(true, false);
463 }
464 dab->offset.rx() = mirrorX;
465 } else /* if (dir == Qt::Vertical) */ {
466 const int mirrorY = -((rc.y() + rc.height()) - center.y()) + center.y();
467
468 if (!skipMirrorPixels) {
469 dab->device->mirror(false, true);
470 }
471 dab->offset.ry() = mirrorY;
472 }
473 }
void mirror(bool horizontal, bool vertical)
KisFixedPaintDeviceSP device
QRect realBounds() const

References KisRenderedDab::device, KisFixedPaintDevice::mirror(), KisRenderedDab::offset, and KisRenderedDab::realBounds().

◆ mirrorDab() [2/2]

void KRITAIMAGE_EXPORT KritaUtils::mirrorDab ( Qt::Orientation dir,
const QPointF & center,
KisRenderedDab * dab,
bool skipMirrorPixels )

Definition at line 475 of file krita_utils.cpp.

476 {
477 const QRect rc = dab->realBounds();
478
479 if (dir == Qt::Horizontal) {
480 const int mirrorX = -((rc.x() + rc.width()) - center.x()) + center.x();
481
482 if (!skipMirrorPixels) {
483 dab->device->mirror(true, false);
484 }
485 dab->offset.rx() = mirrorX;
486 } else /* if (dir == Qt::Vertical) */ {
487 const int mirrorY = -((rc.y() + rc.height()) - center.y()) + center.y();
488
489 if (!skipMirrorPixels) {
490 dab->device->mirror(false, true);
491 }
492 dab->offset.ry() = mirrorY;
493 }
494 }

References KisRenderedDab::device, KisFixedPaintDevice::mirror(), KisRenderedDab::offset, and KisRenderedDab::realBounds().

◆ mirrorPoint() [1/2]

void KRITAIMAGE_EXPORT KritaUtils::mirrorPoint ( Qt::Orientation dir,
const QPoint & center,
QPointF * pt )

Definition at line 518 of file krita_utils.cpp.

519 {
520 if (dir == Qt::Horizontal) {
521 pt->rx() = -(pt->x() - qreal(center.x())) + center.x();
522 } else /* if (dir == Qt::Vertical) */ {
523 pt->ry() = -(pt->y() - qreal(center.y())) + center.y();
524 }
525 }

◆ mirrorPoint() [2/2]

void KRITAIMAGE_EXPORT KritaUtils::mirrorPoint ( Qt::Orientation dir,
const QPointF & center,
QPointF * pt )

Definition at line 527 of file krita_utils.cpp.

528 {
529 if (dir == Qt::Horizontal) {
530 pt->rx() = -(pt->x() - qreal(center.x())) + center.x();
531 } else /* if (dir == Qt::Vertical) */ {
532 pt->ry() = -(pt->y() - qreal(center.y())) + center.y();
533 }
534 }

◆ mirrorRect() [1/2]

void KRITAIMAGE_EXPORT KritaUtils::mirrorRect ( Qt::Orientation dir,
const QPoint & center,
QRect * rc )

Definition at line 496 of file krita_utils.cpp.

497 {
498 if (dir == Qt::Horizontal) {
499 const int mirrorX = -((rc->x() + rc->width()) - center.x()) + center.x();
500 rc->moveLeft(mirrorX);
501 } else /* if (dir == Qt::Vertical) */ {
502 const int mirrorY = -((rc->y() + rc->height()) - center.y()) + center.y();
503 rc->moveTop(mirrorY);
504 }
505 }

◆ mirrorRect() [2/2]

void KRITAIMAGE_EXPORT KritaUtils::mirrorRect ( Qt::Orientation dir,
const QPointF & center,
QRect * rc )

Definition at line 507 of file krita_utils.cpp.

508 {
509 if (dir == Qt::Horizontal) {
510 const int mirrorX = -((rc->x() + rc->width()) - center.x()) + center.x();
511 rc->moveLeft(mirrorX);
512 } else /* if (dir == Qt::Vertical) */ {
513 const int mirrorY = -((rc->y() + rc->height()) - center.y()) + center.y();
514 rc->moveTop(mirrorY);
515 }
516 }

◆ nearestNodeAfterRemoval()

KisNodeSP KRITAIMAGE_EXPORT KritaUtils::nearestNodeAfterRemoval ( KisNodeSP node)

Definition at line 362 of file krita_utils.cpp.

363 {
364 KisNodeSP newNode = node->nextSibling();
365
366 if (!newNode) {
367 newNode = node->prevSibling();
368 }
369
370 if (!newNode) {
371 newNode = node->parent();
372 }
373
374 return newNode;
375 }
KisNodeSP prevSibling() const
Definition kis_node.cpp:402
KisNodeWSP parent
Definition kis_node.cpp:86
KisNodeSP nextSibling() const
Definition kis_node.cpp:408

References KisNode::nextSibling(), KisNode::parent, and KisNode::prevSibling().

◆ optimalPatchSize()

QSize KRITAIMAGE_EXPORT KritaUtils::optimalPatchSize ( )

Definition at line 35 of file krita_utils.cpp.

36 {
37 KisImageConfig cfg(true);
38 return QSize(cfg.updatePatchWidth(),
39 cfg.updatePatchHeight());
40 }

References KisImageConfig::updatePatchHeight(), and KisImageConfig::updatePatchWidth().

◆ pathShapeBooleanSpaceWorkaround()

QTransform KRITAIMAGE_EXPORT KritaUtils::pathShapeBooleanSpaceWorkaround ( KisImageSP image)

Returns a special transformation that converts vector shape coordinates ('pt') into a special coordinate space, where all path boolean operations should happen.

The problem is that Qt's path boolean operation do not support curves, therefore all the curves are converted into lines (see QPathSegments::addPath()). The curves are split into lines using absolute size of the curve for the threshold. Therefore, when applying boolean operations we should convert them into 'image pixel' coordinate space first.

See https://bugs.kde.org/show_bug.cgi?id=411056

Definition at line 536 of file krita_utils.cpp.

537 {
538 return QTransform::fromScale(image->xRes(), image->yRes());
539 }
double xRes() const
double yRes() const

References KisImage::xRes(), and KisImage::yRes().

◆ prettyFormatReal()

QString KRITAIMAGE_EXPORT KritaUtils::prettyFormatReal ( qreal value)

Definition at line 185 of file krita_utils.cpp.

186 {
187 return QLocale().toString(value, 'f', 1);
188 }
float value(const T *src, size_t ch)

References value().

◆ processTwoDevices()

template<class PixelProcessor >
void KritaUtils::processTwoDevices ( const QRect & rc,
KisRandomConstAccessorSP srcIt,
KisRandomAccessorSP dstIt,
const int srcPixelSize,
const int dstPixelSize,
PixelProcessor pixelProcessor )

this is a special helper function for iterating through pixels in an extremely efficient way. One should either pass a functor or a lambda to it.

Definition at line 22 of file KisFastDeviceProcessingUtils.h.

28{
29 qint32 dstY = rc.y();
30 qint32 rowsRemaining = rc.height();
31
32 while (rowsRemaining > 0) {
33 qint32 dstX = rc.x();
34
35 qint32 numContiguousSrcRows = srcIt->numContiguousRows(dstY);
36 qint32 numContiguousDstRows = dstIt->numContiguousRows(dstY);
37 qint32 rows = std::min({rowsRemaining, numContiguousSrcRows, numContiguousDstRows});
38
39 qint32 columnsRemaining = rc.width();
40
41 while (columnsRemaining > 0) {
42
43 qint32 numContiguousSrcColumns = srcIt->numContiguousColumns(dstX);
44 qint32 numContiguousDstColumns = dstIt->numContiguousColumns(dstX);
45 qint32 columns = std::min({columnsRemaining, numContiguousSrcColumns, numContiguousDstColumns});
46
47 qint32 dstRowStride = dstIt->rowStride(dstX, dstY);
48 qint32 srcRowStride = srcIt->rowStride(dstX, dstY);
49
50 dstIt->moveTo(dstX, dstY);
51 srcIt->moveTo(dstX, dstY);
52
53 quint8 *dstRowStart = dstIt->rawData();
54 const quint8 *srcRowStart = srcIt->rawDataConst();
55
56 for (int i = 0; i < rows; i++) {
57 const quint8 *srcPtr = reinterpret_cast<const quint8*>(srcRowStart);
58 quint8 *dstPtr = reinterpret_cast<quint8*>(dstRowStart);
59
60 for (int j = 0; j < columns; j++) {
61 pixelProcessor(srcPtr, dstPtr);
62
63 srcPtr += srcPixelSize;
64 dstPtr += dstPixelSize;
65 }
66
67 srcRowStart += srcRowStride;
68 dstRowStart += dstRowStride;
69 }
70
71 dstX += columns;
72 columnsRemaining -= columns;
73 }
74
75 dstY += rows;
76 rowsRemaining -= rows;
77 }
78}
virtual quint8 * rawData()=0
virtual qint32 rowStride(qint32 x, qint32 y) const =0
virtual qint32 numContiguousRows(qint32 y) const =0
virtual qint32 numContiguousColumns(qint32 x) const =0

References KisRandomConstAccessorNG::moveTo(), KisRandomConstAccessorNG::numContiguousColumns(), KisRandomConstAccessorNG::numContiguousRows(), KisBaseAccessor::rawData(), KisBaseConstAccessor::rawDataConst(), and KisRandomConstAccessorNG::rowStride().

◆ processTwoDevicesWithStrides()

template<class PixelProcessor >
void KritaUtils::processTwoDevicesWithStrides ( const QRect & rc,
KisRandomConstAccessorSP srcIt,
KisRandomAccessorSP dstIt,
PixelProcessor pixelProcessor )

this is a special helper function for iterating through pixels in an extremely efficient way using strides. One should either pass a functor or a lambda to it.

Definition at line 86 of file KisFastDeviceProcessingUtils.h.

90{
91 qint32 dstY = rc.y();
92 qint32 rowsRemaining = rc.height();
93
94 while (rowsRemaining > 0) {
95 qint32 dstX = rc.x();
96
97 qint32 numContiguousSrcRows = srcIt->numContiguousRows(dstY);
98 qint32 numContiguousDstRows = dstIt->numContiguousRows(dstY);
99 qint32 rows = std::min({rowsRemaining, numContiguousSrcRows, numContiguousDstRows});
100
101 qint32 columnsRemaining = rc.width();
102
103 while (columnsRemaining > 0) {
104
105 qint32 numContiguousSrcColumns = srcIt->numContiguousColumns(dstX);
106 qint32 numContiguousDstColumns = dstIt->numContiguousColumns(dstX);
107 qint32 columns = std::min({columnsRemaining, numContiguousSrcColumns, numContiguousDstColumns});
108
109 qint32 dstRowStride = dstIt->rowStride(dstX, dstY);
110 qint32 srcRowStride = srcIt->rowStride(dstX, dstY);
111
112 dstIt->moveTo(dstX, dstY);
113 srcIt->moveTo(dstX, dstY);
114
115 quint8 *dstRowStart = dstIt->rawData();
116 const quint8 *srcRowStart = srcIt->rawDataConst();
117
118 pixelProcessor(srcRowStart, srcRowStride,
119 dstRowStart, dstRowStride,
120 rows, columns);
121
122 dstX += columns;
123 columnsRemaining -= columns;
124 }
125
126 dstY += rows;
127 rowsRemaining -= rows;
128 }
129}

References KisRandomConstAccessorNG::moveTo(), KisRandomConstAccessorNG::numContiguousColumns(), KisRandomConstAccessorNG::numContiguousRows(), KisBaseAccessor::rawData(), KisBaseConstAccessor::rawDataConst(), and KisRandomConstAccessorNG::rowStride().

◆ rasterizeHLine() [1/2]

QVector< QPoint > KRITAIMAGE_EXPORT KritaUtils::rasterizeHLine ( const QPoint & startPoint,
const QPoint & endPoint )

Definition at line 603 of file krita_utils.cpp.

604 {
605 QVector<QPoint> points;
606 rasterizeHLine(startPoint, endPoint, [&points](const QPoint &point) { points.append(point); });
607 return points;
608 }
QVector< QPoint > rasterizeHLine(const QPoint &startPoint, const QPoint &endPoint)

References rasterizeHLine().

◆ rasterizeHLine() [2/2]

template<typename Visitor >
void KritaUtils::rasterizeHLine ( const QPoint & startPoint,
const QPoint & endPoint,
Visitor visitor )

Definition at line 142 of file krita_utils.h.

143 {
144 QVector<QPoint> points;
145 int startX, endX;
146 if (startPoint.x() < endPoint.x()) {
147 startX = startPoint.x();
148 endX = endPoint.x();
149 } else {
150 startX = endPoint.x();
151 endX = startPoint.x();
152 }
153 for (int x = startX; x <= endX; ++x) {
154 visitor(QPoint(x, startPoint.y()));
155 }
156 }

◆ rasterizeLineDDA() [1/2]

QVector< QPoint > KRITAIMAGE_EXPORT KritaUtils::rasterizeLineDDA ( const QPoint & startPoint,
const QPoint & endPoint )

Definition at line 617 of file krita_utils.cpp.

618 {
619 QVector<QPoint> points;
620 rasterizeLineDDA(startPoint, endPoint, [&points](const QPoint &point) { points.append(point); });
621 return points;
622 }
QVector< QPoint > rasterizeLineDDA(const QPoint &startPoint, const QPoint &endPoint)

References rasterizeLineDDA().

◆ rasterizeLineDDA() [2/2]

template<typename Visitor >
void KritaUtils::rasterizeLineDDA ( const QPoint & startPoint,
const QPoint & endPoint,
Visitor visitor )

Definition at line 176 of file krita_utils.h.

177 {
178 QVector<QPoint> points;
179
180 if (startPoint == endPoint) {
181 visitor(startPoint);
182 return;
183 }
184 if (startPoint.y() == endPoint.y()) {
185 rasterizeHLine(startPoint, endPoint, visitor);
186 return;
187 }
188 if (startPoint.x() == endPoint.x()) {
189 rasterizeVLine(startPoint, endPoint, visitor);
190 return;
191 }
192
193 const QPoint delta = endPoint - startPoint;
194 QPoint currentPosition = startPoint;
195 QPointF currentPositionF = startPoint;
196 qreal m = static_cast<qreal>(delta.y()) / static_cast<qreal>(delta.x());
197 int increment;
198
199 if (std::abs(m) > 1.0) {
200 if (delta.y() > 0) {
201 m = 1.0 / m;
202 increment = 1;
203 } else {
204 m = -1.0 / m;
205 increment = -1;
206 }
207 while (currentPosition.y() != endPoint.y()) {
208 currentPositionF.setX(currentPositionF.x() + m);
209 currentPosition = QPoint(static_cast<int>(qRound(currentPositionF.x())),
210 currentPosition.y() + increment);
211 visitor(currentPosition);
212 }
213 } else {
214 if (delta.x() > 0) {
215 increment = 1;
216 } else {
217 increment = -1;
218 m = -m;
219 }
220 while (currentPosition.x() != endPoint.x()) {
221 currentPositionF.setY(currentPositionF.y() + m);
222 currentPosition = QPoint(currentPosition.x() + increment,
223 static_cast<int>(qRound(currentPositionF.y())));
224 visitor(currentPosition);
225 }
226 }
227 }
QVector< QPoint > rasterizeVLine(const QPoint &startPoint, const QPoint &endPoint)

References rasterizeHLine(), and rasterizeVLine().

◆ rasterizePolygonDDA() [1/2]

QVector< QPoint > KRITAIMAGE_EXPORT KritaUtils::rasterizePolygonDDA ( const QVector< QPoint > & polygonPoints)

Definition at line 631 of file krita_utils.cpp.

632 {
633 QVector<QPoint> points;
634 rasterizePolygonDDA(polygonPoints, [&points](const QPoint &point) { points.append(point); });
635 return points;
636 }
QVector< QPoint > rasterizePolygonDDA(const QVector< QPoint > &polygonPoints)

References rasterizePolygonDDA().

◆ rasterizePolygonDDA() [2/2]

template<typename Visitor >
void KritaUtils::rasterizePolygonDDA ( const QVector< QPoint > & polygonPoints,
Visitor visitor )

Definition at line 260 of file krita_utils.h.

261 {
262 // this is a line
263 if (polygonPoints.size() < 3) {
264 rasterizeLineDDA(polygonPoints.first(), polygonPoints.last(), visitor);
265 return;
266 }
267 // rasterize all segments except the last one
268 QPoint lastSegmentStart;
269 if (polygonPoints.first() == polygonPoints.last()) {
270 rasterizePolylineDDA(polygonPoints.mid(0, polygonPoints.size() - 1), visitor);
271 lastSegmentStart = polygonPoints[polygonPoints.size() - 2];
272 } else {
273 rasterizePolylineDDA(polygonPoints, visitor);
274 lastSegmentStart = polygonPoints[polygonPoints.size() - 1];
275 }
276 // close the polygon
277 {
278 QVector<QPoint> points;
279 auto addPoint = [&points](const QPoint &point) -> void { points.append(point); };
280 rasterizeLineDDA(lastSegmentStart, polygonPoints.first(), addPoint);
281 for (int i = 1; i < points.size() - 1; ++i) {
282 visitor(points[i]);
283 }
284 }
285 }
QVector< QPoint > rasterizePolylineDDA(const QVector< QPoint > &polylinePoints)

References rasterizeLineDDA(), and rasterizePolylineDDA().

◆ rasterizePolylineDDA() [1/2]

QVector< QPoint > KRITAIMAGE_EXPORT KritaUtils::rasterizePolylineDDA ( const QVector< QPoint > & polylinePoints)

Definition at line 624 of file krita_utils.cpp.

625 {
626 QVector<QPoint> points;
627 rasterizePolylineDDA(polylinePoints, [&points](const QPoint &point) { points.append(point); });
628 return points;
629 }

References rasterizePolylineDDA().

◆ rasterizePolylineDDA() [2/2]

template<typename Visitor >
void KritaUtils::rasterizePolylineDDA ( const QVector< QPoint > & polylinePoints,
Visitor visitor )

Definition at line 230 of file krita_utils.h.

231 {
232 if (polylinePoints.size() == 0) {
233 return;
234 }
235 if (polylinePoints.size() == 1) {
236 visitor(polylinePoints.first());
237 return;
238 }
239
240 // copy all points from the first segment
241 rasterizeLineDDA(polylinePoints[0], polylinePoints[1], visitor);
242 // for the rest of the segments, copy all points except the first one
243 // (it is the same as the last point in the previous segment)
244 for (int i = 1; i < polylinePoints.size() - 1; ++i) {
245 int pointIndex = 0;
247 polylinePoints[i], polylinePoints[i + 1],
248 [&pointIndex, &visitor](const QPoint &point) -> void
249 {
250 if (pointIndex > 0) {
251 visitor(point);
252 }
253 ++pointIndex;
254 }
255 );
256 }
257 }

References rasterizeLineDDA().

◆ rasterizeVLine() [1/2]

QVector< QPoint > KRITAIMAGE_EXPORT KritaUtils::rasterizeVLine ( const QPoint & startPoint,
const QPoint & endPoint )

Definition at line 610 of file krita_utils.cpp.

611 {
612 QVector<QPoint> points;
613 rasterizeVLine(startPoint, endPoint, [&points](const QPoint &point) { points.append(point); });
614 return points;
615 }

References rasterizeVLine().

◆ rasterizeVLine() [2/2]

template<typename Visitor >
void KritaUtils::rasterizeVLine ( const QPoint & startPoint,
const QPoint & endPoint,
Visitor visitor )

Definition at line 159 of file krita_utils.h.

160 {
161 QVector<QPoint> points;
162 int startY, endY;
163 if (startPoint.y() < endPoint.y()) {
164 startY = startPoint.y();
165 endY = endPoint.y();
166 } else {
167 startY = endPoint.y();
168 endY = startPoint.y();
169 }
170 for (int y = startY; y <= endY; ++y) {
171 visitor(QPoint(startPoint.x(), y));
172 }
173 }

◆ renderExactRect() [1/2]

void KRITAIMAGE_EXPORT KritaUtils::renderExactRect ( QPainter * p,
const QRect & rc )

When drawing a rect Qt uses quite a weird algorithm. It draws 4 lines: o at X-es: rect.x() and rect.right() + 1 o at Y-s: rect.y() and rect.bottom() + 1

Which means that bottom and right lines of the rect are painted outside the virtual rectangle the rect defines. This methods overcome this issue by painting the adjusted rect.

Definition at line 377 of file krita_utils.cpp.

378 {
379 p->drawRect(rc.adjusted(0,0,-1,-1));
380 }

References p.

◆ renderExactRect() [2/2]

void KRITAIMAGE_EXPORT KritaUtils::renderExactRect ( QPainter * p,
const QRect & rc,
const QPen & pen )
See also
renderExactRect(QPainter *p, const QRect &rc)

Definition at line 382 of file krita_utils.cpp.

383 {
384 QPen oldPen = p->pen();
385 p->setPen(pen);
386 renderExactRect(p, rc);
387 p->setPen(oldPen);
388 }
void renderExactRect(QPainter *p, const QRect &rc)

References p, and renderExactRect().

◆ resolveAbsoluteFilePath()

QString KRITAGLOBAL_EXPORT KritaUtils::resolveAbsoluteFilePath ( const QString & baseDir,
const QString & filePath )

Resolve absolute file path from a file path and base dir.

If the filePath is absolute, just return this path, otherwise try to merge baseDir and filePath to form an absolute file path

Definition at line 15 of file KisFileUtils.cpp.

16{
17 if (QFileInfo(fileName).isAbsolute()) {
18 return fileName;
19 }
20
21 QFileInfo fallbackBaseDirInfo(baseDir);
22
23 return QFileInfo(QDir(fallbackBaseDirInfo.isDir() ?
24 fallbackBaseDirInfo.absoluteFilePath() :
25 fallbackBaseDirInfo.absolutePath()),
26 fileName).absoluteFilePath();
27}

◆ restoreControlPoint()

void KritaUtils::restoreControlPoint ( KoPathPoint * pt,
bool restoreFirst,
boost::optional< QPointF > savedPoint )

Definition at line 43 of file KoPathMergeUtils.cpp.

44{
45 if (restoreFirst) {
46 if (savedPoint) {
47 pt->setControlPoint1(*savedPoint);
48 } else {
50 }
51 } else {
52 if (savedPoint) {
53 pt->setControlPoint2(*savedPoint);
54 } else {
56 }
57 }
58}
void removeControlPoint1()
Removes the first control point.
void removeControlPoint2()
Removes the second control point.

References KoPathPoint::removeControlPoint1(), KoPathPoint::removeControlPoint2(), KoPathPoint::setControlPoint1(), and KoPathPoint::setControlPoint2().

◆ splitDisjointPaths()

QList< QPainterPath > KRITAIMAGE_EXPORT KritaUtils::splitDisjointPaths ( const QPainterPath & path)

Split a path path into a set of disjoint (non-intersectable) paths if possible.

It tries to follow odd-even fill rule, but has a small problem: If you have three selections included into each other twice, then the smallest selection will be included into the final subpath, although it shouldn't according to odd-even-fill rule. It is still to be fixed.

Definition at line 279 of file krita_utils.cpp.

280 {
281 QList<QPainterPath> resultList;
282 QList<QPolygonF> inputPolygons = path.toSubpathPolygons();
283
284 Q_FOREACH (const QPolygonF &poly, inputPolygons) {
285 QPainterPath testPath;
286 testPath.addPolygon(poly);
287
288 if (resultList.isEmpty()) {
289 resultList.append(testPath);
290 continue;
291 }
292
293 QPainterPath mergedPath = testPath;
294
295 for (auto it = resultList.begin(); it != resultList.end(); /*noop*/) {
296 if (it->intersects(testPath)) {
297 mergedPath.addPath(*it);
298 it = resultList.erase(it);
299 } else {
300 ++it;
301 }
302 }
303
304 resultList.append(mergedPath);
305 }
306
307 return resultList;
308 }

◆ splitPath()

KRITAIMAGE_EXPORT KisRegion KritaUtils::splitPath ( const QPainterPath & path)

Definition at line 153 of file krita_utils.cpp.

154 {
155 QVector<QRect> dirtyRects;
156 QRect totalRect = path.boundingRect().toAlignedRect();
157
158 // adjust the rect for antialiasing to work
159 totalRect = totalRect.adjusted(-1,-1,1,1);
160
161 const int step = 64;
162 const int right = totalRect.x() + totalRect.width();
163 const int bottom = totalRect.y() + totalRect.height();
164
165 for (int y = totalRect.y(); y < bottom;) {
166 int nextY = qMin((y + step) & ~(step-1), bottom);
167
168 for (int x = totalRect.x(); x < right;) {
169 int nextX = qMin((x + step) & ~(step-1), right);
170
171 QRect rect(x, y, nextX - x, nextY - y);
172
173 if(path.intersects(rect)) {
174 dirtyRects << rect;
175 }
176
177 x = nextX;
178 }
179 y = nextY;
180 }
181
182 return KisRegion(std::move(dirtyRects));
183 }

◆ splitRectIntoPatches()

QVector< QRect > KRITAIMAGE_EXPORT KritaUtils::splitRectIntoPatches ( const QRect & rc,
const QSize & patchSize )

Definition at line 42 of file krita_utils.cpp.

43 {
44 using namespace KisAlgebra2D;
45
46
47 QVector<QRect> patches;
48
49 const qint32 firstCol = divideFloor(rc.x(), patchSize.width());
50 const qint32 firstRow = divideFloor(rc.y(), patchSize.height());
51
52 // TODO: check if -1 is needed here
53 const qint32 lastCol = divideFloor(rc.x() + rc.width(), patchSize.width());
54 const qint32 lastRow = divideFloor(rc.y() + rc.height(), patchSize.height());
55
56 for(qint32 i = firstRow; i <= lastRow; i++) {
57 for(qint32 j = firstCol; j <= lastCol; j++) {
58 QRect maxPatchRect(j * patchSize.width(), i * patchSize.height(),
59 patchSize.width(), patchSize.height());
60 QRect patchRect = rc & maxPatchRect;
61
62 if (!patchRect.isEmpty()) {
63 patches.append(patchRect);
64 }
65 }
66 }
67
68 return patches;
69 }

◆ splitRectIntoPatchesTight()

QVector< QRect > KRITAIMAGE_EXPORT KritaUtils::splitRectIntoPatchesTight ( const QRect & rc,
const QSize & patchSize )

Definition at line 71 of file krita_utils.cpp.

72 {
73 QVector<QRect> patches;
74
75 for (qint32 y = rc.y(); y < rc.y() + rc.height(); y += patchSize.height()) {
76 for (qint32 x = rc.x(); x < rc.x() + rc.width(); x += patchSize.width()) {
77 patches << QRect(x, y,
78 qMin(rc.x() + rc.width() - x, patchSize.width()),
79 qMin(rc.y() + rc.height() - y, patchSize.height()));
80 }
81 }
82
83 return patches;
84 }

◆ splitRegionIntoPatches() [1/2]

QVector< QRect > KRITAIMAGE_EXPORT KritaUtils::splitRegionIntoPatches ( const KisRegion & region,
const QSize & patchSize )

Definition at line 86 of file krita_utils.cpp.

87 {
88 QVector<QRect> patches;
89
90 Q_FOREACH (const QRect rect, region.rects()) {
91 patches << KritaUtils::splitRectIntoPatches(rect, patchSize);
92 }
93
94 return patches;
95 }
QVector< QRect > rects() const
QVector< QRect > splitRectIntoPatches(const QRect &rc, const QSize &patchSize)

References KisRegion::rects(), and splitRectIntoPatches().

◆ splitRegionIntoPatches() [2/2]

QVector< QRect > KRITAIMAGE_EXPORT KritaUtils::splitRegionIntoPatches ( const QRegion & region,
const QSize & patchSize )

◆ splitTriangles()

KRITAIMAGE_EXPORT KisRegion KritaUtils::splitTriangles ( const QPointF & center,
const QVector< QPointF > & points )

Definition at line 104 of file krita_utils.cpp.

106 {
107
108 Q_ASSERT(points.size());
109 Q_ASSERT(!(points.size() & 1));
110
111 QVector<QPolygonF> triangles;
112 QRect totalRect;
113
114 for (int i = 0; i < points.size(); i += 2) {
115 QPolygonF triangle;
116 triangle << center;
117 triangle << points[i];
118 triangle << points[i+1];
119
120 totalRect |= triangle.boundingRect().toAlignedRect();
121 triangles << triangle;
122 }
123
124
125 const int step = 64;
126 const int right = totalRect.x() + totalRect.width();
127 const int bottom = totalRect.y() + totalRect.height();
128
129 QVector<QRect> dirtyRects;
130
131 for (int y = totalRect.y(); y < bottom;) {
132 int nextY = qMin((y + step) & ~(step-1), bottom);
133
134 for (int x = totalRect.x(); x < right;) {
135 int nextX = qMin((x + step) & ~(step-1), right);
136
137 QRect rect(x, y, nextX - x, nextY - y);
138
139 Q_FOREACH (const QPolygonF &triangle, triangles) {
140 if(checkInTriangle(rect, triangle)) {
141 dirtyRects << rect;
142 break;
143 }
144 }
145
146 x = nextX;
147 }
148 y = nextY;
149 }
150 return KisRegion(std::move(dirtyRects));
151 }

References checkInTriangle().

◆ thresholdOpacity()

void KritaUtils::thresholdOpacity ( KisPaintDeviceSP device,
const QRect & rect,
ThresholdMode mode )

Definition at line 558 of file krita_utils.cpp.

559 {
560 const KoColorSpace *cs = device->colorSpace();
561
562 if (mode == ThresholdCeil) {
563 KisSequentialIterator it(device, rect);
564 while (it.nextPixel()) {
565 if (cs->opacityU8(it.rawDataConst()) > 0) {
566 cs->setOpacity(it.rawData(), quint8(255), 1);
567 }
568 }
569 } else if (mode == ThresholdFloor) {
570 KisSequentialIterator it(device, rect);
571 while (it.nextPixel()) {
572 if (cs->opacityU8(it.rawDataConst()) < 255) {
573 cs->setOpacity(it.rawData(), quint8(0), 1);
574 }
575 }
576 } else if (mode == ThresholdMaxOut) {
577 KisSequentialIterator it(device, rect);
578 int numConseqPixels = it.nConseqPixels();
579 while (it.nextPixels(numConseqPixels)) {
580 numConseqPixels = it.nConseqPixels();
581 cs->setOpacity(it.rawData(), quint8(255), numConseqPixels);
582 }
583 }
584 }
virtual void setOpacity(quint8 *pixels, quint8 alpha, qint32 nPixels) const =0

References KisPaintDevice::colorSpace(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nConseqPixels(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixels(), KoColorSpace::opacityU8(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawDataConst(), KoColorSpace::setOpacity(), ThresholdCeil, ThresholdFloor, and ThresholdMaxOut.

◆ thresholdOpacityAlpha8()

void KritaUtils::thresholdOpacityAlpha8 ( KisPaintDeviceSP device,
const QRect & rect,
ThresholdMode mode )

Definition at line 586 of file krita_utils.cpp.

587 {
588 if (mode == ThresholdCeil) {
589 filterAlpha8Device(device, rect,
590 [] (quint8 value) {
591 return value > 0 ? 255 : value;
592 });
593 } else if (mode == ThresholdFloor) {
594 filterAlpha8Device(device, rect,
595 [] (quint8 value) {
596 return value < 255 ? 0 : value;
597 });
598 } else if (mode == ThresholdMaxOut) {
599 device->fill(rect, KoColor(Qt::white, device->colorSpace()));
600 }
601 }
void fill(const QRect &rc, const KoColor &color)
void filterAlpha8Device(KisPaintDeviceSP dev, const QRect &rc, std::function< quint8(quint8)> func)

References KisPaintDevice::colorSpace(), KisPaintDevice::fill(), filterAlpha8Device(), ThresholdCeil, ThresholdFloor, ThresholdMaxOut, and value().

◆ toLocalizedOnOff()

QString KRITAIMAGE_EXPORT KritaUtils::toLocalizedOnOff ( bool value)

Definition at line 358 of file krita_utils.cpp.

358 {
359 return value ? i18n("on") : i18n("off");
360 }

References value().

◆ tryCloseTornSubpathsAfterIntersection()

QPainterPath KRITAIMAGE_EXPORT KritaUtils::tryCloseTornSubpathsAfterIntersection ( QPainterPath path)

Sometimes, when intersecting two paths, QPainterPath does not close some of the subpaths. It causes glitches when rendering them on screen. So we should just close them explicitly.

Note: after intersecting the paths all bezier curves are already converted to polylines, so it should be safe to go through the polygons.

See: https://bugs.kde.org/show_bug.cgi?id=408369

Definition at line 541 of file krita_utils.cpp.

542 {
543 path.setFillRule(Qt::WindingFill);
544 QList<QPolygonF> polys = path.toSubpathPolygons();
545
546 path = QPainterPath();
547 path.setFillRule(Qt::WindingFill);
548 Q_FOREACH (QPolygonF poly, polys) {
549 ENTER_FUNCTION() << ppVar(poly.isClosed());
550 if (!poly.isClosed()) {
551 poly.append(poly.first());
552 }
553 path.addPolygon(poly);
554 }
555 return path;
556 }
#define ENTER_FUNCTION()
Definition kis_debug.h:178
#define ppVar(var)
Definition kis_debug.h:155

References ENTER_FUNCTION, and ppVar.

◆ tryMergePoints()

bool KritaUtils::tryMergePoints ( QPainterPath & path,
const QPointF & startPoint,
const QPointF & endPoint,
qreal & distance,
qreal distanceThreshold,
bool lastSegment )

Definition at line 196 of file krita_utils.cpp.

202 {
203 qreal length = (endPoint - startPoint).manhattanLength();
204
205 if (lastSegment || length > distanceThreshold) {
206 if (lastSegment) {
207 qreal wrappedLength =
208 (endPoint - QPointF(path.elementAt(0))).manhattanLength();
209
210 if (length < distanceThreshold ||
211 wrappedLength < distanceThreshold) {
212
213 return true;
214 }
215 }
216
217 distance = 0;
218 return false;
219 }
220
221 distance += length;
222
223 if (distance > distanceThreshold) {
224 path.lineTo(endPoint);
225 distance = 0;
226 }
227
228 return true;
229 }
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
qreal distance(const QPointF &p1, const QPointF &p2)

References distance(), and length().

◆ trySimplifyPath()

QPainterPath KRITAIMAGE_EXPORT KritaUtils::trySimplifyPath ( const QPainterPath & path,
qreal lengthThreshold )

Definition at line 231 of file krita_utils.cpp.

232 {
233 QPainterPath newPath;
234 QPointF startPoint;
235 qreal distance = 0;
236
237 int count = path.elementCount();
238 for (int i = 0; i < count; i++) {
239 QPainterPath::Element e = path.elementAt(i);
240 QPointF endPoint = QPointF(e.x, e.y);
241
242 switch (e.type) {
243 case QPainterPath::MoveToElement:
244 newPath.moveTo(endPoint);
245 break;
246 case QPainterPath::LineToElement:
247 if (!tryMergePoints(newPath, startPoint, endPoint,
248 distance, lengthThreshold, i == count - 1)) {
249
250 newPath.lineTo(endPoint);
251 }
252 break;
253 case QPainterPath::CurveToElement: {
254 Q_ASSERT(i + 2 < count);
255
256 if (!tryMergePoints(newPath, startPoint, endPoint,
257 distance, lengthThreshold, i == count - 1)) {
258
259 e = path.elementAt(i + 1);
260 Q_ASSERT(e.type == QPainterPath::CurveToDataElement);
261 QPointF ctrl1 = QPointF(e.x, e.y);
262 e = path.elementAt(i + 2);
263 Q_ASSERT(e.type == QPainterPath::CurveToDataElement);
264 QPointF ctrl2 = QPointF(e.x, e.y);
265 newPath.cubicTo(ctrl1, ctrl2, endPoint);
266 }
267
268 i += 2;
269 }
270 default:
271 ;
272 }
273 startPoint = endPoint;
274 }
275
276 return newPath;
277 }
bool tryMergePoints(QPainterPath &path, const QPointF &startPoint, const QPointF &endPoint, qreal &distance, qreal distanceThreshold, bool lastSegment)

References distance(), and tryMergePoints().

◆ workaroundUnsuitableImageColorSpace()

KisImportExportErrorCode KRITAUI_EXPORT KritaUtils::workaroundUnsuitableImageColorSpace ( KisImageSP image,
KisImportUserFeedbackInterface * feedbackInterface,
KisImageBarrierLock & lock )

When the image has a colorspace that is not suitable for displaying, Krita should convert that into something more useful. This tool function asks the user about the desired working color space and converts into it.

The profile has no reverse mapping into for the described color space, so we cannot use it in Krita. We need to ask the user to convert the image right on loading

Here is an extremely tricky part! First we start the conversion stroke, and only after that we unlock the image. The point is that KisDelayedUpdateNodeInterface-based nodes are forbidden to start their update jobs while the image is locked, so this guarantees that no stroke will be started before we actually convert the image into something usable

Definition at line 18 of file KisImportExportUtils.cpp.

21{
22 const KoColorSpace *replacementColorSpace = 0;
24 KoColorConversionTransformation::ConversionFlags replacementColorSpaceConversionFlags = KoColorConversionTransformation::internalConversionFlags();
25
26 const KoColorSpace *colorSpace = image->colorSpace();
27 const KoColorProfile *profile = colorSpace->profile();
28
29 if (profile && !profile->isSuitableForOutput()) {
33
34 KIS_SAFE_ASSERT_RECOVER_NOOP(feedbackInterface);
35 if (feedbackInterface) {
37 feedbackInterface->askUser([&] (QWidget *parent) {
38
39 KisColorSpaceConversionDialog * dlgColorSpaceConversion = new KisColorSpaceConversionDialog(parent, "ColorSpaceConversion");
40 Q_CHECK_PTR(dlgColorSpaceConversion);
41
42 const KoColorSpace* fallbackColorSpace =
44 colorSpace->colorModelId().id(),
45 colorSpace->colorDepthId().id(),
46 nullptr);
47
48 dlgColorSpaceConversion->setCaption(i18n("Convert image color space on import"));
49 dlgColorSpaceConversion->m_page->lblHeadlineWarning->setText(
50 i18nc("the argument is the ICC profile name",
51 "The image has a profile attached that Krita cannot edit images "
52 "in (\"%1\"), please select a space to convert to for editing: \n"
53 , profile->name()));
54 dlgColorSpaceConversion->m_page->lblHeadlineWarning->setVisible(true);
55
56 dlgColorSpaceConversion->setInitialColorSpace(fallbackColorSpace, 0);
57
58 if (dlgColorSpaceConversion->exec() == QDialog::Accepted) {
59
60 replacementColorSpace = dlgColorSpaceConversion->colorSpace();
61 replacementColorSpaceIntent = dlgColorSpaceConversion->conversionIntent();
62 replacementColorSpaceConversionFlags= dlgColorSpaceConversion->conversionFlags();
63 } else {
64 return false;
65 }
66
67 return true;
68 });
69
74 }
75 }
76 }
77
78 if (replacementColorSpace) {
87 image->convertImageColorSpace(replacementColorSpace,
88 replacementColorSpaceIntent,
89 replacementColorSpaceConversionFlags);
90 lock.unlock();
91 image->waitForDone();
92 }
93
95}
KoColorConversionTransformation::Intent conversionIntent() const
void setInitialColorSpace(const KoColorSpace *cs, KisImageSP entireImage)
KoColorConversionTransformation::ConversionFlags conversionFlags() const
void waitForDone()
const KoColorSpace * colorSpace() const
void convertImageColorSpace(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
virtual Result askUser(AskCallback callback)=0
ask the user a question about the loading process
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
virtual const KoColorProfile * profile() const =0
virtual void setCaption(const QString &caption)
Definition KoDialog.cpp:498
QString id() const
Definition KoID.cpp:63
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
virtual bool isSuitableForOutput() const =0
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()

References KisImportUserFeedbackInterface::askUser(), ImportExportCodes::Cancelled, KoColorSpace::colorDepthId(), KoColorSpace::colorModelId(), KisImage::colorSpace(), KisColorSpaceConversionDialog::colorSpace(), KoColorSpaceRegistry::colorSpace(), KisColorSpaceConversionDialog::conversionFlags(), KisColorSpaceConversionDialog::conversionIntent(), KisImage::convertImageColorSpace(), ImportExportCodes::FormatColorSpaceUnsupported, KoID::id(), KoColorSpaceRegistry::instance(), KoColorConversionTransformation::internalConversionFlags(), KoColorConversionTransformation::internalRenderingIntent(), KoColorProfile::isSuitableForOutput(), KIS_SAFE_ASSERT_RECOVER_NOOP, KisColorSpaceConversionDialog::m_page, KoColorProfile::name, ImportExportCodes::OK, KoColorSpace::profile(), KoDialog::setCaption(), KisColorSpaceConversionDialog::setInitialColorSpace(), KisImportUserFeedbackInterface::SuppressedByBatchMode, KisImportUserFeedbackInterface::UserCancelled, and KisImage::waitForDone().