Commits

Vladimir Glazunov  committed 5e5c268 Merge

CWS-TOOLING: integrate CWS fchints01

  • Participants
  • Parent commits a5e0eb0, cf07edd

Comments (0)

Files changed (31)

File vcl/aqua/source/gdi/salatsuifontutils.cxx

 	// all scalable fonts on this platform are subsettable
 	rDFA.mbSubsettable	= true;
 	rDFA.mbEmbeddable	= false;
-	// TODO: these members are needed only for our X11 platform targets
-	rDFA.meAntiAlias	= ANTIALIAS_DONTKNOW;
-	rDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW;
 
 	// prepare iterating over all name strings of the font	
     ItemCount nFontNameCount = 0;

File vcl/inc/vcl/fontmanager.hxx

 // forward declarations
 namespace utl { class MultiAtomProvider; } // see unotools/atom.hxx
 class FontSubsetInfo;
+class ImplFontOptions;
 
 namespace psp {
 class PPDParser; // see ppdparser.hxx
     weight::type            			m_eWeight;
     pitch::type             			m_ePitch;
     rtl_TextEncoding        			m_aEncoding;
-    fcstatus::type                      m_eEmbeddedbitmap;
-    fcstatus::type                      m_eAntialias;
     bool                                m_bSubsettable;
     bool                                m_bEmbeddable;
 
             m_eWidth( width::Unknown ),
             m_eWeight( weight::Unknown ),
             m_ePitch( pitch::Unknown ),
-            m_aEncoding( RTL_TEXTENCODING_DONTKNOW ),
-            m_eEmbeddedbitmap( fcstatus::isunset ),
-            m_eAntialias( fcstatus::isunset )
+            m_aEncoding( RTL_TEXTENCODING_DONTKNOW )
     {}
 };
 
         bool										m_bHaveVerticalSubstitutedGlyphs;
         bool                                        m_bUserOverride;
 
-        fcstatus::type                              m_eEmbeddedbitmap;
-        fcstatus::type                              m_eAntialias;
-
         std::map< sal_Unicode, sal_Int32 >			m_aEncodingVector;
         std::map< sal_Unicode, rtl::OString >		m_aNonEncoded;
 
     false else
      */
     bool matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale );
+    bool getFontOptions( const FastPrintFontInfo&, int nSize, void (*subcallback)(void*), ImplFontOptions& rResult ) const;
 
     rtl::OUString Substitute( const rtl::OUString& rFontName, rtl::OUString& rMissingCodes, 
-        const rtl::OString& rLangAttrib, italic::type eItalic, weight::type eWeight, 
-        width::type eWidth, pitch::type ePitch) const;
+        const rtl::OString& rLangAttrib, italic::type& rItalic, weight::type& rWeight, 
+        width::type& rWidth, pitch::type& rPitch) const;
     bool hasFontconfig() const { return m_bFontconfigSuccess; }
 
     int FreeTypeCharIndex( void *pFace, sal_uInt32 aChar );

File vcl/inc/vcl/glyphcache.hxx

 class ServerFontLayout;
 class ExtraKernInfo;
 struct ImplKernPairData;
+class ImplFontOptions;
 
 #include <tools/gen.hxx>
 #include <hash_map>
 class VCL_DLLPUBLIC GlyphCache
 {
 public:
-                                GlyphCache( GlyphCachePeer& );
-                                ~GlyphCache();
+    explicit                    GlyphCache( GlyphCachePeer& );
+    /*virtual*/                 ~GlyphCache();
 
     static GlyphCache&		GetInstance();
     void                        LoadFonts();
 
     ServerFont*                 CacheFont( const ImplFontSelectData& );
     void                        UncacheFont( ServerFont& );
+    void                        InvalidateAllGlyphs();
 
 protected:
     GlyphCachePeer&             mrPeer;
     struct IFSD_Hash{ size_t operator()( const ImplFontSelectData& ) const; };
     typedef ::std::hash_map<ImplFontSelectData,ServerFont*,IFSD_Hash,IFSD_Equal > FontList;
     FontList                    maFontList;
-
     ULONG                       mnMaxSize;      // max overall cache size in bytes
     mutable ULONG               mnBytesUsed;
     mutable long                mnLruIndex;
     virtual bool                TestFont() const            { return true; }
     virtual void*               GetFtFace() const { return 0; }
     virtual int                 GetLoadFlags() const { return 0; }
+    virtual void                SetFontOptions( const ImplFontOptions&) {}
     virtual bool                NeedsArtificialBold() const { return false; }
-    virtual bool		        NeedsArtificialItalic() const { return false; }
+    virtual bool                NeedsArtificialItalic() const { return false; }
 
     const ImplFontSelectData&   GetFontSelData() const      { return maFontSelData; }
 
 protected:
     friend class GlyphCache;
     friend class ServerFontLayout;
-                                ServerFont( const ImplFontSelectData& );
+    explicit                    ServerFont( const ImplFontSelectData& );
     virtual                     ~ServerFont();
 
     void                        AddRef() const      { ++mnRefCount; }

File vcl/inc/vcl/impfont.hxx

     bool    operator==( const ImplFontMetric& ) const;
 };
 
+// ------------------
+// - ImplFontHints -
+// ------------------
+
+class ImplFontOptions
+{
+public:
+    FontEmbeddedBitmap meEmbeddedBitmap; // whether the embedded bitmaps should be used
+    FontAntiAlias      meAntiAlias;      // whether the font should be antialiased
+    FontAutoHint       meAutoHint;       // whether the font should be autohinted
+    FontHinting        meHinting;        // whether the font should be hinted
+    FontHintStyle      meHintStyle;      // type of font hinting to be used
+public:
+    ImplFontOptions() :
+        meEmbeddedBitmap(EMBEDDEDBITMAP_DONTKNOW), 
+        meAntiAlias(ANTIALIAS_DONTKNOW), 
+        meAutoHint(AUTOHINT_DONTKNOW), 
+        meHinting(HINTING_DONTKNOW), 
+        meHintStyle(HINT_SLIGHT)
+    {}
+    ImplFontOptions( FontEmbeddedBitmap eEmbeddedBitmap, FontAntiAlias eAntiAlias, 
+        FontAutoHint eAutoHint, FontHinting eHinting, FontHintStyle eHintStyle) :
+        meEmbeddedBitmap(eEmbeddedBitmap), 
+        meAntiAlias(eAntiAlias), 
+        meAutoHint(eAutoHint), 
+        meHinting(eHinting), 
+        meHintStyle(eHintStyle)
+    {}
+    FontAutoHint GetUseAutoHint() const { return meAutoHint; }
+    FontHintStyle GetHintStyle() const { return meHintStyle; }
+    bool DontUseEmbeddedBitmaps() const { return meEmbeddedBitmap == EMBEDDEDBITMAP_FALSE; }
+    bool DontUseAntiAlias() const { return meAntiAlias == ANTIALIAS_FALSE; }
+    bool DontUseHinting() const { return (meHinting == HINTING_FALSE) || (GetHintStyle() == HINT_NONE); }
+};
+
 // -------------------
 // - ImplFontCharMap -
 // -------------------

File vcl/inc/vcl/outdev.hxx

 class FontCharMap;
 class SalLayout;
 class ImplLayoutArgs;
+class ImplFontAttributes;
 class VirtualDevice;
 
 namespace com {
 
     SAL_DLLPRIVATE static FontEmphasisMark ImplGetEmphasisMarkStyle( const Font& rFont );
     SAL_DLLPRIVATE static BOOL ImplIsUnderlineAbove( const Font& );
-    
-    
+ 
     // tells whether this output device is RTL in an LTR UI or LTR in a RTL UI
     SAL_DLLPRIVATE bool ImplIsAntiparallel() const ;
 

File vcl/inc/vcl/outfont.hxx

     bool               IsDeviceFont() const      { return mbDevice; }
     bool               IsEmbeddable() const      { return mbEmbeddable; }
     bool               IsSubsettable() const     { return mbSubsettable; }
-    FontEmbeddedBitmap UseEmbeddedBitmap() const { return meEmbeddedBitmap; }
-    FontAntiAlias      UseAntiAlias() const      { return meAntiAlias; }
 
 public: // TODO: hide members behind accessor methods
     String             maMapNames;       // List of family name aliass separated with ';'
     bool               mbDevice;         // true: built in font
     bool               mbSubsettable;    // true: a subset of the font can be created
     bool               mbEmbeddable;     // true: the font can be embedded
-    FontEmbeddedBitmap meEmbeddedBitmap; // whether the embedded bitmaps should be used
-    FontAntiAlias      meAntiAlias;      // whether the font should be antialiased
 };
 
 // ----------------
     short               mnOrientation;      // text angle in 3600 system
     bool                mbInit;             // true if maMetric member is valid
 
-    void                AddFallbackForUnicode( sal_UCS4, const String& rFontName );
-    bool                GetFallbackForUnicode( sal_UCS4, String* pFontName ) const;
-    void                IgnoreFallbackForUnicode( sal_UCS4, const String& rFontName );
+    void                AddFallbackForUnicode( sal_UCS4, FontWeight eWeight, const String& rFontName );
+    bool                GetFallbackForUnicode( sal_UCS4, FontWeight eWeight, String* pFontName ) const;
+    void                IgnoreFallbackForUnicode( sal_UCS4, FontWeight eWeight, const String& rFontName );
 
 private:
     // cache of Unicode characters and replacement font names
     // TODO: a fallback map can be shared with many other ImplFontEntries
     // TODO: at least the ones which just differ in orientation, stretching or height
-    typedef ::std::hash_map<sal_UCS4,String> UnicodeFallbackList;
+    typedef ::std::pair<sal_UCS4,FontWeight> GFBCacheKey;
+    struct GFBCacheKey_Hash{ size_t operator()( const GFBCacheKey& ) const; };
+    typedef ::std::hash_map<GFBCacheKey,String,GFBCacheKey_Hash> UnicodeFallbackList;
     UnicodeFallbackList* mpUnicodeFallbackList;
 };
 

File vcl/inc/vcl/salgdi.hxx

     void                   ReleaseFonts() { SetFont( NULL, 0 ); }
     // get the current font's metrics
     virtual void			GetFontMetric( ImplFontMetricData* ) = 0;
