summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eblomfel@trolltech.com>2009-08-21 14:29:44 (GMT)
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2010-01-14 13:05:08 (GMT)
commitbf919e06127962836a6b566bf119cf248c6a999b (patch)
tree789ca79fa342cf741513cb21e6d4d3728345a511
parent7fbffd29e5904151a3a249004031d0502a16f4fc (diff)
downloadQt-bf919e06127962836a6b566bf119cf248c6a999b.zip
Qt-bf919e06127962836a6b566bf119cf248c6a999b.tar.gz
Qt-bf919e06127962836a6b566bf119cf248c6a999b.tar.bz2
Implement drawStaticTextItem() in OpenGL paint engines
The OpenGL and OpenGL2 engines now have support for static text, as well as the QEmulationPaintEngine. Also contains an optimization: Instead of passing both the position and glyph positions to drawStaticTextItem() we add the position into the glyph position and update it only when it changes. Otherwise we would have to do this work in all engines for every call. This means we have to cache the position in QStaticTextPrivate as well, but it seems like a small price to pay, since it's a per-text overhead and only 16 bytes.
-rw-r--r--src/gui/painting/qemulationpaintengine.cpp5
-rw-r--r--src/gui/painting/qemulationpaintengine_p.h1
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp10
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h2
-rw-r--r--src/gui/painting/qpaintengineex.cpp2
-rw-r--r--src/gui/painting/qpaintengineex_p.h2
-rw-r--r--src/gui/painting/qpainter.cpp20
-rw-r--r--src/gui/text/qstatictext.cpp2
-rw-r--r--src/gui/text/qstatictext_p.h5
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp55
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h3
-rw-r--r--src/opengl/qpaintengine_opengl.cpp96
-rw-r--r--src/opengl/qpaintengine_opengl_p.h1
13 files changed, 135 insertions, 69 deletions
diff --git a/src/gui/painting/qemulationpaintengine.cpp b/src/gui/painting/qemulationpaintengine.cpp
index f2f0c73..4067b97 100644
--- a/src/gui/painting/qemulationpaintengine.cpp
+++ b/src/gui/painting/qemulationpaintengine.cpp
@@ -175,6 +175,11 @@ void QEmulationPaintEngine::drawTextItem(const QPointF &p, const QTextItem &text
real_engine->drawTextItem(p, textItem);
}
+void QEmulationPaintEngine::drawStaticTextItem(QStaticTextItem *item)
+{
+ real_engine->drawStaticTextItem(item);
+}
+
void QEmulationPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s)
{
if (state()->bgMode == Qt::OpaqueMode && pixmap.isQBitmap())
diff --git a/src/gui/painting/qemulationpaintengine_p.h b/src/gui/painting/qemulationpaintengine_p.h
index 0ed641b..5835f10 100644
--- a/src/gui/painting/qemulationpaintengine_p.h
+++ b/src/gui/painting/qemulationpaintengine_p.h
@@ -78,6 +78,7 @@ public:
virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
+ virtual void drawStaticTextItem(QStaticTextItem *item);
virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags);
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 87f374c..1fbfbb4 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3212,19 +3212,11 @@ QRasterPaintEnginePrivate::getPenFunc(const QRectF &rect,
return isUnclipped(rect, penWidth) ? data->unclipped_blend : data->blend;
}
-void QRasterPaintEngine::drawStaticTextItem(const QPointF &p, QStaticTextItem *textItem)
+void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
{
ensurePen();
ensureState();
- // Translate to actual position
- QFixed fx = QFixed::fromReal(p.x());
- QFixed fy = QFixed::fromReal(p.y());
- for (int i=0; i<textItem->numGlyphs; ++i) {
- textItem->glyphPositions[i].x += fx;
- textItem->glyphPositions[i].y += fy;
- }
-
drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions,
textItem->fontEngine);
}
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 0626a48..e441a6b 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -260,7 +260,7 @@ private:
void drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions,
QFontEngine *fontEngine);
- void drawStaticTextItem(const QPointF &p, QStaticTextItem *textItem);
+ void drawStaticTextItem(QStaticTextItem *textItem);
#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
void drawGlyphsS60(const QPointF &p, const QTextItemInt &ti);
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index f167b348..1bbdafa 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -590,10 +590,12 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
}
}
+/*
void QPaintEngineEx::drawStaticTextItem(const QPointF &position, QStaticTextItem *item)
{
// ### Make this pure virtual after implementing in all subclasses
}
+*/
void QPaintEngineEx::draw(const QVectorPath &path)
{
diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h
index 4096907..85090bd 100644
--- a/src/gui/painting/qpaintengineex_p.h
+++ b/src/gui/painting/qpaintengineex_p.h
@@ -201,7 +201,7 @@ public:
virtual void updateState(const QPaintEngineState &state);
- virtual void drawStaticTextItem(const QPointF &position, QStaticTextItem *item);
+ virtual void drawStaticTextItem(QStaticTextItem *item) = 0;
virtual void setState(QPainterState *s);
inline QPainterState *state() { return static_cast<QPainterState *>(QPaintEngine::state); }
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index c75547f..524f243 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -5787,11 +5787,27 @@ void QPainter::drawStaticText(const QPointF &position, const QStaticText &static
// Recreate the layout of the static text because the matrix or font has changed
if (staticTextNeedsReinit)
- staticText_d->init();
+ staticText_d->init();
+
+ if (transformedPosition != staticText_d->position) { // Translate to actual position
+ QFixed fx = QFixed::fromReal(transformedPosition.x());
+ QFixed fy = QFixed::fromReal(transformedPosition.y());
+ QFixed oldX = QFixed::fromReal(staticText_d->position.x());
+ QFixed oldY = QFixed::fromReal(staticText_d->position.y());
+ for (int item=0; item<staticText_d->itemCount;++item) {
+ QStaticTextItem *textItem = staticText_d->items + item;
+ for (int i=0; i<textItem->numGlyphs; ++i) {
+ textItem->glyphPositions[i].x += fx - oldX;
+ textItem->glyphPositions[i].y += fy - oldY;
+ }
+ }
+
+ staticText_d->position = transformedPosition;
+ }
for (int i=0; i<staticText_d->itemCount; ++i) {
QStaticTextItem *item = staticText_d->items + i;
- d->extended->drawStaticTextItem(transformedPosition, item);
+ d->extended->drawStaticTextItem(item);
}
if (restoreWhenFinished)
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index d4f8fbd..56950ed 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -429,6 +429,8 @@ void QStaticTextPrivate::init()
delete[] glyphPool;
delete[] positionPool;
+ position = QPointF(0, 0);
+
// Draw once to count number of items and glyphs, so that we can use as little memory
// as possible to store the data
DrawTextItemDevice counterDevice;
diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h
index 2cb1262..4756773 100644
--- a/src/gui/text/qstatictext_p.h
+++ b/src/gui/text/qstatictext_p.h
@@ -57,7 +57,7 @@
QT_BEGIN_NAMESPACE
-class Q_AUTOTEST_EXPORT QStaticTextItem
+class Q_GUI_EXPORT QStaticTextItem
{
public:
QStaticTextItem() : chars(0), numChars(0), fontEngine(0) {}
@@ -91,6 +91,7 @@ public:
QString text; // 4 bytes per text
QFont font; // 8 bytes per text
QSizeF size; // 16 bytes per text
+ QPointF position; // 16 bytes per text
QTransform matrix; // 80 bytes per text
QStaticTextItem *items; // 4 bytes per text
@@ -98,7 +99,7 @@ public:
glyph_t *glyphPool; // 4 bytes per text
QFixedPoint *positionPool; // 4 bytes per text
// ================
- // 128 bytes per text
+ // 144 bytes per text
static QStaticTextPrivate *get(const QStaticText *q);
};
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index e4fe84f..35087d2 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -77,6 +77,7 @@
#include <private/qfontengine_p.h>
#include <private/qpixmapdata_gl_p.h>
#include <private/qdatabuffer_p.h>
+#include <private/qstatictext_p.h>
#include "qglgradientcache_p.h"
#include "qglengineshadermanager_p.h"
@@ -1212,6 +1213,17 @@ void QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const
d->drawTexture(dest, srcRect, size, false);
}
+void QGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem)
+{
+ Q_D(QGL2PaintEngineEx);
+
+ ensureActive();
+
+ // ### What about transformations and huge fonts? These are not passed through cache
+ // in drawTextItem().
+ d->drawCachedGlyphs(textItem);
+}
+
void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem)
{
Q_D(QGL2PaintEngineEx);
@@ -1246,33 +1258,46 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem
}
if (drawCached) {
- d->drawCachedGlyphs(p, glyphType, ti);
+ QVarLengthArray<QFixedPoint> positions;
+ QVarLengthArray<glyph_t> glyphs;
+ QTransform matrix = QTransform::fromTranslate(p.x(), p.y());
+ ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
+
+ {
+ QStaticTextItem staticTextItem;
+ staticTextItem.chars = ti.chars;
+ staticTextItem.fontEngine = ti.fontEngine;
+ staticTextItem.glyphs = glyphs.data();
+ staticTextItem.numChars = ti.num_chars;
+ staticTextItem.numGlyphs = glyphs.size();
+ staticTextItem.glyphPositions = positions.data();
+
+ d->drawCachedGlyphs(&staticTextItem);
+ }
return;
}
QPaintEngineEx::drawTextItem(p, ti);
}
-void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGlyphCache::Type glyphType,
- const QTextItemInt &ti)
+void QGL2PaintEngineExPrivate::drawCachedGlyphs(QStaticTextItem *staticTextItem)
{
Q_Q(QGL2PaintEngineEx);
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- QTransform matrix = QTransform::fromTranslate(p.x(), p.y());
- ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
+ QFontEngineGlyphCache::Type glyphType = staticTextItem->fontEngine->glyphFormat >= 0
+ ? QFontEngineGlyphCache::Type(staticTextItem->fontEngine->glyphFormat)
+ : QFontEngineGlyphCache::Raster_A8;
QGLTextureGlyphCache *cache =
- (QGLTextureGlyphCache *) ti.fontEngine->glyphCache(ctx, glyphType, QTransform());
-
+ (QGLTextureGlyphCache *) staticTextItem->fontEngine->glyphCache(ctx, glyphType, QTransform());
if (!cache || cache->cacheType() != glyphType) {
cache = new QGLTextureGlyphCache(ctx, glyphType, QTransform());
- ti.fontEngine->setGlyphCache(ctx, cache);
+ staticTextItem->fontEngine->setGlyphCache(ctx, cache);
}
cache->setPaintEnginePrivate(this);
- cache->populate(ti.fontEngine, glyphs.size(), glyphs.constData(), positions.constData());
+ cache->populate(staticTextItem->fontEngine, staticTextItem->numGlyphs, staticTextItem->glyphs,
+ staticTextItem->glyphPositions);
if (cache->width() == 0 || cache->height() == 0)
return;
@@ -1287,10 +1312,10 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly
vertexCoordinateArray.clear();
textureCoordinateArray.clear();
- for (int i=0; i<glyphs.size(); ++i) {
- const QTextureGlyphCache::Coord &c = cache->coords.value(glyphs[i]);
- int x = positions[i].x.toInt() + c.baseLineX - margin;
- int y = positions[i].y.toInt() - c.baseLineY - margin;
+ for (int i=0; i<staticTextItem->numGlyphs; ++i) {
+ const QTextureGlyphCache::Coord &c = cache->coords.value(staticTextItem->glyphs[i]);
+ int x = staticTextItem->glyphPositions[i].x.toInt() + c.baseLineX - margin;
+ int y = staticTextItem->glyphPositions[i].y.toInt() - c.baseLineY - margin;
vertexCoordinateArray.addRect(QRectF(x, y, c.w, c.h));
textureCoordinateArray.addRect(QRectF(c.x*dx, c.y*dy, c.w * dx, c.h * dy));
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index ce1b538..b683b8b 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -133,6 +133,7 @@ public:
virtual void stroke(const QVectorPath &path, const QPen &pen);
virtual void clip(const QVectorPath &path, Qt::ClipOperation op);
+ virtual void drawStaticTextItem(QStaticTextItem *textItem);
Type type() const { return OpenGL2; }
@@ -194,7 +195,7 @@ public:
void stroke(const QVectorPath &path, const QPen &pen);
void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false);
void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints);
- void drawCachedGlyphs(const QPointF &p, QFontEngineGlyphCache::Type glyphType, const QTextItemInt &ti);
+ void drawCachedGlyphs(QStaticTextItem *staticTextItem);
// Calls glVertexAttributePointer if the pointer has changed
inline void setVertexAttributePointer(unsigned int arrayIndex, const GLfloat *pointer);
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index 57918d0..d6175e9 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -60,6 +60,7 @@
#include <private/qglpixelbuffer_p.h>
#include <private/qbezier_p.h>
#include <qglframebufferobject.h>
+#include <private/qstatictext_p.h>
#include "private/qtessellator_p.h"
@@ -4555,7 +4556,7 @@ public:
QGLGlyphCache() : QObject(0) { current_cache = 0; }
~QGLGlyphCache();
QGLGlyphCoord *lookup(QFontEngine *, glyph_t);
- void cacheGlyphs(QGLContext *, const QTextItemInt &, const QVarLengthArray<glyph_t> &);
+ void cacheGlyphs(QGLContext *, QFontEngine *, glyph_t *glyphs, int numGlyphs);
void cleanCache();
void allocTexture(int width, int height, GLuint texture);
@@ -4707,8 +4708,8 @@ static QImage getCurrentTexture(const QColor &color, QGLFontTexture *font_tex)
}
#endif
-void QGLGlyphCache::cacheGlyphs(QGLContext *context, const QTextItemInt &ti,
- const QVarLengthArray<glyph_t> &glyphs)
+void QGLGlyphCache::cacheGlyphs(QGLContext *context, QFontEngine *fontEngine,
+ glyph_t *glyphs, int numGlyphs)
{
QGLContextHash::const_iterator dev_it = qt_context_cache.constFind(context);
QGLFontGlyphHash *font_cache = 0;
@@ -4744,25 +4745,25 @@ void QGLGlyphCache::cacheGlyphs(QGLContext *context, const QTextItemInt &ti,
}
Q_ASSERT(font_cache != 0);
- QGLFontGlyphHash::const_iterator cache_it = font_cache->constFind(ti.fontEngine);
+ QGLFontGlyphHash::const_iterator cache_it = font_cache->constFind(fontEngine);
QGLGlyphHash *cache = 0;
if (cache_it == font_cache->constEnd()) {
cache = new QGLGlyphHash;
- font_cache->insert(ti.fontEngine, cache);
- connect(ti.fontEngine, SIGNAL(destroyed(QObject*)), SLOT(fontEngineDestroyed(QObject*)));
+ font_cache->insert(fontEngine, cache);
+ connect(fontEngine, SIGNAL(destroyed(QObject*)), SLOT(fontEngineDestroyed(QObject*)));
} else {
cache = cache_it.value();
}
current_cache = cache;
quint64 font_key = (reinterpret_cast<quint64>(context_key ? context_key : context) << 32)
- | reinterpret_cast<quint64>(ti.fontEngine);
+ | reinterpret_cast<quint64>(fontEngine);
QGLFontTexHash::const_iterator it = qt_font_textures.constFind(font_key);
QGLFontTexture *font_tex;
if (it == qt_font_textures.constEnd()) {
GLuint font_texture;
glGenTextures(1, &font_texture);
- GLint tex_height = qt_next_power_of_two(qRound(ti.ascent.toReal() + ti.descent.toReal())+2);
+ GLint tex_height = qt_next_power_of_two(qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2);
GLint tex_width = qt_next_power_of_two(tex_height*30); // ###
GLint max_tex_size;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
@@ -4784,16 +4785,16 @@ void QGLGlyphCache::cacheGlyphs(QGLContext *context, const QTextItemInt &ti,
glBindTexture(GL_TEXTURE_2D, font_tex->texture);
}
- for (int i=0; i< glyphs.size(); ++i) {
+ for (int i=0; i< numGlyphs; ++i) {
QGLGlyphHash::const_iterator it = cache->constFind(glyphs[i]);
if (it == cache->constEnd()) {
// render new glyph and put it in the cache
- glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyphs[i]);
+ glyph_metrics_t metrics = fontEngine->boundingBox(glyphs[i]);
int glyph_width = qRound(metrics.width.toReal())+2;
- int glyph_height = qRound(ti.ascent.toReal() + ti.descent.toReal())+2;
+ int glyph_height = qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2;
if (font_tex->x_offset + glyph_width + x_margin > font_tex->width) {
- int strip_height = qt_next_power_of_two(qRound(ti.ascent.toReal() + ti.descent.toReal())+2);
+ int strip_height = qt_next_power_of_two(qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2);
font_tex->x_offset = x_margin;
font_tex->y_offset += strip_height;
if (font_tex->y_offset >= font_tex->height) {
@@ -4826,8 +4827,8 @@ void QGLGlyphCache::cacheGlyphs(QGLContext *context, const QTextItemInt &ti,
}
}
- QImage glyph_im(ti.fontEngine->alphaMapForGlyph(glyphs[i]));
- glyph_im = glyph_im.convertToFormat(QImage::Format_Indexed8);
+ QImage glyph_im(fontEngine->alphaMapForGlyph(glyphs[i]));
+ glyph_im = glyph_im.convertToFormat(QImage::Format_Indexed8);
glyph_width = glyph_im.width();
Q_ASSERT(glyph_width >= 0);
// pad the glyph width to an even number
@@ -4906,30 +4907,15 @@ void qgl_cleanup_glyph_cache(QGLContext *ctx)
qt_glyph_cache()->cleanupContext(ctx);
}
-void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
+void QOpenGLPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
{
Q_D(QOpenGLPaintEngine);
- const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
-
- // fall back to drawing a polygon if the scale factor is large, or
- // we use a gradient pen
- if ((d->matrix.det() > 1) || (d->pen_brush_style >= Qt::LinearGradientPattern
- && d->pen_brush_style <= Qt::ConicalGradientPattern)) {
- QPaintEngine::drawTextItem(p, textItem);
- return;
- }
-
d->flushDrawQueue();
- // add the glyphs used to the glyph texture cache
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- QTransform matrix = QTransform::fromTranslate(qRound(p.x()), qRound(p.y()));
- ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
-
// make sure the glyphs we want to draw are in the cache
- qt_glyph_cache()->cacheGlyphs(d->device->context(), ti, glyphs);
+ qt_glyph_cache()->cacheGlyphs(d->device.context(), textItem->fontEngine, textItem->glyphs,
+ textItem->numGlyphs);
d->setGradientOps(Qt::SolidPattern, QRectF()); // turns off gradient ops
qt_glColor4ubv(d->pen_color);
@@ -4951,13 +4937,13 @@ void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- bool antialias = !(ti.fontEngine->fontDef.styleStrategy & QFont::NoAntialias)
- && (d->matrix.type() > QTransform::TxTranslate);
+ bool antialias = !(textItem->fontEngine->fontDef.styleStrategy & QFont::NoAntialias)
+ && (d->matrix.type() > QTransform::TxTranslate);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, antialias ? GL_LINEAR : GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, antialias ? GL_LINEAR : GL_NEAREST);
- for (int i=0; i< glyphs.size(); ++i) {
- QGLGlyphCoord *g = qt_glyph_cache()->lookup(ti.fontEngine, glyphs[i]);
+ for (int i=0; i< textItem->numGlyphs; ++i) {
+ QGLGlyphCoord *g = qt_glyph_cache()->lookup(textItem->fontEngine, textItem->glyphs[i]);
// we don't cache glyphs with no width/height
if (!g)
@@ -4969,8 +4955,8 @@ void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
x2 = x1 + g->width;
y2 = y1 + g->height;
- QPointF logical_pos((positions[i].x - g->x_offset).toReal(),
- (positions[i].y + g->y_offset).toReal());
+ QPointF logical_pos((textItem->glyphPositions[i].x - g->x_offset).toReal(),
+ (textItem->glyphPositions[i].y + g->y_offset).toReal());
qt_add_rect_to_array(QRectF(logical_pos, QSizeF(g->log_width, g->log_height)), vertexArray);
qt_add_texcoords_to_array(x1, y1, x2, y2, texCoordArray);
@@ -4987,6 +4973,40 @@ void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
// XXX: This may not be needed as this behavior does seem to be caused by driver bug
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
#endif
+
+}
+
+void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
+{
+ Q_D(QOpenGLPaintEngine);
+
+ const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
+
+ // fall back to drawing a polygon if the scale factor is large, or
+ // we use a gradient pen
+ if ((d->matrix.det() > 1) || (d->pen_brush_style >= Qt::LinearGradientPattern
+ && d->pen_brush_style <= Qt::ConicalGradientPattern)) {
+ QPaintEngine::drawTextItem(p, textItem);
+ return;
+ }
+
+ // add the glyphs used to the glyph texture cache
+ QVarLengthArray<QFixedPoint> positions;
+ QVarLengthArray<glyph_t> glyphs;
+ QTransform matrix = QTransform::fromTranslate(qRound(p.x()), qRound(p.y()));
+ ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
+
+ {
+ QStaticTextItem staticTextItem;
+ staticTextItem.chars = ti.chars;
+ staticTextItem.fontEngine = ti.fontEngine;
+ staticTextItem.glyphs = glyphs.data();
+ staticTextItem.numChars = ti.num_chars;
+ staticTextItem.numGlyphs = glyphs.size();
+ staticTextItem.glyphPositions = positions.data();
+ drawStaticTextItem(&staticTextItem);
+ }
+
}
diff --git a/src/opengl/qpaintengine_opengl_p.h b/src/opengl/qpaintengine_opengl_p.h
index de0086a..55f7792 100644
--- a/src/opengl/qpaintengine_opengl_p.h
+++ b/src/opengl/qpaintengine_opengl_p.h
@@ -133,6 +133,7 @@ public:
void drawImage(const QRectF &r, const QImage &image, const QRectF &sr,
Qt::ImageConversionFlags conversionFlags);
void drawTextItem(const QPointF &p, const QTextItem &ti);
+ void drawStaticTextItem(QStaticTextItem *staticTextItem);
void drawEllipse(const QRectF &rect);