summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp34
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h6
-rw-r--r--src/gui/painting/qpaintengineex.cpp2
-rw-r--r--src/gui/painting/qpainter.cpp31
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp7
-rw-r--r--src/gui/painting/qtextureglyphcache_p.h5
-rw-r--r--src/gui/text/qstatictext.cpp77
-rw-r--r--src/gui/text/qstatictext_p.h27
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp2
9 files changed, 130 insertions, 61 deletions
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 387d646..87f374c 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3007,23 +3007,22 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx
blend(current, spans, &s->penData);
}
-void QRasterPaintEngine::drawCachedGlyphs(const QVarLengthArray<glyph_t> &glyphs,
- const QVarLengthArray<QFixedPoint> &positions,
- QFontEngine *fontEngine,
- const QTransform &matrix)
+void QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
+ const QFixedPoint *positions, QFontEngine *fontEngine)
{
Q_D(QRasterPaintEngine);
+ QRasterPaintEngineState *s = state();
QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(fontEngine->glyphFormat) : d->glyphCacheType;
QImageTextureGlyphCache *cache =
- static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphType, matrix));
+ static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphType, s->matrix));
if (!cache) {
- cache = new QImageTextureGlyphCache(glyphType, matrix);
+ cache = new QImageTextureGlyphCache(glyphType, s->matrix);
fontEngine->setGlyphCache(0, cache);
}
- cache->populate(fontEngine, glyphs, positions);
+ cache->populate(fontEngine, numGlyphs, glyphs, positions);
const QImage &image = cache->image();
int bpl = image.bytesPerLine();
@@ -3041,7 +3040,7 @@ void QRasterPaintEngine::drawCachedGlyphs(const QVarLengthArray<glyph_t> &glyphs
const QFixed offs = QFixed::fromReal(aliasedCoordinateDelta);
const uchar *bits = image.bits();
- for (int i=0; i<glyphs.size(); ++i) {
+ for (int i=0; i<numGlyphs; ++i) {
const QTextureGlyphCache::Coord &c = cache->coords.value(glyphs[i]);
int x = qFloor(positions[i].x + offs) + c.baseLineX - margin;
int y = qFloor(positions[i].y + offs) - c.baseLineY - margin;
@@ -3218,19 +3217,16 @@ void QRasterPaintEngine::drawStaticTextItem(const QPointF &p, QStaticTextItem *t
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;
+ for (int i=0; i<textItem->numGlyphs; ++i) {
+ textItem->glyphPositions[i].x += fx;
+ textItem->glyphPositions[i].y += fy;
}
- drawCachedGlyphs(textItem->glyphs, glyphPositions, textItem->fontEngine, matrix);
+
+ drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions,
+ textItem->fontEngine);
}
/*!
@@ -3285,11 +3281,13 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
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);
+ drawCachedGlyphs(glyphs.size(), glyphs.constData(), positions.constData(), ti.fontEngine);
return;
}
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 0250c3d..0626a48 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -257,10 +257,8 @@ private:
void fillRect(const QRectF &rect, QSpanData *data);
void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill);
- void drawCachedGlyphs(const QVarLengthArray<glyph_t> &glyphs,
- const QVarLengthArray<QFixedPoint> &positions,
- QFontEngine *fontEngine,
- const QTransform &matrix);
+ void drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions,
+ QFontEngine *fontEngine);
void drawStaticTextItem(const QPointF &p, QStaticTextItem *textItem);
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 15085f9..f167b348 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -592,7 +592,7 @@ 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())
+ // ### Make this pure virtual after implementing in all subclasses
}
void QPaintEngineEx::draw(const QVectorPath &path)
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 1d7f57d..4eace16 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -5730,11 +5730,12 @@ 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);
+ QStaticTextPrivate *staticText_d =
+ const_cast<QStaticTextPrivate *>(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 (d->extended == 0) {
if (staticText_d->size.isValid())
drawText(QRectF(position, staticText_d->size), staticText_d->text);
else
@@ -5742,14 +5743,33 @@ void QPainter::drawStaticText(const QPointF &position, const QStaticText &static
return;
}
+ // Don't recalculate entire layout because of translation, rather add the dx and dy
+ // into the position to move each text item the correct distance.
+ QPointF translatedPosition = position;
+ QTransform matrix = d->state->transform();
+ if (matrix.isTranslating()) {
+ translatedPosition.rx() += matrix.dx();
+ translatedPosition.ry() += matrix.dy();
+ translate(-matrix.dx(), -matrix.dy());
+ }
+
+ // If the transform is not identical to the text transform,
+ // we have to relayout the text (for other transformations than plain translation)
+ if (staticText_d->matrix != d->state->transform()) {
+ staticText_d->matrix = d->state->transform();
+ staticText_d->init();
+ }
+
bool restoreWhenFinished = false;
if (staticText_d->size.isValid()) {
+ save();
setClipRect(QRectF(position, staticText_d->size));
- save();
restoreWhenFinished = true;
}
+ // ### Should we pick up the painter's font and recalculate the layout, like we do
+ // with the matrix?
if (font() != staticText_d->font) {
setFont(staticText_d->font);
@@ -5759,11 +5779,14 @@ void QPainter::drawStaticText(const QPointF &position, const QStaticText &static
for (int i=0; i<staticText_d->itemCount; ++i) {
QStaticTextItem *item = staticText_d->items + i;
- d->extended->drawStaticTextItem(position, item);
+ d->extended->drawStaticTextItem(translatedPosition, item);
}
if (restoreWhenFinished)
restore();
+
+ if (matrix.isTranslating())
+ setTransform(matrix);
}
/*!
diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp
index 46da88e..5a6a0d9 100644
--- a/src/gui/painting/qtextureglyphcache.cpp
+++ b/src/gui/painting/qtextureglyphcache.cpp
@@ -55,9 +55,8 @@ QT_BEGIN_NAMESPACE
// #define CACHE_DEBUG
-void QTextureGlyphCache::populate(QFontEngine *fontEngine,
- const QVarLengthArray<glyph_t> &glyphs,
- const QVarLengthArray<QFixedPoint> &)
+void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs,
+ const QFixedPoint *)
{
#ifdef CACHE_DEBUG
printf("Populating with '%s'\n", QString::fromRawData(ti.chars, ti.num_chars).toLatin1().data());
@@ -71,7 +70,7 @@ void QTextureGlyphCache::populate(QFontEngine *fontEngine,
int rowHeight = 0;
// check each glyph for its metrics and get the required rowHeight.
- for (int i=0; i < glyphs.size(); ++i) {
+ for (int i=0; i < numGlyphs; ++i) {
const glyph_t glyph = glyphs[i];
if (coords.contains(glyph))
continue;
diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h
index 2f7fc96..b8717b1 100644
--- a/src/gui/painting/qtextureglyphcache_p.h
+++ b/src/gui/painting/qtextureglyphcache_p.h
@@ -91,9 +91,8 @@ public:
int baseLineY;
};
- void populate(QFontEngine *fontEngine,
- const QVarLengthArray<glyph_t> &glyphs,
- const QVarLengthArray<QFixedPoint> &positions);
+ void populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs,
+ const QFixedPoint *positions);
virtual void createTextureData(int width, int height) = 0;
virtual void resizeTextureData(int width, int height) = 0;
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index c43eeb0..e6f2cc6 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -262,7 +262,7 @@ bool QStaticText::isEmpty() const
}
QStaticTextPrivate::QStaticTextPrivate()
- : items(0), itemCount(0)
+ : items(0), itemCount(0), glyphPool(0), positionPool(0)
{
ref = 1;
}
@@ -279,6 +279,8 @@ QStaticTextPrivate::QStaticTextPrivate(const QStaticTextPrivate &other)
QStaticTextPrivate::~QStaticTextPrivate()
{
delete[] items;
+ delete[] glyphPool;
+ delete[] positionPool;
}
QStaticTextPrivate *QStaticTextPrivate::get(const QStaticText *q)
@@ -295,37 +297,58 @@ namespace {
class DrawTextItemRecorder: public QPaintEngine
{
public:
- DrawTextItemRecorder(int expectedItemCount, QStaticTextItem *items)
+ DrawTextItemRecorder(int expectedItemCount, QStaticTextItem *items,
+ int expectedGlyphCount, QFixedPoint *positionPool, glyph_t *glyphPool)
: m_items(items),
m_expectedItemCount(expectedItemCount),
- m_itemCount(0)
+ m_expectedGlyphCount(expectedGlyphCount),
+ m_itemCount(0), m_glyphCount(0),
+ m_positionPool(positionPool),
+ m_glyphPool(glyphPool)
{
}
virtual void drawTextItem(const QPointF &p, const QTextItem &textItem)
{
const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
-
- Q_ASSERT(m_expectedItemCount < 0 || m_itemCount < m_expectedItemCount);
- m_itemCount++;
+ m_itemCount++;
+ m_glyphCount += ti.glyphs.numGlyphs;
if (m_items == 0)
return;
+ Q_ASSERT(m_itemCount <= m_expectedItemCount);
+ Q_ASSERT(m_glyphCount <= m_expectedGlyphCount);
+
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);
+ currentItem->numGlyphs = ti.glyphs.numGlyphs;
+ currentItem->glyphs = m_glyphPool;
+ currentItem->glyphPositions = m_positionPool;
+
+ QVarLengthArray<glyph_t> glyphs;
+ QVarLengthArray<QFixedPoint> positions;
+ ti.fontEngine->getGlyphPositions(ti.glyphs, state->transform(), ti.flags,
+ glyphs, positions);
+
+ int size = glyphs.size();
+ Q_ASSERT(size == ti.glyphs.numGlyphs);
+ Q_ASSERT(size == positions.size());
+
+ memmove(currentItem->glyphs, glyphs.constData(), sizeof(glyph_t) * size);
+ memmove(currentItem->glyphPositions, positions.constData(), sizeof(QFixedPoint) * size);
QFixed fx = QFixed::fromReal(p.x());
QFixed fy = QFixed::fromReal(p.y());
-
- for (int i=0; i<currentItem->glyphPositions.size(); ++i) {
+ for (int i=0; i<size; ++i) {
currentItem->glyphPositions[i].x += fx;
currentItem->glyphPositions[i].y += fy;
}
+
+ m_glyphPool += size;
+ m_positionPool += size;
}
@@ -343,18 +366,31 @@ namespace {
return m_itemCount;
}
+ int glyphCount() const
+ {
+ return m_glyphCount;
+ }
+
private:
QStaticTextItem *m_items;
int m_itemCount;
+ int m_glyphCount;
int m_expectedItemCount;
+ int m_expectedGlyphCount;
+
+ glyph_t *m_glyphPool;
+ QFixedPoint *m_positionPool;
};
class DrawTextItemDevice: public QPaintDevice
{
public:
- DrawTextItemDevice(int expectedItemCount = -1, QStaticTextItem *items = 0)
+ DrawTextItemDevice(int expectedItemCount = -1, QStaticTextItem *items = 0,
+ int expectedGlyphCount = -1, QFixedPoint *positionPool = 0,
+ glyph_t *glyphPool = 0)
{
- m_paintEngine = new DrawTextItemRecorder(expectedItemCount, items);
+ m_paintEngine = new DrawTextItemRecorder(expectedItemCount, items,
+ expectedGlyphCount, positionPool, glyphPool);
}
~DrawTextItemDevice()
@@ -403,7 +439,10 @@ namespace {
return m_paintEngine->itemCount();
}
-
+ int glyphCount() const
+ {
+ return m_paintEngine->glyphCount();
+ }
private:
DrawTextItemRecorder *m_paintEngine;
@@ -414,6 +453,8 @@ namespace {
void QStaticTextPrivate::init()
{
delete[] items;
+ delete[] glyphPool;
+ delete[] positionPool;
// Draw once to count number of items and glyphs, so that we can use as little memory
// as possible to store the data
@@ -421,6 +462,7 @@ void QStaticTextPrivate::init()
{
QPainter painter(&counterDevice);
painter.setFont(font);
+ painter.setTransform(matrix);
if (size.isValid())
painter.drawText(QRectF(QPointF(0, 0), size), text);
@@ -428,14 +470,19 @@ void QStaticTextPrivate::init()
painter.drawText(0, 0, text);
}
- itemCount = counterDevice.itemCount();
+ itemCount = counterDevice.itemCount();
items = new QStaticTextItem[itemCount];
+ int glyphCount = counterDevice.glyphCount();
+ glyphPool = new glyph_t[glyphCount];
+ positionPool = new QFixedPoint[glyphCount];
+
// Draw again to actually record the items and glyphs
- DrawTextItemDevice recorderDevice(itemCount, items);
+ DrawTextItemDevice recorderDevice(itemCount, items, glyphCount, positionPool, glyphPool);
{
QPainter painter(&recorderDevice);
painter.setFont(font);
+ painter.setTransform(matrix);
if (size.isValid())
painter.drawText(QRectF(QPointF(0, 0), size), text);
diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h
index 2a8d23a..e1ae80d 100644
--- a/src/gui/text/qstatictext_p.h
+++ b/src/gui/text/qstatictext_p.h
@@ -63,16 +63,18 @@ 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
+ // ### Use constant length arrays here to minimize memory consumption
+ QFixedPoint *glyphPositions; // 8 bytes per glyph
+ glyph_t *glyphs; // 4 bytes per glyph
const QChar *chars; // 2 bytes per glyph
// =================
// 14 bytes per glyph
+ int numGlyphs; // 4 bytes per item
int numChars; // 4 bytes per item
QFontEngine *fontEngine; // 4 bytes per item
// ================
- // 8 bytes per item
+ // 12 bytes per item
};
class QStaticText;
@@ -85,16 +87,19 @@ public:
void init();
- QAtomicInt ref; // 4 bytes per text
+ QAtomicInt ref; // 4 bytes per text
- QString text; // 4 bytes per text
- QFont font; // 8 bytes per text
- QSizeF size; // 16 bytes per text
+ QString text; // 4 bytes per text
+ QFont font; // 8 bytes per text
+ QSizeF size; // 16 bytes per text
- QStaticTextItem *items; // 4 bytes per text
- int itemCount; // 4 bytes per text
- // ================
- // 40 bytes per text
+ QTransform matrix; // 80 bytes per text
+ QStaticTextItem *items; // 4 bytes per text
+ int itemCount; // 4 bytes per text
+ glyph_t *glyphPool; // 4 bytes per text
+ QFixedPoint *positionPool; // 4 bytes per text
+ // ================
+ // 128 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 02a5246..e4fe84f 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.fontEngine, glyphs, positions);
+ cache->populate(ti.fontEngine, glyphs.size(), glyphs.constData(), positions.constData());
if (cache->width() == 0 || cache->height() == 0)
return;