+
     // get kernign pairs of the current font
     // return only PairCount if (pKernPairs == NULL)
-    virtual ULONG			GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ) = 0;
+    virtual ULONG			GetKernPairs( ULONG nMaxPairCount, ImplKernPairData* ) = 0;
     // get the repertoire of the current font
     virtual ImplFontCharMap* GetImplFontCharMap() const = 0;
     // graphics must fill supplied font list

File vcl/inc/vcl/settings.hxx

     ULONG                           mnPreferredSymbolsStyle;
     USHORT                          mnSkipDisabledInMenus;
     Wallpaper                       maWorkspaceGradient;
+    const void*                     mpFontOptions;
 };
 
 #define DEFAULT_WORKSPACE_GRADIENT_START_COLOR Color( 0xa3, 0xae, 0xb8 )
     BOOL							GetSkipDisabledInMenus() const
                                         { return (BOOL) mpData->mnSkipDisabledInMenus; }
 
+    void                            SetCairoFontOptions( const void *pOptions )
+                                        { CopyData(); mpData->mpFontOptions = pOptions;  }
+    const void*                     GetCairoFontOptions() const
+                                        { return mpData->mpFontOptions; }
+
     void                            SetAppFont( const Font& rFont )
                                         { CopyData(); mpData->maAppFont = rFont; }
     const Font&                     GetAppFont() const

File vcl/inc/vcl/vclenum.hxx

 
 #endif
 
+#ifndef ENUM_FONTAUTOHINT_DECLARED
+#define ENUM_FONTAUTOHINT_DECLARED
+
+enum FontAutoHint { AUTOHINT_DONTKNOW, AUTOHINT_FALSE, AUTOHINT_TRUE };
+
+#endif
+
+#ifndef ENUM_FONTHINTING_DECLARED
+#define ENUM_FONTHINTING_DECLARED
+
+enum FontHinting { HINTING_DONTKNOW, HINTING_FALSE, HINTING_TRUE };
+
+#endif
+
+#ifndef ENUM_FONTHINTSTYLE_DECLARED
+#define ENUM_FONTHINTSTYLE_DECLARED
+
+enum FontHintStyle { HINT_NONE, HINT_SLIGHT, HINT_MEDIUM, HINT_FULL };
+
+#endif
+
 // ------------------------------------------------------------
 
 #ifndef ENUM_KEYFUNCTYPE_DECLARED

File vcl/source/app/settings.cxx

     mnToolbarIconSize			= STYLE_TOOLBAR_ICONSIZE_UNKNOWN;
     mnSymbolsStyle				= STYLE_SYMBOLS_AUTO;
     mnPreferredSymbolsStyle			= STYLE_SYMBOLS_AUTO;
+    mpFontOptions              = NULL;
 
     SetStandardStyles();
 }
     mnToolbarIconSize			= rData.mnToolbarIconSize;
     mnSymbolsStyle				= rData.mnSymbolsStyle;
     mnPreferredSymbolsStyle			= rData.mnPreferredSymbolsStyle;
+    mpFontOptions               = rData.mpFontOptions;
 }
 
 // -----------------------------------------------------------------------

File vcl/source/gdi/outdev3.cxx

 #ifdef ENABLE_GRAPHITE
 #include <vcl/graphite_features.hxx>
 #endif
+#ifdef USE_BUILTIN_RASTERIZER
+#include <vcl/glyphcache.hxx>
+#endif
 
 #include <vcl/unohelp.hxx>
 #include <pdfwriter_impl.hxx>
 
 // -----------------------------------------------------------------------
 
-inline void ImplFontEntry::AddFallbackForUnicode( sal_UCS4 cChar, const String& rFontName )
+size_t ImplFontEntry::GFBCacheKey_Hash::operator()( const GFBCacheKey& rData ) const
+{
+    std::hash<sal_UCS4> a;
+    std::hash<int > b;
+    return a(rData.first) ^ b(rData.second);
+}
+
+inline void ImplFontEntry::AddFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const String& rFontName )
 {
     if( !mpUnicodeFallbackList )
         mpUnicodeFallbackList = new UnicodeFallbackList;
-    (*mpUnicodeFallbackList)[cChar] = rFontName;
-}
-
-// -----------------------------------------------------------------------
-
-inline bool ImplFontEntry::GetFallbackForUnicode( sal_UCS4 cChar, String* pFontName ) const
+    (*mpUnicodeFallbackList)[ GFBCacheKey(cChar,eWeight) ] = rFontName;
+}
+
+// -----------------------------------------------------------------------
+
+inline bool ImplFontEntry::GetFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, String* pFontName ) const
 {
     if( !mpUnicodeFallbackList )
         return false;
 
-    UnicodeFallbackList::const_iterator it = mpUnicodeFallbackList->find( cChar );
+    UnicodeFallbackList::const_iterator it = mpUnicodeFallbackList->find( GFBCacheKey(cChar,eWeight) );
     if( it == mpUnicodeFallbackList->end() )
         return false;
 
 
 // -----------------------------------------------------------------------
 
-inline void ImplFontEntry::IgnoreFallbackForUnicode( sal_UCS4 cChar, const String& rFontName )
+inline void ImplFontEntry::IgnoreFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const String& rFontName )
 {
 //  DBG_ASSERT( mpUnicodeFallbackList, "ImplFontEntry::IgnoreFallbackForUnicode no list" );
-    UnicodeFallbackList::iterator it = mpUnicodeFallbackList->find( cChar );
+    UnicodeFallbackList::iterator it = mpUnicodeFallbackList->find( GFBCacheKey(cChar,eWeight) );
 //  DBG_ASSERT( it != mpUnicodeFallbackList->end(), "ImplFontEntry::IgnoreFallbackForUnicode no match" );
     if( it == mpUnicodeFallbackList->end() )
         return;
         while( nStrIndex < rMissingCodes.getLength() )
         {
             cChar = rMissingCodes.iterateCodePoints( &nStrIndex );
-            bCached = rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, &rFontSelData.maSearchName );
+            bCached = rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, rFontSelData.GetWeight(), &rFontSelData.maSearchName );
             // ignore entries which don't have a fallback
             if( !bCached || (rFontSelData.maSearchName.Len() != 0) )
                 break;
             while( nStrIndex < rMissingCodes.getLength() )
             {
                 cChar = rMissingCodes.iterateCodePoints( &nStrIndex );
-                bCached = rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, &aFontName );
+                bCached = rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, rFontSelData.GetWeight(), &aFontName );
                 if( !bCached || (rFontSelData.maSearchName != aFontName) )
                     pRemainingCodes[ nRemainingLength++ ] = cChar;
             }
             // cache the result even if there was no match
             for(;;)
             {
-                 if( !rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, &rFontSelData.maSearchName ) )
-                     rFontSelData.mpFontEntry->AddFallbackForUnicode( cChar, rFontSelData.maSearchName );
+                 if( !rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, rFontSelData.GetWeight(), &rFontSelData.maSearchName ) )
+                     rFontSelData.mpFontEntry->AddFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName );
                  if( nStrIndex >= aOldMissingCodes.getLength() )
                      break;
                  cChar = aOldMissingCodes.iterateCodePoints( &nStrIndex );
                 for( nStrIndex = 0; nStrIndex < rMissingCodes.getLength(); )
                 {
                     cChar = rMissingCodes.iterateCodePoints( &nStrIndex );
-                    rFontSelData.mpFontEntry->IgnoreFallbackForUnicode( cChar, rFontSelData.maSearchName );
+                    rFontSelData.mpFontEntry->IgnoreFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName );
                 }
             }
         }
     maFontInstanceList.clear();
 
     DBG_ASSERT( (mnRef0Count==0), "ImplFontCache::Invalidate() - mnRef0Count non-zero" );
+
+#ifdef USE_BUILTIN_RASTERIZER
+    // TODO: eventually move into SalGraphics layer
+    GlyphCache::GetInstance().InvalidateAllGlyphs();
+#endif
 }
 
 // =======================================================================

File vcl/source/glyphs/gcach_ftyp.cxx

 #include "vcl/svapp.hxx"
 #include "vcl/outfont.hxx"
 #include "vcl/impfont.hxx"
-#include "vcl/bitmap.hxx"
-#include "vcl/bmpacc.hxx"
 
 #include "tools/poly.hxx"
 #include "basegfx/matrix/b2dhommatrix.hxx"
 // TODO: move file mapping stuff to OSL
 #if defined(UNX)
     #if !defined(HPUX)
-        // PORTERS: dlfcn is used for code dependend on FT version
+        // PORTERS: dlfcn is used for getting symbols from FT versions newer than baseline
         #include <dlfcn.h>
     #endif
     #include <unistd.h>
     #define strncasecmp strnicmp
 #endif
 
-#include "vcl/svapp.hxx"
-#include "vcl/settings.hxx"
-#include "i18npool/lang.h"
-
 typedef const unsigned char* CPU8;
 inline sal_uInt16 NEXT_U16( CPU8& p ) { p+=2; return (p[-2]<<8)|p[-1]; }
 inline sal_Int16  NEXT_S16( CPU8& p ) { return (sal_Int16)NEXT_U16(p); }
             aDFA.mbSubsettable= false;
             aDFA.mbEmbeddable = false;
 
-            aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW;
-            aDFA.meAntiAlias = ANTIALIAS_DONTKNOW;
-
             FT_Done_Face( aFaceFT );
             AddFontFile( aCFileName, nFaceNum, ++mnNextFontId, aDFA, NULL );
             ++nCount;
 :   ServerFont( rFSD ),
     mnPrioEmbedded(nDefaultPrioEmbedded),
     mnPrioAntiAlias(nDefaultPrioAntiAlias),
+    mnPrioAutoHint(nDefaultPrioAutoHint),
     mpFontInfo( pFI ),
     maFaceFT( NULL ),
     maSizeFT( NULL ),
 
     mbArtItalic = (rFSD.meItalic != ITALIC_NONE && pFI->GetFontAttributes().GetSlant() == ITALIC_NONE);
     mbArtBold = (rFSD.meWeight > WEIGHT_MEDIUM && pFI->GetFontAttributes().GetWeight() <= WEIGHT_MEDIUM);
