diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 53 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_raster_p.h | 7 | ||||
-rw-r--r-- | src/gui/painting/qpaintengineex.cpp | 6 | ||||
-rw-r--r-- | src/gui/painting/qpaintengineex_p.h | 3 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 22 | ||||
-rw-r--r-- | src/gui/painting/qtextureglyphcache.cpp | 16 | ||||
-rw-r--r-- | src/gui/painting/qtextureglyphcache_p.h | 7 | ||||
-rw-r--r-- | src/gui/text/qstatictext.cpp | 93 | ||||
-rw-r--r-- | src/gui/text/qstatictext_p.h | 38 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 2 |
10 files changed, 137 insertions, 110 deletions
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 3f2322e..387d646 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -67,6 +67,7 @@ // #include <private/qpolygonclipper_p.h> // #include <private/qrasterizer_p.h> #include <private/qimage_p.h> +#include <private/qstatictext_p.h> #include "qpaintengine_raster_p.h" // #include "qbezier_p.h" @@ -3006,27 +3007,23 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx blend(current, spans, &s->penData); } -void QRasterPaintEngine::drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti) +void QRasterPaintEngine::drawCachedGlyphs(const QVarLengthArray<glyph_t> &glyphs, + const QVarLengthArray<QFixedPoint> &positions, + QFontEngine *fontEngine, + const QTransform &matrix) { Q_D(QRasterPaintEngine); - QRasterPaintEngineState *s = state(); - - QVarLengthArray<QFixedPoint> positions; - QVarLengthArray<glyph_t> glyphs; - QTransform matrix = s->matrix; - matrix.translate(p.x(), p.y()); - ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); - QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(ti.fontEngine->glyphFormat) : d->glyphCacheType; + QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(fontEngine->glyphFormat) : d->glyphCacheType; QImageTextureGlyphCache *cache = - (QImageTextureGlyphCache *) ti.fontEngine->glyphCache(0, glyphType, s->matrix); + static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphType, matrix)); if (!cache) { - cache = new QImageTextureGlyphCache(glyphType, s->matrix); - ti.fontEngine->setGlyphCache(0, cache); + cache = new QImageTextureGlyphCache(glyphType, matrix); + fontEngine->setGlyphCache(0, cache); } - cache->populate(ti, glyphs, positions); + cache->populate(fontEngine, glyphs, positions); const QImage &image = cache->image(); int bpl = image.bytesPerLine(); @@ -3216,6 +3213,26 @@ QRasterPaintEnginePrivate::getPenFunc(const QRectF &rect, return isUnclipped(rect, penWidth) ? data->unclipped_blend : data->blend; } +void QRasterPaintEngine::drawStaticTextItem(const QPointF &p, QStaticTextItem *textItem) +{ + ensurePen(); + ensureState(); + + QTransform matrix; + matrix.translate(p.x(), p.y()); + + // Translate to actual position + QVarLengthArray<QFixedPoint> glyphPositions = textItem->glyphPositions; + + QFixed fx = QFixed::fromReal(p.x()); + QFixed fy = QFixed::fromReal(p.y()); + for (int i=0; i<glyphPositions.size(); ++i) { + glyphPositions[i].x += fx; + glyphPositions[i].y += fy; + } + drawCachedGlyphs(textItem->glyphs, glyphPositions, textItem->fontEngine, matrix); +} + /*! \reimp */ @@ -3264,7 +3281,15 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte drawCached = false; #endif if (drawCached) { - drawCachedGlyphs(p, ti); + QRasterPaintEngineState *s = state(); + + QVarLengthArray<QFixedPoint> positions; + QVarLengthArray<glyph_t> glyphs; + QTransform matrix = s->matrix; + matrix.translate(p.x(), p.y()); + ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); + + drawCachedGlyphs(glyphs, positions, ti.fontEngine, matrix); return; } diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index b937f66..0250c3d 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -257,7 +257,12 @@ private: void fillRect(const QRectF &rect, QSpanData *data); void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill); - void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti); + void drawCachedGlyphs(const QVarLengthArray<glyph_t> &glyphs, + const QVarLengthArray<QFixedPoint> &positions, + QFontEngine *fontEngine, + const QTransform &matrix); + + void drawStaticTextItem(const QPointF &p, 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 058f226..15085f9 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -44,6 +44,7 @@ #include "qstroker_p.h" #include "qbezier_p.h" #include <private/qpainterpath_p.h> +#include <private/qstatictext_p.h> #include <qvarlengtharray.h> #include <qdebug.h> @@ -589,6 +590,11 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) } } +void QPaintEngineEx::drawStaticTextItem(const QPointF &position, QStaticTextItem *item) +{ + // ### fall back (we need to recalculate the text item and call drawTextItem()) +} + void QPaintEngineEx::draw(const QVectorPath &path) { const QBrush &brush = state()->brush; diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h index fccd1dc..4096907 100644 --- a/src/gui/painting/qpaintengineex_p.h +++ b/src/gui/painting/qpaintengineex_p.h @@ -70,6 +70,7 @@ QT_MODULE(Gui) class QPainterState; class QPaintEngineExPrivate; +class QStaticTextItem; struct StrokeHandler; struct QIntRect { @@ -200,6 +201,8 @@ public: virtual void updateState(const QPaintEngineState &state); + virtual void drawStaticTextItem(const QPointF &position, QStaticTextItem *item); + virtual void setState(QPainterState *s); inline QPainterState *state() { return static_cast<QPainterState *>(QPaintEngine::state); } inline const QPainterState *state() const { return static_cast<const QPainterState *>(QPaintEngine::state); } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 83f66e2..1d7f57d 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5719,8 +5719,10 @@ void QPainter::drawText(const QPointF &p, const QString &str) /*! Draws the given \a staticText beginning at the given \a position. - This function can be used to optimize drawing text if the text and its layout is updated + This function can be used to optimize drawing text if the text and its layout is updated seldomly. + + \sa QStaticText */ void QPainter::drawStaticText(const QPointF &position, const QStaticText &staticText) { @@ -5728,9 +5730,19 @@ void QPainter::drawStaticText(const QPointF &position, const QStaticText &static if (!d->engine || staticText.isEmpty() || pen().style() == Qt::NoPen) return; - const QStaticTextPrivate *staticText_d = QStaticTextPrivate::get(&staticText); - bool restoreWhenFinished = false; + const QStaticTextPrivate *staticText_d = QStaticTextPrivate::get(&staticText); + // If we don't have an extended paint engine, or if the painter is transformed, + // we go through standard code path + if (d->extended == 0 || !d->state->matrix.isIdentity()) { + if (staticText_d->size.isValid()) + drawText(QRectF(position, staticText_d->size), staticText_d->text); + else + drawText(position, staticText_d->text); + return; + } + + bool restoreWhenFinished = false; if (staticText_d->size.isValid()) { setClipRect(QRectF(position, staticText_d->size)); @@ -5746,8 +5758,8 @@ void QPainter::drawStaticText(const QPointF &position, const QStaticText &static } for (int i=0; i<staticText_d->itemCount; ++i) { - const QTextItemInt &gf = staticText_d->items[i]; - d->engine->drawTextItem(staticText_d->itemPositions[i] + position, gf); + QStaticTextItem *item = staticText_d->items + i; + d->extended->drawStaticTextItem(position, item); } if (restoreWhenFinished) diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 7b7f325..46da88e 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE // #define CACHE_DEBUG -void QTextureGlyphCache::populate(const QTextItemInt &ti, +void QTextureGlyphCache::populate(QFontEngine *fontEngine, const QVarLengthArray<glyph_t> &glyphs, const QVarLengthArray<QFixedPoint> &) { @@ -64,7 +64,7 @@ void QTextureGlyphCache::populate(const QTextItemInt &ti, qDebug() << " -> current transformation: " << m_transform; #endif - m_current_textitem = &ti; + m_current_fontengine = fontEngine; const int margin = glyphMargin(); QHash<glyph_t, Coord> listItemCoordinates; @@ -77,7 +77,7 @@ void QTextureGlyphCache::populate(const QTextItemInt &ti, continue; if (listItemCoordinates.contains(glyph)) continue; - glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyph, m_transform); + glyph_metrics_t metrics = fontEngine->boundingBox(glyph, m_transform); #ifdef CACHE_DEBUG printf("'%c' (%4x): w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f, ti.ascent=%.2f, ti.descent=%.2f\n", @@ -182,7 +182,7 @@ QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g) const break; }; - QFontEngineFT *ft = static_cast<QFontEngineFT*> (m_current_textitem->fontEngine); + QFontEngineFT *ft = static_cast<QFontEngineFT*> (m_current_fontengine); QFontEngineFT::QGlyphSet *gset = ft->loadTransformedGlyphSet(m_transform); if (gset && ft->loadGlyphs(gset, &g, 1, format)) { @@ -194,9 +194,9 @@ QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g) const } else #endif if (m_type == QFontEngineGlyphCache::Raster_RGBMask) - return m_current_textitem->fontEngine->alphaRGBMapForGlyph(g, glyphMargin(), m_transform); + return m_current_fontengine->alphaRGBMapForGlyph(g, glyphMargin(), m_transform); else - return m_current_textitem->fontEngine->alphaMapForGlyph(g, m_transform); + return m_current_fontengine->alphaMapForGlyph(g, m_transform); return QImage(); } @@ -321,13 +321,13 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g) #ifdef CACHE_DEBUG // QPainter p(&m_image); // p.drawLine( - QPoint base(c.x + glyphMargin(), c.y + glyphMargin() + c.baseLineY-1); + /*QPoint base(c.x + glyphMargin(), c.y + glyphMargin() + c.baseLineY-1); if (m_image.rect().contains(base)) m_image.setPixel(base, 255); m_image.save(QString::fromLatin1("cache-%1-%2-%3.png") .arg(m_current_textitem->font().family()) .arg(m_current_textitem->font().pointSize()) - .arg(m_transform.type())); + .arg(m_transform.type()));*/ #endif } diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h index d347e61..2f7fc96 100644 --- a/src/gui/painting/qtextureglyphcache_p.h +++ b/src/gui/painting/qtextureglyphcache_p.h @@ -76,7 +76,8 @@ class Q_GUI_EXPORT QTextureGlyphCache : public QFontEngineGlyphCache { public: QTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix) - : QFontEngineGlyphCache(matrix, type), m_w(0), m_h(0), m_cx(0), m_cy(0) { } + : QFontEngineGlyphCache(matrix, type), m_w(0), m_h(0), m_cx(0), m_cy(0), + m_current_fontengine(0) { } virtual ~QTextureGlyphCache() { } @@ -90,7 +91,7 @@ public: int baseLineY; }; - void populate(const QTextItemInt &ti, + void populate(QFontEngine *fontEngine, const QVarLengthArray<glyph_t> &glyphs, const QVarLengthArray<QFixedPoint> &positions); @@ -113,7 +114,7 @@ public: QImage textureMapForGlyph(glyph_t g) const; protected: - const QTextItemInt *m_current_textitem; + QFontEngine *m_current_fontengine; int m_w; // image width int m_h; // image height diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index 70e1c47..c43eeb0 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -262,7 +262,7 @@ bool QStaticText::isEmpty() const } QStaticTextPrivate::QStaticTextPrivate() - : glyphLayoutMemory(0), logClusterMemory(0), items(0), itemPositions(0), itemCount(0) + : items(0), itemCount(0) { ref = 1; } @@ -278,10 +278,7 @@ QStaticTextPrivate::QStaticTextPrivate(const QStaticTextPrivate &other) QStaticTextPrivate::~QStaticTextPrivate() { - delete[] glyphLayoutMemory; - delete[] logClusterMemory; - delete[] items; - delete[] itemPositions; + delete[] items; } QStaticTextPrivate *QStaticTextPrivate::get(const QStaticText *q) @@ -298,43 +295,37 @@ namespace { class DrawTextItemRecorder: public QPaintEngine { public: - DrawTextItemRecorder(int expectedItemCount, int expectedGlyphCount, - QTextItemInt *items, - QPointF *positions, - char *glyphLayoutMemory, - unsigned short *logClusterMemory) + DrawTextItemRecorder(int expectedItemCount, QStaticTextItem *items) : m_items(items), - m_positions(positions), - m_glyphLayoutMemory(glyphLayoutMemory), - m_logClusterMemory(logClusterMemory), - m_glyphLayoutMemoryOffset(0), - m_logClusterMemoryOffset(0), m_expectedItemCount(expectedItemCount), - m_expectedGlyphCount(expectedGlyphCount), - m_glyphCount(0), m_itemCount(0) { } virtual void drawTextItem(const QPointF &p, const QTextItem &textItem) { - const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); - + const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); + + Q_ASSERT(m_expectedItemCount < 0 || m_itemCount < m_expectedItemCount); m_itemCount++; - m_glyphCount += ti.glyphs.numGlyphs; - Q_ASSERT(m_expectedItemCount < 0 || m_itemCount <= m_expectedItemCount); - Q_ASSERT(m_expectedGlyphCount < 0 || m_glyphCount <= m_expectedGlyphCount); - - if (m_items == 0 || m_glyphLayoutMemory == 0 || m_logClusterMemory == 0 || m_positions == 0) + if (m_items == 0) return; - m_items[m_itemCount - 1] = ti.clone(m_glyphLayoutMemory + m_glyphLayoutMemoryOffset, - m_logClusterMemory + m_logClusterMemoryOffset); - m_positions[m_itemCount - 1] = p; + QStaticTextItem *currentItem = (m_items + (m_itemCount - 1)); + currentItem->fontEngine = ti.fontEngine; + currentItem->chars = ti.chars; + currentItem->numChars = ti.num_chars; + ti.fontEngine->getGlyphPositions(ti.glyphs, QTransform(), ti.flags, currentItem->glyphs, + currentItem->glyphPositions); + + QFixed fx = QFixed::fromReal(p.x()); + QFixed fy = QFixed::fromReal(p.y()); - m_glyphLayoutMemoryOffset += QGlyphLayout::spaceNeededForGlyphLayout(ti.glyphs.numGlyphs); - m_logClusterMemoryOffset += ti.glyphs.numGlyphs; + for (int i=0; i<currentItem->glyphPositions.size(); ++i) { + currentItem->glyphPositions[i].x += fx; + currentItem->glyphPositions[i].y += fy; + } } @@ -347,40 +338,23 @@ namespace { return User; } - int glyphCount() const - { - return m_glyphCount; - } - int itemCount() const { return m_itemCount; } private: - QTextItemInt *m_items; - char *m_glyphLayoutMemory; - unsigned short *m_logClusterMemory; - QPointF *m_positions; - - int m_glyphLayoutMemoryOffset; - int m_logClusterMemoryOffset; - int m_expectedGlyphCount; - int m_expectedItemCount; - int m_glyphCount; + QStaticTextItem *m_items; int m_itemCount; + int m_expectedItemCount; }; class DrawTextItemDevice: public QPaintDevice { public: - DrawTextItemDevice(int expectedItemCount = -1, int expectedGlyphCount = -1, - QTextItemInt *items = 0, QPointF *positions = 0, - char *glyphLayoutMemory = 0, unsigned short *logClusterMemory = 0) + DrawTextItemDevice(int expectedItemCount = -1, QStaticTextItem *items = 0) { - m_paintEngine = new DrawTextItemRecorder(expectedItemCount, expectedGlyphCount, - items, positions,glyphLayoutMemory, - logClusterMemory); + m_paintEngine = new DrawTextItemRecorder(expectedItemCount, items); } ~DrawTextItemDevice() @@ -424,11 +398,6 @@ namespace { return m_paintEngine; } - int glyphCount() const - { - return m_paintEngine->glyphCount(); - } - int itemCount() const { return m_paintEngine->itemCount(); @@ -438,17 +407,13 @@ namespace { private: DrawTextItemRecorder *m_paintEngine; - QRectF brect; }; } void QStaticTextPrivate::init() { - delete[] glyphLayoutMemory; - delete[] logClusterMemory; delete[] items; - delete[] itemPositions; // Draw once to count number of items and glyphs, so that we can use as little memory // as possible to store the data @@ -464,16 +429,10 @@ void QStaticTextPrivate::init() } itemCount = counterDevice.itemCount(); - items = new QTextItemInt[itemCount]; - itemPositions = new QPointF[itemCount]; - - int glyphCount = counterDevice.glyphCount(); - glyphLayoutMemory = new char[QGlyphLayout::spaceNeededForGlyphLayout(glyphCount)]; - logClusterMemory = new unsigned short[glyphCount]; + items = new QStaticTextItem[itemCount]; // Draw again to actually record the items and glyphs - DrawTextItemDevice recorderDevice(itemCount, glyphCount, items, itemPositions, - glyphLayoutMemory, logClusterMemory); + DrawTextItemDevice recorderDevice(itemCount, items); { QPainter painter(&recorderDevice); painter.setFont(font); diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h index f5fd8d3..2a8d23a 100644 --- a/src/gui/text/qstatictext_p.h +++ b/src/gui/text/qstatictext_p.h @@ -54,8 +54,26 @@ // #include <private/qtextengine_p.h> +#include <private/qfontengine_p.h> -QT_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE + +class QStaticTextItem +{ +public: + QStaticTextItem() : chars(0), numChars(0), fontEngine(0) {} + + QVarLengthArray<QFixedPoint> glyphPositions; // 8 bytes per glyph + QVarLengthArray<glyph_t> glyphs; // 4 bytes per glyph + const QChar *chars; // 2 bytes per glyph + // ================= + // 14 bytes per glyph + + int numChars; // 4 bytes per item + QFontEngine *fontEngine; // 4 bytes per item + // ================ + // 8 bytes per item +}; class QStaticText; class QStaticTextPrivate @@ -67,19 +85,17 @@ public: void init(); - QAtomicInt ref; + QAtomicInt ref; // 4 bytes per text - QString text; - QFont font; - QSizeF size; + QString text; // 4 bytes per text + QFont font; // 8 bytes per text + QSizeF size; // 16 bytes per text - QTextItemInt *items; - QPointF *itemPositions; - int itemCount; + QStaticTextItem *items; // 4 bytes per text + int itemCount; // 4 bytes per text + // ================ + // 40 bytes per text - char *glyphLayoutMemory; - unsigned short *logClusterMemory; - static QStaticTextPrivate *get(const QStaticText *q); }; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index caa679b..02a5246 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1272,7 +1272,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly } cache->setPaintEnginePrivate(this); - cache->populate(ti, glyphs, positions); + cache->populate(ti.fontEngine, glyphs, positions); if (cache->width() == 0 || cache->height() == 0) return; |