diff options
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/qgrayraster.c | 50 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 9 | ||||
-rw-r--r-- | src/gui/painting/qpaintengineex.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 10 | ||||
-rw-r--r-- | src/gui/painting/qpdf.cpp | 18 | ||||
-rw-r--r-- | src/gui/painting/qpdf_p.h | 2 | ||||
-rw-r--r-- | src/gui/painting/qrasterdefs_p.h | 3 | ||||
-rw-r--r-- | src/gui/painting/qrasterizer.cpp | 178 | ||||
-rw-r--r-- | src/gui/painting/qstroker.cpp | 9 | ||||
-rw-r--r-- | src/gui/painting/qstroker_p.h | 3 |
10 files changed, 157 insertions, 127 deletions
diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index 94039fb..ec9ebeb 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -233,7 +233,7 @@ /* new algorithms */ typedef int TCoord; /* integer scanline/pixel coordinate */ - typedef long TPos; /* sub-pixel coordinate */ + typedef int TPos; /* sub-pixel coordinate */ /* determine the type used to store cell areas. This normally takes at */ /* least PIXEL_BITS*2 + 1 bits. On 16-bit systems, we need to use */ @@ -317,6 +317,7 @@ PCell* ycells; int ycount; + int skip_spans; } TWorker, *PWorker; @@ -324,13 +325,19 @@ { void* buffer; long buffer_size; + long buffer_allocated_size; int band_size; void* memory; PWorker worker; } TRaster, *PRaster; - + int q_gray_rendered_spans(TRaster *raster) + { + if ( raster && raster->worker ) + return raster->worker->skip_spans > 0 ? 0 : -raster->worker->skip_spans; + return 0; + } /*************************************************************************/ /* */ @@ -538,7 +545,7 @@ TCoord y2 ) { TCoord ex1, ex2, fx1, fx2, delta; - long p, first, dx; + int p, first, dx; int incr, lift, mod, rem; @@ -643,7 +650,7 @@ { TCoord ey1, ey2, fy1, fy2; TPos dx, dy, x, x2; - long p, first; + int p, first; int delta, rem, mod, lift, incr; @@ -1178,6 +1185,7 @@ { QT_FT_Span* span; int coverage; + int skip; /* compute the coverage line's coverage, depending on the */ @@ -1228,9 +1236,16 @@ if ( ras.num_gray_spans >= QT_FT_MAX_GRAY_SPANS ) { - if ( ras.render_span ) - ras.render_span( ras.num_gray_spans, ras.gray_spans, + if ( ras.render_span && ras.num_gray_spans > ras.skip_spans ) + { + skip = ras.skip_spans > 0 ? ras.skip_spans : 0; + ras.render_span( ras.num_gray_spans - skip, + ras.gray_spans + skip, ras.render_span_data ); + } + + ras.skip_spans -= ras.num_gray_spans; + /* ras.render_span( span->y, ras.gray_spans, count ); */ #ifdef DEBUG_GRAYS @@ -1600,7 +1615,8 @@ TBand* volatile band; int volatile n, num_bands; TPos volatile min, max, max_y; - QT_FT_BBox* clip; + QT_FT_BBox* clip; + int skip; ras.num_gray_spans = 0; @@ -1670,7 +1686,7 @@ { PCell cells_max; int yindex; - long cell_start, cell_end, cell_mod; + int cell_start, cell_end, cell_mod; ras.ycells = (PCell*)ras.buffer; @@ -1741,9 +1757,15 @@ } } - if ( ras.render_span && ras.num_gray_spans > 0 ) - ras.render_span( ras.num_gray_spans, - ras.gray_spans, ras.render_span_data ); + if ( ras.render_span && ras.num_gray_spans > ras.skip_spans ) + { + skip = ras.skip_spans > 0 ? ras.skip_spans : 0; + ras.render_span( ras.num_gray_spans - skip, + ras.gray_spans + skip, + ras.render_span_data ); + } + + ras.skip_spans -= ras.num_gray_spans; if ( ras.band_shoot > 8 && ras.band_size > 16 ) ras.band_size = ras.band_size / 2; @@ -1764,10 +1786,13 @@ if ( !raster || !raster->buffer || !raster->buffer_size ) return ErrRaster_Invalid_Argument; + if ( raster->worker ) + raster->worker->skip_spans = params->skip_spans; + // If raster object and raster buffer are allocated, but // raster size isn't of the minimum size, indicate out of // memory. - if (raster && raster->buffer && raster->buffer_size < MINIMUM_POOL_SIZE ) + if (raster->buffer_allocated_size < MINIMUM_POOL_SIZE ) return ErrRaster_OutOfMemory; /* return immediately if the outline is empty */ @@ -1906,6 +1931,7 @@ rast->buffer_size = 0; rast->worker = NULL; } + rast->buffer_allocated_size = pool_size; } } diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 94d7578..dbf7b26 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -4136,6 +4136,10 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, rasterize(outline, callback, (void *)spanData, rasterBuffer); } +extern "C" { + int q_gray_rendered_spans(QT_FT_Raster raster); +} + void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *) @@ -4200,10 +4204,13 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, bool done = false; int error; + int rendered_spans = 0; + while (!done) { rasterParams.flags |= (QT_FT_RASTER_FLAG_AA | QT_FT_RASTER_FLAG_DIRECT); rasterParams.gray_spans = callback; + rasterParams.skip_spans = rendered_spans; error = qt_ft_grays_raster.raster_render(*grayRaster.data(), &rasterParams); // Out of memory, reallocate some more and try again... @@ -4214,6 +4221,8 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, break; } + rendered_spans += q_gray_rendered_spans(*grayRaster.data()); + #if defined(Q_WS_WIN64) _aligned_free(rasterPoolBase); #else diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 1e857e4..c1e3d66 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -517,7 +517,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath()); d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform()); } else { - d->activeStroker->setCurveThresholdFromTransform(state()->matrix); + d->activeStroker->setCurveThresholdFromTransform(QTransform()); d->activeStroker->begin(d->strokeHandler); if (types) { while (points < lastPoint) { diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 35a74c9..b0ca6ed 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -2780,7 +2780,7 @@ void QPainter::setClipRect(const QRectF &rect, Qt::ClipOperation op) Q_D(QPainter); if (d->extended) { - if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip)) + if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip)) op = Qt::ReplaceClip; if (!d->engine) { @@ -2838,7 +2838,7 @@ void QPainter::setClipRect(const QRect &rect, Qt::ClipOperation op) return; } - if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip)) + if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip)) op = Qt::ReplaceClip; if (d->extended) { @@ -2893,7 +2893,7 @@ void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op) return; } - if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip)) + if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip)) op = Qt::ReplaceClip; if (d->extended) { @@ -3298,7 +3298,7 @@ void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation op) return; } - if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip)) + if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip)) op = Qt::ReplaceClip; if (d->extended) { @@ -6311,7 +6311,7 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF * By default, QPainter draws text anti-aliased. - \note The y-position is used as the baseline of the font. + \note The y-position is used as the top of the font. \sa Qt::AlignmentFlag, Qt::TextFlag */ diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 6e02435..ba5d164 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -916,24 +916,6 @@ const char *QPdf::paperSizeToString(QPrinter::PaperSize paperSize) } -QByteArray QPdf::stripSpecialCharacters(const QByteArray &string) -{ - QByteArray s = string; - s.replace(' ', ""); - s.replace('(', ""); - s.replace(')', ""); - s.replace('<', ""); - s.replace('>', ""); - s.replace('[', ""); - s.replace(']', ""); - s.replace('{', ""); - s.replace('}', ""); - s.replace('/', ""); - s.replace('%', ""); - return s; -} - - // -------------------------- base engine, shared code between PS and PDF ----------------------- QPdfBaseEngine::QPdfBaseEngine(QPdfBaseEnginePrivate &dd, PaintEngineFeatures f) diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index 9c4d05d..5c5ceb4 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -156,8 +156,6 @@ namespace QPdf { PaperSize paperSize(QPrinter::PaperSize paperSize); const char *paperSizeToString(QPrinter::PaperSize paperSize); - - QByteArray stripSpecialCharacters(const QByteArray &string); } diff --git a/src/gui/painting/qrasterdefs_p.h b/src/gui/painting/qrasterdefs_p.h index 19a0b16..f6339ed 100644 --- a/src/gui/painting/qrasterdefs_p.h +++ b/src/gui/painting/qrasterdefs_p.h @@ -100,7 +100,7 @@ QT_FT_BEGIN_HEADER /* distances in integer font units, or 16,16, or 26.6 fixed float */ /* pixel coordinates. */ /* */ - typedef signed long QT_FT_Pos; + typedef signed int QT_FT_Pos; /*************************************************************************/ @@ -1088,6 +1088,7 @@ QT_FT_BEGIN_HEADER QT_FT_Raster_BitSet_Func bit_set; /* doesn't work! */ void* user; QT_FT_BBox clip_box; + int skip_spans; } QT_FT_Raster_Params; diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp index c92d8d5..9d89b10 100644 --- a/src/gui/painting/qrasterizer.cpp +++ b/src/gui/painting/qrasterizer.cpp @@ -65,6 +65,12 @@ typedef int Q16Dot16; #define COORD_ROUNDING 0 // 0: round up, 1: round down #define COORD_OFFSET 0 // 26.6, 32 is half a pixel +static inline QT_FT_Vector PointToVector(const QPointF &p) +{ + QT_FT_Vector result = { QT_FT_Pos(p.x() * 64), QT_FT_Pos(p.y() * 64) }; + return result; +} + class QSpanBuffer { public: QSpanBuffer(ProcessSpans blend, void *data, const QRect &clipRect) @@ -693,9 +699,9 @@ static Q16Dot16 intersectPixelFP(int x, Q16Dot16 top, Q16Dot16 bottom, Q16Dot16 } } -static inline bool q16Dot16Compare(qreal p1, qreal p2) +static inline bool q26Dot6Compare(qreal p1, qreal p2) { - return FloatToQ16Dot16(p2 - p1) == 0; + return int((p2 - p1) * 64.) == 0; } static inline qreal qFloorF(qreal v) @@ -708,6 +714,12 @@ static inline qreal qFloorF(qreal v) return floor(v); } +static inline QPointF snapTo26Dot6Grid(const QPointF &p) +{ + return QPointF(qFloorF(p.x() * 64) * (1 / qreal(64)), + qFloorF(p.y() * 64) * (1 / qreal(64))); +} + void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bool squareCap) { if (a == b || width == 0 || d->clipRect.isEmpty()) @@ -718,17 +730,21 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, QPointF pa = a; QPointF pb = b; + if (squareCap) { + QPointF delta = pb - pa; + pa -= (0.5f * width) * delta; + pb += (0.5f * width) * delta; + } + QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5; - if (squareCap) - offs += QPointF(offs.y(), offs.x()); const QRectF clip(d->clipRect.topLeft() - offs, d->clipRect.bottomRight() + QPoint(1, 1) + offs); - if (!clip.contains(a) || !clip.contains(b)) { + if (!clip.contains(pa) || !clip.contains(pb)) { qreal t1 = 0; qreal t2 = 1; - const qreal o[2] = { a.x(), a.y() }; - const qreal d[2] = { b.x() - a.x(), b.y() - a.y() }; + const qreal o[2] = { pa.x(), pa.y() }; + const qreal d[2] = { pb.x() - pa.x(), pb.y() - pa.y() }; const qreal low[2] = { clip.left(), clip.top() }; const qreal high[2] = { clip.right(), clip.bottom() }; @@ -751,8 +767,12 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, if (t1 >= t2) return; } - pa = a + (b - a) * t1; - pb = a + (b - a) * t2; + + QPointF npa = pa + (pb - pa) * t1; + QPointF npb = pa + (pb - pa) * t2; + + pa = npa; + pb = npb; } if (!d->antialiased) { @@ -763,15 +783,6 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, } { - const qreal gridResolution = 64; - const qreal reciprocal = 1 / gridResolution; - - // snap to grid to prevent large slopes - pa.rx() = qFloorF(pa.rx() * gridResolution) * reciprocal; - pa.ry() = qFloorF(pa.ry() * gridResolution) * reciprocal; - pb.rx() = qFloorF(pb.rx() * gridResolution) * reciprocal; - pb.ry() = qFloorF(pb.ry() * gridResolution) * reciprocal; - // old delta const QPointF d0 = a - b; const qreal w0 = d0.x() * d0.x() + d0.y() * d0.y(); @@ -789,7 +800,7 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, QSpanBuffer buffer(d->blend, d->data, d->clipRect); - if (q16Dot16Compare(pa.y(), pb.y())) { + if (q26Dot6Compare(pa.y(), pb.y())) { const qreal x = (pa.x() + pb.x()) * 0.5f; const qreal dx = qAbs(pb.x() - pa.x()) * 0.5f; @@ -799,26 +810,16 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, pa = QPointF(x, y - dy); pb = QPointF(x, y + dy); - if (squareCap) - width = 1 / width + 1.0f; - else - width = 1 / width; - - squareCap = false; + width = 1 / width; } - if (q16Dot16Compare(pa.x(), pb.x())) { + if (q26Dot6Compare(pa.x(), pb.x())) { if (pa.y() > pb.y()) qSwap(pa, pb); const qreal dy = pb.y() - pa.y(); const qreal halfWidth = 0.5f * width * dy; - if (squareCap) { - pa.ry() -= halfWidth; - pb.ry() += halfWidth; - } - qreal left = pa.x() - halfWidth; qreal right = pa.x() + halfWidth; @@ -828,7 +829,7 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, pa.ry() = qBound(qreal(d->clipRect.top()), pa.y(), qreal(d->clipRect.bottom() + 1)); pb.ry() = qBound(qreal(d->clipRect.top()), pb.y(), qreal(d->clipRect.bottom() + 1)); - if (q16Dot16Compare(left, right) || q16Dot16Compare(pa.y(), pb.y())) + if (q26Dot6Compare(left, right) || q26Dot6Compare(pa.y(), pb.y())) return; if (d->antialiased) { @@ -899,11 +900,6 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, delta *= 0.5f * width; const QPointF perp(delta.y(), -delta.x()); - if (squareCap) { - pa -= delta; - pb += delta; - } - QPointF top; QPointF left; QPointF right; @@ -921,14 +917,36 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bottom = pb + perp; } + top = snapTo26Dot6Grid(top); + bottom = snapTo26Dot6Grid(bottom); + left = snapTo26Dot6Grid(left); + right = snapTo26Dot6Grid(right); + const qreal topBound = qBound(qreal(d->clipRect.top()), top.y(), qreal(d->clipRect.bottom())); const qreal bottomBound = qBound(qreal(d->clipRect.top()), bottom.y(), qreal(d->clipRect.bottom())); - const qreal leftSlope = (left.x() - top.x()) / (left.y() - top.y()); - const qreal rightSlope = -1.0f / leftSlope; + const QPointF topLeftEdge = left - top; + const QPointF topRightEdge = right - top; + const QPointF bottomLeftEdge = bottom - left; + const QPointF bottomRightEdge = bottom - right; + + const qreal topLeftSlope = topLeftEdge.x() / topLeftEdge.y(); + const qreal bottomLeftSlope = bottomLeftEdge.x() / bottomLeftEdge.y(); + + const qreal topRightSlope = topRightEdge.x() / topRightEdge.y(); + const qreal bottomRightSlope = bottomRightEdge.x() / bottomRightEdge.y(); + + const Q16Dot16 topLeftSlopeFP = FloatToQ16Dot16(topLeftSlope); + const Q16Dot16 topRightSlopeFP = FloatToQ16Dot16(topRightSlope); - const Q16Dot16 leftSlopeFP = FloatToQ16Dot16(leftSlope); - const Q16Dot16 rightSlopeFP = FloatToQ16Dot16(rightSlope); + const Q16Dot16 bottomLeftSlopeFP = FloatToQ16Dot16(bottomLeftSlope); + const Q16Dot16 bottomRightSlopeFP = FloatToQ16Dot16(bottomRightSlope); + + const Q16Dot16 invTopLeftSlopeFP = FloatToQ16Dot16(1 / topLeftSlope); + const Q16Dot16 invTopRightSlopeFP = FloatToQ16Dot16(1 / topRightSlope); + + const Q16Dot16 invBottomLeftSlopeFP = FloatToQ16Dot16(1 / bottomLeftSlope); + const Q16Dot16 invBottomRightSlopeFP = FloatToQ16Dot16(1 / bottomRightSlope); if (d->antialiased) { const Q16Dot16 iTopFP = IntToQ16Dot16(int(topBound)); @@ -936,16 +954,16 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, const Q16Dot16 iRightFP = IntToQ16Dot16(int(right.y())); const Q16Dot16 iBottomFP = IntToQ16Dot16(int(bottomBound)); - Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * leftSlope); - Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * rightSlope); + Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topLeftSlope); + Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topRightSlope); Q16Dot16 leftIntersectBf = 0; Q16Dot16 rightIntersectBf = 0; if (iLeftFP < iTopFP) - leftIntersectBf = FloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * rightSlope); + leftIntersectBf = FloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * bottomLeftSlope); if (iRightFP < iTopFP) - rightIntersectBf = FloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * leftSlope); + rightIntersectBf = FloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * bottomRightSlope); Q16Dot16 rowTop, rowBottomLeft, rowBottomRight, rowTopLeft, rowTopRight, rowBottom; Q16Dot16 topLeftIntersectAf, topLeftIntersectBf, topRightIntersectAf, topRightIntersectBf; @@ -960,9 +978,9 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, rowTop = qMax(iTopFP, yTopFP); topLeftIntersectAf = leftIntersectAf + - Q16Dot16Multiply(leftSlopeFP, rowTop - iTopFP); + Q16Dot16Multiply(topLeftSlopeFP, rowTop - iTopFP); topRightIntersectAf = rightIntersectAf + - Q16Dot16Multiply(rightSlopeFP, rowTop - iTopFP); + Q16Dot16Multiply(topRightSlopeFP, rowTop - iTopFP); Q16Dot16 yFP = iTopFP; while (yFP <= iBottomFP) { @@ -974,30 +992,30 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, if (yFP == iLeftFP) { const int y = Q16Dot16ToInt(yFP); - leftIntersectBf = FloatToQ16Dot16(left.x() + (y - left.y()) * rightSlope); - topLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(rightSlopeFP, rowTopLeft - yFP); - bottomLeftIntersectAf = leftIntersectAf + Q16Dot16Multiply(leftSlopeFP, rowBottomLeft - yFP); + leftIntersectBf = FloatToQ16Dot16(left.x() + (y - left.y()) * bottomLeftSlope); + topLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowTopLeft - yFP); + bottomLeftIntersectAf = leftIntersectAf + Q16Dot16Multiply(topLeftSlopeFP, rowBottomLeft - yFP); } else { topLeftIntersectBf = leftIntersectBf; - bottomLeftIntersectAf = leftIntersectAf + leftSlopeFP; + bottomLeftIntersectAf = leftIntersectAf + topLeftSlopeFP; } if (yFP == iRightFP) { const int y = Q16Dot16ToInt(yFP); - rightIntersectBf = FloatToQ16Dot16(right.x() + (y - right.y()) * leftSlope); - topRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(leftSlopeFP, rowTopRight - yFP); - bottomRightIntersectAf = rightIntersectAf + Q16Dot16Multiply(rightSlopeFP, rowBottomRight - yFP); + rightIntersectBf = FloatToQ16Dot16(right.x() + (y - right.y()) * bottomRightSlope); + topRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowTopRight - yFP); + bottomRightIntersectAf = rightIntersectAf + Q16Dot16Multiply(topRightSlopeFP, rowBottomRight - yFP); } else { topRightIntersectBf = rightIntersectBf; - bottomRightIntersectAf = rightIntersectAf + rightSlopeFP; + bottomRightIntersectAf = rightIntersectAf + topRightSlopeFP; } if (yFP == iBottomFP) { - bottomLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(rightSlopeFP, rowBottom - yFP); - bottomRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(leftSlopeFP, rowBottom - yFP); + bottomLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowBottom - yFP); + bottomRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowBottom - yFP); } else { - bottomLeftIntersectBf = leftIntersectBf + rightSlopeFP; - bottomRightIntersectBf = rightIntersectBf + leftSlopeFP; + bottomLeftIntersectBf = leftIntersectBf + bottomLeftSlopeFP; + bottomRightIntersectBf = rightIntersectBf + bottomRightSlopeFP; } if (yFP < iLeftFP) { @@ -1042,21 +1060,21 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, if (yFP <= iLeftFP) excluded += intersectPixelFP(x, rowTop, rowBottomLeft, bottomLeftIntersectAf, topLeftIntersectAf, - leftSlopeFP, -rightSlopeFP); + topLeftSlopeFP, invTopLeftSlopeFP); if (yFP >= iLeftFP) excluded += intersectPixelFP(x, rowTopLeft, rowBottom, topLeftIntersectBf, bottomLeftIntersectBf, - rightSlopeFP, -leftSlopeFP); + bottomLeftSlopeFP, invBottomLeftSlopeFP); if (x >= rightMin) { if (yFP <= iRightFP) excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, topRightIntersectAf, bottomRightIntersectAf, - rightSlopeFP, -leftSlopeFP); + topRightSlopeFP, invTopRightSlopeFP); if (yFP >= iRightFP) excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, bottomRightIntersectBf, topRightIntersectBf, - leftSlopeFP, -rightSlopeFP); + bottomRightSlopeFP, invBottomRightSlopeFP); } Q16Dot16 coverage = rowHeight - excluded; @@ -1074,11 +1092,11 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, if (yFP <= iRightFP) excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, topRightIntersectAf, bottomRightIntersectAf, - rightSlopeFP, -leftSlopeFP); + topRightSlopeFP, invTopRightSlopeFP); if (yFP >= iRightFP) excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, bottomRightIntersectBf, topRightIntersectBf, - leftSlopeFP, -rightSlopeFP); + bottomRightSlopeFP, invBottomRightSlopeFP); Q16Dot16 coverage = rowHeight - excluded; buffer.addSpan(x, 1, Q16Dot16ToInt(yFP), @@ -1086,10 +1104,10 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, ++x; } - leftIntersectAf += leftSlopeFP; - leftIntersectBf += rightSlopeFP; - rightIntersectAf += rightSlopeFP; - rightIntersectBf += leftSlopeFP; + leftIntersectAf += topLeftSlopeFP; + leftIntersectBf += bottomLeftSlopeFP; + rightIntersectAf += topRightSlopeFP; + rightIntersectBf += bottomRightSlopeFP; topLeftIntersectAf = leftIntersectAf; topRightIntersectAf = rightIntersectAf; @@ -1103,10 +1121,10 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, int iBottom = bottom.y() < 0.5f? -1 : int(bottom.y() - 0.5f); int iMiddle = qMin(iLeft, iRight); - Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + 0.5f + (iTop + 0.5f - top.y()) * leftSlope); - Q16Dot16 leftIntersectBf = FloatToQ16Dot16(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * rightSlope); - Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() - 0.5f + (iTop + 0.5f - top.y()) * rightSlope); - Q16Dot16 rightIntersectBf = FloatToQ16Dot16(right.x() - 0.5f + (iRight + 1.5f - right.y()) * leftSlope); + Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + 0.5f + (iTop + 0.5f - top.y()) * topLeftSlope); + Q16Dot16 leftIntersectBf = FloatToQ16Dot16(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * bottomLeftSlope); + Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() - 0.5f + (iTop + 0.5f - top.y()) * topRightSlope); + Q16Dot16 rightIntersectBf = FloatToQ16Dot16(right.x() - 0.5f + (iRight + 1.5f - right.y()) * bottomRightSlope); int ny; int y = iTop; @@ -1128,10 +1146,10 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, ri += rs; \ } - DO_SEGMENT(iMiddle, leftIntersectAf, rightIntersectAf, leftSlopeFP, rightSlopeFP) - DO_SEGMENT(iRight, leftIntersectBf, rightIntersectAf, rightSlopeFP, rightSlopeFP) - DO_SEGMENT(iLeft, leftIntersectAf, rightIntersectBf, leftSlopeFP, leftSlopeFP) - DO_SEGMENT(iBottom, leftIntersectBf, rightIntersectBf, rightSlopeFP, leftSlopeFP) + DO_SEGMENT(iMiddle, leftIntersectAf, rightIntersectAf, topLeftSlopeFP, topRightSlopeFP) + DO_SEGMENT(iRight, leftIntersectBf, rightIntersectAf, bottomLeftSlopeFP, topRightSlopeFP) + DO_SEGMENT(iLeft, leftIntersectAf, rightIntersectBf, topLeftSlopeFP, bottomRightSlopeFP); + DO_SEGMENT(iBottom, leftIntersectBf, rightIntersectBf, bottomLeftSlopeFP, bottomRightSlopeFP); #undef DO_SEGMENT } } @@ -1183,12 +1201,6 @@ void QRasterizer::rasterize(const QT_FT_Outline *outline, Qt::FillRule fillRule) d->scanConverter.end(); } -static inline QT_FT_Vector PointToVector(const QPointF &p) -{ - QT_FT_Vector result = { QT_FT_Pos(p.x() * 64), QT_FT_Pos(p.y() * 64) }; - return result; -} - void QRasterizer::rasterize(const QPainterPath &path, Qt::FillRule fillRule) { if (path.isEmpty()) diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 9cff339..9decf41 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -190,6 +190,7 @@ static inline qreal adapted_angle_on_x(const QLineF &line) QStrokerOps::QStrokerOps() : m_elements(0) , m_curveThreshold(qt_real_to_fixed(0.25)) + , m_dashThreshold(qt_real_to_fixed(0.25)) , m_customData(0) , m_moveTo(0) , m_lineTo(0) @@ -243,7 +244,7 @@ void QStrokerOps::strokePath(const QPainterPath &path, void *customData, const Q if (path.isEmpty()) return; - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(customData); int count = path.elementCount(); if (matrix.isIdentity()) { @@ -315,7 +316,7 @@ void QStrokerOps::strokePolygon(const QPointF *points, int pointCount, bool impl if (!pointCount) return; - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(data); if (matrix.isIdentity()) { moveTo(qt_real_to_fixed(points[0].x()), qt_real_to_fixed(points[0].y())); @@ -356,7 +357,7 @@ void QStrokerOps::strokeEllipse(const QRectF &rect, void *data, const QTransform } } - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(data); moveTo(qt_real_to_fixed(start.x()), qt_real_to_fixed(start.y())); for (int i=0; i<12; i+=3) { @@ -1142,7 +1143,7 @@ void QDashStroker::processCurrentSubpath() QPainterPath dashPath; - QSubpathFlatIterator it(&m_elements, m_curveThreshold); + QSubpathFlatIterator it(&m_elements, m_dashThreshold); qfixed2d prev = it.next(); bool clipping = !m_clip_rect.isEmpty(); diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h index d646135..5607a8e 100644 --- a/src/gui/painting/qstroker_p.h +++ b/src/gui/painting/qstroker_p.h @@ -168,7 +168,7 @@ public: { qreal scale; qt_scaleForTransform(transform, &scale); - setCurveThreshold(scale == 0 ? qreal(0.5) : (qreal(0.5) / scale)); + m_dashThreshold = scale == 0 ? qreal(0.5) : (qreal(0.5) / scale); } void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; } @@ -184,6 +184,7 @@ protected: QRectF m_clip_rect; qfixed m_curveThreshold; + qfixed m_dashThreshold; void *m_customData; qStrokerMoveToHook m_moveTo; |