Paste P137

Fix rounding in wrap around mode for KisPainter
ActivePublic

Authored by alvinhochun on Nov 19 2017, 4:32 PM.
commit b4d0e46ea81503b3bf5db43383952ffeb491fc42
Author: Alvin Wong <alvinhochun@gmail.com>
Date: Mon Nov 20 00:07:55 2017 +0800
change rounding method
diff --git a/libs/image/kis_painter.cc b/libs/image/kis_painter.cc
index 1e7a5be599..eac1b06d2c 100644
--- a/libs/image/kis_painter.cc
+++ b/libs/image/kis_painter.cc
@@ -73,10 +73,6 @@
// Maximum distance from a Bezier control point to the line through the start
// and end points for the curve to be considered flat.
#define BEZIER_FLATNESS_THRESHOLD 0.5
-#define trunc(x) ((int)(x))
-#ifndef Q_OS_WIN
-
-#endif
struct Q_DECL_HIDDEN KisPainter::Private {
Private(KisPainter *_q) : q(_q) {}
@@ -1547,10 +1543,10 @@ inline void KisPainter::compositeOnePixel(quint8 *dst, const KoColor &color)
/**/
void KisPainter::drawLine(const QPointF& start, const QPointF& end, qreal width, bool antialias){
- int x1 = start.x();
- int y1 = start.y();
- int x2 = end.x();
- int y2 = end.y();
+ int x1 = qFloor(start.x());
+ int y1 = qFloor(start.y());
+ int x2 = qFloor(end.x());
+ int y2 = qFloor(end.y());
if ((x2 == x1 ) && (y2 == y1)) return;
@@ -1636,11 +1632,11 @@ void KisPainter::drawLine(const QPointF & start, const QPointF & end)
void KisPainter::drawDDALine(const QPointF & start, const QPointF & end)
{
- int x = int(start.x());
- int y = int(start.y());
+ int x = qFloor(start.x());
+ int y = qFloor(start.y());
- int x2 = int(end.x());
- int y2 = int(end.y());
+ int x2 = qFloor(end.x());
+ int y2 = qFloor(end.y());
// Width and height of the line
int xd = x2 - x;
@@ -1702,19 +1698,19 @@ void KisPainter::drawDDALine(const QPointF & start, const QPointF & end)
void KisPainter::drawWobblyLine(const QPointF & start, const QPointF & end)
{
- KisRandomAccessorSP accessor = d->device->createRandomAccessorNG(start.x(), start.y());
+ KoColor mycolor(d->paintColor);
+
+ int x1 = qFloor(start.x());
+ int y1 = qFloor(start.y());
+ int x2 = qFloor(end.x());
+ int y2 = qFloor(end.y());
+
+ KisRandomAccessorSP accessor = d->device->createRandomAccessorNG(x1, y1);
KisRandomConstAccessorSP selectionAccessor;
if (d->selection) {
- selectionAccessor = d->selection->projection()->createRandomConstAccessorNG(start.x(), start.y());
+ selectionAccessor = d->selection->projection()->createRandomConstAccessorNG(x1, y1);
}
- KoColor mycolor(d->paintColor);
-
- int x1 = start.x();
- int y1 = start.y();
- int x2 = end.x();
- int y2 = end.y();
-
// Width and height of the line
int xd = (x2 - x1);
int yd = (y2 - y1);
@@ -1735,8 +1731,8 @@ void KisPainter::drawWobblyLine(const QPointF & start, const QPointF & end)
y = y + inc;
x = qRound(fx);
- float br1 = int(fx + 1) - fx;
- float br2 = fx - (int)fx;
+ float br1 = qFloor(fx + 1) - fx;
+ float br2 = fx - qFloor(fx);
accessor->moveTo(x, y);
if (selectionAccessor) selectionAccessor->moveTo(x, y);
@@ -1762,8 +1758,8 @@ void KisPainter::drawWobblyLine(const QPointF & start, const QPointF & end)
x = x + inc;
y = qRound(fy);
- float br1 = int(fy + 1) - fy;
- float br2 = fy - (int)fy;
+ float br1 = qFloor(fy + 1) - fy;
+ float br2 = fy - qFloor(fy);
accessor->moveTo(x, y);
if (selectionAccessor) selectionAccessor->moveTo(x, y);
@@ -1787,19 +1783,18 @@ void KisPainter::drawWobblyLine(const QPointF & start, const QPointF & end)
void KisPainter::drawWuLine(const QPointF & start, const QPointF & end)
{
- KisRandomAccessorSP accessor = d->device->createRandomAccessorNG(start.x(), start.y());
- KisRandomConstAccessorSP selectionAccessor;
- if (d->selection) {
- selectionAccessor = d->selection->projection()->createRandomConstAccessorNG(start.x(), start.y());
- }
-
KoColor lineColor(d->paintColor);
- int x1 = start.x();
- int y1 = start.y();
- int x2 = end.x();
- int y2 = end.y();
+ int x1 = qFloor(start.x());
+ int y1 = qFloor(start.y());
+ int x2 = qFloor(end.x());
+ int y2 = qFloor(end.y());
+ KisRandomAccessorSP accessor = d->device->createRandomAccessorNG(x1, y1);
+ KisRandomConstAccessorSP selectionAccessor;
+ if (d->selection) {
+ selectionAccessor = d->selection->projection()->createRandomConstAccessorNG(x1, y1);
+ }
float grad, xd, yd;
float xgap, ygap, xend, yend, yf, xf;
@@ -1854,21 +1849,20 @@ void KisPainter::drawWuLine(const QPointF & start, const QPointF & end)
// horizontal line
// line have to be paint from left to right
if (x1 > x2) {
- float tmp;
- tmp = x1; x1 = x2; x2 = tmp;
- tmp = y1; y1 = y2; y2 = tmp;
+ std::swap(x1, x2);
+ std::swap(y1, y2);
xd = (x2 - x1);
yd = (y2 - y1);
}
grad = yd / xd;
// nearest X,Y interger coordinates
- xend = static_cast<int>(x1 + 0.5f);
+ xend = x1;
yend = y1 + grad * (xend - x1);
xgap = invertFrac(x1 + 0.5f);
- ix1 = static_cast<int>(xend);
- iy1 = static_cast<int>(yend);
+ ix1 = x1;
+ iy1 = qFloor(yend);
// calc the intensity of the other end point pixel pair.
brightness1 = invertFrac(yend) * xgap;
@@ -1896,13 +1890,13 @@ void KisPainter::drawWuLine(const QPointF & start, const QPointF & end)
// calc first Y-intersection for main loop
yf = yend + grad;
- xend = trunc(x2 + 0.5f);
+ xend = x2;
yend = y2 + grad * (xend - x2);
xgap = invertFrac(x2 - 0.5f);
- ix2 = static_cast<int>(xend);
- iy2 = static_cast<int>(yend);
+ ix2 = x2;
+ iy2 = qFloor(yend);
brightness1 = invertFrac(yend) * xgap;
brightness2 = frac(yend) * xgap;
@@ -1933,16 +1927,16 @@ void KisPainter::drawWuLine(const QPointF & start, const QPointF & end)
c1 = (int)(brightness1 * OPACITY_OPAQUE_U8);
c2 = (int)(brightness2 * OPACITY_OPAQUE_U8);
- accessor->moveTo(x, int (yf));
- if (selectionAccessor) selectionAccessor->moveTo(x, int (yf));
+ accessor->moveTo(x, qFloor(yf));
+ if (selectionAccessor) selectionAccessor->moveTo(x, qFloor(yf));
if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
lineColor.setOpacity(c1);
compositeOnePixel(accessor->rawData(), lineColor);
}
- accessor->moveTo(x, int (yf) + 1);
- if (selectionAccessor) selectionAccessor->moveTo(x, int (yf) + 1);
+ accessor->moveTo(x, qFloor(yf) + 1);
+ if (selectionAccessor) selectionAccessor->moveTo(x, qFloor(yf) + 1);
if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
lineColor.setOpacity(c2);
@@ -1955,9 +1949,8 @@ void KisPainter::drawWuLine(const QPointF & start, const QPointF & end)
//vertical
// line have to be painted from left to right
if (y1 > y2) {
- float tmp;
- tmp = x1; x1 = x2; x2 = tmp;
- tmp = y1; y1 = y2; y2 = tmp;
+ std::swap(x1, x2);
+ std::swap(y1, y2);
xd = (x2 - x1);
yd = (y2 - y1);
}
@@ -1965,13 +1958,13 @@ void KisPainter::drawWuLine(const QPointF & start, const QPointF & end)
grad = xd / yd;
// nearest X,Y interger coordinates
- yend = static_cast<int>(y1 + 0.5f);
+ yend = y1;
xend = x1 + grad * (yend - y1);
- ygap = invertFrac(y1 + 0.5f);
+ ygap = y1;
- ix1 = static_cast<int>(xend);
- iy1 = static_cast<int>(yend);
+ ix1 = qFloor(xend);
+ iy1 = y1;
// calc the intensity of the other end point pixel pair.
brightness1 = invertFrac(xend) * ygap;
@@ -1999,13 +1992,13 @@ void KisPainter::drawWuLine(const QPointF & start, const QPointF & end)
// calc first Y-intersection for main loop
xf = xend + grad;
- yend = trunc(y2 + 0.5f);
+ yend = y2;
xend = x2 + grad * (yend - y2);
ygap = invertFrac(y2 - 0.5f);
- ix2 = static_cast<int>(xend);
- iy2 = static_cast<int>(yend);
+ ix2 = qFloor(xend);
+ iy2 = y2;
brightness1 = invertFrac(xend) * ygap;
brightness2 = frac(xend) * ygap;
@@ -2036,16 +2029,16 @@ void KisPainter::drawWuLine(const QPointF & start, const QPointF & end)
c1 = (int)(brightness1 * OPACITY_OPAQUE_U8);
c2 = (int)(brightness2 * OPACITY_OPAQUE_U8);
- accessor->moveTo(int (xf), y);
- if (selectionAccessor) selectionAccessor->moveTo(int (xf), y);
+ accessor->moveTo(qFloor(xf), y);
+ if (selectionAccessor) selectionAccessor->moveTo(qFloor(xf), y);
if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
lineColor.setOpacity(c1);
compositeOnePixel(accessor->rawData(), lineColor);
}
- accessor->moveTo(int (xf) + 1, y);
- if (selectionAccessor) selectionAccessor->moveTo(int (xf) + 1, y);
+ accessor->moveTo(qFloor(xf) + 1, y);
+ if (selectionAccessor) selectionAccessor->moveTo(qFloor(xf) + 1, y);
if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
lineColor.setOpacity(c2);
@@ -2235,11 +2228,11 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
yfb = y0b + gradb;
for (x = ix1 + 1; x <= ix2 - 1; x++) {
- fraca = yfa - int (yfa);
+ fraca = yfa - qFloor(yfa);
b1a = 1 - fraca;
b2a = fraca;
- fracb = yfb - int (yfb);
+ fracb = yfb - qFloor(yfb);
b1b = 1 - fracb;
b2b = fracb;
@@ -2247,8 +2240,8 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
opacity = ((x - ix1) / dstX) * c2.opacityF() + (1 - (x - ix1) / dstX) * c1.opacityF();
c3.setOpacity(opacity);
- accessor->moveTo(x, (int)yfa);
- if (selectionAccessor) selectionAccessor->moveTo(x, (int)yfa);
+ accessor->moveTo(x, qFloor(yfa));
+ if (selectionAccessor) selectionAccessor->moveTo(x, qFloor(yfa));
if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
qreal alpha = cs->opacityF(accessor->rawData());
@@ -2259,8 +2252,8 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
// color first pixel of top line
if (!(startWidth == 1 && endWidth == 1)) {
- accessor->moveTo(x, (int)yfb);
- if (selectionAccessor) selectionAccessor->moveTo(x, (int)yfb);
+ accessor->moveTo(x, qFloor(yfb));
+ if (selectionAccessor) selectionAccessor->moveTo(x, qFloor(yfb));
if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
qreal alpha = cs->opacityF(accessor->rawData());
@@ -2273,8 +2266,8 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
// color second pixel of bottom line
if (grada != 0 && grada != 1) { // if not flat or exact diagonal
- accessor->moveTo(x, int (yfa) + 1);
- if (selectionAccessor) selectionAccessor->moveTo(x, int (yfa) + 1);
+ accessor->moveTo(x, qFloor(yfa) + 1);
+ if (selectionAccessor) selectionAccessor->moveTo(x, qFloor(yfa) + 1);
if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
qreal alpha = cs->opacityF(accessor->rawData());
@@ -2288,8 +2281,8 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
// color second pixel of top line
if (gradb != 0 && gradb != 1 && !(startWidth == 1 && endWidth == 1)) {
- accessor->moveTo(x, int (yfb) + 1);
- if (selectionAccessor) selectionAccessor->moveTo(x, int (yfb) + 1);
+ accessor->moveTo(x, qFloor(yfb) + 1);
+ if (selectionAccessor) selectionAccessor->moveTo(x, qFloor(yfb) + 1);
if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
qreal alpha = cs->opacityF(accessor->rawData());
@@ -2303,7 +2296,7 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
// fill remaining pixels
if (!(startWidth == 1 && endWidth == 1)) {
if (yfa < yfb)
- for (int i = yfa + 1; i <= yfb; i++) {
+ for (int i = qFloor(yfa) + 1; i <= qFloor(yfb); i++) {
accessor->moveTo(x, i);
if (selectionAccessor) selectionAccessor->moveTo(x, i);
@@ -2313,7 +2306,7 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
}
}
else
- for (int i = yfa + 1; i >= yfb; i--) {
+ for (int i = qFloor(yfa) + 1; i >= qFloor(yfb); i--) {
accessor->moveTo(x, i);
if (selectionAccessor) selectionAccessor->moveTo(x, i);
@@ -2353,11 +2346,11 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
xfb = x0b + gradb;
for (y = iy1 + 1; y <= iy2 - 1; y++) {
- fraca = xfa - int (xfa);
+ fraca = xfa - qFloor(xfa);
b1a = 1 - fraca;
b2a = fraca;
- fracb = xfb - int (xfb);
+ fracb = xfb - qFloor(xfb);
b1b = 1 - fracb;
b2b = fracb;
@@ -2365,8 +2358,8 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
opacity = ((y - iy1) / dstY) * c2.opacityF() + (1 - (y - iy1) / dstY) * c1.opacityF();
c3.setOpacity(opacity);
- accessor->moveTo(int (xfa), y);
- if (selectionAccessor) selectionAccessor->moveTo(int (xfa), y);
+ accessor->moveTo(qFloor(xfa), y);
+ if (selectionAccessor) selectionAccessor->moveTo(qFloor(xfa), y);
if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
qreal alpha = cs->opacityF(accessor->rawData());
@@ -2378,8 +2371,8 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
// color first pixel of right line
if (!(startWidth == 1 && endWidth == 1)) {
- accessor->moveTo(int(xfb), y);
- if (selectionAccessor) selectionAccessor->moveTo(int(xfb), y);
+ accessor->moveTo(qFloor(xfb), y);
+ if (selectionAccessor) selectionAccessor->moveTo(qFloor(xfb), y);
if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
qreal alpha = cs->opacityF(accessor->rawData());
@@ -2392,8 +2385,8 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
// color second pixel of left line
if (grada != 0 && grada != 1) { // if not flat or exact diagonal
- accessor->moveTo(int(xfa) + 1, y);
- if (selectionAccessor) selectionAccessor->moveTo(int(xfa) + 1, y);
+ accessor->moveTo(qFloor(xfa) + 1, y);
+ if (selectionAccessor) selectionAccessor->moveTo(qFloor(xfa) + 1, y);
if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
qreal alpha = cs->opacityF(accessor->rawData());
@@ -2407,8 +2400,8 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
// color second pixel of right line
if (gradb != 0 && gradb != 1 && !(startWidth == 1 && endWidth == 1)) {
- accessor->moveTo(int(xfb) + 1, y);
- if (selectionAccessor) selectionAccessor->moveTo(int(xfb) + 1, y);
+ accessor->moveTo(qFloor(xfb) + 1, y);
+ if (selectionAccessor) selectionAccessor->moveTo(qFloor(xfb) + 1, y);
if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
qreal alpha = cs->opacityF(accessor->rawData());
@@ -2421,7 +2414,7 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
// fill remaining pixels between current xfa,xfb
if (!(startWidth == 1 && endWidth == 1)) {
if (xfa < xfb)
- for (int i = (int) xfa + 1; i <= (int) xfb; i++) {
+ for (int i = qFloor(xfa) + 1; i <= qFloor(xfb); i++) {
accessor->moveTo(i, y);
if (selectionAccessor) selectionAccessor->moveTo(i, y);
@@ -2431,7 +2424,7 @@ void KisPainter::drawThickLine(const QPointF & start, const QPointF & end, int s
}
}
else
- for (int i = (int) xfb; i <= (int) xfa + 1; i++) {
+ for (int i = qFloor(xfb); i <= qFloor(xfa) + 1; i++) {
accessor->moveTo(i, y);
if (selectionAccessor) selectionAccessor->moveTo(i, y);