diff -r 2f34d5167611 -r fcece45ef507 src/openvg/qpaintengine_vg.cpp --- a/src/openvg/qpaintengine_vg.cpp Fri Apr 16 15:50:13 2010 +0300 +++ b/src/openvg/qpaintengine_vg.cpp Mon May 03 13:17:34 2010 +0300 @@ -131,9 +131,8 @@ void draw(VGPath path, const QPen& pen, const QBrush& brush, VGint rule = VG_EVEN_ODD); void stroke(VGPath path, const QPen& pen); void fill(VGPath path, const QBrush& brush, VGint rule = VG_EVEN_ODD); - inline void releasePath(VGPath path); - VGPath vectorPathToVGPath(const QVectorPath& path, bool forceNewPath = false); - VGPath painterPathToVGPath(const QPainterPath& path, bool forceNewPath = false); + VGPath vectorPathToVGPath(const QVectorPath& path); + VGPath painterPathToVGPath(const QPainterPath& path); VGPath roundedRectPath(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode); VGPaintType setBrush (VGPaint paint, const QBrush& brush, VGMatrixMode mode, @@ -179,13 +178,12 @@ VGPath roundRectPath; // Cached path for quick drawing of rounded rects. #endif - VGPath reusablePath; // Reusable path for vectorPathToVGPath(), etc. - QTransform transform; // Currently active transform. bool simpleTransform; // True if the transform is simple (non-projective). qreal penScale; // Pen scaling factor from "transform". QTransform pathTransform; // Calculated VG path transformation. + QTransform glyphTransform; // Calculated VG glyph transformation. QTransform imageTransform; // Calculated VG image transformation. bool pathTransformSet; // True if path transform set in the VG context. @@ -353,8 +351,6 @@ roundRectPath = 0; #endif - reusablePath = 0; - simpleTransform = true; pathTransformSet = false; penScale = 1.0; @@ -451,15 +447,6 @@ VG_PATH_CAPABILITY_ALL); vgAppendPathData(linePath, 2, segments, coords); #endif - - // This path can be reused over and over by calling vgClearPath(). - reusablePath = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - 32 + 1, // segmentCapacityHint - 32 * 2, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); } void QVGPaintEnginePrivate::destroy() @@ -479,8 +466,6 @@ if (roundRectPath) vgDestroyPath(roundRectPath); #endif - if (reusablePath) - vgDestroyPath(reusablePath); #if !defined(QVG_NO_DRAW_GLYPHS) QVGFontCache::Iterator it; @@ -516,79 +501,67 @@ void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev) { - VGfloat devh = pdev->height() - 1; + VGfloat devh = pdev->height(); // Construct the VG transform by combining the Qt transform with // the following viewport transformation: - // | 1 0 0 | | 1 0 0.5 | | 1 0 0.5 | - // | 0 -1 devh | * | 0 1 -0.5 | = | 0 -1 (0.5 + devh) | - // | 0 0 1 | | 0 0 1 | | 0 0 1 | + // | 1 0 0 | + // | 0 -1 devh | + // | 0 0 1 | + // The glyph transform uses a slightly different transformation: + // | 1 0 0 | | 1 0 0.5 | | 1 0 0.5 | + // | 0 -1 devh - 1 | * | 0 1 -0.5 | = | 0 -1 (devh - 0.5) | + // | 0 0 1 | | 0 0 1 | | 0 0 1 | // The full VG transform is effectively: // 1. Apply the user's transformation matrix. - // 2. Translate by (0.5, -0.5) to correct for Qt and VG putting - // the centre of the pixel at different positions. + // 2. Translate glyphs by an extra (0.5, -0.5). // 3. Flip the co-ordinate system upside down. QTransform viewport(1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, - 0.5f, devh + 0.5f, 1.0f); - - // Compute the path transform and determine if it is projective. - pathTransform = transform * viewport; - bool projective = (pathTransform.m13() != 0.0f || - pathTransform.m23() != 0.0f || - pathTransform.m33() != 1.0f); - + 0.0f, devh, 1.0f); + QTransform gviewport(1.0f, 0.0f, 0.0f, + 0.0f, -1.0f, 0.0f, + 0.5f, devh - 0.5f, 1.0f); + + // Compute the path transform and determine if it is projective. + pathTransform = transform * viewport; + glyphTransform = transform * gviewport; + bool projective = (pathTransform.m13() != 0.0f || + pathTransform.m23() != 0.0f || + pathTransform.m33() != 1.0f); if (projective) { // The engine cannot do projective path transforms for us, // so we will have to convert the co-ordinates ourselves. // Change the matrix to just the viewport transformation. pathTransform = viewport; + glyphTransform = gviewport; simpleTransform = false; } else { simpleTransform = true; } pathTransformSet = false; - // The image transform is always the full transformation, - // because it can be projective. It also does not need the - // (0.5, -0.5) translation because vgDrawImage() implicitly - // adds 0.5 to each co-ordinate. - QTransform viewport2(1.0f, 0.0f, 0.0f, - 0.0f, -1.0f, 0.0f, - 0.0f, devh, 1.0f); - imageTransform = transform * viewport2; + // The image transform is always the full transformation, + imageTransform = transform * viewport; // Calculate the scaling factor to use for turning cosmetic pens // into ordinary non-cosmetic pens. qt_scaleForTransform(transform, &penScale); } -inline void QVGPaintEnginePrivate::releasePath(VGPath path) -{ - if (path == reusablePath) - vgClearPath(path, VG_PATH_CAPABILITY_ALL); - else - vgDestroyPath(path); -} - -VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path, bool forceNewPath) +VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path) { int count = path.elementCount(); const qreal *points = path.points(); const QPainterPath::ElementType *elements = path.elements(); - VGPath vgpath; - if (forceNewPath) { - vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - count + 1, // segmentCapacityHint - count * 2, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); - } else { - vgpath = reusablePath; - } + VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + count + 1, // segmentCapacityHint + count * 2, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); // Size is sufficient segments for drawRoundedRect() paths. QVarLengthArray segments; @@ -760,22 +733,17 @@ return vgpath; } -VGPath QVGPaintEnginePrivate::painterPathToVGPath(const QPainterPath& path, bool forceNewPath) +VGPath QVGPaintEnginePrivate::painterPathToVGPath(const QPainterPath& path) { int count = path.elementCount(); - VGPath vgpath; - if (forceNewPath) { - vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - count + 1, // segmentCapacityHint - count * 2, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); - } else { - vgpath = reusablePath; - } + VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + count + 1, // segmentCapacityHint + count * 2, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); if (count == 0) return vgpath; @@ -994,7 +962,13 @@ vgModifyPathCoords(vgpath, 0, 9, pts); } #else - VGPath vgpath = reusablePath; + VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + 10, // segmentCapacityHint + 17 * 2, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); vgAppendPathData(vgpath, 10, roundedrect_types, pts); #endif @@ -1550,7 +1524,7 @@ d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); else d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); - d->releasePath(vgpath); + vgDestroyPath(vgpath); } void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush) @@ -1561,7 +1535,7 @@ d->fill(vgpath, brush, VG_EVEN_ODD); else d->fill(vgpath, brush, VG_NON_ZERO); - d->releasePath(vgpath); + vgDestroyPath(vgpath); } void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen) @@ -1569,7 +1543,7 @@ Q_D(QVGPaintEngine); VGPath vgpath = d->vectorPathToVGPath(path); d->stroke(vgpath, pen); - d->releasePath(vgpath); + vgDestroyPath(vgpath); } // Determine if a co-ordinate transform is simple enough to allow @@ -1765,7 +1739,7 @@ default: break; } - d->releasePath(vgpath); + vgDestroyPath(vgpath); vgSeti(VG_MASKING, VG_TRUE); d->maskValid = true; @@ -2082,7 +2056,7 @@ default: break; } - d->releasePath(vgpath); + vgDestroyPath(vgpath); vgSeti(VG_MASKING, VG_TRUE); d->maskValid = true; @@ -2096,7 +2070,7 @@ void QVGPaintEnginePrivate::ensureMask (QVGPaintEngine *engine, int width, int height) { - scissorMask = false; + scissorMask = false; if (maskIsSet) { vgMask(VG_INVALID_HANDLE, VG_FILL_MASK, 0, 0, width, height); maskRect = QRect(); @@ -2522,7 +2496,7 @@ VGPath vgpath = d->roundedRectPath(rect, xrad, yrad, mode); d->draw(vgpath, s->pen, s->brush); #if defined(QVG_NO_MODIFY_PATH) - d->releasePath(vgpath); + vgDestroyPath(vgpath); #endif } else { QPaintEngineEx::drawRoundedRect(rect, xrad, yrad, mode); @@ -2671,7 +2645,13 @@ Q_D(QVGPaintEngine); if (d->simpleTransform) { QVGPainterState *s = state(); - VGPath path = d->reusablePath; + VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + 4, // segmentCapacityHint + 12, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); static VGubyte segments[4] = { VG_MOVE_TO_ABS, VG_SCCWARC_TO_REL, @@ -2695,7 +2675,7 @@ coords[11] = 0.0f; vgAppendPathData(path, 4, segments, coords); d->draw(path, s->pen, s->brush); - d->releasePath(path); + vgDestroyPath(path); } else { // The projective transform version of an ellipse is difficult. // Generate a QVectorPath containing cubic curves and transform that. @@ -2719,7 +2699,7 @@ d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); else d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); - d->releasePath(vgpath); + vgDestroyPath(vgpath); } void QVGPaintEngine::drawPoints(const QPointF *points, int pointCount) @@ -2794,7 +2774,13 @@ { Q_D(QVGPaintEngine); QVGPainterState *s = state(); - VGPath path = d->reusablePath; + VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + pointCount + 1, // segmentCapacityHint + pointCount * 2, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); QVarLengthArray coords; QVarLengthArray segments; for (int i = 0; i < pointCount; ++i, ++points) { @@ -2828,14 +2814,20 @@ d->draw(path, s->pen, s->brush, VG_EVEN_ODD); break; } - d->releasePath(path); + vgDestroyPath(path); } void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) { Q_D(QVGPaintEngine); QVGPainterState *s = state(); - VGPath path = d->reusablePath; + VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + pointCount + 1, // segmentCapacityHint + pointCount * 2, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); QVarLengthArray coords; QVarLengthArray segments; for (int i = 0; i < pointCount; ++i, ++points) { @@ -2869,7 +2861,7 @@ d->draw(path, s->pen, s->brush, VG_EVEN_ODD); break; } - d->releasePath(path); + vgDestroyPath(path); } void QVGPaintEnginePrivate::setImageOptions() @@ -3268,7 +3260,7 @@ ti.fontEngine->getUnscaledGlyph(glyph, &path, &metrics); VGPath vgPath; if (!path.isEmpty()) { - vgPath = d->painterPathToVGPath(path, true); + vgPath = d->painterPathToVGPath(path); } else { // Probably a "space" character with no visible outline. vgPath = VG_INVALID_HANDLE; @@ -3328,7 +3320,7 @@ } // Set the transformation to use for drawing the current glyphs. - QTransform glyphTransform(d->pathTransform); + QTransform glyphTransform(d->glyphTransform); glyphTransform.translate(p.x(), p.y()); #if defined(QVG_NO_IMAGE_GLYPHS) glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY); @@ -3661,10 +3653,10 @@ } else { // Set the path transform to the default viewport transformation. - VGfloat devh = screenSize.height() - 1; + VGfloat devh = screenSize.height(); QTransform viewport(1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, - -0.5f, devh + 0.5f, 1.0f); + 0.0f, devh, 1.0f); d->setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, viewport); // Set the brush to use to fill the background. @@ -3700,10 +3692,10 @@ } // Set the image transformation and modes. - VGfloat devh = screenSize.height() - 1; + VGfloat devh = screenSize.height(); QTransform transform(1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, - -0.5f, devh + 0.5f, 1.0f); + 0.0f, devh, 1.0f); transform.translate(offset.x(), offset.y()); d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform); d->setImageMode(VG_DRAW_IMAGE_NORMAL);