Support synthesized oblique and bold in SceneGraph
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>
Fri, 16 Sep 2011 09:58:09 +0000 (11:58 +0200)
committerQt by Nokia <qt-info@nokia.com>
Mon, 19 Sep 2011 08:24:25 +0000 (10:24 +0200)
When fetching the outlines we need to synthesize the weight and
style of the requested font. This is currently only supported
on FreeType versions that have the Embolden and Oblique functions.
We also use FreeType's Oblique function for regular text when
possible, and only use the matrix approach when that function
is unavailable.

Task-number: QTBUG-21202
Change-Id: I0656ab66cc3ec70d6a7675b8c78d06632625261c
Reviewed-on: http://codereview.qt-project.org/5076
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Jiang Jiang <jiang.jiang@nokia.com>
src/gui/text/qfontengine_ft.cpp
src/gui/text/qfontengine_ft_p.h

index 0755d9d..6a65aad 100644 (file)
@@ -99,6 +99,14 @@ QT_BEGIN_NAMESPACE
 #define Q_FT_GLYPHSLOT_EMBOLDEN(slot)
 #endif
 
+/* FreeType 2.1.10 starts to provide FT_GlyphSlot_Oblique */
+#if (FREETYPE_MAJOR*10000+FREETYPE_MINOR*100+FREETYPE_PATCH) >= 20110
+#define Q_HAS_FT_GLYPHSLOT_OBLIQUE
+#define Q_FT_GLYPHSLOT_OBLIQUE(slot)   FT_GlyphSlot_Oblique(slot)
+#else
+#define Q_FT_GLYPHSLOT_OBLIQUE(slot)
+#endif
+
 #define FLOOR(x)    ((x) & -64)
 #define CEIL(x)            (((x)+63) & -64)
 #define TRUNC(x)    ((x) >> 6)
@@ -627,6 +635,7 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd)
     kerning_pairs_loaded = false;
     transform = false;
     embolden = false;
+    obliquen = false;
     antialias = true;
     freetype = 0;
     default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
@@ -698,12 +707,16 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
 
     if (FT_IS_SCALABLE(face)) {
         bool fake_oblique = (fontDef.style != QFont::StyleNormal) && !(face->style_flags & FT_STYLE_FLAG_ITALIC);
-        if (fake_oblique)
+        if (fake_oblique) {
+#if !defined(Q_HAS_FT_GLYPHSLOT_OBLIQUE)
             matrix.xy = 0x10000*3/10;
+            transform = true;
+#else
+            obliquen = true;
+#endif
+        }
         FT_Set_Transform(face, &matrix, 0);
         freetype->matrix = matrix;
-        if (fake_oblique)
-            transform = true;
         // fake bold
         if ((fontDef.weight == QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face))
             embolden = true;
@@ -879,6 +892,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
 
     FT_GlyphSlot slot = face->glyph;
     if (embolden) Q_FT_GLYPHSLOT_EMBOLDEN(slot);
+    if (obliquen) Q_FT_GLYPHSLOT_OBLIQUE(slot);
     FT_Library library = qt_getFreetype();
 
     info.xOff = TRUNC(ROUND(slot->advance.x));
@@ -1488,6 +1502,8 @@ void QFontEngineFT::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int
         FT_GlyphSlot g = face->glyph;
         if (g->format != FT_GLYPH_FORMAT_OUTLINE)
             continue;
+        if (embolden) Q_FT_GLYPHSLOT_EMBOLDEN(g);
+        if (obliquen) Q_FT_GLYPHSLOT_OBLIQUE(g);
         QFreetypeFace::addGlyphToPath(face, g, positions[gl], path, xsize, ysize);
     }
     unlockFace();
@@ -1981,6 +1997,7 @@ bool QFontEngineFT::initFromFontEngine(const QFontEngineFT *fe)
     antialias = fe->antialias;
     transform = fe->transform;
     embolden = fe->embolden;
+    obliquen = fe->obliquen;
     subpixelType = fe->subpixelType;
     lcdFilterType = fe->lcdFilterType;
     canUploadGlyphsToServer = fe->canUploadGlyphsToServer;
index e320be4..62edaee 100644 (file)
@@ -335,6 +335,7 @@ protected:
     bool antialias;
     bool transform;
     bool embolden;
+    bool obliquen;
     SubpixelAntialiasingType subpixelType;
     int lcdFilterType;
     bool canUploadGlyphsToServer;