diff options
author | Caolán McNamara <cmc@openoffice.org> | 2010-04-02 13:16:59 +0100 |
---|---|---|
committer | Caolán McNamara <cmc@openoffice.org> | 2010-04-02 13:16:59 +0100 |
commit | fab2ad2791f0dbc88c06e601e3357aa8d1732de1 (patch) | |
tree | 64cc2e734c71632dcc6ce8f91e77cfe50ebd200f /vcl | |
parent | 438d3eef38d0b13ee54f5ab2f0365893dbdff68a (diff) | |
parent | f099cd4586bf41f30dea8190dbd2bd7b4234cf60 (diff) |
cmcfixes73: merge with DEV300 m75
Diffstat (limited to 'vcl')
29 files changed, 722 insertions, 317 deletions
diff --git a/vcl/aqua/source/gdi/salatsuifontutils.cxx b/vcl/aqua/source/gdi/salatsuifontutils.cxx index 1566f0961f54..8281c41ceeab 100644 --- a/vcl/aqua/source/gdi/salatsuifontutils.cxx +++ b/vcl/aqua/source/gdi/salatsuifontutils.cxx @@ -217,9 +217,6 @@ static bool GetDevFontAttributes( ATSUFontID nFontID, ImplDevFontAttributes& rDF // 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; diff --git a/vcl/inc/vcl/fontmanager.hxx b/vcl/inc/vcl/fontmanager.hxx index 7e1733b49bca..6ebd777f1c61 100644 --- a/vcl/inc/vcl/fontmanager.hxx +++ b/vcl/inc/vcl/fontmanager.hxx @@ -49,6 +49,7 @@ // forward declarations namespace utl { class MultiAtomProvider; } // see unotools/atom.hxx class FontSubsetInfo; +class ImplFontOptions; namespace psp { class PPDParser; // see ppdparser.hxx @@ -162,8 +163,6 @@ struct FastPrintFontInfo 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; @@ -175,9 +174,7 @@ struct FastPrintFontInfo 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 ) {} }; @@ -294,9 +291,6 @@ class VCL_DLLPUBLIC PrintFontManager 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; @@ -736,10 +730,11 @@ public: 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 ); diff --git a/vcl/inc/vcl/glyphcache.hxx b/vcl/inc/vcl/glyphcache.hxx index 8c7d6e41b168..fa3e99f2373f 100644 --- a/vcl/inc/vcl/glyphcache.hxx +++ b/vcl/inc/vcl/glyphcache.hxx @@ -39,6 +39,7 @@ class ServerFontLayoutEngine; class ServerFontLayout; class ExtraKernInfo; struct ImplKernPairData; +class ImplFontOptions; #include <tools/gen.hxx> #include <hash_map> @@ -59,8 +60,8 @@ class ServerFontLayout; class VCL_DLLPUBLIC GlyphCache { public: - GlyphCache( GlyphCachePeer& ); - ~GlyphCache(); + explicit GlyphCache( GlyphCachePeer& ); + /*virtual*/ ~GlyphCache(); static GlyphCache& GetInstance(); void LoadFonts(); @@ -74,6 +75,7 @@ public: ServerFont* CacheFont( const ImplFontSelectData& ); void UncacheFont( ServerFont& ); + void InvalidateAllGlyphs(); protected: GlyphCachePeer& mrPeer; @@ -96,7 +98,6 @@ private: 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; @@ -179,6 +180,7 @@ public: 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; } @@ -208,7 +210,7 @@ public: protected: friend class GlyphCache; friend class ServerFontLayout; - ServerFont( const ImplFontSelectData& ); + explicit ServerFont( const ImplFontSelectData& ); virtual ~ServerFont(); void AddRef() const { ++mnRefCount; } diff --git a/vcl/inc/vcl/impfont.hxx b/vcl/inc/vcl/impfont.hxx index d53785bc691a..6ce9f21500b5 100644 --- a/vcl/inc/vcl/impfont.hxx +++ b/vcl/inc/vcl/impfont.hxx @@ -133,6 +133,41 @@ public: 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 - // ------------------- diff --git a/vcl/inc/vcl/outdev.hxx b/vcl/inc/vcl/outdev.hxx index 101a368b0586..be5c0a880ed7 100644 --- a/vcl/inc/vcl/outdev.hxx +++ b/vcl/inc/vcl/outdev.hxx @@ -77,6 +77,7 @@ class AlphaMask; class FontCharMap; class SalLayout; class ImplLayoutArgs; +class ImplFontAttributes; class VirtualDevice; namespace com { @@ -541,7 +542,6 @@ public: 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 ; diff --git a/vcl/inc/vcl/outfont.hxx b/vcl/inc/vcl/outfont.hxx index 87c20ebfd7f9..995fcd6009ff 100644 --- a/vcl/inc/vcl/outfont.hxx +++ b/vcl/inc/vcl/outfont.hxx @@ -94,8 +94,6 @@ public: // TODO: create matching interface class 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 ';' @@ -104,8 +102,6 @@ public: // TODO: hide members behind accessor methods 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 }; // ---------------- @@ -339,15 +335,17 @@ public: // TODO: make data members private 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; }; diff --git a/vcl/inc/vcl/salgdi.hxx b/vcl/inc/vcl/salgdi.hxx index f72c4df57481..02e9efbc0f94 100644 --- a/vcl/inc/vcl/salgdi.hxx +++ b/vcl/inc/vcl/salgdi.hxx @@ -234,9 +234,10 @@ public: 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 diff --git a/vcl/inc/vcl/settings.hxx b/vcl/inc/vcl/settings.hxx index e55c2a53345b..24fd30750501 100644 --- a/vcl/inc/vcl/settings.hxx +++ b/vcl/inc/vcl/settings.hxx @@ -437,6 +437,7 @@ private: ULONG mnPreferredSymbolsStyle; USHORT mnSkipDisabledInMenus; Wallpaper maWorkspaceGradient; + const void* mpFontOptions; }; #define DEFAULT_WORKSPACE_GRADIENT_START_COLOR Color( 0xa3, 0xae, 0xb8 ) @@ -754,6 +755,11 @@ public: 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 diff --git a/vcl/inc/vcl/vclenum.hxx b/vcl/inc/vcl/vclenum.hxx index ded36cc163f0..a34c633479e7 100644 --- a/vcl/inc/vcl/vclenum.hxx +++ b/vcl/inc/vcl/vclenum.hxx @@ -281,6 +281,27 @@ enum FontAntiAlias { ANTIALIAS_DONTKNOW, ANTIALIAS_FALSE, ANTIALIAS_TRUE }; #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 diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx index 1aebe5913959..5ad3f6787461 100644 --- a/vcl/source/app/settings.cxx +++ b/vcl/source/app/settings.cxx @@ -433,6 +433,7 @@ ImplStyleData::ImplStyleData() mnToolbarIconSize = STYLE_TOOLBAR_ICONSIZE_UNKNOWN; mnSymbolsStyle = STYLE_SYMBOLS_AUTO; mnPreferredSymbolsStyle = STYLE_SYMBOLS_AUTO; + mpFontOptions = NULL; SetStandardStyles(); } @@ -539,6 +540,7 @@ ImplStyleData::ImplStyleData( const ImplStyleData& rData ) : mnToolbarIconSize = rData.mnToolbarIconSize; mnSymbolsStyle = rData.mnSymbolsStyle; mnPreferredSymbolsStyle = rData.mnPreferredSymbolsStyle; + mpFontOptions = rData.mpFontOptions; } // ----------------------------------------------------------------------- diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx index 895a98dfaf1a..6ca90540d8ee 100644 --- a/vcl/source/gdi/outdev3.cxx +++ b/vcl/source/gdi/outdev3.cxx @@ -68,6 +68,9 @@ #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> @@ -995,21 +998,28 @@ ImplFontEntry::~ImplFontEntry() // ----------------------------------------------------------------------- -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; + (*mpUnicodeFallbackList)[ GFBCacheKey(cChar,eWeight) ] = rFontName; } // ----------------------------------------------------------------------- -inline bool ImplFontEntry::GetFallbackForUnicode( sal_UCS4 cChar, String* pFontName ) const +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; @@ -1019,10 +1029,10 @@ inline bool ImplFontEntry::GetFallbackForUnicode( sal_UCS4 cChar, String* pFontN // ----------------------------------------------------------------------- -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; @@ -1417,7 +1427,7 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData& 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; @@ -1433,7 +1443,7 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData& 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; } @@ -1452,8 +1462,8 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData& // 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 ); @@ -1464,7 +1474,7 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData& for( nStrIndex = 0; nStrIndex < rMissingCodes.getLength(); ) { cChar = rMissingCodes.iterateCodePoints( &nStrIndex ); - rFontSelData.mpFontEntry->IgnoreFallbackForUnicode( cChar, rFontSelData.maSearchName ); + rFontSelData.mpFontEntry->IgnoreFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName ); } } } @@ -2780,6 +2790,11 @@ void ImplFontCache::Invalidate() 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 } // ======================================================================= diff --git a/vcl/source/glyphs/gcach_ftyp.cxx b/vcl/source/glyphs/gcach_ftyp.cxx index a337f2553ff7..ebdd59f517af 100644 --- a/vcl/source/glyphs/gcach_ftyp.cxx +++ b/vcl/source/glyphs/gcach_ftyp.cxx @@ -38,8 +38,6 @@ #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" @@ -80,7 +78,7 @@ typedef FT_Vector* FT_Vector_CPtr; // 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> @@ -93,10 +91,6 @@ typedef FT_Vector* FT_Vector_CPtr; #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); } @@ -623,9 +617,6 @@ long FreetypeManager::AddFontDir( const String& rUrlName ) 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; @@ -705,6 +696,7 @@ FreetypeServerFont::FreetypeServerFont( const ImplFontSelectData& rFSD, FtFontIn : ServerFont( rFSD ), mnPrioEmbedded(nDefaultPrioEmbedded), mnPrioAntiAlias(nDefaultPrioAntiAlias), + mnPrioAutoHint(nDefaultPrioAutoHint), mpFontInfo( pFI ), maFaceFT( NULL ), maSizeFT( NULL ), @@ -838,46 +830,71 @@ FreetypeServerFont::FreetypeServerFont( const ImplFontSelectData& rFSD, FtFontIn mbArtItalic = (rFSD.meItalic != ITALIC_NONE && pFI->GetFontAttributes().GetSlant() == ITALIC_NONE); mbArtBold = (rFSD.meWeight > WEIGHT_MEDIUM && pFI->GetFontAttributes().GetWeight() <= WEIGHT_MEDIUM); - - //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 ) + 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; - else - mbUseGamma = false; + } + + if( ((mnCos != 0) && (mnSin != 0)) || (mnPrioEmbedded <= 0) ) + mnLoadFlags |= FT_LOAD_NO_BITMAP; +} + +void FreetypeServerFont::SetFontOptions( const ImplFontOptions& rFontOptions) +{ + FontAutoHint eHint = rFontOptions.GetUseAutoHint(); + if( eHint == AUTOHINT_DONTKNOW ) + eHint = mbUseGamma ? AUTOHINT_TRUE : AUTOHINT_FALSE; - if (mbUseGamma) + 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; } // ----------------------------------------------------------------------- @@ -1231,13 +1248,15 @@ int FreetypeServerFont::FixupGlyphIndex( int nGlyphIndex, sal_UCS4 aChar ) const } } -#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 ) @@ -1377,13 +1396,13 @@ bool FreetypeServerFont::GetGlyphBitmap1( int nGlyphIndex, RawBitmap& rRawBitmap 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; @@ -1548,7 +1567,7 @@ bool FreetypeServerFont::GetGlyphBitmap8( int nGlyphIndex, RawBitmap& rRawBitmap // 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 diff --git a/vcl/source/glyphs/gcach_ftyp.hxx b/vcl/source/glyphs/gcach_ftyp.hxx index 2a181b494c9f..5ebe70bcbdf9 100644 --- a/vcl/source/glyphs/gcach_ftyp.hxx +++ b/vcl/source/glyphs/gcach_ftyp.hxx @@ -33,6 +33,7 @@ #include <ft2build.h> #include FT_FREETYPE_H + class FreetypeServerFont; struct FT_GlyphRec_; @@ -85,10 +86,6 @@ public: 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; } @@ -178,6 +175,7 @@ public: virtual int GetFontFaceNum() const { return mpFontInfo->GetFaceNum(); } virtual bool TestFont() const; virtual void* GetFtFace() const; + 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; } @@ -213,6 +211,7 @@ private: int mnWidth; int mnPrioEmbedded; int mnPrioAntiAlias; + int mnPrioAutoHint; FtFontInfo* mpFontInfo; FT_Int mnLoadFlags; double mfStretch; diff --git a/vcl/source/glyphs/glyphcache.cxx b/vcl/source/glyphs/glyphcache.cxx index 34133a39ac95..ea0f18896b7a 100644 --- a/vcl/source/glyphs/glyphcache.cxx +++ b/vcl/source/glyphs/glyphcache.cxx @@ -69,13 +69,22 @@ GlyphCache::GlyphCache( GlyphCachePeer& rPeer ) 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 +} // ----------------------------------------------------------------------- @@ -582,3 +591,4 @@ int ExtraKernInfo::GetUnscaledKernValue( sal_Unicode cLeft, sal_Unicode cRight ) } // ======================================================================= + diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx index 372d10fa5aaf..869189fb1415 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -45,6 +45,8 @@ #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; @@ -3469,12 +3471,25 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings ) // 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) +#if !GTK_CHECK_VERSION(2,9,0) + 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 ); diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx index 5d7fcabb7c8f..ba42cfc5ae82 100644 --- a/vcl/unx/gtk/window/gtkframe.cxx +++ b/vcl/unx/gtk/window/gtkframe.cxx @@ -3124,10 +3124,13 @@ void GtkSalFrame::signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer fram // 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 diff --git a/vcl/unx/headless/svpgdi.cxx b/vcl/unx/headless/svpgdi.cxx index 114bd4c8a5bc..e65c9faf1432 100644 --- a/vcl/unx/headless/svpgdi.cxx +++ b/vcl/unx/headless/svpgdi.cxx @@ -584,3 +584,4 @@ bool SvpSalGraphics::supportsOperation( OutDevSupportType ) const { return false; } + diff --git a/vcl/unx/headless/svpgdi.hxx b/vcl/unx/headless/svpgdi.hxx index 9e25b67394e7..132dafaa9adf 100644 --- a/vcl/unx/headless/svpgdi.hxx +++ b/vcl/unx/headless/svpgdi.hxx @@ -170,3 +170,4 @@ public: }; #endif + diff --git a/vcl/unx/headless/svppspgraphics.cxx b/vcl/unx/headless/svppspgraphics.cxx index 353b10467d40..7f551051c1a7 100644 --- a/vcl/unx/headless/svppspgraphics.cxx +++ b/vcl/unx/headless/svppspgraphics.cxx @@ -1160,32 +1160,6 @@ ImplDevFontAttributes PspGraphics::Info2DevFontAttributes( const psp::FastPrintF 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: diff --git a/vcl/unx/headless/svppspgraphics.hxx b/vcl/unx/headless/svppspgraphics.hxx index 8addbc3de5f7..82ba613615cb 100644 --- a/vcl/unx/headless/svppspgraphics.hxx +++ b/vcl/unx/headless/svppspgraphics.hxx @@ -190,3 +190,4 @@ public: }; #endif // _SVP_PSPGRAPHICS_HXX + diff --git a/vcl/unx/inc/pspgraphics.h b/vcl/unx/inc/pspgraphics.h index 4dce4ee8b06c..2eae73cdaa86 100644 --- a/vcl/unx/inc/pspgraphics.h +++ b/vcl/unx/inc/pspgraphics.h @@ -103,7 +103,7 @@ public: 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* ); diff --git a/vcl/unx/inc/salgdi.h b/vcl/unx/inc/salgdi.h index 09e85c6840b8..da69f04b6f8f 100644 --- a/vcl/unx/inc/salgdi.h +++ b/vcl/unx/inc/salgdi.h @@ -250,7 +250,7 @@ public: 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* ); diff --git a/vcl/unx/source/fontmanager/fontcache.cxx b/vcl/unx/source/fontmanager/fontcache.cxx index 803e92d3cb14..db4a7d05e5fc 100644 --- a/vcl/unx/source/fontmanager/fontcache.cxx +++ b/vcl/unx/source/fontmanager/fontcache.cxx @@ -212,9 +212,9 @@ void FontCache::flush() 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 ) { @@ -424,9 +424,6 @@ void FontCache::read() = 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 ) { @@ -558,8 +555,6 @@ void FontCache::copyPrintFont( const PrintFontManager::PrintFont* pFrom, PrintFo 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; } /* @@ -621,9 +616,7 @@ bool FontCache::equalsPrintFont( const PrintFontManager::PrintFont* pLeft, Print 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; diff --git a/vcl/unx/source/fontmanager/fontconfig.cxx b/vcl/unx/source/fontmanager/fontconfig.cxx index 1d4573518879..18d8a8d85a43 100644 --- a/vcl/unx/source/fontmanager/fontconfig.cxx +++ b/vcl/unx/source/fontmanager/fontconfig.cxx @@ -30,37 +30,45 @@ #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> @@ -117,6 +125,7 @@ class FontCfgWrapper 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*); @@ -220,6 +229,8 @@ public: { 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 ) @@ -231,7 +242,9 @@ public: { 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 ) @@ -321,6 +334,8 @@ FontCfgWrapper::FontCfgWrapper() 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 *)) @@ -371,6 +386,7 @@ FontCfgWrapper::FontCfgWrapper() m_pFcDefaultSubstitute && m_pFcConfigSubstitute && m_pFcPatternAddInteger && + m_pFcPatternAddDouble && m_pFcPatternAddCharSet && m_pFcPatternAddBool && m_pFcPatternAddString @@ -503,53 +519,52 @@ namespace return candidate; } +} +FcResult FontCfgWrapper::FamilyFromPattern(FcPattern* pPattern, FcChar8 **family) +{ + FcChar8 *origfamily; + FcResult eFamilyRes = FcPatternGetString( pPattern, FC_FAMILY, 0, &origfamily ); + *family = origfamily; - FcResult lcl_FamilyFromPattern(FontCfgWrapper& rWrapper, FcPattern* pPattern, FcChar8 **family, - std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash > &aFontconfigNameToLocalized) + if( eFamilyRes == FcResultMatch) { - FcChar8 *origfamily; - FcResult eFamilyRes = rWrapper.FcPatternGetString( pPattern, FC_FAMILY, 0, &origfamily ); - *family = origfamily; - - if( eFamilyRes == FcResultMatch) + FcChar8* familylang = NULL; + if (FcPatternGetString( pPattern, FC_FAMILYLANG, 0, &familylang ) == 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) { - std::vector< lang_and_family > lang_and_families; + 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)); - 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; - } + ++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); + //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)); - } + 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; } -} + return eFamilyRes; +} /* * PrintFontManager::initFontconfig @@ -562,6 +577,72 @@ bool 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; @@ -585,18 +666,16 @@ int PrintFontManager::countFontconfigFonts() 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; @@ -691,60 +770,15 @@ int PrintFontManager::countFontconfigFonts() 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 ); @@ -880,8 +914,8 @@ static void addtopattern(FontCfgWrapper& rWrapper, FcPattern *pPattern, 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(); @@ -916,7 +950,7 @@ rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName, 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 ); @@ -949,10 +983,21 @@ rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName, 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 @@ -981,6 +1026,89 @@ rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName, 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(); diff --git a/vcl/unx/source/fontmanager/fontmanager.cxx b/vcl/unx/source/fontmanager/fontmanager.cxx index aad53549f1ea..7d5224707f72 100644 --- a/vcl/unx/source/fontmanager/fontmanager.cxx +++ b/vcl/unx/source/fontmanager/fontmanager.cxx @@ -353,9 +353,7 @@ PrintFontManager::PrintFont::PrintFont( fonttype::type eType ) : m_nXMax( 0 ), m_nYMax( 0 ), m_bHaveVerticalSubstitutedGlyphs( false ), - m_bUserOverride( false ), - m_eEmbeddedbitmap( fcstatus::isunset ), - m_eAntialias( fcstatus::isunset ) + m_bUserOverride( false ) { } @@ -2630,8 +2628,6 @@ void PrintFontManager::fillPrintFontInfo( PrintFont* pFont, FastPrintFontInfo& r 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 @@ -3936,8 +3932,6 @@ bool PrintFontManager::readOverrideMetrics() 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; diff --git a/vcl/unx/source/gdi/pspgraphics.cxx b/vcl/unx/source/gdi/pspgraphics.cxx index 10a51afeb696..d599e09e71f2 100644 --- a/vcl/unx/source/gdi/pspgraphics.cxx +++ b/vcl/unx/source/gdi/pspgraphics.cxx @@ -1284,32 +1284,6 @@ ImplDevFontAttributes PspGraphics::Info2DevFontAttributes( const psp::FastPrintF 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: diff --git a/vcl/unx/source/gdi/salgdi3.cxx b/vcl/unx/source/gdi/salgdi3.cxx index bb5e7c68b356..0c1fcd7c77bd 100644 --- a/vcl/unx/source/gdi/salgdi3.cxx +++ b/vcl/unx/source/gdi/salgdi3.cxx @@ -630,12 +630,26 @@ bool X11SalGraphics::setFont( const ImplFontSelectData *pEntry, int nFallbackLev 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; } @@ -743,6 +757,8 @@ private: 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; } @@ -778,6 +794,10 @@ public: { (*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; @@ -847,6 +867,10 @@ CairoWrapper::CairoWrapper() 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 && @@ -863,7 +887,9 @@ CairoWrapper::CairoWrapper() 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 ); @@ -971,6 +997,9 @@ void X11SalGraphics::DrawCairoAAFontString( const ServerFontLayout& rLayout ) 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) @@ -1601,6 +1630,122 @@ void X11SalGraphics::GetDevFontSubstList( OutputDevice* ) // ---------------------------------------------------------------------------- +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 ) { @@ -1876,8 +2021,10 @@ void RegisterFontSubstitutors( ImplDevFontList* pList ) // ----------------------------------------------------------------------- -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; @@ -1945,7 +2092,72 @@ static rtl::OUString GetFcSubstitute(const ImplFontSelectData &rFontSelData, OUS } 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 + ); + } } //-------------------------------------------------------------------------- @@ -1953,7 +2165,7 @@ static rtl::OUString GetFcSubstitute(const ImplFontSelectData &rFontSelData, OUS 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) @@ -1961,21 +2173,33 @@ bool FcPreMatchSubstititution::FindFontSubstitute( ImplFontSelectData &rFontSelD 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; } // ----------------------------------------------------------------------- @@ -1991,22 +2215,33 @@ bool FcGlyphFallbackSubstititution::FindFontSubstitute( ImplFontSelectData& rFon || 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; } // =========================================================================== diff --git a/vcl/unx/source/gdi/xlfd_extd.cxx b/vcl/unx/source/gdi/xlfd_extd.cxx index 8449fcc5872e..73731eddf115 100644 --- a/vcl/unx/source/gdi/xlfd_extd.cxx +++ b/vcl/unx/source/gdi/xlfd_extd.cxx @@ -102,9 +102,6 @@ ExtendedXlfd::ExtendedXlfd( bool bScalable ) mbSubsettable = false; mbEmbeddable = false; - meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW; - meAntiAlias = ANTIALIAS_DONTKNOW; - mnQuality = -1; } diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx index 84695baf3557..ebe470d3eb7e 100644 --- a/vcl/win/source/gdi/salgdi3.cxx +++ b/vcl/win/source/gdi/salgdi3.cxx @@ -590,11 +590,7 @@ static ImplDevFontAttributes WinFont2DevFontAttributes( const ENUMLOGFONTEXA& rE aDFA.mnQuality += 500; } - aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW; - aDFA.meAntiAlias = ANTIALIAS_DONTKNOW; - // TODO: add alias names - return aDFA; } @@ -669,9 +665,6 @@ static ImplDevFontAttributes WinFont2DevFontAttributes( const ENUMLOGFONTEXW& rE aDFA.mnQuality += 500; } - aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW; - aDFA.meAntiAlias = ANTIALIAS_DONTKNOW; - // TODO: add alias names return aDFA; } @@ -1998,8 +1991,6 @@ static bool ImplGetFontAttrFromFile( const String& rFontFileURL, 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"; @@ -2126,8 +2117,6 @@ bool WinSalGraphics::AddTempDevFont( ImplDevFontList* pFontList, 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" |