src/gui/text/qfontengine_mac.mm
changeset 37 758a864f9613
parent 33 3e2da88830cd
--- a/src/gui/text/qfontengine_mac.mm	Fri Sep 17 08:34:18 2010 +0300
+++ b/src/gui/text/qfontengine_mac.mm	Mon Oct 04 01:19:32 2010 +0300
@@ -349,11 +349,32 @@
                                             int *nglyphs, QTextEngine::ShaperFlags flags) const
 {
     *nglyphs = len;
+    QCFType<CFStringRef> cfstring;
+
     QVarLengthArray<CGGlyph> cgGlyphs(len);
     CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len);
 
-    for (int i = 0; i < len; ++i)
-        glyphs->glyphs[i] = cgGlyphs[i];
+    for (int i = 0; i < len; ++i) {
+        if (cgGlyphs[i]) {
+            glyphs->glyphs[i] = cgGlyphs[i];
+	} else {
+            if (!cfstring)
+                cfstring = CFStringCreateWithCharactersNoCopy(0, reinterpret_cast<const UniChar *>(str), len, kCFAllocatorNull);
+            QCFType<CTFontRef> substituteFont = CTFontCreateForString(ctfont, cfstring, CFRangeMake(i, 1));
+            CGGlyph substituteGlyph = 0;
+            CTFontGetGlyphsForCharacters(substituteFont, (const UniChar*)str + i, &substituteGlyph, 1);
+            if (substituteGlyph) {
+                const uint fontIndex = (fontIndexForFont(substituteFont) << 24);
+                glyphs->glyphs[i] = substituteGlyph | fontIndex;
+                if (!(flags & QTextEngine::GlyphIndicesOnly)) {
+                    CGSize advance;
+                    CTFontGetAdvancesForGlyphs(substituteFont, kCTFontHorizontalOrientation, &substituteGlyph, &advance, 1);
+                    glyphs->advances_x[i] = QFixed::fromReal(advance.width);
+                    glyphs->advances_y[i] = QFixed::fromReal(advance.height);
+                }
+            }
+        }
+    }
 
     if (flags & QTextEngine::GlyphIndicesOnly)
         return true;
@@ -362,9 +383,14 @@
     CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), len);
 
     for (int i = 0; i < len; ++i) {
+        if (glyphs->glyphs[i] & 0xff000000)
+            continue;
         glyphs->advances_x[i] = QFixed::fromReal(advances[i].width);
         glyphs->advances_y[i] = QFixed::fromReal(advances[i].height);
-        if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
+    }
+
+    if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
+        for (int i = 0; i < len; ++i) {
             glyphs->advances_x[i] = glyphs->advances_x[i].round();
             glyphs->advances_y[i] = glyphs->advances_y[i].round();
         }
@@ -429,12 +455,13 @@
 glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs)
 {
     QFixed w;
+    bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics;
+
     for (int i = 0; i < glyphs.numGlyphs; ++i) {
-        w += (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
-             ? glyphs.effectiveAdvance(i).round()
-             : glyphs.effectiveAdvance(i);
+        w += round ? glyphs.effectiveAdvance(i).round()
+                   : glyphs.effectiveAdvance(i);
     }
-    return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0);
+    return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0);
 }
 glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph)
 {
@@ -1454,12 +1481,12 @@
 glyph_metrics_t QFontEngineMac::boundingBox(const QGlyphLayout &glyphs)
 {
     QFixed w;
+    bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics;
     for (int i = 0; i < glyphs.numGlyphs; ++i) {
-        w += (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
-             ? glyphs.effectiveAdvance(i).round()
-             : glyphs.effectiveAdvance(i);
+        w += round ? glyphs.effectiveAdvance(i).round()
+                   : glyphs.effectiveAdvance(i);
     }
-    return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0);
+    return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0);
 }
 
 glyph_metrics_t QFontEngineMac::boundingBox(glyph_t glyph)