--- 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<VGubyte, 20> 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<VGfloat, 16> coords;
QVarLengthArray<VGubyte, 10> 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<VGfloat, 16> coords;
QVarLengthArray<VGubyte, 10> 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);