--- a/src/gui/painting/qtextureglyphcache.cpp Wed Jun 23 19:07:03 2010 +0300
+++ b/src/gui/painting/qtextureglyphcache.cpp Tue Jul 06 15:10:48 2010 +0300
@@ -55,16 +55,29 @@
// #define CACHE_DEBUG
-void QTextureGlyphCache::populate(const QTextItemInt &ti,
- const QVarLengthArray<glyph_t> &glyphs,
- const QVarLengthArray<QFixedPoint> &)
+// returns the highest number closest to v, which is a power of 2
+// NB! assumes 32 bit ints
+static inline int qt_next_power_of_two(int v)
+{
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ ++v;
+ return v;
+}
+
+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());
+ printf("Populating with %d glyphs\n", numGlyphs);
qDebug() << " -> current transformation: " << m_transform;
#endif
- m_current_textitem = &ti;
+ m_current_fontengine = fontEngine;
const int margin = glyphMargin();
const int paddingDoubled = glyphPadding() * 2;
@@ -72,26 +85,23 @@
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;
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",
- ti.chars[i].toLatin1(),
+ printf("(%4x): w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f\n",
glyph,
metrics.width.toReal(),
metrics.height.toReal(),
metrics.xoff.toReal(),
metrics.yoff.toReal(),
metrics.x.toReal(),
- metrics.y.toReal(),
- ti.ascent.toReal(),
- ti.descent.toReal());
+ metrics.y.toReal());
#endif
int glyph_width = metrics.width.ceil().toInt();
int glyph_height = metrics.height.ceil().toInt();
@@ -117,26 +127,25 @@
rowHeight += margin * 2 + paddingDoubled;
if (isNull())
- createCache(QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH, rowHeight);
+ createCache(QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH, qt_next_power_of_two(rowHeight));
// now actually use the coords and paint the wanted glyps into cache.
QHash<glyph_t, Coord>::iterator iter = listItemCoordinates.begin();
while (iter != listItemCoordinates.end()) {
Coord c = iter.value();
+ m_currentRowHeight = qMax(m_currentRowHeight, c.h + margin * 2);
+
if (m_cx + c.w > m_w) {
// no room on the current line, start new glyph strip
m_cx = 0;
- m_cy = m_h + paddingDoubled;
+ m_cy += m_currentRowHeight + paddingDoubled;
+ m_currentRowHeight = 0; // New row
}
if (m_cy + c.h > m_h) {
- int new_height;
- if (m_cx == 0) { // add a whole row
- new_height = m_h + rowHeight;
- m_cy = m_h;
- } else { // just extend row
- new_height = m_cy + rowHeight;
- }
+ int new_height = m_h*2;
+ while (new_height < m_cy + c.h)
+ new_height *= 2;
// if no room in the current texture - realloc a larger texture
resizeTextureData(m_w, new_height);
m_h = new_height;
@@ -148,14 +157,7 @@
fillTexture(c, iter.key());
coords.insert(iter.key(), c);
- if (m_cx + c.w > m_w) {
- m_cx = 0;
- m_cy += rowHeight;
- } else {
- // for the Mono case, glyph_width is 8-bit aligned,
- // and therefore so will m_cx
- m_cx += c.w + paddingDoubled;
- }
+ m_cx += c.w + paddingDoubled;
++iter;
}
@@ -183,11 +185,11 @@
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)) {
- QFontEngineFT::Glyph *glyph = gset->glyph_data.value(g);
+ QFontEngineFT::Glyph *glyph = gset->getGlyph(g);
const int bytesPerLine = (format == QFontEngineFT::Format_Mono ? ((glyph->width + 31) & ~31) >> 3
: (glyph->width + 3) & ~3);
return QImage(glyph->data, glyph->width, glyph->height, bytesPerLine, imageFormat);
@@ -195,9 +197,9 @@
} 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();
}
@@ -325,10 +327,7 @@
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()));
+ m_image.save(QString::fromLatin1("cache-%1.png").arg(int(this)));
#endif
}