summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2011-03-28 21:42:03 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2011-03-28 21:42:03 (GMT)
commit53f16164661f8692aef9bd941b92697a047c0f4c (patch)
tree16912d8c0c5a58eb726493415b60f6b18fb831f0
parent4da2ba2e788bb63a155e1d10ae559d4366eed875 (diff)
parent2e7af8c4e8ced21ced3e7f23590faeffffa1e0ff (diff)
downloadQt-53f16164661f8692aef9bd941b92697a047c0f4c.zip
Qt-53f16164661f8692aef9bd941b92697a047c0f4c.tar.gz
Qt-53f16164661f8692aef9bd941b92697a047c0f4c.tar.bz2
Merge branch 'master' of scm.dev.nokia.troll.no:qt/qt-fire-staging into master-integration
* 'master' of scm.dev.nokia.troll.no:qt/qt-fire-staging: Fix crash and infinite recursion caused by previous commits Fix remaining regressions in QWS Take Xft.hintstyle by default to match the behavior of GTK+ Fixed remaining issues in subpixel positioning with FreeType Fix QTransform debug output qFloor the decoration line width before painting Let QTextLine decide its own x position in QPainter Avoid repeatedly trying to load unloadable plugins, causing slowness Reset GL glyph cache when texture limit is reached unlockFace was put in the wrong place in previous patch Implement subpixel positioning with FreeType
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp8
-rw-r--r--src/corelib/plugin/qlibrary.cpp9
-rw-r--r--src/gui/kernel/qapplication_x11.cpp4
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp252
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h2
-rw-r--r--src/gui/painting/qpaintengine_x11.cpp2
-rw-r--r--src/gui/painting/qpainter.cpp15
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp17
-rw-r--r--src/gui/painting/qtransform.cpp3
-rw-r--r--src/gui/text/qfontdatabase_x11.cpp1
-rw-r--r--src/gui/text/qfontengine_ft.cpp173
-rw-r--r--src/gui/text/qfontengine_ft_p.h55
-rw-r--r--src/gui/text/qfontengine_qpf.cpp2
-rw-r--r--src/gui/text/qfontengine_x11.cpp23
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp9
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp15
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h2
-rw-r--r--src/opengl/qgl.cpp15
-rw-r--r--src/opengl/qgl_p.h1
19 files changed, 366 insertions, 242 deletions
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp
index 6c4d9f1..c202e1f 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp
@@ -1052,16 +1052,16 @@ HB_Bool HB_SelectScript(HB_ShaperItem *shaper_item, const HB_OpenTypeFeature *fe
{
HB_Script script = shaper_item->item.script;
- if (!shaper_item->face->supported_scripts[script])
- return false;
-
HB_Face face = shaper_item->face;
if (face->current_script == script && face->current_flags == shaper_item->shaperFlags)
- return true;
+ return shaper_item->face->supported_scripts[script] ? true : false;
face->current_script = script;
face->current_flags = shaper_item->shaperFlags;
+ if (!shaper_item->face->supported_scripts[script])
+ return false;
+
assert(script < HB_ScriptCount);
// find script in our list of supported scripts.
unsigned int tag = ot_scripts[script].tag;
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index ecd1aac..80e927b 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -516,6 +516,8 @@ bool QLibraryPrivate::loadPlugin()
libraryUnloadCount.ref();
return true;
}
+ if (pluginState == IsNotAPlugin)
+ return false;
if (load()) {
instance = (QtPluginInstanceFunction)resolve("qt_plugin_instance");
#if defined(Q_OS_SYMBIAN)
@@ -528,6 +530,9 @@ bool QLibraryPrivate::loadPlugin()
#endif
return instance;
}
+ if (qt_debug_component())
+ qWarning() << "QLibraryPrivate::loadPlugin failed on" << fileName << ":" << errorString;
+ pluginState = IsNotAPlugin;
return false;
}
@@ -687,7 +692,7 @@ bool QLibraryPrivate::isPlugin(QSettings *settings)
.arg((QT_VERSION & 0xff00) >> 8)
.arg(QLIBRARY_AS_DEBUG ? QLatin1String("debug") : QLatin1String("false"))
.arg(fileName);
-#ifdef Q_WS_MAC
+#ifdef Q_WS_MAC
// On Mac, add the application arch to the reg key in order to
// cache plugin information separately for each arch. This prevents
// Qt from wrongly caching plugin load failures when the archs
@@ -702,7 +707,7 @@ bool QLibraryPrivate::isPlugin(QSettings *settings)
regkey += QLatin1String("-ppc");
#endif
#endif // Q_WS_MAC
-
+
QStringList reg;
#ifndef QT_NO_SETTINGS
if (!settings) {
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 589b12e..31f70c7 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -1587,6 +1587,9 @@ static void getXDefault(const char *group, const char *key, int *val)
int v = strtol(str, &end, 0);
if (str != end)
*val = v;
+ // otherwise use fontconfig to convert the string to integer
+ else
+ FcNameConstant((FcChar8 *) str, val);
}
}
@@ -2237,6 +2240,7 @@ void qt_init(QApplicationPrivate *priv, int,
}
getXDefault("Xft", FC_ANTIALIAS, &X11->fc_antialias);
#ifdef FC_HINT_STYLE
+ X11->fc_hint_style = -1;
getXDefault("Xft", FC_HINT_STYLE, &X11->fc_hint_style);
#endif
#if 0
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 9242fb6..9f3b9b9 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3076,65 +3076,150 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx
blend(current, spans, &s->penData);
}
-void QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
+bool 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;
+#if !defined(QT_NO_FREETYPE)
+ if (fontEngine->type() == QFontEngine::Freetype) {
+ QFontEngineFT *fe = static_cast<QFontEngineFT *>(fontEngine);
+ QFontEngineFT::GlyphFormat neededFormat =
+ painter()->device()->devType() == QInternal::Widget
+ ? fe->defaultGlyphFormat()
+ : QFontEngineFT::Format_A8;
+
+ if (d_func()->mono_surface
+ || fe->isBitmapFont() // alphaPenBlt can handle mono, too
+ )
+ neededFormat = QFontEngineFT::Format_Mono;
+
+ if (neededFormat == QFontEngineFT::Format_None)
+ neededFormat = QFontEngineFT::Format_A8;
+
+ QFontEngineFT::QGlyphSet *gset = fe->defaultGlyphs();
+ if (s->matrix.type() >= QTransform::TxScale) {
+ if (s->matrix.isAffine())
+ gset = fe->loadTransformedGlyphSet(s->matrix);
+ else
+ gset = 0;
+ }
- QImageTextureGlyphCache *cache =
- static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphType, s->matrix));
- if (!cache) {
- cache = new QImageTextureGlyphCache(glyphType, s->matrix);
- fontEngine->setGlyphCache(0, cache);
- }
+ if (!gset || gset->outline_drawing
+ || !fe->loadGlyphs(gset, glyphs, numGlyphs, positions, neededFormat))
+ return false;
+
+ FT_Face lockedFace = 0;
+
+ int depth;
+ switch (neededFormat) {
+ case QFontEngineFT::Format_Mono:
+ depth = 1;
+ break;
+ case QFontEngineFT::Format_A8:
+ depth = 8;
+ break;
+ case QFontEngineFT::Format_A32:
+ depth = 32;
+ break;
+ default:
+ Q_ASSERT(false);
+ depth = 0;
+ };
+
+ for (int i = 0; i < numGlyphs; i++) {
+ QFixed spp = fe->subPixelPositionForX(positions[i].x);
+ QFontEngineFT::Glyph *glyph = gset->getGlyph(glyphs[i], spp);
+
+ if (!glyph || glyph->format != neededFormat) {
+ if (!lockedFace)
+ lockedFace = fe->lockFace();
+ glyph = fe->loadGlyph(gset, glyphs[i], spp, neededFormat);
+ }
+
+ if (!glyph || !glyph->data)
+ continue;
+
+ int pitch;
+ switch (neededFormat) {
+ case QFontEngineFT::Format_Mono:
+ pitch = ((glyph->width + 31) & ~31) >> 3;
+ break;
+ case QFontEngineFT::Format_A8:
+ pitch = (glyph->width + 3) & ~3;
+ break;
+ case QFontEngineFT::Format_A32:
+ pitch = glyph->width * 4;
+ break;
+ default:
+ Q_ASSERT(false);
+ pitch = 0;
+ };
+
+ alphaPenBlt(glyph->data, pitch, depth,
+ qFloor(positions[i].x) + glyph->x,
+ qFloor(positions[i].y) - glyph->y,
+ glyph->width, glyph->height);
+ }
+ if (lockedFace)
+ fe->unlockFace();
+ } else
+#endif
+ {
+ QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(fontEngine->glyphFormat) : d->glyphCacheType;
- cache->populate(fontEngine, numGlyphs, glyphs, positions);
- cache->fillInPendingGlyphs();
+ QImageTextureGlyphCache *cache =
+ static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphType, s->matrix));
+ if (!cache) {
+ cache = new QImageTextureGlyphCache(glyphType, s->matrix);
+ fontEngine->setGlyphCache(0, cache);
+ }
- const QImage &image = cache->image();
- int bpl = image.bytesPerLine();
+ cache->populate(fontEngine, numGlyphs, glyphs, positions);
+ cache->fillInPendingGlyphs();
- int depth = image.depth();
- int rightShift = 0;
- int leftShift = 0;
- if (depth == 32)
- leftShift = 2; // multiply by 4
- else if (depth == 1)
- rightShift = 3; // divide by 8
+ const QImage &image = cache->image();
+ int bpl = image.bytesPerLine();
- int margin = cache->glyphMargin();
+ int depth = image.depth();
+ int rightShift = 0;
+ int leftShift = 0;
+ if (depth == 32)
+ leftShift = 2; // multiply by 4
+ else if (depth == 1)
+ rightShift = 3; // divide by 8
- bool supportsSubPixelPositions = fontEngine->supportsSubPixelPositions();
+ int margin = cache->glyphMargin();
- const uchar *bits = image.bits();
- for (int i=0; i<numGlyphs; ++i) {
+ bool supportsSubPixelPositions = fontEngine->supportsSubPixelPositions();
- QFixed subPixelPosition;
- if (supportsSubPixelPositions)
- subPixelPosition = cache->subPixelPositionForX(positions[i].x);
- QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], subPixelPosition);
- const QTextureGlyphCache::Coord &c = cache->coords[glyph];
- if (c.isNull())
- continue;
+ const uchar *bits = image.bits();
+ for (int i=0; i<numGlyphs; ++i) {
- int x = qFloor(positions[i].x) + c.baseLineX - margin;
- int y = qFloor(positions[i].y) - c.baseLineY - margin;
+ QFixed subPixelPosition;
+ if (supportsSubPixelPositions)
+ subPixelPosition = cache->subPixelPositionForX(positions[i].x);
+ QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], subPixelPosition);
+ const QTextureGlyphCache::Coord &c = cache->coords[glyph];
+ if (c.isNull())
+ continue;
-// printf("drawing [%d %d %d %d] baseline [%d %d], glyph: %d, to: %d %d, pos: %d %d\n",
-// c.x, c.y,
-// c.w, c.h,
-// c.baseLineX, c.baseLineY,
-// glyphs[i],
-// x, y,
-// positions[i].x.toInt(), positions[i].y.toInt());
+ int x = qFloor(positions[i].x) + c.baseLineX - margin;
+ int y = qFloor(positions[i].y) - c.baseLineY - margin;
- alphaPenBlt(bits + ((c.x << leftShift) >> rightShift) + c.y * bpl, bpl, depth, x, y, c.w, c.h);
- }
+ // printf("drawing [%d %d %d %d] baseline [%d %d], glyph: %d, to: %d %d, pos: %d %d\n",
+ // c.x, c.y,
+ // c.w, c.h,
+ // c.baseLineX, c.baseLineY,
+ // glyphs[i],
+ // x, y,
+ // positions[i].x.toInt(), positions[i].y.toInt());
- return;
+ alphaPenBlt(bits + ((c.x << leftShift) >> rightShift) + c.y * bpl, bpl, depth, x, y, c.w, c.h);
+ }
+ }
+ return true;
}
#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
@@ -3445,91 +3530,10 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
if (glyphs.size() == 0)
return;
- // only use subpixel antialiasing when drawing to widgets
- QFontEngineFT::GlyphFormat neededFormat =
- painter()->device()->devType() == QInternal::Widget
- ? fe->defaultGlyphFormat()
- : QFontEngineFT::Format_A8;
-
- if (d_func()->mono_surface
- || fe->isBitmapFont() // alphaPenBlt can handle mono, too
- )
- neededFormat = QFontEngineFT::Format_Mono;
-
- if (neededFormat == QFontEngineFT::Format_None)
- neededFormat = QFontEngineFT::Format_A8;
-
- QFontEngineFT::QGlyphSet *gset = fe->defaultGlyphs();
- if (s->matrix.type() >= QTransform::TxScale) {
- if (s->matrix.isAffine())
- gset = fe->loadTransformedGlyphSet(s->matrix);
- else
- gset = 0;
-
- }
-
- if (!gset || gset->outline_drawing
- || !fe->loadGlyphs(gset, glyphs.data(), glyphs.size(), neededFormat))
- {
+ if (!drawCachedGlyphs(glyphs.size(), glyphs.constData(), positions.constData(), fontEngine))
QPaintEngine::drawTextItem(p, ti);
- return;
- }
-
- FT_Face lockedFace = 0;
-
- int depth;
- switch (neededFormat) {
- case QFontEngineFT::Format_Mono:
- depth = 1;
- break;
- case QFontEngineFT::Format_A8:
- depth = 8;
- break;
- case QFontEngineFT::Format_A32:
- depth = 32;
- break;
- default:
- Q_ASSERT(false);
- depth = 0;
- };
- for(int i = 0; i < glyphs.size(); i++) {
- QFontEngineFT::Glyph *glyph = gset->getGlyph(glyphs[i]);
-
- if (!glyph || glyph->format != neededFormat) {
- if (!lockedFace)
- lockedFace = fe->lockFace();
- glyph = fe->loadGlyph(gset, glyphs[i], neededFormat);
- }
-
- if (!glyph || !glyph->data)
- continue;
-
- int pitch;
- switch (neededFormat) {
- case QFontEngineFT::Format_Mono:
- pitch = ((glyph->width + 31) & ~31) >> 3;
- break;
- case QFontEngineFT::Format_A8:
- pitch = (glyph->width + 3) & ~3;
- break;
- case QFontEngineFT::Format_A32:
- pitch = glyph->width * 4;
- break;
- default:
- Q_ASSERT(false);
- pitch = 0;
- };
-
- alphaPenBlt(glyph->data, pitch, depth,
- qFloor(positions[i].x) + glyph->x,
- qFloor(positions[i].y) - glyph->y,
- glyph->width, glyph->height);
- }
- if (lockedFace)
- fe->unlockFace();
return;
-
#endif
#endif
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 7f902a8..52f51fa 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -261,7 +261,7 @@ private:
void fillRect(const QRectF &rect, QSpanData *data);
void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill);
- void drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions,
+ bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions,
QFontEngine *fontEngine);
#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp
index 8b71b83..94828fb 100644
--- a/src/gui/painting/qpaintengine_x11.cpp
+++ b/src/gui/painting/qpaintengine_x11.cpp
@@ -2385,7 +2385,7 @@ void QX11PaintEngine::drawFreetype(const QPointF &p, const QTextItemInt &ti)
set = ft->loadTransformedGlyphSet(d->matrix);
if (!set || set->outline_drawing
- || !ft->loadGlyphs(set, glyphs.data(), glyphs.size(), QFontEngineFT::Format_Render))
+ || !ft->loadGlyphs(set, glyphs.constData(), glyphs.size(), positions.constData(), QFontEngineFT::Format_Render))
{
QPaintEngine::drawTextItem(p, ti);
return;
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 2c25e70..14fb772 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -6463,7 +6463,7 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
pen.setWidthF(fe->lineThickness().toReal());
pen.setCapStyle(Qt::FlatCap);
- QLineF line(pos.x(), pos.y(), pos.x() + width, pos.y());
+ QLineF line(pos.x(), pos.y(), pos.x() + qFloor(width), pos.y());
const qreal underlineOffset = fe->underlinePosition().toReal();
// deliberately ceil the offset to avoid the underline coming too close to
@@ -8149,6 +8149,10 @@ start_lengthVariant:
engine.option.setTextDirection(layout_direction);
if (tf & Qt::AlignJustify)
engine.option.setAlignment(Qt::AlignJustify);
+ else if (tf & Qt::AlignRight)
+ engine.option.setAlignment(Qt::AlignRight);
+ else if (tf & Qt::AlignHCenter)
+ engine.option.setAlignment(Qt::AlignHCenter);
else
engine.option.setAlignment(Qt::AlignLeft); // do not do alignment twice
@@ -8244,14 +8248,7 @@ start_lengthVariant:
for (int i = 0; i < textLayout.lineCount(); i++) {
QTextLine line = textLayout.lineAt(i);
-
- qreal advance = line.horizontalAdvance();
- if (tf & Qt::AlignRight)
- xoff = r.width() - advance;
- else if (tf & Qt::AlignHCenter)
- xoff = (r.width() - advance)/2;
-
- line.draw(painter, QPointF(r.x() + xoff + line.x(), r.y() + yoff));
+ line.draw(painter, QPointF(r.x(), r.y() + yoff));
}
if (restore) {
diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp
index e75c0f5..f0db805 100644
--- a/src/gui/painting/qtextureglyphcache.cpp
+++ b/src/gui/painting/qtextureglyphcache.cpp
@@ -134,9 +134,13 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
if (!supportsSubPixelPositions) {
m_subPixelPositionCount = 1;
} else {
+#if !defined(Q_WS_X11)
int i = 0;
while (m_subPixelPositionCount == 0 && i < numGlyphs)
m_subPixelPositionCount = calculateSubPixelPositionCount(glyphs[i++]);
+#else
+ m_subPixelPositionCount = 4;
+#endif
}
}
@@ -234,6 +238,11 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
}
}
+ if (maxTextureHeight() > 0 && m_cy + c.h > maxTextureHeight()) {
+ // We can't make a cache of the required size, so we bail out
+ return false;
+ }
+
c.x = m_cx;
c.y = m_cy;
@@ -307,9 +316,11 @@ QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition
QFontEngineFT *ft = static_cast<QFontEngineFT*> (m_current_fontengine);
QFontEngineFT::QGlyphSet *gset = ft->loadTransformedGlyphSet(m_transform);
+ QFixedPoint positions[1];
+ positions[0].x = subPixelPosition;
- if (gset && ft->loadGlyphs(gset, &g, 1, format)) {
- QFontEngineFT::Glyph *glyph = gset->getGlyph(g);
+ if (gset && ft->loadGlyphs(gset, &g, 1, positions, format)) {
+ QFontEngineFT::Glyph *glyph = gset->getGlyph(g, subPixelPosition);
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);
@@ -356,7 +367,7 @@ void QImageTextureGlyphCache::createTextureData(int width, int height)
int QImageTextureGlyphCache::glyphMargin() const
{
-#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
+#if (defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) || defined(Q_WS_X11)
return 0;
#else
return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0;
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 4441b30..7d11e2f 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -1085,8 +1085,11 @@ QDebug operator<<(QDebug dbg, const QTransform &m)
"TxNone",
"TxTranslate",
"TxScale",
+ 0,
"TxRotate",
+ 0, 0, 0,
"TxShear",
+ 0, 0, 0, 0, 0, 0, 0,
"TxProject"
};
diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp
index 02b0148..0c0c4c8 100644
--- a/src/gui/text/qfontdatabase_x11.cpp
+++ b/src/gui/text/qfontdatabase_x11.cpp
@@ -746,6 +746,7 @@ QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &request)
QFontDef fontDef;
fontDef.styleStrategy = request.styleStrategy;
+ fontDef.hintingPreference = request.hintingPreference;
FcChar8 *value = 0;
if (FcPatternGetString(pattern, FC_FAMILY, 0, &value) == FcResultMatch) {
fontDef.family = QString::fromUtf8(reinterpret_cast<const char *>(value));
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index f5e9e1c..db0156a 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -174,9 +174,7 @@ int QFreetypeFace::fsType() const
HB_Error QFreetypeFace::getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints)
{
- int load_flags = (flags & HB_ShaperFlag_UseDesignMetrics) ? FT_LOAD_NO_HINTING : FT_LOAD_DEFAULT;
-
- if (HB_Error error = (HB_Error)FT_Load_Glyph(face, glyph, load_flags))
+ if (HB_Error error = (HB_Error)FT_Load_Glyph(face, glyph, flags))
return error;
if (face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
@@ -760,12 +758,9 @@ void QFontEngineFT::setDefaultHintStyle(HintStyle style)
default_hint_style = style;
}
-QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph, GlyphFormat format) const
+int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags,
+ bool &hsubpixel, int &vfactor) const
{
- Glyph *g = set->getGlyph(glyph);
- if (g && g->format == format)
- return g;
-
int load_flags = FT_LOAD_DEFAULT | default_load_flags;
int load_target = default_hint_style == HintLight
? FT_LOAD_TARGET_LIGHT
@@ -777,20 +772,35 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph
if (subpixelType == QFontEngineFT::Subpixel_RGB || subpixelType == QFontEngineFT::Subpixel_BGR) {
if (default_hint_style == HintFull)
load_target = FT_LOAD_TARGET_LCD;
+ hsubpixel = true;
} else if (subpixelType == QFontEngineFT::Subpixel_VRGB || subpixelType == QFontEngineFT::Subpixel_VBGR) {
if (default_hint_style == HintFull)
load_target = FT_LOAD_TARGET_LCD_V;
+ vfactor = 3;
}
}
- if (set->outline_drawing)
+ if (set && set->outline_drawing)
load_flags = FT_LOAD_NO_BITMAP;
- if (default_hint_style == HintNone)
+ if (default_hint_style == HintNone || (flags & HB_ShaperFlag_UseDesignMetrics))
load_flags |= FT_LOAD_NO_HINTING;
else
load_flags |= load_target;
+ return load_flags;
+}
+
+QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph, GlyphFormat format) const
+{
+ Glyph *g = set->getGlyph(glyph);
+ if (g && g->format == format)
+ return g;
+
+ bool hsubpixel = false;
+ int vfactor = 1;
+ int load_flags = loadFlags(set, format, 0, hsubpixel, vfactor);
+
// apply our matrix to this, but note that the metrics will not be affected by this.
FT_Face face = lockFace();
FT_Matrix matrix = this->matrix;
@@ -881,7 +891,10 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph
return g;
}
-QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, GlyphFormat format, bool fetchMetricsOnly) const
+QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
+ QFixed subPixelPosition,
+ GlyphFormat format,
+ bool fetchMetricsOnly) const
{
// Q_ASSERT(freetype->lock == 1);
@@ -896,10 +909,10 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, Glyph
}
}
- Glyph *g = set->getGlyph(glyph);
+ Glyph *g = set->getGlyph(glyph, subPixelPosition);
if (g && g->format == format) {
if (uploadToServer && !g->uploadedToServer) {
- set->setGlyph(glyph, 0);
+ set->setGlyph(glyph, subPixelPosition, 0);
delete g;
g = 0;
} else {
@@ -912,33 +925,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, Glyph
Q_ASSERT(format != Format_None);
bool hsubpixel = false;
int vfactor = 1;
- int load_flags = FT_LOAD_DEFAULT | default_load_flags;
-
- int load_target = default_hint_style == HintLight
- ? FT_LOAD_TARGET_LIGHT
- : FT_LOAD_TARGET_NORMAL;
-
- if (set->outline_drawing)
- load_flags |= FT_LOAD_NO_BITMAP;
-
- if (format == Format_Mono) {
- load_target = FT_LOAD_TARGET_MONO;
- } else if (format == Format_A32) {
- if (subpixelType == QFontEngineFT::Subpixel_RGB || subpixelType == QFontEngineFT::Subpixel_BGR) {
- if (default_hint_style == HintFull)
- load_target = FT_LOAD_TARGET_LCD;
- hsubpixel = true;
- } else if (subpixelType == QFontEngineFT::Subpixel_VRGB || subpixelType == QFontEngineFT::Subpixel_VBGR) {
- if (default_hint_style == HintFull)
- load_target = FT_LOAD_TARGET_LCD_V;
- vfactor = 3;
- }
- }
-
- if (default_hint_style == HintNone)
- load_flags |= FT_LOAD_NO_HINTING;
- else
- load_flags |= load_target;
+ int load_flags = loadFlags(set, format, 0, hsubpixel, vfactor);
#ifndef Q_WS_QWS
if (format != Format_Mono && !embeddedbitmap)
@@ -955,6 +942,12 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, Glyph
load_flags |= FT_LOAD_NO_BITMAP;
FT_Face face = freetype->face;
+
+ FT_Vector v;
+ v.x = format == Format_Mono ? 0 : FT_Pos(subPixelPosition.toReal() * 64);
+ v.y = 0;
+ FT_Set_Transform(face, &freetype->matrix, &v);
+
FT_Error err = FT_Load_Glyph(face, glyph, load_flags);
if (err && (load_flags & FT_LOAD_NO_BITMAP)) {
load_flags &= ~FT_LOAD_NO_BITMAP;
@@ -1055,6 +1048,10 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, Glyph
top = CEIL(top);
int hpixels = TRUNC(right - left);
+ // subpixel position requires one more pixel
+ if (subPixelPosition > 0 && format != Format_Mono)
+ hpixels++;
+
if (hsubpixel)
hpixels = hpixels*3 + 8;
info.width = hpixels;
@@ -1197,7 +1194,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, Glyph
uploadGlyphToServer(set, glyph, g, &info, glyph_buffer_size);
}
- set->setGlyph(glyph, g);
+ set->setGlyph(glyph, subPixelPosition, g);
return g;
}
@@ -1430,12 +1427,28 @@ QFontEngineFT::QGlyphSet *QFontEngineFT::loadTransformedGlyphSet(const QTransfor
return gs;
}
-bool QFontEngineFT::loadGlyphs(QGlyphSet *gs, glyph_t *glyphs, int num_glyphs, GlyphFormat format)
+QFixed QFontEngineFT::subPixelPositionForX(QFixed x)
+{
+ int m_subPixelPositionCount = 4;
+
+ QFixed subPixelPosition;
+ if (x != 0) {
+ subPixelPosition = x - x.floor();
+ QFixed fraction = (subPixelPosition / QFixed::fromReal(1.0 / m_subPixelPositionCount)).floor();
+ subPixelPosition = fraction / QFixed(m_subPixelPositionCount);
+ }
+ return subPixelPosition;
+}
+
+bool QFontEngineFT::loadGlyphs(QGlyphSet *gs, const glyph_t *glyphs, int num_glyphs,
+ const QFixedPoint *positions,
+ GlyphFormat format)
{
FT_Face face = 0;
for (int i = 0; i < num_glyphs; ++i) {
- Glyph *glyph = gs->getGlyph(glyphs[i]);
+ QFixed spp = subPixelPositionForX(positions[i].x);
+ Glyph *glyph = gs->getGlyph(glyphs[i], spp);
if (glyph == 0 || glyph->format != format) {
if (!face) {
face = lockFace();
@@ -1444,7 +1457,7 @@ bool QFontEngineFT::loadGlyphs(QGlyphSet *gs, glyph_t *glyphs, int num_glyphs, G
FT_Set_Transform(face, &m, 0);
freetype->matrix = m;
}
- if (!loadGlyph(gs, glyphs[i], format)) {
+ if (!loadGlyph(gs, glyphs[i], spp, format)) {
unlockFace();
return false;
}
@@ -1668,32 +1681,23 @@ bool QFontEngineFT::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs
void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
{
FT_Face face = 0;
- if (flags & QTextEngine::DesignMetrics) {
- for (int i = 0; i < glyphs->numGlyphs; i++) {
- Glyph *g = defaultGlyphSet.getGlyph(glyphs->glyphs[i]);
- if (g) {
- glyphs->advances_x[i] = QFixed::fromFixed(g->linearAdvance);
- } else {
- if (!face)
- face = lockFace();
- g = loadGlyph(glyphs->glyphs[i], Format_None, true);
- glyphs->advances_x[i] = QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10);
- }
- glyphs->advances_y[i] = 0;
- }
- } else {
- for (int i = 0; i < glyphs->numGlyphs; i++) {
- Glyph *g = defaultGlyphSet.getGlyph(glyphs->glyphs[i]);
- if (g) {
- glyphs->advances_x[i] = QFixed(g->advance);
- } else {
- if (!face)
- face = lockFace();
- g = loadGlyph(glyphs->glyphs[i], Format_None, true);
- glyphs->advances_x[i] = QFixed::fromFixed(face->glyph->metrics.horiAdvance).round();
- }
- glyphs->advances_y[i] = 0;
+ bool design = (default_hint_style == HintNone ||
+ default_hint_style == HintLight ||
+ (flags & HB_ShaperFlag_UseDesignMetrics));
+ for (int i = 0; i < glyphs->numGlyphs; i++) {
+ Glyph *g = defaultGlyphSet.getGlyph(glyphs->glyphs[i]);
+ if (g) {
+ glyphs->advances_x[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
+ } else {
+ if (!face)
+ face = lockFace();
+ g = loadGlyph(glyphs->glyphs[i], 0, Format_None, true);
+ glyphs->advances_x[i] = design ? QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10)
+ : QFixed::fromFixed(face->glyph->metrics.horiAdvance).round();
}
+ if (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
+ glyphs->advances_x[i] = glyphs->advances_x[i].round();
+ glyphs->advances_y[i] = 0;
}
if (face)
unlockFace();
@@ -1716,7 +1720,7 @@ glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs)
if (!g) {
if (!face)
face = lockFace();
- g = loadGlyph(glyphs.glyphs[i], Format_None, true);
+ g = loadGlyph(glyphs.glyphs[i], 0, Format_None, true);
}
if (g) {
QFixed x = overall.xoff + glyphs.offsets[i].x + g->x;
@@ -1757,7 +1761,7 @@ glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph)
Glyph *g = defaultGlyphSet.getGlyph(glyph);
if (!g) {
face = lockFace();
- g = loadGlyph(glyph, Format_None, true);
+ g = loadGlyph(glyph, 0, Format_None, true);
}
if (g) {
overall.x = g->x;
@@ -1765,6 +1769,8 @@ glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph)
overall.width = g->width;
overall.height = g->height;
overall.xoff = g->advance;
+ if (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
+ overall.xoff = overall.xoff.round();
} else {
int left = FLOOR(face->glyph->metrics.horiBearingX);
int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width);
@@ -1860,13 +1866,13 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, const QTransfo
return overall;
}
-QImage QFontEngineFT::alphaMapForGlyph(glyph_t g)
+QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition)
{
lockFace();
GlyphFormat glyph_format = antialias ? Format_A8 : Format_Mono;
- Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, glyph_format);
+ Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, subPixelPosition, glyph_format);
if (!glyph) {
unlockFace();
return QFontEngine::alphaMapForGlyph(g);
@@ -1905,7 +1911,7 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, in
GlyphFormat glyph_format = Format_A32;
- Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, glyph_format);
+ Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, subPixelPosition, glyph_format);
if (!glyph) {
unlockFace();
return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, margin, t);
@@ -1920,7 +1926,7 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, in
void QFontEngineFT::removeGlyphFromCache(glyph_t glyph)
{
- defaultGlyphSet.removeGlyphFromCache(glyph);
+ defaultGlyphSet.removeGlyphFromCache(glyph, 0);
}
int QFontEngineFT::glyphCount() const
@@ -2000,9 +2006,9 @@ void QFontEngineFT::QGlyphSet::clear()
glyph_data.clear();
}
-void QFontEngineFT::QGlyphSet::removeGlyphFromCache(int index)
+void QFontEngineFT::QGlyphSet::removeGlyphFromCache(glyph_t index, QFixed subPixelPosition)
{
- if (index < 256) {
+ if (useFastGlyphData(index, subPixelPosition)) {
if (fast_glyph_data[index]) {
delete fast_glyph_data[index];
fast_glyph_data[index] = 0;
@@ -2010,18 +2016,18 @@ void QFontEngineFT::QGlyphSet::removeGlyphFromCache(int index)
--fast_glyph_count;
}
} else {
- delete glyph_data.take(index);
+ delete glyph_data.take(GlyphAndSubPixelPosition(index, subPixelPosition));
}
}
-void QFontEngineFT::QGlyphSet::setGlyph(int index, Glyph *glyph)
+void QFontEngineFT::QGlyphSet::setGlyph(glyph_t index, QFixed subPixelPosition, Glyph *glyph)
{
- if (index < 256) {
+ if (useFastGlyphData(index, subPixelPosition)) {
if (!fast_glyph_data[index])
++fast_glyph_count;
fast_glyph_data[index] = glyph;
} else {
- glyph_data.insert(index, glyph);
+ glyph_data.insert(GlyphAndSubPixelPosition(index, subPixelPosition), glyph);
}
}
@@ -2038,7 +2044,10 @@ void QFontEngineFT::freeServerGlyphSet(unsigned long id)
HB_Error QFontEngineFT::getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints)
{
lockFace();
- HB_Error result = freetype->getPointInOutline(glyph, flags, point, xpos, ypos, nPoints);
+ bool hsubpixel = true;
+ int vfactor = 1;
+ int load_flags = loadFlags(0, Format_A8, flags, hsubpixel, vfactor);
+ HB_Error result = freetype->getPointInOutline(glyph, load_flags, point, xpos, ypos, nPoints);
unlockFace();
return result;
}
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index abdbd20..fc3ac82 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -166,6 +166,19 @@ public:
};
#endif
+ struct GlyphAndSubPixelPosition
+ {
+ GlyphAndSubPixelPosition(glyph_t g, QFixed spp) : glyph(g), subPixelPosition(spp) {}
+
+ bool operator==(const GlyphAndSubPixelPosition &other) const
+ {
+ return glyph == other.glyph && subPixelPosition == other.subPixelPosition;
+ }
+
+ glyph_t glyph;
+ QFixed subPixelPosition;
+ };
+
struct QGlyphSet
{
QGlyphSet();
@@ -174,18 +187,21 @@ public:
unsigned long id; // server sided id, GlyphSet for X11
bool outline_drawing;
- void removeGlyphFromCache(int index);
+ void removeGlyphFromCache(glyph_t index, QFixed subPixelPosition);
void clear();
- inline Glyph *getGlyph(int index) const
+ inline bool useFastGlyphData(glyph_t index, QFixed subPixelPosition) const {
+ return (index < 256 && subPixelPosition == 0);
+ }
+ inline Glyph *getGlyph(glyph_t index, QFixed subPixelPosition = 0) const
{
- if (index < 256)
+ if (useFastGlyphData(index, subPixelPosition))
return fast_glyph_data[index];
- return glyph_data.value(index);
+ return glyph_data.value(GlyphAndSubPixelPosition(index, subPixelPosition));
}
- void setGlyph(int index, Glyph *glyph);
+ void setGlyph(glyph_t index, QFixed spp, Glyph *glyph);
private:
- mutable QHash<int, Glyph *> glyph_data; // maps from glyph index to glyph data
+ mutable QHash<GlyphAndSubPixelPosition, Glyph *> glyph_data; // maps from glyph index to glyph data
mutable Glyph *fast_glyph_data[256]; // for fast lookup of glyphs < 256
mutable int fast_glyph_count;
};
@@ -193,6 +209,11 @@ private:
virtual QFontEngine::FaceId faceId() const;
virtual QFontEngine::Properties properties() const;
virtual QFixed emSquareSize() const;
+ virtual bool supportsSubPixelPositions() const
+ {
+ return default_hint_style == HintLight ||
+ default_hint_style == HintNone;
+ }
virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
virtual int synthesized() const;
@@ -233,7 +254,8 @@ private:
virtual glyph_metrics_t boundingBox(glyph_t glyph, const QTransform &matrix);
virtual void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const;
- virtual QImage alphaMapForGlyph(glyph_t);
+ virtual QImage alphaMapForGlyph(glyph_t g) { return alphaMapForGlyph(g, 0); }
+ virtual QImage alphaMapForGlyph(glyph_t, QFixed);
virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, const QTransform &matrix,
QFontEngine::GlyphFormat format);
@@ -254,17 +276,20 @@ private:
inline bool invalid() const { return xsize == 0 && ysize == 0; }
inline bool isBitmapFont() const { return defaultFormat == Format_Mono; }
- inline Glyph *loadGlyph(uint glyph, GlyphFormat format = Format_None, bool fetchMetricsOnly = false) const
- { return loadGlyph(&defaultGlyphSet, glyph, format, fetchMetricsOnly); }
- Glyph *loadGlyph(QGlyphSet *set, uint glyph, GlyphFormat = Format_None, bool fetchMetricsOnly = false) const;
+ inline Glyph *loadGlyph(uint glyph, QFixed subPixelPosition, GlyphFormat format = Format_None, bool fetchMetricsOnly = false) const
+ { return loadGlyph(&defaultGlyphSet, glyph, subPixelPosition, format, fetchMetricsOnly); }
+ Glyph *loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat = Format_None, bool fetchMetricsOnly = false) const;
QGlyphSet *defaultGlyphs() { return &defaultGlyphSet; }
GlyphFormat defaultGlyphFormat() const { return defaultFormat; }
- inline Glyph *cachedGlyph(glyph_t g) const { return defaultGlyphSet.getGlyph(g); }
+ inline Glyph *cachedGlyph(glyph_t g) const { return defaultGlyphSet.getGlyph(g, 0); }
QGlyphSet *loadTransformedGlyphSet(const QTransform &matrix);
- bool loadGlyphs(QGlyphSet *gs, glyph_t *glyphs, int num_glyphs, GlyphFormat format = Format_Render);
+ QFixed subPixelPositionForX(QFixed x);
+ bool loadGlyphs(QGlyphSet *gs, const glyph_t *glyphs, int num_glyphs,
+ const QFixedPoint *positions,
+ GlyphFormat format = Format_Render);
#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
virtual void draw(QPaintEngine * /*p*/, qreal /*x*/, qreal /*y*/, const QTextItemInt & /*si*/) {}
@@ -309,6 +334,7 @@ protected:
private:
QFontEngineFT::Glyph *loadGlyphMetrics(QGlyphSet *set, uint glyph, GlyphFormat format) const;
+ int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const;
GlyphFormat defaultFormat;
FT_Matrix matrix;
@@ -330,6 +356,11 @@ private:
mutable bool kerning_pairs_loaded;
};
+inline uint qHash(const QFontEngineFT::GlyphAndSubPixelPosition &g)
+{
+ return (g.glyph << 8) | (g.subPixelPosition * 10).round().toInt();
+}
+
QT_END_NAMESPACE
#endif // QT_NO_FREETYPE
diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp
index 2fd4716..d35bbe5 100644
--- a/src/gui/text/qfontengine_qpf.cpp
+++ b/src/gui/text/qfontengine_qpf.cpp
@@ -306,6 +306,8 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng
glyphMapEntries = 0;
glyphDataOffset = 0;
glyphDataSize = 0;
+ if (renderingFontEngine)
+ glyphFormat = renderingFontEngine->glyphFormat;
kerning_pairs_loaded = false;
readOnly = true;
diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp
index d5ec584..9f3f8d3 100644
--- a/src/gui/text/qfontengine_x11.cpp
+++ b/src/gui/text/qfontengine_x11.cpp
@@ -1012,10 +1012,29 @@ QFontEngineX11FT::QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int s
}
}
+ if (fd.hintingPreference != QFont::PreferDefaultHinting) {
+ switch (fd.hintingPreference) {
+ case QFont::PreferNoHinting:
+ default_hint_style = HintNone;
+ break;
+ case QFont::PreferVerticalHinting:
+ default_hint_style = HintLight;
+ break;
+ case QFont::PreferFullHinting:
+ default:
+ default_hint_style = HintFull;
+ break;
+ }
+ }
#ifdef FC_HINT_STYLE
- {
+ else {
int hint_style = 0;
- if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
+ // Try to use Xft.hintstyle from XDefaults first if running in GNOME, to match
+ // the behavior of cairo
+ if (X11->fc_hint_style > -1 && X11->desktopEnvironment == DE_GNOME)
+ hint_style = X11->fc_hint_style;
+ else if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch
+ && X11->fc_hint_style > -1)
hint_style = X11->fc_hint_style;
switch (hint_style) {
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index ad77d7f..6678522 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1577,8 +1577,13 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
// cache so this text is performed before we test if the cache size has changed.
if (recreateVertexArrays) {
cache->setPaintEnginePrivate(this);
- cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs,
- staticTextItem->glyphs, staticTextItem->glyphPositions);
+ if (!cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs,
+ staticTextItem->glyphs, staticTextItem->glyphPositions)) {
+ // No space for glyphs in cache. We need to reset it and try again.
+ cache->clear();
+ cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs,
+ staticTextItem->glyphs, staticTextItem->glyphPositions);
+ }
cache->fillInPendingGlyphs();
}
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
index 9e8e828..c867d60 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
@@ -378,4 +378,19 @@ int QGLTextureGlyphCache::maxTextureHeight() const
else
return ctx->d_ptr->maxTextureSize();
}
+
+void QGLTextureGlyphCache::clear()
+{
+ if (ctx != 0) {
+ m_textureResource.cleanup(ctx);
+
+ m_w = 0;
+ m_h = 0;
+ m_cx = 0;
+ m_cy = 0;
+ m_currentRowHeight = 0;
+ coords.clear();
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
index cc6de28..133289e 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
@@ -142,6 +142,8 @@ public:
FilterMode filterMode() const { return m_filterMode; }
void setFilterMode(FilterMode m) { m_filterMode = m; }
+ void clear();
+
void freeResource(void *) { ctx = 0; }
private:
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 19858e7..4698a5c 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -5606,6 +5606,21 @@ void *QGLContextGroupResourceBase::value(const QGLContext *context)
return group->m_resources.value(this, 0);
}
+void QGLContextGroupResourceBase::cleanup(const QGLContext *ctx)
+{
+ void *resource = value(ctx);
+
+ if (resource != 0) {
+ QGLShareContextScope scope(ctx);
+ freeResource(resource);
+
+ QGLContextGroup *group = QGLContextPrivate::contextGroup(ctx);
+ group->m_resources.remove(this);
+ m_groups.removeOne(group);
+ active.deref();
+ }
+}
+
void QGLContextGroupResourceBase::cleanup(const QGLContext *ctx, void *value)
{
#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 5a5e5cc..b2261a2 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -687,6 +687,7 @@ public:
virtual ~QGLContextGroupResourceBase();
void insert(const QGLContext *context, void *value);
void *value(const QGLContext *context);
+ void cleanup(const QGLContext *context);
void cleanup(const QGLContext *context, void *value);
virtual void freeResource(void *value) = 0;