--- a/src/openvg/qpaintengine_vg.cpp Wed Jun 23 19:07:03 2010 +0300
+++ b/src/openvg/qpaintengine_vg.cpp Tue Jul 06 15:10:48 2010 +0300
@@ -45,15 +45,15 @@
#include "qvgcompositionhelper_p.h"
#include "qvgimagepool_p.h"
#if !defined(QT_NO_EGL)
-#include <QtGui/private/qegl_p.h>
+#include <QtGui/private/qeglcontext_p.h>
#include "qwindowsurface_vgegl_p.h"
#endif
#include <QtCore/qvarlengtharray.h>
#include <QtGui/private/qdrawhelper_p.h>
-#include <QtGui/private/qtextureglyphcache_p.h>
#include <QtGui/private/qtextengine_p.h>
#include <QtGui/private/qfontengine_p.h>
#include <QtGui/private/qpainterpath_p.h>
+#include <QtGui/private/qstatictext_p.h>
#include <QDebug>
#include <QSet>
@@ -86,15 +86,14 @@
QVGFontGlyphCache();
~QVGFontGlyphCache();
- void cacheGlyphs(QVGPaintEnginePrivate *d,
- const QTextItemInt &ti,
- const QVarLengthArray<glyph_t> &glyphs);
- void setScaleFromText(const QTextItemInt &ti);
+ void cacheGlyphs(QVGPaintEnginePrivate *d, QFontEngine *fontEngine, const glyph_t *g, int count);
+
+ void setScaleFromText(const QFont &font, QFontEngine *fontEngine);
VGFont font;
VGfloat scaleX;
VGfloat scaleY;
-
+
uint cachedGlyphsMask[256 / 32];
QSet<glyph_t> cachedGlyphs;
};
@@ -1014,7 +1013,7 @@
int height = sourceImage.height();
int width = sourceImage.width();
for (int y=0; y<height; ++y) {
- uchar *source = sourceImage.scanLine(y);
+ const uchar *source = sourceImage.constScanLine(y);
QRgb *target = reinterpret_cast<QRgb *>(dest.scanLine(y));
for (int x=0; x < width; ++x)
target[x] = (source[x>>3] >> (x&7)) & 1 ? fg : bg;
@@ -1022,9 +1021,6 @@
return dest;
}
-// defined in qpixmapdata_vg.cpp.
-const uchar *qt_vg_imageBits(const QImage& image);
-
static VGImage toVGImage
(const QImage & image, Qt::ImageConversionFlags flags = Qt::AutoColor)
{
@@ -1058,7 +1054,7 @@
break;
}
- const uchar *pixels = qt_vg_imageBits(img);
+ const uchar *pixels = img.constBits();
VGImage vgImg = QVGImagePool::instance()->createPermanentImage
(format, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
@@ -1102,7 +1098,7 @@
break;
}
- const uchar *pixels = qt_vg_imageBits(img) + bpp * sr.x() +
+ const uchar *pixels = img.constBits() + bpp * sr.x() +
img.bytesPerLine() * sr.y();
VGImage vgImg = QVGImagePool::instance()->createPermanentImage
@@ -1124,7 +1120,7 @@
painter.drawImage(0, 0, image);
painter.end();
- const uchar *pixels = qt_vg_imageBits(img);
+ const uchar *pixels = img.constBits();
VGImage vgImg = QVGImagePool::instance()->createPermanentImage
(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
@@ -1146,7 +1142,7 @@
painter.drawImage(QPoint(0, 0), image, sr);
painter.end();
- const uchar *pixels = qt_vg_imageBits(img);
+ const uchar *pixels = img.constBits();
VGImage vgImg = QVGImagePool::instance()->createPermanentImage
(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
@@ -3116,9 +3112,8 @@
// (i.e. no opacity), no rotation or scaling, and drawing the full
// pixmap rather than parts of the pixmap. Even having just one of
// these conditions will improve performance.
-void QVGPaintEngine::drawPixmaps
- (const QDrawPixmaps::Data *drawingData, int dataCount,
- const QPixmap &pixmap, QFlags<QDrawPixmaps::DrawingHint> hints)
+void QVGPaintEngine::drawPixmapFragments(const QPainter::PixmapFragment *drawingData, int dataCount,
+ const QPixmap &pixmap, QFlags<QPainter::PixmapFragmentHint> hints)
{
#if !defined(QT_SHIVAVG)
Q_D(QVGPaintEngine);
@@ -3129,7 +3124,7 @@
if (!pd)
return; // null QPixmap
if (pd->classId() != QPixmapData::OpenVGClass || !d->simpleTransform) {
- QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
+ QPaintEngineEx::drawPixmapFragments(drawingData, dataCount, pixmap, hints);
return;
}
@@ -3153,7 +3148,7 @@
QVarLengthArray<QRect> cachedSources;
// Select the opacity paint object.
- if ((hints & QDrawPixmaps::OpaqueHint) != 0 && d->opacity == 1.0f) {
+ if ((hints & QPainter::OpaqueHint) != 0 && d->opacity == 1.0f) {
d->setImageMode(VG_DRAW_IMAGE_NORMAL);
} else {
hints = 0;
@@ -3165,12 +3160,13 @@
for (int i = 0; i < dataCount; ++i) {
QTransform transform(d->imageTransform);
- transform.translate(drawingData[i].point.x(), drawingData[i].point.y());
+ transform.translate(drawingData[i].x, drawingData[i].y);
transform.rotate(drawingData[i].rotation);
VGImage child;
QSize imageSize = vgpd->size();
- QRectF sr = drawingData[i].source;
+ QRectF sr(drawingData[i].sourceLeft, drawingData[i].sourceTop,
+ drawingData[i].width, drawingData[i].height);
if (sr.topLeft().isNull() && sr.size() == imageSize) {
child = vgImg;
} else {
@@ -3199,7 +3195,7 @@
transform.scale(scaleX, scaleY);
d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
- if ((hints & QDrawPixmaps::OpaqueHint) == 0) {
+ if ((hints & QPainter::OpaqueHint) == 0) {
qreal opacity = d->opacity * drawingData[i].opacity;
if (opacity != 1.0f) {
if (d->paintOpacity != opacity) {
@@ -3225,7 +3221,7 @@
for (int i = 0; i < cachedImages.size(); ++i)
vgDestroyImage(cachedImages[i]);
#else
- QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
+ QPaintEngineEx::drawPixmapFragments(drawingData, dataCount, pixmap, hints);
#endif
}
@@ -3265,22 +3261,20 @@
vgDestroyFont(font);
}
-void QVGFontGlyphCache::setScaleFromText(const QTextItemInt &ti)
+void QVGFontGlyphCache::setScaleFromText(const QFont &font, QFontEngine *fontEngine)
{
- QFontInfo fi(ti.font());
+ QFontInfo fi(font);
qreal pixelSize = fi.pixelSize();
- qreal emSquare = ti.fontEngine->properties().emSquare.toReal();
+ qreal emSquare = fontEngine->properties().emSquare.toReal();
scaleX = scaleY = static_cast<VGfloat>(pixelSize / emSquare);
}
-void QVGFontGlyphCache::cacheGlyphs
- (QVGPaintEnginePrivate *d, const QTextItemInt &ti,
- const QVarLengthArray<glyph_t> &glyphs)
+void QVGFontGlyphCache::cacheGlyphs(QVGPaintEnginePrivate *d,
+ QFontEngine *fontEngine,
+ const glyph_t *g, int count)
{
VGfloat origin[2];
VGfloat escapement[2];
- const glyph_t *g = glyphs.constData();
- int count = glyphs.size();
glyph_metrics_t metrics;
// Some Qt font engines don't set yoff in getUnscaledGlyph().
// Zero the metric structure so that everything has a default value.
@@ -3299,21 +3293,21 @@
}
#if !defined(QVG_NO_IMAGE_GLYPHS)
Q_UNUSED(d);
- QImage scaledImage = ti.fontEngine->alphaMapForGlyph(glyph);
+ QImage scaledImage = fontEngine->alphaMapForGlyph(glyph);
VGImage vgImage = VG_INVALID_HANDLE;
- metrics = ti.fontEngine->boundingBox(glyph);
+ metrics = fontEngine->boundingBox(glyph);
if (!scaledImage.isNull()) { // Not a space character
if (scaledImage.format() == QImage::Format_Indexed8) {
vgImage = vgCreateImage(VG_A_8, scaledImage.width(), scaledImage.height(), VG_IMAGE_QUALITY_FASTER);
- vgImageSubData(vgImage, qt_vg_imageBits(scaledImage), scaledImage.bytesPerLine(), VG_A_8, 0, 0, scaledImage.width(), scaledImage.height());
+ vgImageSubData(vgImage, scaledImage.constBits(), scaledImage.bytesPerLine(), VG_A_8, 0, 0, scaledImage.width(), scaledImage.height());
} else if (scaledImage.format() == QImage::Format_Mono) {
QImage img = scaledImage.convertToFormat(QImage::Format_Indexed8);
vgImage = vgCreateImage(VG_A_8, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
- vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_A_8, 0, 0, img.width(), img.height());
+ vgImageSubData(vgImage, img.constBits(), img.bytesPerLine(), VG_A_8, 0, 0, img.width(), img.height());
} else {
QImage img = scaledImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
vgImage = vgCreateImage(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
- vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height());
+ vgImageSubData(vgImage, img.constBits(), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height());
}
}
origin[0] = -metrics.x.toReal();
@@ -3325,7 +3319,7 @@
#else
// Calculate the path for the glyph and cache it.
QPainterPath path;
- ti.fontEngine->getUnscaledGlyph(glyph, &path, &metrics);
+ fontEngine->getUnscaledGlyph(glyph, &path, &metrics);
VGPath vgPath;
if (!path.isEmpty()) {
vgPath = d->painterPathToVGPath(path);
@@ -3357,15 +3351,37 @@
QPaintEngineEx::drawTextItem(p, textItem);
return;
}
-
+
// Get the glyphs and positions associated with the text item.
QVarLengthArray<QFixedPoint> positions;
QVarLengthArray<glyph_t> glyphs;
QTransform matrix;
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
+ if (!drawCachedGlyphs(glyphs.size(), glyphs.data(), ti.font(), ti.fontEngine, p, positions.data()))
+ QPaintEngineEx::drawTextItem(p, textItem);
+#else
+ // OpenGL 1.0 does not have support for VGFont and glyphs,
+ // so fall back to the default Qt path stroking algorithm.
+ QPaintEngineEx::drawTextItem(p, textItem);
+#endif
+}
+
+void QVGPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
+{
+ drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->font, textItem->fontEngine,
+ QPointF(0, 0), textItem->glyphPositions);
+}
+
+ bool QVGPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFont &font,
+ QFontEngine *fontEngine, const QPointF &p,
+ const QFixedPoint *positions)
+ {
+#if !defined(QVG_NO_DRAW_GLYPHS)
+ Q_D(QVGPaintEngine);
+
// Find the glyph cache for this font.
- QVGFontCache::ConstIterator it = d->fontCache.constFind(ti.fontEngine);
+ QVGFontCache::ConstIterator it = d->fontCache.constFind(fontEngine);
QVGFontGlyphCache *glyphCache;
if (it != d->fontCache.constEnd()) {
glyphCache = it.value();
@@ -3374,14 +3390,13 @@
if (glyphCache->font == VG_INVALID_HANDLE) {
qWarning("QVGPaintEngine::drawTextItem: OpenVG fonts are not supported by the OpenVG engine");
delete glyphCache;
- QPaintEngineEx::drawTextItem(p, textItem);
- return;
+ return false;
}
- glyphCache->setScaleFromText(ti);
- d->fontCache.insert(ti.fontEngine, glyphCache);
+ glyphCache->setScaleFromText(font, fontEngine);
+ d->fontCache.insert(fontEngine, glyphCache);
if (!d->fontEngineCleaner)
d->fontEngineCleaner = new QVGFontEngineCleaner(d);
- QObject::connect(ti.fontEngine, SIGNAL(destroyed()),
+ QObject::connect(fontEngine, SIGNAL(destroyed()),
d->fontEngineCleaner, SLOT(fontEngineDestroyed()));
}
@@ -3394,12 +3409,12 @@
d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, glyphTransform);
// Add the glyphs from the text item into the glyph cache.
- glyphCache->cacheGlyphs(d, ti, glyphs);
+ glyphCache->cacheGlyphs(d, fontEngine, glyphs, numGlyphs);
// Create the array of adjustments between glyphs
- QVarLengthArray<VGfloat> adjustments_x(glyphs.size());
- QVarLengthArray<VGfloat> adjustments_y(glyphs.size());
- for (int i = 1; i < glyphs.size(); ++i) {
+ QVarLengthArray<VGfloat> adjustments_x(numGlyphs);
+ QVarLengthArray<VGfloat> adjustments_y(numGlyphs);
+ for (int i = 1; i < numGlyphs; ++i) {
adjustments_x[i-1] = (positions[i].x - positions[i-1].x).toReal();
adjustments_y[i-1] = (positions[i].y - positions[i-1].y).toReal();
}
@@ -3421,12 +3436,17 @@
// Draw the glyphs. We need to fill with the brush associated with
// the Qt pen, not the Qt brush.
d->ensureBrush(state()->pen.brush());
- vgDrawGlyphs(glyphCache->font, glyphs.size(), (VGuint*)glyphs.data(),
+ vgDrawGlyphs(glyphCache->font, numGlyphs, (VGuint*)glyphs,
adjustments_x.data(), adjustments_y.data(), VG_FILL_PATH, VG_TRUE);
+ return true;
#else
- // OpenGL 1.0 does not have support for VGFont and glyphs,
- // so fall back to the default Qt path stroking algorithm.
- QPaintEngineEx::drawTextItem(p, textItem);
+ Q_UNUSED(numGlyphs);
+ Q_UNUSED(glyphs);
+ Q_UNUSED(font);
+ Q_UNUSED(fontEngine);
+ Q_UNUSED(p);
+ Q_UNUSED(positions);
+ return false;
#endif
}
@@ -3787,7 +3807,7 @@
if (vgImage == VG_INVALID_HANDLE)
return;
vgImageSubData
- (vgImage, qt_vg_imageBits(img) + img.bytesPerLine() * (img.height() - 1),
+ (vgImage, img.constBits() + img.bytesPerLine() * (img.height() - 1),
-(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0,
img.width(), img.height());