[PATCH] [coretext] Fix drawing fallback fonts

Khaled Hosny (via Code Review) gerrit at gerrit.libreoffice.org
Fri May 10 08:16:44 PDT 2013


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/3846

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/46/3846/1

[coretext] Fix drawing fallback fonts

Core Text will apply its font fallback mechanism when typesetting a
CTLine, and we can't assume that the returned run all use the original
font. This fixes the random glyphs drawn when we hit font fallback.

Change-Id: Id4d7098cb7bd3464cba6abab22be3ac3942c8889
---
M vcl/coretext/salcoretextlayout.cxx
1 file changed, 38 insertions(+), 9 deletions(-)



diff --git a/vcl/coretext/salcoretextlayout.cxx b/vcl/coretext/salcoretextlayout.cxx
index e324ef7..5599747 100644
--- a/vcl/coretext/salcoretextlayout.cxx
+++ b/vcl/coretext/salcoretextlayout.cxx
@@ -76,6 +76,8 @@
     // mutable members since these details are all lazy initialized
     mutable int mnGlyphCount;
 
+    mutable CTFontRef* mpGlyphFonts;
+
     mutable CGGlyph* mpGlyphs;
     mutable CGFloat* mpCharWidths;
     mutable int* mpGlyphs2Chars;
@@ -106,6 +108,7 @@
     mpStyle(style),
     mnCharCount(-1),
     mnGlyphCount(-1),
+    mpGlyphFonts(NULL),
     mpGlyphs(NULL),
     mpCharWidths(NULL),
     mpGlyphs2Chars(NULL),
@@ -182,6 +185,10 @@
 
 void CoreTextLayout::InvalidateMeasurements()
 {
+    if( mpGlyphFonts ) {
+        delete[] mpGlyphFonts;
+        mpGlyphFonts = NULL;
+    }
     if( mpGlyphs ) {
         delete[] mpGlyphs;
         mpGlyphs = NULL;
@@ -213,14 +220,7 @@
     if( mnCharCount <= 0 || !gr.CheckContext() )
         return;
 
-    CGFontRef cg_font = CTFontCopyGraphicsFont(mpStyle->GetFont(), NULL);
-    if( !cg_font ) {
-        SAL_INFO( "vcl.coretext.layout", "Error cg_font is NULL" );
-        return;
-    }
     CGContextSaveGState( gr.mrContext );
-    CGContextSetFont(gr.mrContext, cg_font);
-    CGContextSetFontSize(gr.mrContext, CTFontGetSize(mpStyle->GetFont()));
     CGContextSetTextDrawingMode(gr.mrContext, kCGTextFill);
     CGContextSetShouldAntialias( gr.mrContext, true );
     CGContextSetShouldSubpixelPositionFonts( gr.mrContext, false );
@@ -231,7 +231,7 @@
     else {
         CGContextSetRGBFillColor(gr.mrContext, 0.0, 0.0, 0.0, 1.0);
     }
-    CFRelease(cg_font);
+
     CGContextSetTextMatrix(gr.mrContext, CGAffineTransformMakeScale(1.0, -1.0));
     CGContextSetShouldAntialias( gr.mrContext, !gr.mbNonAntialiasedText );
 
@@ -245,7 +245,30 @@
 
     CGContextTranslateCTM(gr.mrContext, pos.X(), pos.Y());
 
-    CGContextShowGlyphsWithAdvances(gr.mrContext, mpGlyphs, mpGlyphAdvances, mnGlyphCount);
+    int i = 0;
+    while (i < mnGlyphCount)
+    {
+        CTFontRef pCTFont = mpGlyphFonts[i];
+
+        // Find the number of glyphs using the same font
+        int nGlyphs = 1;
+        while ((i + nGlyphs < mnGlyphCount) && CFEqual(mpGlyphFonts[i + nGlyphs], pCTFont))
+            nGlyphs++;
+
+        CGFontRef pCGFont = CTFontCopyGraphicsFont(pCTFont, NULL);
+        if (!pCGFont) {
+            SAL_INFO("vcl.coretext.layout", "Error pCGFont is NULL");
+            return;
+        }
+
+        CGContextSetFont(gr.mrContext, pCGFont);
+        CFRelease(pCGFont);
+        CGContextSetFontSize(gr.mrContext, CTFontGetSize(pCTFont));
+
+        CGContextShowGlyphsWithAdvances(gr.mrContext, &mpGlyphs[i], &mpGlyphAdvances[i], nGlyphs);
+
+        i += nGlyphs;
+    }
 
 #ifndef IOS
     // Request an update of the changed window area. Like in the ATSUI
@@ -572,6 +595,7 @@
 {
     InvalidateMeasurements();
 
+    mpGlyphFonts = new CTFontRef[ mnGlyphCount ];
     mpGlyphs = new CGGlyph[ mnGlyphCount ];
     mpCharWidths = new CGFloat[ mnCharCount ];
     mpGlyphs2Chars = new int[ mnGlyphCount ];
@@ -587,6 +611,9 @@
         CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex( runs, runIx );
         if ( !run )
             continue;
+
+        CFDictionaryRef runAttributes = CTRunGetAttributes(run);
+        CTFontRef runFont = (CTFontRef)CFDictionaryGetValue(runAttributes, kCTFontAttributeName);
 
         std::ostringstream glyphPositionInfo;
         std::ostringstream glyphAdvancesInfo;
@@ -622,6 +649,8 @@
                 mpGlyphs2Chars[ lineGlyphIx ] = charIx;
 
                 mpCharWidths[ charIx ] = mpGlyphAdvances[ lineGlyphIx ].width;
+
+                mpGlyphFonts[ lineGlyphIx ] = runFont;
             }
 #ifdef SAL_LOG_INFO
             for ( int i = 0; i < runGlyphCount; i++ ) {

-- 
To view, visit https://gerrit.libreoffice.org/3846
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id4d7098cb7bd3464cba6abab22be3ac3942c8889
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: master
Gerrit-Owner: Khaled Hosny <khaledhosny at eglug.org>



More information about the LibreOffice mailing list