Use maximum ascent/descent/leading from fallback fonts in shaping
authorJiang Jiang <jiang.jiang@nokia.com>
Wed, 27 Apr 2011 14:05:09 +0000 (16:05 +0200)
committerJiang Jiang <jiang.jiang@nokia.com>
Fri, 29 Apr 2011 09:02:25 +0000 (11:02 +0200)
When shaping a QScriptItem with a multi font engine, currently we
only take the ascent/descent/leading from the primary (first) font
engine in that multi font engine, however, subsequent engines used
during shaping may have larger ascent/descent/leading, disregarding
them may cause clipping issues in some cases.

It's fixed by checking each font engine used in the shaping process
and take the maximum value instead of the first one. On ATSUI we
merely make it compile.

Task-number: QTBUG-16719
Reviewed-by: Eskil
(cherry picked from commit c501403cb5a0c9ec21b00e0c2f640ae85566e0cf)

src/gui/text/qfontengine_coretext.mm
src/gui/text/qfontengine_coretext_p.h
src/gui/text/qfontengine_mac.mm
src/gui/text/qfontengine_mac_p.h
src/gui/text/qtextengine.cpp
src/gui/text/qtextengine_mac.cpp

index c4d2d47..d4df218 100644 (file)
@@ -162,8 +162,10 @@ uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef font) const
     return engines.count() - 1;
 }
 
-bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
-                  unsigned short *logClusters, const HB_CharAttributes *) const
+bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
+                                            int *nglyphs, QTextEngine::ShaperFlags flags,
+                                            unsigned short *logClusters, const HB_CharAttributes *,
+                                            QScriptItem *si) const
 {
     QCFType<CFStringRef> cfstring = CFStringCreateWithCharactersNoCopy(0,
                                                                reinterpret_cast<const UniChar *>(str),
@@ -254,7 +256,12 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
             if (!runAttribs)
                 runAttribs = attributeDict;
             CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttribs, NSFontAttributeName));
-            const uint fontIndex = (fontIndexForFont(runFont) << 24);
+            uint fontIndex = fontIndexForFont(runFont);
+            const QFontEngine *engine = engineAt(fontIndex);
+            fontIndex <<= 24;
+            si->ascent = qMax(engine->ascent(), si->ascent);
+            si->descent = qMax(engine->descent(), si->descent);
+            si->leading = qMax(engine->leading(), si->leading);
             //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont));
             if (endWithPDF)
                 glyphCount--;
index aa5f91a..bb80a9b 100644 (file)
@@ -120,7 +120,8 @@ public:
                               QTextEngine::ShaperFlags flags) const;
     bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
                       QTextEngine::ShaperFlags flags,
-                      unsigned short *logClusters, const HB_CharAttributes *charAttributes) const;
+                      unsigned short *logClusters, const HB_CharAttributes *charAttributes,
+                      QScriptItem *si) const;
 
     virtual const char *name() const { return "CoreText"; }
 protected:
index 673a7c8..9f094ad 100644 (file)
@@ -377,7 +377,7 @@ bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *
 }
 
 bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
-                                       unsigned short *logClusters, const HB_CharAttributes *charAttributes) const
+                                       unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const
 {
     if (*nglyphs < len) {
         *nglyphs = len;
index 385fa83..292ea98 100644 (file)
@@ -131,7 +131,7 @@ public:
 
     virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
     bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
-                      unsigned short *logClusters, const HB_CharAttributes *charAttributes) const;
+                      unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const;
 
     virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
     virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const;
index cc150c5..ff27bc6 100644 (file)
@@ -1274,6 +1274,10 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
             actualFontEngine = static_cast<QFontEngineMulti *>(font)->engine(engineIdx);
         }
 
+        si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
+        si.descent = qMax(actualFontEngine->descent(), si.descent);
+        si.leading = qMax(actualFontEngine->leading(), si.leading);
+
         shaper_item.font = actualFontEngine->harfbuzzFont();
         shaper_item.face = actualFontEngine->harfbuzzFace();
 
index 97e8c5b..2c6e579 100644 (file)
@@ -605,11 +605,11 @@ void QTextEngine::shapeTextMac(int item) const
     unsigned short *log_clusters = logClusters(&si);
 
     bool stringToCMapFailed = false;
-    if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) {
+    if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes(), &si)) {
         ensureSpace(num_glyphs);
         g = availableGlyphs(&si);
         stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
-                                               attributes());
+                                               attributes(), &si);
     }
 
     if (!stringToCMapFailed) {