+    mbUseGamma = false;
+    if( mbArtBold )
+    {
+	    //static const int TT_CODEPAGE_RANGE_874  = (1L << 16); // Thai
+	    //static const int TT_CODEPAGE_RANGE_932  = (1L << 17); // JIS/Japan
+	    //static const int TT_CODEPAGE_RANGE_936  = (1L << 18); // Chinese: Simplified
+	    //static const int TT_CODEPAGE_RANGE_949  = (1L << 19); // Korean Wansung
+	    //static const int TT_CODEPAGE_RANGE_950  = (1L << 20); // Chinese: Traditional
+	    //static const int TT_CODEPAGE_RANGE_1361 = (1L << 21); // Korean Johab
+	    static const int TT_CODEPAGE_RANGES1_CJKT = 0x3F0000; // all of the above
+	    const TT_OS2* pOs2 = (const TT_OS2*)FT_Get_Sfnt_Table( maFaceFT, ft_sfnt_os2 );
+	    if ((pOs2) && (pOs2->ulCodePageRange1 & TT_CODEPAGE_RANGES1_CJKT )
+		&& rFSD.mnHeight < 20)
+		mbUseGamma = true;
+    }
 
-    //static const int TT_CODEPAGE_RANGE_874  = (1L << 16); // Thai
-    //static const int TT_CODEPAGE_RANGE_932  = (1L << 17); // JIS/Japan
-    //static const int TT_CODEPAGE_RANGE_936  = (1L << 18); // Chinese: Simplified
-    //static const int TT_CODEPAGE_RANGE_949  = (1L << 19); // Korean Wansung
-    //static const int TT_CODEPAGE_RANGE_950  = (1L << 20); // Chinese: Traditional
-    //static const int TT_CODEPAGE_RANGE_1361 = (1L << 21); // Korean Johab
-    static const int TT_CODEPAGE_RANGES1_CJKT = 0x3F0000; // all of the above
-    const TT_OS2* pOs2 = (const TT_OS2*)FT_Get_Sfnt_Table( maFaceFT, ft_sfnt_os2 );
-    if ((pOs2) && (pOs2->ulCodePageRange1 & TT_CODEPAGE_RANGES1_CJKT )
-        && rFSD.mnHeight < 20)
-        mbUseGamma = true;
-    else
-        mbUseGamma = false;
+    if( ((mnCos != 0) && (mnSin != 0)) || (mnPrioEmbedded <= 0) )
+        mnLoadFlags |= FT_LOAD_NO_BITMAP;
+}
 
-    if (mbUseGamma)
+void FreetypeServerFont::SetFontOptions( const ImplFontOptions& rFontOptions)
+{
+    FontAutoHint eHint = rFontOptions.GetUseAutoHint();
+    if( eHint == AUTOHINT_DONTKNOW )
+        eHint = mbUseGamma ? AUTOHINT_TRUE : AUTOHINT_FALSE;
+
+    if( eHint == AUTOHINT_TRUE )
         mnLoadFlags |= FT_LOAD_FORCE_AUTOHINT;
 
     if( (mnSin != 0) && (mnCos != 0) ) // hinting for 0/90/180/270 degrees only
         mnLoadFlags |= FT_LOAD_NO_HINTING;
     mnLoadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; //#88334#
 
-    if (mpFontInfo->DontUseAntiAlias())
-        mnPrioAntiAlias = 0;
-    if (mpFontInfo->DontUseEmbeddedBitmaps())
-        mnPrioEmbedded = 0;
+    if( rFontOptions.DontUseAntiAlias() )
+      mnPrioAntiAlias = 0;
+    if( rFontOptions.DontUseEmbeddedBitmaps() )
+      mnPrioEmbedded = 0;
+    if( rFontOptions.DontUseHinting() )
+      mnPrioAutoHint = 0;
 
 #if (FTVERSION >= 2005) || defined(TT_CONFIG_OPTION_BYTECODE_INTERPRETER)
-    if( nDefaultPrioAutoHint <= 0 )
+    if( mnPrioAutoHint <= 0 )
 #endif
         mnLoadFlags |= FT_LOAD_NO_HINTING;
 
-#ifdef FT_LOAD_TARGET_LIGHT
-    // enable "light hinting" if available
+#if defined(FT_LOAD_TARGET_LIGHT) && defined(FT_LOAD_TARGET_NORMAL)
     if( !(mnLoadFlags & FT_LOAD_NO_HINTING) && (nFTVERSION >= 2103))
-        mnLoadFlags |= FT_LOAD_TARGET_LIGHT;
+    {
+       mnLoadFlags |= FT_LOAD_TARGET_NORMAL;
+       switch( rFontOptions.GetHintStyle() )
+       {
+           case HINT_NONE:
+                mnLoadFlags |= FT_LOAD_NO_HINTING;
+                break;
+           case HINT_SLIGHT:
+                mnLoadFlags |= FT_LOAD_TARGET_LIGHT;
+                break;
+           case HINT_MEDIUM:
+                break;
+           case HINT_FULL:
+           default:
+                break;
+       }
+    }
 #endif
-
-    if( ((mnCos != 0) && (mnSin != 0)) || (mnPrioEmbedded <= 0) )
-        mnLoadFlags |= FT_LOAD_NO_BITMAP;
 }
 
 // -----------------------------------------------------------------------
         }
     }
 
-#if !defined(TT_CONFIG_OPTION_BYTECODE_INTERPRETER)
+#if 0
     // #95556# autohinting not yet optimized for non-western glyph styles
     if( !(mnLoadFlags & (FT_LOAD_NO_HINTING | FT_LOAD_FORCE_AUTOHINT) )
     &&  ( (aChar >= 0x0600 && aChar < 0x1E00)   // south-east asian + arabic
         ||(aChar >= 0x2900 && aChar < 0xD800)   // CJKV
         ||(aChar >= 0xF800) ) )                 // presentation + symbols
+    {
         nGlyphFlags |= GF_UNHINTED;
+    }
 #endif
 
     if( nGlyphIndex != 0 )
         nLoadFlags |= FT_LOAD_NO_BITMAP;
 
 #if (FTVERSION >= 2002)
-    // for 0/90/180/270 degree fonts enable autohinting even if not advisable
+    // for 0/90/180/270 degree fonts enable hinting even if not advisable
     // non-hinted and non-antialiased bitmaps just look too ugly
-    if( (mnCos==0 || mnSin==0) && (nDefaultPrioAutoHint > 0) )
+    if( (mnCos==0 || mnSin==0) && (mnPrioAutoHint > 0) )
         nLoadFlags &= ~FT_LOAD_NO_HINTING;
 #endif
 
-    if( mnPrioEmbedded <= nDefaultPrioAutoHint )
+    if( mnPrioEmbedded <= mnPrioAutoHint )
         nLoadFlags |= FT_LOAD_NO_BITMAP;
 
     FT_Error rc = -1;
     // autohinting in FT<=2.0.4 makes antialiased glyphs look worse
     nLoadFlags |= FT_LOAD_NO_HINTING;
 #else
-    if( (nGlyphFlags & GF_UNHINTED) || (nDefaultPrioAutoHint < mnPrioAntiAlias) )
+    if( (nGlyphFlags & GF_UNHINTED) || (mnPrioAutoHint < mnPrioAntiAlias) )
         nLoadFlags |= FT_LOAD_NO_HINTING;
 #endif
 

File vcl/source/glyphs/gcach_ftyp.hxx

 
 #include <ft2build.h>
 #include FT_FREETYPE_H
+
 class FreetypeServerFont;
 struct FT_GlyphRec_;
 
     int                   GetFaceNum() const        { return mnFaceNum; }
     int                   GetSynthetic() const      { return mnSynthetic; }
     sal_IntPtr            GetFontId() const         { return mnFontId; }
-    bool                  DontUseAntiAlias() const  
-        { return maDevFontAttributes.UseAntiAlias() == ANTIALIAS_FALSE; }
-    bool                  DontUseEmbeddedBitmaps() const 
-        { return maDevFontAttributes.UseEmbeddedBitmap() == EMBEDDEDBITMAP_FALSE; }
     bool                  IsSymbolFont() const      { return maDevFontAttributes.IsSymbolFont(); }
     const ImplFontAttributes& GetFontAttributes() const { return maDevFontAttributes; }
 
     virtual int                 GetFontFaceNum() const { return mpFontInfo->GetFaceNum(); }
     virtual bool                TestFont() const;
     virtual void*               GetFtFace() const;
-    virtual int               	GetLoadFlags() const { return (mnLoadFlags & ~FT_LOAD_IGNORE_TRANSFORM); }
+    virtual void                SetFontOptions( const ImplFontOptions&);
+    virtual int                 GetLoadFlags() const { return (mnLoadFlags & ~FT_LOAD_IGNORE_TRANSFORM); }
     virtual bool                NeedsArtificialBold() const { return mbArtBold; }
     virtual bool                NeedsArtificialItalic() const { return mbArtItalic; }
 
     int                         mnWidth;
     int                         mnPrioEmbedded;
     int                         mnPrioAntiAlias;
+    int                         mnPrioAutoHint;
     FtFontInfo*                 mpFontInfo;
     FT_Int                      mnLoadFlags;
     double                      mfStretch;

File vcl/source/glyphs/glyphcache.cxx

 
 GlyphCache::~GlyphCache()
 {
-// TODO:
-//  for( FontList::iterator it = maFontList.begin(); it != maFontList.end(); ++it )
-//      delete const_cast<ServerFont*>( it->second );
+    InvalidateAllGlyphs();
     if( mpFtManager )
         delete mpFtManager;
 }
 
+// -----------------------------------------------------------------------
+
+void GlyphCache::InvalidateAllGlyphs()
+{
+#if 0 // TODO: implement uncaching of all glyph shapes and metrics
+    for( FontList::iterator it = maFontList.begin(); it != maFontList.end(); ++it )
+        delete const_cast<ServerFont*>( it->second );
+    maFontList.clear();
+    mpCurrentGCFont = NULL;
+#endif
+}
 
 // -----------------------------------------------------------------------
 
 }
 
 // =======================================================================
+

File vcl/source/window/winproc.cxx

File contents unchanged.

File vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx

 #include "saldisp.hxx"
 #include "vcl/svapp.hxx"
 
