[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