9#include <QtCore/qmath.h>
13#include <QPainterPath>
49 const qint32 firstCol = divideFloor(rc.x(), patchSize.width());
50 const qint32 firstRow = divideFloor(rc.y(), patchSize.height());
53 const qint32 lastCol = divideFloor(rc.x() + rc.width(), patchSize.width());
54 const qint32 lastRow = divideFloor(rc.y() + rc.height(), patchSize.height());
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;
62 if (!patchRect.isEmpty()) {
63 patches.append(patchRect);
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()));
90 Q_FOREACH (
const QRect
rect, region.
rects()) {
98 const QPolygonF &triangle)
100 return triangle.intersected(
rect).boundingRect().isValid();
108 Q_ASSERT(points.size());
109 Q_ASSERT(!(points.size() & 1));
114 for (
int i = 0; i < points.size(); i += 2) {
117 triangle << points[i];
118 triangle << points[i+1];
120 totalRect |= triangle.boundingRect().toAlignedRect();
121 triangles << triangle;
126 const int right = totalRect.x() + totalRect.width();
127 const int bottom = totalRect.y() + totalRect.height();
131 for (
int y = totalRect.y(); y < bottom;) {
132 int nextY = qMin((y + step) & ~(step-1), bottom);
134 for (
int x = totalRect.x(); x < right;) {
135 int nextX = qMin((x + step) & ~(step-1), right);
137 QRect
rect(x, y, nextX - x, nextY - y);
139 Q_FOREACH (
const QPolygonF &triangle, triangles) {
156 QRect totalRect = path.boundingRect().toAlignedRect();
159 totalRect = totalRect.adjusted(-1,-1,1,1);
162 const int right = totalRect.x() + totalRect.width();
163 const int bottom = totalRect.y() + totalRect.height();
165 for (
int y = totalRect.y(); y < bottom;) {
166 int nextY = qMin((y + step) & ~(step-1), bottom);
168 for (
int x = totalRect.x(); x < right;) {
169 int nextX = qMin((x + step) & ~(step-1), right);
171 QRect
rect(x, y, nextX - x, nextY - y);
173 if(path.intersects(
rect)) {
187 return QLocale().toString(
value,
'f', 1);
192 qreal maxDimension = qMax(
bounds.width(),
bounds.height());
193 return qMax(portion * maxDimension, minValue);
201 Q_FOREACH (
const QPolygonF &poly, inputPolygons) {
202 QPainterPath testPath;
203 testPath.addPolygon(poly);
205 if (resultList.isEmpty()) {
206 resultList.append(testPath);
210 QPainterPath mergedPath = testPath;
212 for (
auto it = resultList.begin(); it != resultList.end(); ) {
213 if (it->intersects(testPath)) {
214 mergedPath.addPath(*it);
215 it = resultList.erase(it);
221 resultList.append(mergedPath);
238 opacity *= parentOpacity;
245 QBitArray flags = childFlags;
247 if (!flags.isEmpty() &&
248 !parentFlags.isEmpty() &&
249 flags.size() == parentFlags.size()) {
251 flags &= parentFlags;
253 }
else if (!parentFlags.isEmpty()) {
262 if (f1.isNull() && f2.isNull())
return true;
265 f1.fill(
true, f2.size());
269 f2.fill(
true, f1.size());
276 return value ? i18n(
"on") : i18n(
"off");
296 p->drawRect(rc.adjusted(0,0,-1,-1));
301 QPen oldPen =
p->pen();
309 QImage dstImage(image.size(), QImage::Format_ARGB32);
312 const QSize size = image.size();
313 for(
int y = 0; y < size.height(); ++y) {
314 for(
int x = 0; x < size.width(); ++x) {
315 const QRgb pixel = image.pixel(x,y);
316 const int gray = qGray(pixel);
317 dstImage.setPixel(x, y, qRgba(gray, gray, gray, qAlpha(pixel)));
335 quint8 *dstPtr = dstIt.
rawData();
336 *dstPtr = func(*dstPtr);
343 const qreal linearPortion = std::sqrt(samplePortion);
344 const qreal ratio = qreal(
rect.width()) /
rect.height();
345 const int xStep = qMax(1, qRound(1.0 / linearPortion * ratio));
346 const int yStep = qMax(1, qRound(1.0 / linearPortion / ratio));
348 int numTransparentPixels = 0;
352 for (
int y =
rect.y(); y <=
rect.bottom(); y += yStep) {
353 for (
int x =
rect.x(); x <=
rect.right(); x += xStep) {
358 numTransparentPixels++;
365 if (numPixels == 0) {
368 return qreal(numTransparentPixels) / numPixels;
375 if (dir == Qt::Horizontal) {
376 const int mirrorX = -((rc.x() + rc.width()) - center.x()) + center.x();
378 if (!skipMirrorPixels) {
381 dab->
offset.rx() = mirrorX;
383 const int mirrorY = -((rc.y() + rc.height()) - center.y()) + center.y();
385 if (!skipMirrorPixels) {
388 dab->
offset.ry() = mirrorY;
396 if (dir == Qt::Horizontal) {
397 const int mirrorX = -((rc.x() + rc.width()) - center.x()) + center.x();
399 if (!skipMirrorPixels) {
402 dab->
offset.rx() = mirrorX;
404 const int mirrorY = -((rc.y() + rc.height()) - center.y()) + center.y();
406 if (!skipMirrorPixels) {
409 dab->
offset.ry() = mirrorY;
413 void mirrorRect(Qt::Orientation dir,
const QPoint ¢er, QRect *rc)
415 if (dir == Qt::Horizontal) {
416 const int mirrorX = -((rc->x() + rc->width()) - center.x()) + center.x();
417 rc->moveLeft(mirrorX);
419 const int mirrorY = -((rc->y() + rc->height()) - center.y()) + center.y();
420 rc->moveTop(mirrorY);
424 void mirrorRect(Qt::Orientation dir,
const QPointF ¢er, QRect *rc)
426 if (dir == Qt::Horizontal) {
427 const int mirrorX = -((rc->x() + rc->width()) - center.x()) + center.x();
428 rc->moveLeft(mirrorX);
430 const int mirrorY = -((rc->y() + rc->height()) - center.y()) + center.y();
431 rc->moveTop(mirrorY);
435 void mirrorPoint(Qt::Orientation dir,
const QPoint ¢er, QPointF *pt)
437 if (dir == Qt::Horizontal) {
438 pt->rx() = -(pt->x() - qreal(center.x())) + center.x();
440 pt->ry() = -(pt->y() - qreal(center.y())) + center.y();
444 void mirrorPoint(Qt::Orientation dir,
const QPointF ¢er, QPointF *pt)
446 if (dir == Qt::Horizontal) {
447 pt->rx() = -(pt->x() - qreal(center.x())) + center.x();
449 pt->ry() = -(pt->y() - qreal(center.y())) + center.y();
455 return QTransform::fromScale(image->
xRes(), image->
yRes());
460 path.setFillRule(Qt::WindingFill);
463 path = QPainterPath();
464 path.setFillRule(Qt::WindingFill);
465 Q_FOREACH (QPolygonF poly, polys) {
467 if (!poly.isClosed()) {
468 poly.append(poly.first());
470 path.addPolygon(poly);
523 rasterizeHLine(startPoint, endPoint, [&points](
const QPoint &point) { points.append(point); });
530 rasterizeVLine(startPoint, endPoint, [&points](
const QPoint &point) { points.append(point); });
537 rasterizeLineDDA(startPoint, endPoint, [&points](
const QPoint &point) { points.append(point); });
551 rasterizePolygonDDA(polygonPoints, [&points](
const QPoint &point) { points.append(point); });
float value(const T *src, size_t ch)
const qreal OPACITY_OPAQUE_F
const quint8 OPACITY_OPAQUE_U8
virtual const quint8 * rawDataConst() const =0
void mirror(bool horizontal, bool vertical)
int updatePatchWidth() const
int updatePatchHeight() const
KisRandomConstAccessorSP createRandomConstAccessorNG() const
void fill(const QRect &rc, const KoColor &color)
const KoColorSpace * colorSpace() const
virtual void moveTo(qint32 x, qint32 y)=0
QVector< QRect > rects() const
bool nextPixels(int numPixels)
ALWAYS_INLINE quint8 * rawData()
int nConseqPixels() const
ALWAYS_INLINE const quint8 * rawDataConst() const
virtual void setOpacity(quint8 *pixels, quint8 alpha, qint32 nPixels) const =0
virtual quint8 opacityU8(const quint8 *pixel) const =0
static bool qFuzzyCompare(half p1, half p2)
qreal KRITAIMAGE_EXPORT maxDimensionPortion(const QRectF &bounds, qreal portion, qreal minValue)
QVector< QRect > splitRectIntoPatches(const QRect &rc, const QSize &patchSize)
quint8 mergeOpacityU8(quint8 opacity, quint8 parentOpacity)
void filterAlpha8Device(KisPaintDeviceSP dev, const QRect &rc, std::function< quint8(quint8)> func)
bool compareChannelFlags(QBitArray f1, QBitArray f2)
QString KRITAIMAGE_EXPORT toLocalizedOnOff(bool value)
void thresholdOpacity(KisPaintDeviceSP device, const QRect &rect, ThresholdMode mode)
QVector< QPoint > rasterizeLineDDA(const QPoint &startPoint, const QPoint &endPoint)
QString KRITAIMAGE_EXPORT prettyFormatReal(qreal value)
KisRegion splitPath(const QPainterPath &path)
QVector< QPoint > rasterizePolygonDDA(const QVector< QPoint > &polygonPoints)
QTransform pathShapeBooleanSpaceWorkaround(KisImageSP image)
KisNodeSP nearestNodeAfterRemoval(KisNodeSP node)
qreal mergeOpacityF(qreal opacity, qreal parentOpacity)
QImage convertQImageToGrayA(const QImage &image)
QPainterPath tryCloseTornSubpathsAfterIntersection(QPainterPath path)
QVector< QRect > splitRegionIntoPatches(const KisRegion ®ion, const QSize &patchSize)
qreal estimatePortionOfTransparentPixels(KisPaintDeviceSP dev, const QRect &rect, qreal samplePortion)
void mirrorDab(Qt::Orientation dir, const QPoint ¢er, KisRenderedDab *dab, bool skipMirrorPixels)
bool checkInTriangle(const QRectF &rect, const QPolygonF &triangle)
QList< QPainterPath > splitDisjointPaths(const QPainterPath &path)
void applyToAlpha8Device(KisPaintDeviceSP dev, const QRect &rc, std::function< void(quint8)> func)
QBitArray mergeChannelFlags(const QBitArray &childFlags, const QBitArray &parentFlags)
QVector< QPoint > rasterizeVLine(const QPoint &startPoint, const QPoint &endPoint)
KisRegion splitTriangles(const QPointF ¢er, const QVector< QPointF > &points)
QVector< QRect > splitRectIntoPatchesTight(const QRect &rc, const QSize &patchSize)
void thresholdOpacityAlpha8(KisPaintDeviceSP device, const QRect &rect, ThresholdMode mode)
void mirrorPoint(Qt::Orientation dir, const QPoint ¢er, QPointF *pt)
void mirrorRect(Qt::Orientation dir, const QPoint ¢er, QRect *rc)
void renderExactRect(QPainter *p, const QRect &rc)
QVector< QPoint > rasterizeHLine(const QPoint &startPoint, const QPoint &endPoint)
QVector< QPoint > rasterizePolylineDDA(const QVector< QPoint > &polylinePoints)
KisNodeSP prevSibling() const
KisNodeSP nextSibling() const
KisFixedPaintDeviceSP device