+typedef struct _cairo_font_options cairo_font_options_t;
+
 // initialize statics
 BOOL GtkSalGraphics::bThemeChanged = TRUE;
 BOOL GtkSalGraphics::bNeedPixmapPaint = FALSE;
     // preferred icon style
     gchar* pIconThemeName = NULL;
     g_object_get( gtk_settings_get_default(), "gtk-icon-theme-name", &pIconThemeName, (char *)NULL );
-    aStyleSet.SetPreferredSymbolsStyleName( OUString::createFromAscii(pIconThemeName) );
-    g_free (pIconThemeName);
+    aStyleSet.SetPreferredSymbolsStyleName( OUString::createFromAscii( pIconThemeName ) );
+    g_free( pIconThemeName );
 
     //  FIXME: need some way of fetching toolbar icon size.
 //	aStyleSet.SetToolbarIconSize( STYLE_TOOLBAR_ICONSIZE_SMALL );
 
+    const cairo_font_options_t* pNewOptions = NULL;
+    if( GdkScreen* pScreen = gdk_display_get_screen( gdk_display_get_default(), m_nScreen ) )
+    {
+#if !GTK_CHECK_VERSION(2,8,1)
+	static cairo_font_options_t* (*gdk_screen_get_font_options)(GdkScreen*) = 
+		(cairo_font_options_t*(*)(GdkScreen*))osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gdk_screen_get_font_options" );
+	if( gdk_screen_get_font_options != NULL )
+#endif
+		pNewOptions = gdk_screen_get_font_options( pScreen );
+    }
+    aStyleSet.SetCairoFontOptions( pNewOptions );
+
     // finally update the collected settings
     rSettings.SetStyleSettings( aStyleSet );
 

File vcl/unx/gtk/window/gtkframe.cxx

     // redraw itself to adjust to the new style
     // where there IS no new style resulting in tremendous unnecessary flickering
     if( pPrevious != NULL )
+    {
         // signalStyleSet does NOT usually have the gdk lock
         // so post user event to safely dispatch the SALEVENT_SETTINGSCHANGED
         // note: settings changed for multiple frames is avoided in winproc.cxx ImplHandleSettings
         pThis->getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_SETTINGSCHANGED );
