[PATCH libreoffice-4-1] Fix PDF export with fallback fonts in Core Text

Khaled Hosny (via Code Review) gerrit at gerrit.libreoffice.org
Sat Jun 15 19:35:56 PDT 2013


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/4301

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/01/4301/1

Fix PDF export with fallback fonts in Core Text

We need to pass the real font used to layout the glyphs in case it
differs from the requested font, otherwise we end with garbage in PDF
files.

Change-Id: I9caa8e60429e45ee864f5347fd9392f5e440864e
---
M vcl/coretext/ctfonts.cxx
M vcl/coretext/ctfonts.hxx
M vcl/coretext/ctlayout.cxx
M vcl/coretext/salgdi2.cxx
4 files changed, 47 insertions(+), 24 deletions(-)



diff --git a/vcl/coretext/ctfonts.cxx b/vcl/coretext/ctfonts.cxx
index 9c58891..ab738d9 100644
--- a/vcl/coretext/ctfonts.cxx
+++ b/vcl/coretext/ctfonts.cxx
@@ -33,22 +33,6 @@
 
 // =======================================================================
 
-// CoreText specific physically available font face
-class CTFontData
-:   public ImplMacFontData
-{
-public:
-    explicit                CTFontData( const ImplDevFontAttributes&, sal_IntPtr nFontId );
-    virtual                 ~CTFontData( void );
-    virtual PhysicalFontFace*   Clone( void ) const;
-
-    virtual ImplMacTextStyle*   CreateMacTextStyle( const FontSelectPattern& ) const;
-    virtual ImplFontEntry*      CreateFontInstance( /*const*/ FontSelectPattern& ) const;
-    virtual int                 GetFontTable( const char pTagName[5], unsigned char* ) const;
-};
-
-// =======================================================================
-
 class CTFontList
 :   public SystemFontList
 {
@@ -327,10 +311,8 @@
 
 // =======================================================================
 
-static void CTFontEnumCallBack( const void* pValue, void* pContext )
+ImplDevFontAttributes DevFontFromCTFontDescriptor( CTFontDescriptorRef pFD, bool* bFontEnabled )
 {
-    CTFontDescriptorRef pFD = static_cast<CTFontDescriptorRef>(pValue);
-
     // all CoreText fonts are device fonts that can rotate just fine
     ImplDevFontAttributes rDFA;
     rDFA.mbOrientation = true;
@@ -358,9 +340,12 @@
     rDFA.SetStyleName( GetOUString( pStyleName ) );
 
     // get font-enabled status
-    int bFontEnabled = FALSE;
-    CFNumberRef pFontEnabled = (CFNumberRef)CTFontDescriptorCopyAttribute( pFD, kCTFontEnabledAttribute );
-    CFNumberGetValue( pFontEnabled, kCFNumberIntType, &bFontEnabled );
+    if( bFontEnabled ) {
+        int bEnabled = FALSE;
+        CFNumberRef pEnabled = (CFNumberRef)CTFontDescriptorCopyAttribute( pFD, kCTFontEnabledAttribute );
+        CFNumberGetValue( pEnabled, kCFNumberIntType, &bEnabled );
+        *bFontEnabled = bEnabled;
+    }
 
     // get font attributes
     CFDictionaryRef pAttrDict = (CFDictionaryRef)CTFontDescriptorCopyAttribute( pFD, kCTFontTraitsAttribute );
@@ -419,6 +404,16 @@
     // TODO? also use the HEAD table if available to get more attributes
 //  CFDataRef CTFontCopyTable( CTFontRef, kCTFontTableHead, /*kCTFontTableOptionNoOptions*/kCTFontTableOptionExcludeSynthetic );
 
+    return rDFA;
+}
+
+static void CTFontEnumCallBack( const void* pValue, void* pContext )
+{
+    CTFontDescriptorRef pFD = static_cast<CTFontDescriptorRef>(pValue);
+
+    bool bFontEnabled;
+    ImplDevFontAttributes rDFA = DevFontFromCTFontDescriptor( pFD, &bFontEnabled );
+
     if( bFontEnabled)
     {
         const sal_IntPtr nFontId = (sal_IntPtr)pValue;
diff --git a/vcl/coretext/ctfonts.hxx b/vcl/coretext/ctfonts.hxx
index d80a566..f4a2147 100644
--- a/vcl/coretext/ctfonts.hxx
+++ b/vcl/coretext/ctfonts.hxx
@@ -46,5 +46,22 @@
     CFMutableDictionaryRef  GetStyleDict( void ) const { return mpStyleDict; }
 };
 
-// =======================================================================
+// CoreText specific physically available font face
+class CTFontData
+:   public ImplMacFontData
+{
+public:
+    explicit                CTFontData( const ImplDevFontAttributes&, sal_IntPtr nFontId );
+    explicit                CTFontData( CTFontDescriptorRef pFontDesc );
+    virtual                 ~CTFontData( void );
+    virtual PhysicalFontFace*   Clone( void ) const;
 
+    virtual ImplMacTextStyle*   CreateMacTextStyle( const FontSelectPattern& ) const;
+    virtual ImplFontEntry*      CreateFontInstance( /*const*/ FontSelectPattern& ) const;
+    virtual int                 GetFontTable( const char pTagName[5], unsigned char* ) const;
+};
+
+SystemFontList* GetCoretextFontList(void);
+ImplDevFontAttributes DevFontFromCTFontDescriptor( CTFontDescriptorRef, bool* );
+
+// =======================================================================
diff --git a/vcl/coretext/ctlayout.cxx b/vcl/coretext/ctlayout.cxx
index 0334cff..18df73e 100644
--- a/vcl/coretext/ctlayout.cxx
+++ b/vcl/coretext/ctlayout.cxx
@@ -293,6 +293,18 @@
         }
 
         const PhysicalFontFace* pFallbackFont = NULL;
+        if( pFallbackFonts ) {
+            CFDictionaryRef pRunAttributes = CTRunGetAttributes( pGlyphRun );
+            CTFontRef pRunFont = (CTFontRef)CFDictionaryGetValue( pRunAttributes, kCTFontAttributeName );
+
+            CFDictionaryRef pAttributes = mpTextStyle->GetStyleDict();
+            CTFontRef pFont = (CTFontRef)CFDictionaryGetValue( pAttributes, kCTFontAttributeName );
+            if ( !CFEqual( pRunFont,  pFont ) ) {
+                CTFontDescriptorRef pFontDesc = CTFontCopyFontDescriptor( pRunFont );
+                ImplDevFontAttributes rDevFontAttr = DevFontFromCTFontDescriptor( pFontDesc, NULL );
+                pFallbackFont = new CTFontData( rDevFontAttr, (sal_IntPtr)pFontDesc );
+            }
+        }
 
         // get the details for each interesting glyph
         // TODO: handle nLen>1
diff --git a/vcl/coretext/salgdi2.cxx b/vcl/coretext/salgdi2.cxx
index 2f7da5b..8e98f84 100644
--- a/vcl/coretext/salgdi2.cxx
+++ b/vcl/coretext/salgdi2.cxx
@@ -422,7 +422,6 @@
     // through it as should be all event handlers
 
     SalData* pSalData = GetSalData();
-    SystemFontList* GetCoretextFontList(void); // forward declaration
     if( !pSalData->mpFontList )
         pSalData->mpFontList = GetCoretextFontList();
 

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

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



More information about the LibreOffice mailing list