+        pThis->getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_FONTCHANGED );
+    }
 
     /* #i64117# gtk sets a nice background pixmap
     *  but we actually don't really want that, so save

File vcl/unx/headless/svpgdi.cxx

 {
     return false;
 }
+

File vcl/unx/headless/svpgdi.hxx

 };
 
 #endif
+

File vcl/unx/headless/svppspgraphics.cxx

     aDFA.mePitch        = ToFontPitch (rInfo.m_ePitch);
     aDFA.mbSymbolFlag   = (rInfo.m_aEncoding == RTL_TEXTENCODING_SYMBOL);
 
-    switch (rInfo.m_eEmbeddedbitmap)
-    {
-        default:
-            aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW;
-            break;
-        case psp::fcstatus::istrue:
-            aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_TRUE;
-            break;
-        case psp::fcstatus::isfalse:
-            aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_FALSE;
-            break;
-    }
-
-    switch (rInfo.m_eAntialias)
-    {
-        default:
-            aDFA.meAntiAlias = ANTIALIAS_DONTKNOW;
-            break;
-        case psp::fcstatus::istrue:
-            aDFA.meAntiAlias = ANTIALIAS_TRUE;
-            break;
-        case psp::fcstatus::isfalse:
-            aDFA.meAntiAlias = ANTIALIAS_FALSE;
-            break;
-    }
-
     switch( rInfo.m_eType )
     {
         case psp::fonttype::Builtin:

File vcl/unx/headless/svppspgraphics.hxx

 };
 
 #endif // _SVP_PSPGRAPHICS_HXX
+

File vcl/unx/inc/pspgraphics.h

     virtual void			SetTextColor( SalColor nSalColor );
     virtual USHORT          SetFont( ImplFontSelectData*, int nFallbackLevel );
     virtual void			GetFontMetric( ImplFontMetricData* );
-    virtual ULONG			GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs );
+    virtual ULONG			GetKernPairs( ULONG nMaxPairs, ImplKernPairData* );
     virtual ImplFontCharMap* GetImplFontCharMap() const;
     virtual void			GetDevFontList( ImplDevFontList* );
     virtual void			GetDevFontSubstList( OutputDevice* );

File vcl/unx/inc/salgdi.h

     virtual void			SetTextColor( SalColor nSalColor );
     virtual USHORT			SetFont( ImplFontSelectData*, int nFallbackLevel );
     virtual void			GetFontMetric( ImplFontMetricData* );
-    virtual ULONG			GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs );
+    virtual ULONG			GetKernPairs( ULONG nMaxPairs, ImplKernPairData* );
     virtual ImplFontCharMap* GetImplFontCharMap() const;
     virtual void			GetDevFontList( ImplDevFontList* );
     virtual void			GetDevFontSubstList( OutputDevice* );

File vcl/unx/source/fontmanager/fontcache.cxx

                 aLine.Append( ';' );
                 aLine.Append( (*it)->m_bUserOverride ? "1" : "0" );
                 aLine.Append( ';' );
-                aLine.Append( ByteString::CreateFromInt32( (*it)->m_eEmbeddedbitmap ) );
+                aLine.Append( ByteString::CreateFromInt32( 0 ) );
                 aLine.Append( ';' );
-                aLine.Append( ByteString::CreateFromInt32( (*it)->m_eAntialias ) );
+                aLine.Append( ByteString::CreateFromInt32( 0 ) );
 
                 switch( (*it)->m_eType )
                 {
                                     = atoi( pLine + nTokenPos[14] );
                 pFont->m_bUserOverride
                                     = (atoi( pLine + nTokenPos[15] ) != 0);
-                pFont->m_eEmbeddedbitmap
-                                    = (fcstatus::type)atoi(pLine+nTokenPos[16]);
-                pFont->m_eAntialias = (fcstatus::type)atoi(pLine+nTokenPos[17]);
                 int nStyleTokenNr = 18;
                 switch( eType )
                 {
     pTo->m_nYMax			= pFrom->m_nYMax;
     pTo->m_bHaveVerticalSubstitutedGlyphs = pFrom->m_bHaveVerticalSubstitutedGlyphs;
     pTo->m_bUserOverride    = pFrom->m_bUserOverride;
-    pTo->m_eEmbeddedbitmap  = pFrom->m_eEmbeddedbitmap;
-    pTo->m_eAntialias       = pFrom->m_eAntialias;
 }
 
 /*
         pRight->m_nXMax				!= pLeft->m_nXMax			||
         pRight->m_nYMax				!= pLeft->m_nYMax			||
         pRight->m_bHaveVerticalSubstitutedGlyphs != pLeft->m_bHaveVerticalSubstitutedGlyphs ||
-        pRight->m_bUserOverride     != pLeft->m_bUserOverride   ||
-        pRight->m_eEmbeddedbitmap   != pLeft->m_eEmbeddedbitmap ||
-        pRight->m_eAntialias        != pLeft->m_eAntialias
+        pRight->m_bUserOverride     != pLeft->m_bUserOverride
         )
         return false;
     std::list< int >::const_iterator lit, rit;

File vcl/unx/source/fontmanager/fontconfig.cxx

 
 #include "vcl/fontmanager.hxx"
 #include "vcl/fontcache.hxx"
+#include "vcl/impfont.hxx"
 
 using namespace psp;
 
 #ifdef ENABLE_FONTCONFIG
-#include <fontconfig/fontconfig.h>
-#include <ft2build.h>
-#include <fontconfig/fcfreetype.h>
-// be compatible with fontconfig 2.2.0 release
-#ifndef FC_WEIGHT_BOOK
-    #define FC_WEIGHT_BOOK 75
-#endif
-#ifndef FC_EMBEDDED_BITMAP
-    #define FC_EMBEDDED_BITMAP "embeddedbitmap"
-#endif
-#ifndef FC_FAMILYLANG
-    #define FC_FAMILYLANG "familylang"
-#endif
+    #include <fontconfig/fontconfig.h>
+    #include <ft2build.h>
+    #include <fontconfig/fcfreetype.h>
+    // allow compile on baseline (currently with fontconfig 2.2.0)
+    #ifndef FC_WEIGHT_BOOK		// TODO: remove when baseline moves to fc>=2.2.1
+        #define FC_WEIGHT_BOOK 75
+    #endif
+    #ifndef FC_EMBEDDED_BITMAP	// TODO: remove when baseline moves to fc>=2.3.92
+        #define FC_EMBEDDED_BITMAP "embeddedbitmap"
+    #endif
+    #ifndef FC_FAMILYLANG		// TODO: remove when baseline moves to fc>=2.2.97
+        #define FC_FAMILYLANG "familylang"
+    #endif
+    #ifndef FC_HINT_STYLE		// TODO: remove when baseline moves to fc>=2.2.91
+    	#define FC_HINT_STYLE  "hintstyle"
+    	#define FC_HINT_NONE   0
+    	#define FC_HINT_SLIGHT 1
+    	#define FC_HINT_MEDIUM 2
+    	#define FC_HINT_FULL   3
+	#endif
 #else
-typedef void FcConfig;
-typedef void FcObjectSet;
-typedef void FcPattern;
-typedef void FcFontSet;
-typedef void FcCharSet;
-typedef int FcResult;
-typedef int FcBool;
-typedef int FcMatchKind;
-typedef char FcChar8;
-typedef int FcChar32;
-typedef unsigned int FT_UInt;
-typedef void* FT_Face;
-typedef int FcSetName;
+    typedef void FcConfig;
+    typedef void FcObjectSet;
+    typedef void FcPattern;
+    typedef void FcFontSet;
+    typedef void FcCharSet;
+    typedef int FcResult;
+    typedef int FcBool;
+    typedef int FcMatchKind;
+    typedef char FcChar8;
+    typedef int FcChar32;
+    typedef unsigned int FT_UInt;
+    typedef void* FT_Face;
+    typedef int FcSetName;
 #endif
 
 #include <cstdio>
     FcBool			(*m_pFcConfigAppFontAddDir)(FcConfig*, const FcChar8*);
     FcBool			(*m_pFcConfigSubstitute)(FcConfig*,FcPattern*,FcMatchKind);
     FcBool			(*m_pFcPatternAddInteger)(FcPattern*,const char*,int);
+    FcBool                    (*m_pFcPatternAddDouble)(FcPattern*,const char*,double);
     FcBool                    (*m_pFcPatternAddBool)(FcPattern*,const char*,FcBool);
     FcBool                    (*m_pFcPatternAddCharSet)(FcPattern*,const char*,const FcCharSet*);
     FcBool			(*m_pFcPatternAddString)(FcPattern*,const char*,const FcChar8*);
     { return m_pFcConfigSubstitute( pConfig, pPattern, eKind ); }
     FcBool FcPatternAddInteger( FcPattern* pPattern, const char* pObject, int nValue )
     { return m_pFcPatternAddInteger( pPattern, pObject, nValue ); }
+    FcBool FcPatternAddDouble( FcPattern* pPattern, const char* pObject, double nValue )
+    { return m_pFcPatternAddDouble( pPattern, pObject, nValue ); }
     FcBool FcPatternAddString( FcPattern* pPattern, const char* pObject, const FcChar8* pString )
     { return m_pFcPatternAddString( pPattern, pObject, pString ); }
     FcBool FcPatternAddBool( FcPattern* pPattern, const char* pObject, bool nValue )
     { return m_pFcFreeTypeCharIndex ? m_pFcFreeTypeCharIndex( face, ucs4 ) : 0; }
 
 public: // TODO: cleanup
-    std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash > m_aFontconfigNameToLocalized;
+    FcResult FamilyFromPattern(FcPattern* pPattern, FcChar8 **family);
+    std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash > m_aFontNameToLocalized;
+    std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash > m_aLocalizedToCanonical;
 };
 
 oslGenericFunction FontCfgWrapper::loadSymbol( const char* pSymbol )
         loadSymbol( "FcConfigSubstitute" );
     m_pFcPatternAddInteger = (FcBool(*)(FcPattern*,const char*,int))
         loadSymbol( "FcPatternAddInteger" );
+    m_pFcPatternAddDouble = (FcBool(*)(FcPattern*,const char*,double))
+        loadSymbol( "FcPatternAddDouble" );
     m_pFcPatternAddBool = (FcBool(*)(FcPattern*,const char*,FcBool))
         loadSymbol( "FcPatternAddBool" );
     m_pFcPatternAddCharSet = (FcBool(*)(FcPattern*,const char*,const FcCharSet *))
             m_pFcDefaultSubstitute			&&
             m_pFcConfigSubstitute			&&
             m_pFcPatternAddInteger			&&
+            m_pFcPatternAddDouble                     &&
             m_pFcPatternAddCharSet			&&
             m_pFcPatternAddBool 			&&
             m_pFcPatternAddString
 
         return candidate;
     }
-
-
-    FcResult lcl_FamilyFromPattern(FontCfgWrapper& rWrapper, FcPattern* pPattern, FcChar8 **family, 
-        std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash > &aFontconfigNameToLocalized)
-    {
-        FcChar8 *origfamily;
-        FcResult eFamilyRes	= rWrapper.FcPatternGetString( pPattern, FC_FAMILY, 0, &origfamily );
-        *family = origfamily;
-        
-        if( eFamilyRes == FcResultMatch)
-        {
-            FcChar8* familylang = NULL;
-            if (rWrapper.FcPatternGetString( pPattern, FC_FAMILYLANG, 0, &familylang ) == FcResultMatch)
-            {
-                std::vector< lang_and_family > lang_and_families;
-                lang_and_families.push_back(lang_and_family(familylang, *family));
-                int k = 1;
-                while (1)
-                {
-                    if (rWrapper.FcPatternGetString( pPattern, FC_FAMILYLANG, k, &familylang ) != FcResultMatch)
-                        break;
-                    if (rWrapper.FcPatternGetString( pPattern, FC_FAMILY, k, family ) != FcResultMatch)
-                        break;
-                    lang_and_families.push_back(lang_and_family(familylang, *family));
-                    ++k;
-                }
-                
-                //possible to-do, sort by UILocale instead of process locale
-                rtl_Locale* pLoc;
-                osl_getProcessLocale(&pLoc);
-                localizedsorter aSorter(pLoc);
-                *family = aSorter.bestname(lang_and_families);
-                
-                std::vector<lang_and_family>::const_iterator aEnd = lang_and_families.end();
-                for (std::vector<lang_and_family>::const_iterator aIter = lang_and_families.begin(); aIter != aEnd; ++aIter)
-                {
-                    const char *candidate = (const char*)(aIter->second);
-                    if (rtl_str_compare(candidate, (const char*)(*family)) != 0)
-                        aFontconfigNameToLocalized[OString(candidate)] = OString((const char*)(*family));
-                }
-            }
-        }
-        
-        return eFamilyRes;
-    }
 }
 
+FcResult FontCfgWrapper::FamilyFromPattern(FcPattern* pPattern, FcChar8 **family)
+{
+    FcChar8 *origfamily;
+    FcResult eFamilyRes	= FcPatternGetString( pPattern, FC_FAMILY, 0, &origfamily );
+    *family = origfamily;
+    
+    if( eFamilyRes == FcResultMatch)
+    {
+        FcChar8* familylang = NULL;
+        if (FcPatternGetString( pPattern, FC_FAMILYLANG, 0, &familylang ) == FcResultMatch)
+        {
+            std::vector< lang_and_family > lang_and_families;
+            lang_and_families.push_back(lang_and_family(familylang, *family));
+            int k = 1;
+            while (1)
+            {
+                if (FcPatternGetString( pPattern, FC_FAMILYLANG, k, &familylang ) != FcResultMatch)
+                    break;
+                if (FcPatternGetString( pPattern, FC_FAMILY, k, family ) != FcResultMatch)
+                    break;
+                lang_and_families.push_back(lang_and_family(familylang, *family));
+                ++k;
+            }
+            
+            //possible to-do, sort by UILocale instead of process locale
+            rtl_Locale* pLoc;
+            osl_getProcessLocale(&pLoc);
+            localizedsorter aSorter(pLoc);
+            *family = aSorter.bestname(lang_and_families);
+            
+            std::vector<lang_and_family>::const_iterator aEnd = lang_and_families.end();
+            for (std::vector<lang_and_family>::const_iterator aIter = lang_and_families.begin(); aIter != aEnd; ++aIter)
+            {
+                const char *candidate = (const char*)(aIter->second);
+                if (rtl_str_compare(candidate, (const char*)(*family)) != 0)
+                    m_aFontNameToLocalized[OString(candidate)] = OString((const char*)(*family));
+            }
+            if (rtl_str_compare((const char*)origfamily, (const char*)(*family)) != 0)
+                m_aLocalizedToCanonical[OString((const char*)(*family))] = OString((const char*)origfamily);
+        }
+    }
+    
+    return eFamilyRes;
+}
 
 /*
  * PrintFontManager::initFontconfig
     return true;
 }
 
+namespace
+{
+    weight::type convertWeight(int weight)
+    {
+        // set weight
+        if( weight <= FC_WEIGHT_THIN )
+            return weight::Thin;
+        else if( weight <= FC_WEIGHT_ULTRALIGHT )
+            return weight::UltraLight;
+        else if( weight <= FC_WEIGHT_LIGHT )
+            return weight::Light;
+        else if( weight <= FC_WEIGHT_BOOK )
+            return weight::SemiLight;
+        else if( weight <= FC_WEIGHT_NORMAL )
+            return weight::Normal;
+        else if( weight <= FC_WEIGHT_MEDIUM )
+            return weight::Medium;
+        else if( weight <= FC_WEIGHT_SEMIBOLD )
+            return weight::SemiBold;
+        else if( weight <= FC_WEIGHT_BOLD )
+            return weight::Bold;
+        else if( weight <= FC_WEIGHT_ULTRABOLD )
+            return weight::UltraBold;
+        return weight::Black;
+    }
+
+    italic::type convertSlant(int slant)
+    {
+        // set italic
+        if( slant == FC_SLANT_ITALIC )
+            return italic::Italic;
+        else if( slant == FC_SLANT_OBLIQUE )
+            return italic::Oblique;
+        return italic::Upright;
+    }
+
+    pitch::type convertSpacing(int spacing)
+    {
+        // set pitch
+        if( spacing == FC_MONO || spacing == FC_CHARCELL )
+            return pitch::Fixed;
+        return pitch::Variable;
+    }
+
+    width::type convertWidth(int width)
+    {
+        if (width == FC_WIDTH_ULTRACONDENSED)
+            return width::UltraCondensed;
+        else if (width == FC_WIDTH_EXTRACONDENSED)
+            return width::ExtraCondensed;
+        else if (width == FC_WIDTH_CONDENSED)
+            return width::Condensed;
+        else if (width == FC_WIDTH_SEMICONDENSED)
+            return width::SemiCondensed;
+        else if (width == FC_WIDTH_SEMIEXPANDED)
+            return width::SemiExpanded;
+        else if (width == FC_WIDTH_EXPANDED)
+            return width::Expanded;
+        else if (width == FC_WIDTH_EXTRAEXPANDED)
+            return width::ExtraExpanded;
+        else if (width == FC_WIDTH_ULTRAEXPANDED)
+            return width::UltraExpanded;
+        return width::Normal;
+    }
+}
+
 int PrintFontManager::countFontconfigFonts()
 {
     int nFonts = 0;
             int weight = 0;
             int spacing = 0;
             int nCollectionEntry = -1;
-            FcBool outline = false, embitmap = true, antialias = true;
+            FcBool outline = false;
             
             FcResult eFileRes	      = rWrapper.FcPatternGetString( pFSet->fonts[i], FC_FILE, 0, &file );
-            FcResult eFamilyRes       = lcl_FamilyFromPattern(rWrapper, pFSet->fonts[i], &family, rWrapper.m_aFontconfigNameToLocalized );
+            FcResult eFamilyRes       = rWrapper.FamilyFromPattern( pFSet->fonts[i], &family );
             FcResult eStyleRes	      = rWrapper.FcPatternGetString( pFSet->fonts[i], FC_STYLE, 0, &style );
             FcResult eSlantRes	      = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_SLANT, 0, &slant );
             FcResult eWeightRes	      = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_WEIGHT, 0, &weight );
             FcResult eSpacRes	      = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_SPACING, 0, &spacing );
             FcResult eOutRes	      = rWrapper.FcPatternGetBool( pFSet->fonts[i], FC_OUTLINE, 0, &outline );
             FcResult eIndexRes        = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_INDEX, 0, &nCollectionEntry );
-            FcResult eEmbeddedBitmap  = rWrapper.FcPatternGetBool( pFSet->fonts[i], FC_EMBEDDED_BITMAP, 0, &embitmap );
-            FcResult eAntialias       = rWrapper.FcPatternGetBool( pFSet->fonts[i], FC_ANTIALIAS, 0, &antialias );
             
             if( eFileRes != FcResultMatch || eFamilyRes != FcResultMatch || eOutRes != FcResultMatch )
                 continue;
                     pUpdate->m_nFamilyName = nFamilyName;
                 }
                 if( eWeightRes == FcResultMatch )
-                {
-                    // set weight
-                    if( weight <= FC_WEIGHT_THIN )
-                        pUpdate->m_eWeight = weight::Thin;
-                    else if( weight <= FC_WEIGHT_ULTRALIGHT )
-                        pUpdate->m_eWeight = weight::UltraLight;
-                    else if( weight <= FC_WEIGHT_LIGHT )
-                        pUpdate->m_eWeight = weight::Light;
-                    else if( weight <= FC_WEIGHT_BOOK )
-                        pUpdate->m_eWeight = weight::SemiLight;
-                    else if( weight <= FC_WEIGHT_NORMAL )
-                        pUpdate->m_eWeight = weight::Normal;
-                    else if( weight <= FC_WEIGHT_MEDIUM )
-                        pUpdate->m_eWeight = weight::Medium;
-                    else if( weight <= FC_WEIGHT_SEMIBOLD )
-                        pUpdate->m_eWeight = weight::SemiBold;
-                    else if( weight <= FC_WEIGHT_BOLD )
-                        pUpdate->m_eWeight = weight::Bold;
-                    else if( weight <= FC_WEIGHT_ULTRABOLD )
-                        pUpdate->m_eWeight = weight::UltraBold;
-                    else
-                        pUpdate->m_eWeight = weight::Black;
-                }
+					pUpdate->m_eWeight = convertWeight(weight);
                 if( eSpacRes == FcResultMatch )
-                {
-                    // set pitch
-                    if( spacing == FC_PROPORTIONAL )
-                        pUpdate->m_ePitch = pitch::Variable;
-                    else if( spacing == FC_MONO || spacing == FC_CHARCELL )
-                        pUpdate->m_ePitch = pitch::Fixed;
-                }
+                    pUpdate->m_ePitch = convertSpacing(spacing);
                 if( eSlantRes == FcResultMatch )
-                {
-                    // set italic
-                    if( slant == FC_SLANT_ROMAN )
-                        pUpdate->m_eItalic = italic::Upright;
-                    else if( slant == FC_SLANT_ITALIC )
-                        pUpdate->m_eItalic = italic::Italic;
-                    else if( slant == FC_SLANT_OBLIQUE )
-                        pUpdate->m_eItalic = italic::Oblique;
-                }
+					pUpdate->m_eItalic = convertSlant(slant);
                 if( eStyleRes == FcResultMatch )
                 {
                     pUpdate->m_aStyleName = OStringToOUString( OString( (sal_Char*)style ), RTL_TEXTENCODING_UTF8 );
                 }
-                if( eEmbeddedBitmap == FcResultMatch )
-                {
-                  pUpdate->m_eEmbeddedbitmap = embitmap ? fcstatus::istrue : fcstatus::isfalse;
-                }
-                if( eAntialias == FcResultMatch )
-                {
-                  pUpdate->m_eAntialias = antialias ? fcstatus::istrue : fcstatus::isfalse;
-                }
-
                 
                 // update font cache
                 m_pFontCache->updateFontCacheEntry( pUpdate, false );
 
 rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName,
     rtl::OUString& rMissingCodes, const rtl::OString &rLangAttrib,
-    italic::type eItalic, weight::type eWeight,
-    width::type eWidth, pitch::type ePitch) const
+    italic::type &rItalic, weight::type &rWeight,
+    width::type &rWidth, pitch::type &rPitch) const
 {
     rtl::OUString aName;
     FontCfgWrapper& rWrapper = FontCfgWrapper::get();
        rWrapper.FcCharSetDestroy( unicodes );
     }
 
-    addtopattern(rWrapper, pPattern, eItalic, eWeight, eWidth, ePitch);
+    addtopattern(rWrapper, pPattern, rItalic, rWeight, rWidth, rPitch);
 
     // query fontconfig for a substitute
     rWrapper.FcConfigSubstitute( rWrapper.FcConfigGetCurrent(), pPattern, FcMatchPattern );
             if( eFileRes == FcResultMatch )
             {
                 OString sFamily((sal_Char*)family);
-                std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash >::const_iterator aI = rWrapper.m_aFontconfigNameToLocalized.find(sFamily);
-                if (aI != rWrapper.m_aFontconfigNameToLocalized.end())
+                std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash >::const_iterator aI = rWrapper.m_aFontNameToLocalized.find(sFamily);
+                if (aI != rWrapper.m_aFontNameToLocalized.end())
                     sFamily = aI->second;
                 aName = rtl::OStringToOUString( sFamily, RTL_TEXTENCODING_UTF8 );
+
+
+                int val = 0;
+                if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_WEIGHT, 0, &val))
+                    rWeight = convertWeight(val);
+                if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_SLANT, 0, &val))
+                    rItalic = convertSlant(val);
+                if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_SPACING, 0, &val))
+                    rPitch = convertSpacing(val);
+                if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_WIDTH, 0, &val))
+                    rWidth = convertWidth(val);
             }
 
 			// update rMissingCodes by removing resolved unicodes
     return aName;
 }
 
+bool PrintFontManager::getFontOptions( 
+    const FastPrintFontInfo& rInfo, int nSize, void (*subcallback)(void*),
+    ImplFontOptions& rOptions) const
+{
+#ifndef ENABLE_FONTCONFIG
+    return false;
+#else // ENABLE_FONTCONFIG
+    FontCfgWrapper& rWrapper = FontCfgWrapper::get();
+    if( ! rWrapper.isValid() )
+        return false;
+
+    FcConfig* pConfig = rWrapper.FcConfigGetCurrent();
+    FcPattern* pPattern = rWrapper.FcPatternCreate();
+
+    OString sFamily = OUStringToOString( rInfo.m_aFamilyName, RTL_TEXTENCODING_UTF8 );
+
+    std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash >::const_iterator aI = rWrapper.m_aLocalizedToCanonical.find(sFamily);
+    if (aI != rWrapper.m_aLocalizedToCanonical.end())
+        sFamily = aI->second;
+    if( sFamily.getLength() )
+        rWrapper.FcPatternAddString( pPattern, FC_FAMILY, (FcChar8*)sFamily.getStr() );
+
+    addtopattern(rWrapper, pPattern, rInfo.m_eItalic, rInfo.m_eWeight, rInfo.m_eWidth, rInfo.m_ePitch);
+    rWrapper.FcPatternAddDouble( pPattern, FC_PIXEL_SIZE, nSize);
+
+    FcBool embitmap = true, antialias = true, autohint = true, hinting = true;
+    int hintstyle = FC_HINT_FULL;
+
+    rWrapper.FcConfigSubstitute( pConfig, pPattern, FcMatchPattern );
+    if (subcallback) subcallback(pPattern);
+    rWrapper.FcDefaultSubstitute( pPattern );
+
+    FcResult eResult = FcResultNoMatch;
+    FcFontSet* pFontSet = rWrapper.getFontSet();
+    FcPattern* pResult = rWrapper.FcFontSetMatch( pConfig, &pFontSet, 1, pPattern, &eResult );
+    if( pResult )
+    {
+        FcFontSet* pSet = rWrapper.FcFontSetCreate();
+        rWrapper.FcFontSetAdd( pSet, pResult );
+        if( pSet->nfont > 0 )
+        {
+            FcResult eEmbeddedBitmap = rWrapper.FcPatternGetBool(pSet->fonts[0],
+                FC_EMBEDDED_BITMAP, 0, &embitmap);
+            FcResult eAntialias = rWrapper.FcPatternGetBool(pSet->fonts[0],
+                FC_ANTIALIAS, 0, &antialias);
+            FcResult eAutoHint = rWrapper.FcPatternGetBool(pSet->fonts[0], 
+                FC_AUTOHINT, 0, &autohint);
+            FcResult eHinting = rWrapper.FcPatternGetBool(pSet->fonts[0], 
+                FC_HINTING, 0, &hinting);
+            /*FcResult eHintStyle =*/ rWrapper.FcPatternGetInteger( pSet->fonts[0],
+                FC_HINT_STYLE, 0, &hintstyle);
+         
+            if( eEmbeddedBitmap == FcResultMatch )
+                rOptions.meEmbeddedBitmap = embitmap ? EMBEDDEDBITMAP_TRUE : EMBEDDEDBITMAP_FALSE;
+            if( eAntialias == FcResultMatch )
+                rOptions.meAntiAlias = antialias ? ANTIALIAS_TRUE : ANTIALIAS_FALSE;
+            if( eAutoHint == FcResultMatch )
+                rOptions.meAutoHint = autohint ? AUTOHINT_TRUE : AUTOHINT_FALSE;
+            if( eHinting == FcResultMatch )
+                rOptions.meHinting = hinting ? HINTING_TRUE : HINTING_FALSE;
+            switch (hintstyle)
+            {
+                case FC_HINT_NONE:   rOptions.meHintStyle = HINT_NONE; break;
+                case FC_HINT_SLIGHT: rOptions.meHintStyle = HINT_SLIGHT; break;
+                case FC_HINT_MEDIUM: rOptions.meHintStyle = HINT_MEDIUM; break;
+                default: // fall through
+                case FC_HINT_FULL:   rOptions.meHintStyle = HINT_FULL; break;
+            }
+        }
+        // info: destroying the pSet destroys pResult implicitly
+        // since pResult was "added" to pSet
+        rWrapper.FcFontSetDestroy( pSet );
+    }
+
+    // cleanup
+    rWrapper.FcPatternDestroy( pPattern );
+
+    // TODO: return true only if non-default font options are set
+    const bool bOK = (pResult != NULL);
+    return bOK;
+#endif
+}
+
 bool PrintFontManager::matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale )
 {
     FontCfgWrapper& rWrapper = FontCfgWrapper::get();

File vcl/unx/source/fontmanager/fontmanager.cxx

         m_nXMax( 0 ),
         m_nYMax( 0 ),
         m_bHaveVerticalSubstitutedGlyphs( false ),
-        m_bUserOverride( false ),
-        m_eEmbeddedbitmap( fcstatus::isunset ),
-        m_eAntialias( fcstatus::isunset )
+        m_bUserOverride( false )
 {
 }
 
     rInfo.m_eWeight         = pFont->m_eWeight;
     rInfo.m_ePitch          = pFont->m_ePitch;
     rInfo.m_aEncoding       = pFont->m_aEncoding;
-    rInfo.m_eEmbeddedbitmap = pFont->m_eEmbeddedbitmap;
-    rInfo.m_eAntialias      = pFont->m_eAntialias;
 
     rInfo.m_bEmbeddable  = (pFont->m_eType == fonttype::Type1);
     rInfo.m_bSubsettable = (pFont->m_eType == fonttype::TrueType); // TODO: rename to SfntType
         BuiltinFont* pFont = new BuiltinFont();
         pFont->m_nDirectory = 0;
         pFont->m_bUserOverride = false;
-        pFont->m_eEmbeddedbitmap = fcstatus::isunset;
-        pFont->m_eAntialias = fcstatus::isunset;
         pFont->m_pMetrics = new PrintFontMetrics;
         memset( pFont->m_pMetrics->m_aPages, 0xff, sizeof( pFont->m_pMetrics->m_aPages ) );
         pFont->m_pMetrics->m_bKernPairsQueried = true;

File vcl/unx/source/gdi/pspgraphics.cxx

     aDFA.mbSubsettable  = rInfo.m_bSubsettable;
     aDFA.mbEmbeddable   = rInfo.m_bEmbeddable;
 
-    switch (rInfo.m_eEmbeddedbitmap)
-    {
-        default:
-            aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW;
-            break;
-        case psp::fcstatus::istrue:
-            aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_TRUE;
-            break;
-        case psp::fcstatus::isfalse:
-            aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_FALSE;
-            break;
-    }
-
-    switch (rInfo.m_eAntialias)
-    {
-        default:
-            aDFA.meAntiAlias = ANTIALIAS_DONTKNOW;
-            break;
-        case psp::fcstatus::istrue:
-            aDFA.meAntiAlias = ANTIALIAS_TRUE;
-            break;
-        case psp::fcstatus::isfalse:
-            aDFA.meAntiAlias = ANTIALIAS_FALSE;
-            break;
-    }
-
     switch( rInfo.m_eType )
     {
         case psp::fonttype::Builtin:

File vcl/unx/source/gdi/salgdi3.cxx

     ServerFont* pServerFont = GlyphCache::GetInstance().CacheFont( *pEntry );
     if( pServerFont != NULL )
     {
+        // ignore fonts with e.g. corrupted font files
         if( !pServerFont->TestFont() )
         {
             GlyphCache::GetInstance().UncacheFont( *pServerFont );
             return false;
         }
+
+        // register to use the font
         mpServerFont[ nFallbackLevel ] = pServerFont;
+
+        // apply font specific-hint settings if needed 
+	if( !bPrinter_ )
+	{
+            // TODO: is it worth it to cache the hint settings, e.g. in the ImplFontEntry?
+            ImplFontOptions aFontOptions;
+            bool GetFCFontOptions( const ImplFontAttributes&, int nSize, ImplFontOptions&);
+            if( GetFCFontOptions( *pEntry->mpFontData, pEntry->mnHeight, aFontOptions ) )
+                pServerFont->SetFontOptions( aFontOptions );
+        }
+
         return true;
     }
 
     void (*mp_set_font_matrix)(cairo_t *, const cairo_matrix_t *);
     void (*mp_show_glyphs)(cairo_t *, const cairo_glyph_t *, int );
     void (*mp_set_source_rgb)(cairo_t *, double , double , double );
+    void (*mp_set_font_options)(cairo_t *, const void *);
+    void (*mp_ft_font_options_substitute)(const void*, void*);
 
     bool canEmbolden() const { return false; }
 
         { (*mp_show_glyphs)(cr, glyphs, no_glyphs); }
     void set_source_rgb(cairo_t *cr, double red, double green, double blue)
         { (*mp_set_source_rgb)(cr, red, green, blue); }
+    void set_font_options(cairo_t *cr, const void *options)
+        { (*mp_set_font_options)(cr, options); }
+    void ft_font_options_substitute(const void *options, void *pattern)
+        { (*mp_ft_font_options_substitute)(options, pattern); }
 };
 
 static CairoWrapper* pCairoInstance = NULL;
         osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_show_glyphs" );
     mp_set_source_rgb = (void (*)(cairo_t *, double , double , double ))
         osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_set_source_rgb" );
+    mp_set_font_options = (void (*)(cairo_t *, const void *options ))
+        osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_set_font_options" );
+    mp_ft_font_options_substitute = (void (*)(const void *, void *))
+        osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_ft_font_options_substitute" );
 
     if( !( 
             mp_xlib_surface_create_with_xrender_format &&
             mp_matrix_rotate &&
             mp_set_font_matrix &&
             mp_show_glyphs &&
-            mp_set_source_rgb
+            mp_set_source_rgb &&
+            mp_set_font_options &&
+            mp_ft_font_options_substitute
         ) )
     {
         osl_unloadModule( mpCairoLib );
     cairo_t *cr = rCairo.create(surface);
     rCairo.surface_destroy(surface);
 
+    if (const void *pOptions = Application::GetSettings().GetStyleSettings().GetCairoFontOptions())
+        rCairo.set_font_options( cr, pOptions);
+
     if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) )
     {
 	for (long i = 0; i < pClipRegion_->numRects; ++i)
 
 // ----------------------------------------------------------------------------
 
+void cairosubcallback( void* pPattern )
+{
+    CairoWrapper& rCairo = CairoWrapper::get();
+    if( rCairo.isValid() )
+    {
+	const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+        rCairo.ft_font_options_substitute( rStyleSettings.GetCairoFontOptions(), pPattern);
+    }
+}
+
+bool GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize,
+	ImplFontOptions& rFontOptions)
+{
+    // TODO: get rid of these insane enum-conversions
+    // e.g. by using the classic vclenum values inside VCL
+
+    psp::FastPrintFontInfo aInfo;
+    // set family name
+    aInfo.m_aFamilyName = rFontAttributes.GetFamilyName();
+    // set italic
+    switch( rFontAttributes.GetSlant() )
+    {
+        case ITALIC_NONE:
+            aInfo.m_eItalic = psp::italic::Upright;
+            break;
+        case ITALIC_NORMAL:
+            aInfo.m_eItalic = psp::italic::Italic;
+            break;
+        case ITALIC_OBLIQUE:
+            aInfo.m_eItalic = psp::italic::Oblique;
+            break;
+        default:
+            aInfo.m_eItalic = psp::italic::Unknown;
+            break;
+
+    }
+    // set weight
+    switch( rFontAttributes.GetWeight() )
+    {
+        case WEIGHT_THIN:
+            aInfo.m_eWeight = psp::weight::Thin;
+            break;
+        case WEIGHT_ULTRALIGHT:
+            aInfo.m_eWeight = psp::weight::UltraLight;
+            break;
+        case WEIGHT_LIGHT:
+            aInfo.m_eWeight = psp::weight::Light;
+            break;
+        case WEIGHT_SEMILIGHT:
+            aInfo.m_eWeight = psp::weight::SemiLight;
+            break;
+        case WEIGHT_NORMAL:
+            aInfo.m_eWeight = psp::weight::Normal;
+            break;
+        case WEIGHT_MEDIUM:
+            aInfo.m_eWeight = psp::weight::Medium;
+            break;
+        case WEIGHT_SEMIBOLD:
+            aInfo.m_eWeight = psp::weight::SemiBold;
+            break;
+        case WEIGHT_BOLD:
+            aInfo.m_eWeight = psp::weight::Bold;
+            break;
+        case WEIGHT_ULTRABOLD:
+            aInfo.m_eWeight = psp::weight::UltraBold;
+            break;
+        case WEIGHT_BLACK:
+            aInfo.m_eWeight = psp::weight::Black;
+            break;
+        default:
+            aInfo.m_eWeight = psp::weight::Unknown;
+            break;
+    }
+    // set width
+    switch( rFontAttributes.GetWidthType() )
+    {
+        case WIDTH_ULTRA_CONDENSED:
+            aInfo.m_eWidth = psp::width::UltraCondensed;
+            break;
+        case WIDTH_EXTRA_CONDENSED:
+            aInfo.m_eWidth = psp::width::ExtraCondensed;
+            break;
+        case WIDTH_CONDENSED:
+            aInfo.m_eWidth = psp::width::Condensed;
+            break;
+        case WIDTH_SEMI_CONDENSED:
+            aInfo.m_eWidth = psp::width::SemiCondensed;
+            break;
+        case WIDTH_NORMAL:
+            aInfo.m_eWidth = psp::width::Normal;
+            break;
+        case WIDTH_SEMI_EXPANDED:
+            aInfo.m_eWidth = psp::width::SemiExpanded;
+            break;
+        case WIDTH_EXPANDED:
+            aInfo.m_eWidth = psp::width::Expanded;
+            break;
+        case WIDTH_EXTRA_EXPANDED:
+            aInfo.m_eWidth = psp::width::ExtraExpanded;
+            break;
+        case WIDTH_ULTRA_EXPANDED:
+            aInfo.m_eWidth = psp::width::UltraExpanded;
+            break;
+        default:
+            aInfo.m_eWidth = psp::width::Unknown;
+            break;
+    }
+
+    const psp::PrintFontManager& rPFM = psp::PrintFontManager::get();
+    bool bOK = rPFM.getFontOptions( aInfo, nSize, cairosubcallback, rFontOptions);
+
+    return bOK;
+}
+
+// ----------------------------------------------------------------------------
+
 void
 X11SalGraphics::GetFontMetric( ImplFontMetricData *pMetric )
 {
 
 // -----------------------------------------------------------------------
 
-static rtl::OUString GetFcSubstitute(const ImplFontSelectData &rFontSelData, OUString& rMissingCodes )
+static ImplFontSelectData GetFcSubstitute(const ImplFontSelectData &rFontSelData, OUString& rMissingCodes )
 {
+    ImplFontSelectData aRet(rFontSelData);
+
     const rtl::OString aLangAttrib; //TODO: = MsLangId::convertLanguageToIsoByteString( rFontSelData.meLanguage );
 
     psp::italic::type eItalic = psp::italic::Unknown;
     }
 
     const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
-    return rMgr.Substitute( rFontSelData.maTargetName, rMissingCodes, aLangAttrib, eItalic, eWeight, eWidth, ePitch);
+    aRet.maSearchName = rMgr.Substitute( rFontSelData.maTargetName, rMissingCodes, aLangAttrib, eItalic, eWeight, eWidth, ePitch);
+
+    switch (eItalic)
+    {
+        case psp::italic::Upright: aRet.meItalic = ITALIC_NONE; break;
+        case psp::italic::Italic: aRet.meItalic = ITALIC_NORMAL; break;
+        case psp::italic::Oblique: aRet.meItalic = ITALIC_OBLIQUE; break;
+        default:
+            break;
+    }
+
+    switch (eWeight)
+    {
+        case psp::weight::Thin: aRet.meWeight = WEIGHT_THIN; break;
+        case psp::weight::UltraLight: aRet.meWeight = WEIGHT_ULTRALIGHT; break;
+        case psp::weight::Light: aRet.meWeight = WEIGHT_LIGHT; break;
+        case psp::weight::SemiLight: aRet.meWeight = WEIGHT_SEMILIGHT; break;
+        case psp::weight::Normal: aRet.meWeight = WEIGHT_NORMAL; break;
+        case psp::weight::Medium: aRet.meWeight = WEIGHT_MEDIUM; break;
+        case psp::weight::SemiBold: aRet.meWeight = WEIGHT_SEMIBOLD; break;
+        case psp::weight::Bold: aRet.meWeight = WEIGHT_BOLD; break;
+        case psp::weight::UltraBold: aRet.meWeight = WEIGHT_ULTRABOLD; break;
+        case psp::weight::Black: aRet.meWeight = WEIGHT_BLACK; break;
+        default:
+                break;
+    }
+
+    switch (eWidth)
+    {
+        case psp::width::UltraCondensed: aRet.meWidthType = WIDTH_ULTRA_CONDENSED; break;
+        case psp::width::ExtraCondensed: aRet.meWidthType = WIDTH_EXTRA_CONDENSED; break;
+        case psp::width::Condensed: aRet.meWidthType = WIDTH_CONDENSED; break;
+        case psp::width::SemiCondensed: aRet.meWidthType = WIDTH_SEMI_CONDENSED; break;
+        case psp::width::Normal: aRet.meWidthType = WIDTH_NORMAL; break;
+        case psp::width::SemiExpanded: aRet.meWidthType = WIDTH_SEMI_EXPANDED; break;
+        case psp::width::Expanded: aRet.meWidthType = WIDTH_EXPANDED; break;
+        case psp::width::ExtraExpanded: aRet.meWidthType = WIDTH_EXTRA_EXPANDED; break;
+        case psp::width::UltraExpanded: aRet.meWidthType = WIDTH_ULTRA_EXPANDED; break;
+        default:
+            break;
+    }
+
+    switch (ePitch)
+    {
+        case psp::pitch::Fixed: aRet.mePitch = PITCH_FIXED; break;
+        case psp::pitch::Variable: aRet.mePitch = PITCH_VARIABLE; break;
+        default:
+            break;
+    }
+
+    return aRet;
+}
+
+namespace
+{
+    bool uselessmatch(const ImplFontSelectData &rOrig, const ImplFontSelectData &rNew)
+    {
+        return
+          (
+            rOrig.maTargetName == rNew.maSearchName &&
+            rOrig.meWeight == rNew.meWeight &&
+            rOrig.meItalic == rNew.meItalic &&
+            rOrig.mePitch == rNew.mePitch &&
+            rOrig.meWidthType == rNew.meWidthType
+          );
+    }
 }
 
 //--------------------------------------------------------------------------
 bool FcPreMatchSubstititution::FindFontSubstitute( ImplFontSelectData &rFontSelData ) const
 {
     // We dont' actually want to talk to Fontconfig at all for symbol fonts
-    if (rFontSelData.IsSymbolFont())
+    if( rFontSelData.IsSymbolFont() )
         return false;
     // StarSymbol is a unicode font, but it still deserves the symbol flag
     if( 0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "starsymbol", 10)
         return false;
 
     rtl::OUString aDummy;
-    const rtl::OUString aOUName = GetFcSubstitute( rFontSelData, aDummy );
-    if( !aOUName.getLength() )
-        return false;
-    const String aName( aOUName );
-    if( aName == rFontSelData.maTargetName )
+    const ImplFontSelectData aOut = GetFcSubstitute( rFontSelData, aDummy );
+    // TODO: cache the font substitution suggestion
+    // FC doing it would be preferable because it knows the invariables
+    // e.g. FC knows the FC rule that all Arial gets replaced by LiberationSans
+    // whereas we would have to check for every size or attribute
+    if( !aOut.maSearchName.Len() )
         return false;
 
+    const bool bHaveSubstitute = !uselessmatch( rFontSelData, aOut );
+
 #ifdef DEBUG
-    ByteString aOrigName( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 );
-    ByteString aSubstName( aName, RTL_TEXTENCODING_UTF8 );
-    printf( "FcPreMatchSubstititution \"%s\" -> \"%s\"\n",
-        aOrigName.GetBuffer(), aSubstName.GetBuffer() );
+    const ByteString aOrigName( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 );
+    const ByteString aSubstName( aOut.maSearchName, RTL_TEXTENCODING_UTF8 );
+    printf( "FcPreMatchSubstititution \"%s\" bipw=%d%d%d%d -> ",
+        aOrigName.GetBuffer(), rFontSelData.meWeight, rFontSelData.meItalic,
+        rFontSelData.mePitch, rFontSelData.meWidthType );
+    if( !bHaveSubstitute )
+        printf( "no substitute available\n" );
+    else
+        printf( "\"%s\" bipw=%d%d%d%d\n", aSubstName.GetBuffer(),
+	    aOut.meWeight, aOut.meItalic, aOut.mePitch, aOut.meWidthType );
 #endif
-    rFontSelData.maSearchName = aName;
-    return true;
+
+    if( bHaveSubstitute )
+        rFontSelData = aOut;
+
+    return bHaveSubstitute;
 }
 
 // -----------------------------------------------------------------------
     ||  0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "opensymbol", 10) )
         return false;
 
-    const rtl::OUString aOUName = GetFcSubstitute( rFontSelData, rMissingCodes );
-    // TODO: cache the unicode+font specific result
-    if( !aOUName.getLength() )
-        return false;
-    const String aName( aOUName );
-    if( aName == rFontSelData.maTargetName )
+    const ImplFontSelectData aOut = GetFcSubstitute( rFontSelData, rMissingCodes );
+    // TODO: cache the unicode + srcfont specific result
+    // FC doing it would be preferable because it knows the invariables
+    // e.g. FC knows the FC rule that all Arial gets replaced by LiberationSans
+    // whereas we would have to check for every size or attribute
+    if( !aOut.maSearchName.Len() )
         return false;
 
+    const bool bHaveSubstitute = !uselessmatch( rFontSelData, aOut );
+
 #ifdef DEBUG
-    ByteString aOrigName( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 );
-    ByteString aSubstName( aName, RTL_TEXTENCODING_UTF8 );
-    printf( "FcGlyphFallbackSubstititution \"%s\" -> \"%s\"\n",
-        aOrigName.GetBuffer(), aSubstName.GetBuffer() );
+    const ByteString aOrigName( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 );
+    const ByteString aSubstName( aOut.maSearchName, RTL_TEXTENCODING_UTF8 );
+    printf( "FcGFSubstititution \"%s\" bipw=%d%d%d%d ->",
+        aOrigName.GetBuffer(), rFontSelData.meWeight, rFontSelData.meItalic,
+        rFontSelData.mePitch, rFontSelData.meWidthType );
+    if( !bHaveSubstitute )
+        printf( "no substitute available\n" );
+    else
+        printf( "\"%s\" bipw=%d%d%d%d\n", aSubstName.GetBuffer(),
+	    aOut.meWeight, aOut.meItalic, aOut.mePitch, aOut.meWidthType );
 #endif
-    rFontSelData.maSearchName = aName;
-    return true;
+
+    if( bHaveSubstitute )
+        rFontSelData = aOut;
+
+    return bHaveSubstitute;
 }
 
 // ===========================================================================

File vcl/unx/source/gdi/xlfd_extd.cxx

     mbSubsettable  = false;
     mbEmbeddable   = false;
 
-    meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW;
-    meAntiAlias = ANTIALIAS_DONTKNOW;
-
     mnQuality      = -1;
 }
 

File vcl/win/inc/salgdi.h

File contents unchanged.

File vcl/win/source/gdi/salgdi3.cxx

             aDFA.mnQuality += 500;
     }
 
-    aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW;
-    aDFA.meAntiAlias = ANTIALIAS_DONTKNOW;
-
     // TODO: add alias names
-
     return aDFA;
 }
 
             aDFA.mnQuality += 500;
     }
 
-    aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW;
-    aDFA.meAntiAlias = ANTIALIAS_DONTKNOW;
-
     // TODO: add alias names
     return aDFA;
 }
     rDFA.mePitch      = PITCH_DONTKNOW;;
     rDFA.mbSubsettable= true;
     rDFA.mbEmbeddable = false;
-    rDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW;
-    rDFA.meAntiAlias = ANTIALIAS_DONTKNOW;
 
     // Create temporary file name
     char aFileName[] = "soAAT.fot";
     aDFA.mePitch      = PITCH_DONTKNOW;;
     aDFA.mbSubsettable= true;
     aDFA.mbEmbeddable = false;
-    aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW;
-    aDFA.meAntiAlias = ANTIALIAS_DONTKNOW;
 
     /*
     // TODO: improve ImplDevFontAttributes using the "font resource file"