1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_vcl.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "fontcache.hxx" 32*cdf0e10cSrcweir #include "impfont.hxx" 33*cdf0e10cSrcweir #include "vcl/fontmanager.hxx" 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir using namespace psp; 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir #ifdef ENABLE_FONTCONFIG 38*cdf0e10cSrcweir #include <fontconfig/fontconfig.h> 39*cdf0e10cSrcweir #include <ft2build.h> 40*cdf0e10cSrcweir #include <fontconfig/fcfreetype.h> 41*cdf0e10cSrcweir // allow compile on baseline (currently with fontconfig 2.2.0) 42*cdf0e10cSrcweir #ifndef FC_WEIGHT_BOOK // TODO: remove when baseline moves to fc>=2.2.1 43*cdf0e10cSrcweir #define FC_WEIGHT_BOOK 75 44*cdf0e10cSrcweir #endif 45*cdf0e10cSrcweir #ifndef FC_EMBEDDED_BITMAP // TODO: remove when baseline moves to fc>=2.3.92 46*cdf0e10cSrcweir #define FC_EMBEDDED_BITMAP "embeddedbitmap" 47*cdf0e10cSrcweir #endif 48*cdf0e10cSrcweir #ifndef FC_FAMILYLANG // TODO: remove when baseline moves to fc>=2.2.97 49*cdf0e10cSrcweir #define FC_FAMILYLANG "familylang" 50*cdf0e10cSrcweir #endif 51*cdf0e10cSrcweir #ifndef FC_HINT_STYLE // TODO: remove when baseline moves to fc>=2.2.91 52*cdf0e10cSrcweir #define FC_HINT_STYLE "hintstyle" 53*cdf0e10cSrcweir #define FC_HINT_NONE 0 54*cdf0e10cSrcweir #define FC_HINT_SLIGHT 1 55*cdf0e10cSrcweir #define FC_HINT_MEDIUM 2 56*cdf0e10cSrcweir #define FC_HINT_FULL 3 57*cdf0e10cSrcweir #endif 58*cdf0e10cSrcweir #else 59*cdf0e10cSrcweir typedef void FcConfig; 60*cdf0e10cSrcweir typedef void FcObjectSet; 61*cdf0e10cSrcweir typedef void FcPattern; 62*cdf0e10cSrcweir typedef void FcFontSet; 63*cdf0e10cSrcweir typedef void FcCharSet; 64*cdf0e10cSrcweir typedef int FcResult; 65*cdf0e10cSrcweir typedef int FcBool; 66*cdf0e10cSrcweir typedef int FcMatchKind; 67*cdf0e10cSrcweir typedef char FcChar8; 68*cdf0e10cSrcweir typedef int FcChar32; 69*cdf0e10cSrcweir typedef unsigned int FT_UInt; 70*cdf0e10cSrcweir typedef void* FT_Face; 71*cdf0e10cSrcweir typedef int FcSetName; 72*cdf0e10cSrcweir #endif 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir #include <cstdio> 75*cdf0e10cSrcweir #include <cstdarg> 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir #include "unotools/atom.hxx" 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir #include "osl/module.h" 80*cdf0e10cSrcweir #include "osl/thread.h" 81*cdf0e10cSrcweir #include "osl/process.h" 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 84*cdf0e10cSrcweir #include "rtl/locale.hxx" 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir #include "sal/alloca.h" 87*cdf0e10cSrcweir 88*cdf0e10cSrcweir #include <utility> 89*cdf0e10cSrcweir #include <algorithm> 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir using namespace osl; 92*cdf0e10cSrcweir using namespace rtl; 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir class FontCfgWrapper 95*cdf0e10cSrcweir { 96*cdf0e10cSrcweir oslModule m_pLib; 97*cdf0e10cSrcweir FcFontSet* m_pOutlineSet; 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir int m_nFcVersion; 100*cdf0e10cSrcweir FcBool (*m_pFcInit)(); 101*cdf0e10cSrcweir int (*m_pFcGetVersion)(); 102*cdf0e10cSrcweir FcConfig* (*m_pFcConfigGetCurrent)(); 103*cdf0e10cSrcweir FcObjectSet* (*m_pFcObjectSetVaBuild)(const char*,va_list); 104*cdf0e10cSrcweir void (*m_pFcObjectSetDestroy)(FcObjectSet* pSet); 105*cdf0e10cSrcweir FcPattern* (*m_pFcPatternCreate)(); 106*cdf0e10cSrcweir void (*m_pFcPatternDestroy)(FcPattern*); 107*cdf0e10cSrcweir FcFontSet* (*m_pFcFontList)(FcConfig*,FcPattern*,FcObjectSet*); 108*cdf0e10cSrcweir FcFontSet* (*m_pFcConfigGetFonts)(FcConfig*,FcSetName); 109*cdf0e10cSrcweir FcFontSet* (*m_pFcFontSetCreate)(); 110*cdf0e10cSrcweir FcCharSet* (*m_pFcCharSetCreate)(); 111*cdf0e10cSrcweir FcBool (*m_pFcCharSetAddChar)(FcCharSet *, FcChar32); 112*cdf0e10cSrcweir FcBool (*m_pFcCharSetHasChar)(FcCharSet *, FcChar32); 113*cdf0e10cSrcweir void (*m_pFcCharSetDestroy)(FcCharSet*); 114*cdf0e10cSrcweir void (*m_pFcFontSetDestroy)(FcFontSet*); 115*cdf0e10cSrcweir FcBool (*m_pFcFontSetAdd)(FcFontSet*,FcPattern*); 116*cdf0e10cSrcweir void (*m_pFcPatternReference)(FcPattern*); 117*cdf0e10cSrcweir FcResult (*m_pFcPatternGetCharSet)(const FcPattern*,const char*,int,FcCharSet**); 118*cdf0e10cSrcweir FcResult (*m_pFcPatternGetString)(const FcPattern*,const char*,int,FcChar8**); 119*cdf0e10cSrcweir FcResult (*m_pFcPatternGetInteger)(const FcPattern*,const char*,int,int*); 120*cdf0e10cSrcweir FcResult (*m_pFcPatternGetDouble)(const FcPattern*,const char*,int,double*); 121*cdf0e10cSrcweir FcResult (*m_pFcPatternGetBool)(const FcPattern*,const char*,int,FcBool*); 122*cdf0e10cSrcweir void (*m_pFcDefaultSubstitute)(FcPattern *); 123*cdf0e10cSrcweir FcPattern* (*m_pFcFontSetMatch)(FcConfig*,FcFontSet**, int, FcPattern*,FcResult*); 124*cdf0e10cSrcweir FcPattern* (*m_pFcFontMatch)(FcConfig*,FcPattern*,FcResult*); 125*cdf0e10cSrcweir FcBool (*m_pFcConfigAppFontAddFile)(FcConfig*, const FcChar8*); 126*cdf0e10cSrcweir FcBool (*m_pFcConfigAppFontAddDir)(FcConfig*, const FcChar8*); 127*cdf0e10cSrcweir FcBool (*m_pFcConfigParseAndLoad)(FcConfig*,const FcChar8*,FcBool); 128*cdf0e10cSrcweir FcBool (*m_pFcConfigSubstitute)(FcConfig*,FcPattern*,FcMatchKind); 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir FcPattern* (*m_pFcPatternDuplicate)(const FcPattern*); 131*cdf0e10cSrcweir FcBool (*m_pFcPatternAddInteger)(FcPattern*,const char*,int); 132*cdf0e10cSrcweir FcBool (*m_pFcPatternAddDouble)(FcPattern*,const char*,double); 133*cdf0e10cSrcweir FcBool (*m_pFcPatternAddBool)(FcPattern*,const char*,FcBool); 134*cdf0e10cSrcweir FcBool (*m_pFcPatternAddCharSet)(FcPattern*,const char*,const FcCharSet*); 135*cdf0e10cSrcweir FcBool (*m_pFcPatternAddString)(FcPattern*,const char*,const FcChar8*); 136*cdf0e10cSrcweir FcBool (*m_pFcPatternDel)(FcPattern*,const char*); 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir FT_UInt (*m_pFcFreeTypeCharIndex)(FT_Face,FcChar32); 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir oslGenericFunction loadSymbol( const char* ); 141*cdf0e10cSrcweir void addFontSet( FcSetName ); 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir FontCfgWrapper(); 144*cdf0e10cSrcweir ~FontCfgWrapper(); 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir public: 147*cdf0e10cSrcweir static FontCfgWrapper& get(); 148*cdf0e10cSrcweir static void release(); 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir bool isValid() const 151*cdf0e10cSrcweir { return m_pLib != NULL;} 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir FcFontSet* getFontSet(); 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir FcBool FcInit() 156*cdf0e10cSrcweir { return m_pFcInit(); } 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir int FcGetVersion() 159*cdf0e10cSrcweir { return m_pFcGetVersion(); } 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir FcConfig* FcConfigGetCurrent() 162*cdf0e10cSrcweir { return m_pFcConfigGetCurrent(); } 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir FcObjectSet* FcObjectSetBuild( const char* first, ... ) 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir va_list ap; 167*cdf0e10cSrcweir va_start( ap, first ); 168*cdf0e10cSrcweir FcObjectSet* pSet = m_pFcObjectSetVaBuild( first, ap ); 169*cdf0e10cSrcweir va_end( ap ); 170*cdf0e10cSrcweir return pSet; 171*cdf0e10cSrcweir } 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir void FcObjectSetDestroy( FcObjectSet* pSet ) 174*cdf0e10cSrcweir { m_pFcObjectSetDestroy( pSet ); } 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir FcPattern* FcPatternCreate() 177*cdf0e10cSrcweir { return m_pFcPatternCreate(); } 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir void FcPatternDestroy( FcPattern* pPattern ) 180*cdf0e10cSrcweir { m_pFcPatternDestroy( pPattern ); } 181*cdf0e10cSrcweir 182*cdf0e10cSrcweir FcFontSet* FcFontList( FcConfig* pConfig, FcPattern* pPattern, FcObjectSet* pSet ) 183*cdf0e10cSrcweir { return m_pFcFontList( pConfig, pPattern, pSet ); } 184*cdf0e10cSrcweir 185*cdf0e10cSrcweir FcFontSet* FcConfigGetFonts( FcConfig* pConfig, FcSetName eSet) 186*cdf0e10cSrcweir { return m_pFcConfigGetFonts( pConfig, eSet ); } 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir FcFontSet* FcFontSetCreate() 189*cdf0e10cSrcweir { return m_pFcFontSetCreate(); } 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir FcCharSet* FcCharSetCreate() 192*cdf0e10cSrcweir { return m_pFcCharSetCreate(); } 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir FcBool FcCharSetAddChar(FcCharSet *fcs, FcChar32 ucs4) 195*cdf0e10cSrcweir { return m_pFcCharSetAddChar(fcs, ucs4); } 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir FcBool FcCharSetHasChar(FcCharSet *fcs, FcChar32 ucs4) 198*cdf0e10cSrcweir { return m_pFcCharSetHasChar(fcs, ucs4); } 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir void FcCharSetDestroy( FcCharSet* pSet ) 201*cdf0e10cSrcweir { m_pFcCharSetDestroy( pSet );} 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir void FcFontSetDestroy( FcFontSet* pSet ) 204*cdf0e10cSrcweir { m_pFcFontSetDestroy( pSet );} 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir FcBool FcFontSetAdd( FcFontSet* pSet, FcPattern* pPattern ) 207*cdf0e10cSrcweir { return m_pFcFontSetAdd( pSet, pPattern ); } 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir void FcPatternReference( FcPattern* pPattern ) 210*cdf0e10cSrcweir { m_pFcPatternReference( pPattern ); } 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir FcResult FcPatternGetCharSet( const FcPattern* pPattern, const char* object, int n, FcCharSet** s ) 213*cdf0e10cSrcweir { return m_pFcPatternGetCharSet( pPattern, object, n, s ); } 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir FcResult FcPatternGetString( const FcPattern* pPattern, const char* object, int n, FcChar8** s ) 216*cdf0e10cSrcweir { return m_pFcPatternGetString( pPattern, object, n, s ); } 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir FcResult FcPatternGetInteger( const FcPattern* pPattern, const char* object, int n, int* s ) 219*cdf0e10cSrcweir { return m_pFcPatternGetInteger( pPattern, object, n, s ); } 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir FcResult FcPatternGetDouble( const FcPattern* pPattern, const char* object, int n, double* s ) 222*cdf0e10cSrcweir { return m_pFcPatternGetDouble( pPattern, object, n, s ); } 223*cdf0e10cSrcweir 224*cdf0e10cSrcweir FcResult FcPatternGetBool( const FcPattern* pPattern, const char* object, int n, FcBool* s ) 225*cdf0e10cSrcweir { return m_pFcPatternGetBool( pPattern, object, n, s ); } 226*cdf0e10cSrcweir FcBool FcConfigAppFontAddFile( FcConfig* pConfig, const FcChar8* pFileName ) 227*cdf0e10cSrcweir { return m_pFcConfigAppFontAddFile( pConfig, pFileName ); } 228*cdf0e10cSrcweir FcBool FcConfigAppFontAddDir(FcConfig* pConfig, const FcChar8* pDirName ) 229*cdf0e10cSrcweir { return m_pFcConfigAppFontAddDir( pConfig, pDirName ); } 230*cdf0e10cSrcweir FcBool FcConfigParseAndLoad( FcConfig* pConfig, const FcChar8* pFileName, FcBool bComplain ) 231*cdf0e10cSrcweir { return m_pFcConfigParseAndLoad( pConfig, pFileName, bComplain ); } 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir void FcDefaultSubstitute( FcPattern* pPattern ) 234*cdf0e10cSrcweir { m_pFcDefaultSubstitute( pPattern ); } 235*cdf0e10cSrcweir FcPattern* FcFontSetMatch( FcConfig* pConfig, FcFontSet **ppFontSet, int nset, FcPattern* pPattern, FcResult* pResult ) 236*cdf0e10cSrcweir { return m_pFcFontSetMatch ? m_pFcFontSetMatch( pConfig, ppFontSet, nset, pPattern, pResult ) : 0; } 237*cdf0e10cSrcweir FcPattern* FcFontMatch( FcConfig* pConfig, FcPattern* pPattern, FcResult* pResult ) 238*cdf0e10cSrcweir { return m_pFcFontMatch( pConfig, pPattern, pResult ); } 239*cdf0e10cSrcweir FcBool FcConfigSubstitute( FcConfig* pConfig, FcPattern* pPattern, FcMatchKind eKind ) 240*cdf0e10cSrcweir { return m_pFcConfigSubstitute( pConfig, pPattern, eKind ); } 241*cdf0e10cSrcweir 242*cdf0e10cSrcweir FcPattern* FcPatternDuplicate( const FcPattern* pPattern ) const 243*cdf0e10cSrcweir { return m_pFcPatternDuplicate( pPattern ); } 244*cdf0e10cSrcweir FcBool FcPatternAddInteger( FcPattern* pPattern, const char* pObject, int nValue ) 245*cdf0e10cSrcweir { return m_pFcPatternAddInteger( pPattern, pObject, nValue ); } 246*cdf0e10cSrcweir FcBool FcPatternAddDouble( FcPattern* pPattern, const char* pObject, double nValue ) 247*cdf0e10cSrcweir { return m_pFcPatternAddDouble( pPattern, pObject, nValue ); } 248*cdf0e10cSrcweir FcBool FcPatternAddString( FcPattern* pPattern, const char* pObject, const FcChar8* pString ) 249*cdf0e10cSrcweir { return m_pFcPatternAddString( pPattern, pObject, pString ); } 250*cdf0e10cSrcweir FcBool FcPatternAddBool( FcPattern* pPattern, const char* pObject, bool nValue ) 251*cdf0e10cSrcweir { return m_pFcPatternAddBool( pPattern, pObject, nValue ); } 252*cdf0e10cSrcweir FcBool FcPatternAddCharSet(FcPattern* pPattern,const char* pObject,const FcCharSet*pCharSet) 253*cdf0e10cSrcweir { return m_pFcPatternAddCharSet(pPattern,pObject,pCharSet); } 254*cdf0e10cSrcweir FcBool FcPatternDel(FcPattern* pPattern, const char* object) 255*cdf0e10cSrcweir { return m_pFcPatternDel( pPattern, object); } 256*cdf0e10cSrcweir 257*cdf0e10cSrcweir FT_UInt FcFreeTypeCharIndex( FT_Face face, FcChar32 ucs4 ) 258*cdf0e10cSrcweir { return m_pFcFreeTypeCharIndex ? m_pFcFreeTypeCharIndex( face, ucs4 ) : 0; } 259*cdf0e10cSrcweir 260*cdf0e10cSrcweir public: // TODO: cleanup 261*cdf0e10cSrcweir FcResult FamilyFromPattern(FcPattern* pPattern, FcChar8 **family); 262*cdf0e10cSrcweir std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash > m_aFontNameToLocalized; 263*cdf0e10cSrcweir std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash > m_aLocalizedToCanonical; 264*cdf0e10cSrcweir }; 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir oslGenericFunction FontCfgWrapper::loadSymbol( const char* pSymbol ) 267*cdf0e10cSrcweir { 268*cdf0e10cSrcweir OUString aSym( OUString::createFromAscii( pSymbol ) ); 269*cdf0e10cSrcweir oslGenericFunction pSym = osl_getFunctionSymbol( m_pLib, aSym.pData ); 270*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 271*cdf0e10cSrcweir fprintf( stderr, "%s %s\n", pSymbol, pSym ? "found" : "not found" ); 272*cdf0e10cSrcweir #endif 273*cdf0e10cSrcweir return pSym; 274*cdf0e10cSrcweir } 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir FontCfgWrapper::FontCfgWrapper() 277*cdf0e10cSrcweir : m_pLib( NULL ), 278*cdf0e10cSrcweir m_pOutlineSet( NULL ), 279*cdf0e10cSrcweir m_nFcVersion( 0 ) 280*cdf0e10cSrcweir { 281*cdf0e10cSrcweir OUString aLib( RTL_CONSTASCII_USTRINGPARAM( "libfontconfig.so.1" ) ); 282*cdf0e10cSrcweir m_pLib = osl_loadModule( aLib.pData, SAL_LOADMODULE_LAZY ); 283*cdf0e10cSrcweir if( !m_pLib ) 284*cdf0e10cSrcweir { 285*cdf0e10cSrcweir aLib = OUString( RTL_CONSTASCII_USTRINGPARAM( "libfontconfig.so" ) ); 286*cdf0e10cSrcweir m_pLib = osl_loadModule( aLib.pData, SAL_LOADMODULE_LAZY ); 287*cdf0e10cSrcweir } 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir if( ! m_pLib ) 290*cdf0e10cSrcweir { 291*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 292*cdf0e10cSrcweir fprintf( stderr, "no libfontconfig\n" ); 293*cdf0e10cSrcweir #endif 294*cdf0e10cSrcweir return; 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir m_pFcInit = (FcBool(*)()) 298*cdf0e10cSrcweir loadSymbol( "FcInit" ); 299*cdf0e10cSrcweir m_pFcGetVersion = (int(*)()) 300*cdf0e10cSrcweir loadSymbol( "FcGetVersion" ); 301*cdf0e10cSrcweir m_pFcConfigGetCurrent = (FcConfig *(*)()) 302*cdf0e10cSrcweir loadSymbol( "FcConfigGetCurrent" ); 303*cdf0e10cSrcweir m_pFcObjectSetVaBuild = (FcObjectSet*(*)(const char*,va_list)) 304*cdf0e10cSrcweir loadSymbol( "FcObjectSetVaBuild" ); 305*cdf0e10cSrcweir m_pFcObjectSetDestroy = (void(*)(FcObjectSet*)) 306*cdf0e10cSrcweir loadSymbol( "FcObjectSetDestroy" ); 307*cdf0e10cSrcweir m_pFcPatternCreate = (FcPattern*(*)()) 308*cdf0e10cSrcweir loadSymbol( "FcPatternCreate" ); 309*cdf0e10cSrcweir m_pFcPatternDestroy = (void(*)(FcPattern*)) 310*cdf0e10cSrcweir loadSymbol( "FcPatternDestroy" ); 311*cdf0e10cSrcweir m_pFcFontList = (FcFontSet*(*)(FcConfig*,FcPattern*,FcObjectSet*)) 312*cdf0e10cSrcweir loadSymbol( "FcFontList" ); 313*cdf0e10cSrcweir m_pFcConfigGetFonts = (FcFontSet*(*)(FcConfig*,FcSetName)) 314*cdf0e10cSrcweir loadSymbol( "FcConfigGetFonts" ); 315*cdf0e10cSrcweir m_pFcFontSetCreate = (FcFontSet*(*)()) 316*cdf0e10cSrcweir loadSymbol( "FcFontSetCreate" ); 317*cdf0e10cSrcweir m_pFcCharSetCreate = (FcCharSet*(*)()) 318*cdf0e10cSrcweir loadSymbol( "FcCharSetCreate" ); 319*cdf0e10cSrcweir m_pFcCharSetAddChar = (FcBool(*)(FcCharSet*, FcChar32)) 320*cdf0e10cSrcweir loadSymbol( "FcCharSetAddChar" ); 321*cdf0e10cSrcweir m_pFcCharSetHasChar = (FcBool(*)(FcCharSet*, FcChar32)) 322*cdf0e10cSrcweir loadSymbol( "FcCharSetHasChar" ); 323*cdf0e10cSrcweir m_pFcCharSetDestroy = (void(*)(FcCharSet*)) 324*cdf0e10cSrcweir loadSymbol( "FcCharSetDestroy" ); 325*cdf0e10cSrcweir m_pFcFontSetDestroy = (void(*)(FcFontSet*)) 326*cdf0e10cSrcweir loadSymbol( "FcFontSetDestroy" ); 327*cdf0e10cSrcweir m_pFcFontSetAdd = (FcBool(*)(FcFontSet*,FcPattern*)) 328*cdf0e10cSrcweir loadSymbol( "FcFontSetAdd" ); 329*cdf0e10cSrcweir m_pFcPatternReference = (void(*)(FcPattern*)) 330*cdf0e10cSrcweir loadSymbol( "FcPatternReference" ); 331*cdf0e10cSrcweir m_pFcPatternGetCharSet = (FcResult(*)(const FcPattern*,const char*,int,FcCharSet**)) 332*cdf0e10cSrcweir loadSymbol( "FcPatternGetCharSet" ); 333*cdf0e10cSrcweir m_pFcPatternGetString = (FcResult(*)(const FcPattern*,const char*,int,FcChar8**)) 334*cdf0e10cSrcweir loadSymbol( "FcPatternGetString" ); 335*cdf0e10cSrcweir m_pFcPatternGetInteger = (FcResult(*)(const FcPattern*,const char*,int,int*)) 336*cdf0e10cSrcweir loadSymbol( "FcPatternGetInteger" ); 337*cdf0e10cSrcweir m_pFcPatternGetDouble = (FcResult(*)(const FcPattern*,const char*,int,double*)) 338*cdf0e10cSrcweir loadSymbol( "FcPatternGetDouble" ); 339*cdf0e10cSrcweir m_pFcPatternGetBool = (FcResult(*)(const FcPattern*,const char*,int,FcBool*)) 340*cdf0e10cSrcweir loadSymbol( "FcPatternGetBool" ); 341*cdf0e10cSrcweir m_pFcConfigAppFontAddFile = (FcBool(*)(FcConfig*, const FcChar8*)) 342*cdf0e10cSrcweir loadSymbol( "FcConfigAppFontAddFile" ); 343*cdf0e10cSrcweir m_pFcConfigAppFontAddDir = (FcBool(*)(FcConfig*, const FcChar8*)) 344*cdf0e10cSrcweir loadSymbol( "FcConfigAppFontAddDir" ); 345*cdf0e10cSrcweir m_pFcConfigParseAndLoad = (FcBool(*)(FcConfig*, const FcChar8*, FcBool)) 346*cdf0e10cSrcweir loadSymbol( "FcConfigParseAndLoad" ); 347*cdf0e10cSrcweir m_pFcDefaultSubstitute = (void(*)(FcPattern *)) 348*cdf0e10cSrcweir loadSymbol( "FcDefaultSubstitute" ); 349*cdf0e10cSrcweir m_pFcFontSetMatch = (FcPattern*(*)(FcConfig*,FcFontSet**,int,FcPattern*,FcResult*)) 350*cdf0e10cSrcweir loadSymbol( "FcFontSetMatch" ); 351*cdf0e10cSrcweir m_pFcFontMatch = (FcPattern*(*)(FcConfig*,FcPattern*,FcResult*)) 352*cdf0e10cSrcweir loadSymbol( "FcFontMatch" ); 353*cdf0e10cSrcweir m_pFcConfigSubstitute = (FcBool(*)(FcConfig*,FcPattern*,FcMatchKind)) 354*cdf0e10cSrcweir loadSymbol( "FcConfigSubstitute" ); 355*cdf0e10cSrcweir 356*cdf0e10cSrcweir m_pFcPatternDuplicate = (FcPattern*(*)(const FcPattern*)) 357*cdf0e10cSrcweir loadSymbol( "FcPatternDuplicate" ); 358*cdf0e10cSrcweir m_pFcPatternAddInteger = (FcBool(*)(FcPattern*,const char*,int)) 359*cdf0e10cSrcweir loadSymbol( "FcPatternAddInteger" ); 360*cdf0e10cSrcweir m_pFcPatternAddDouble = (FcBool(*)(FcPattern*,const char*,double)) 361*cdf0e10cSrcweir loadSymbol( "FcPatternAddDouble" ); 362*cdf0e10cSrcweir m_pFcPatternAddBool = (FcBool(*)(FcPattern*,const char*,FcBool)) 363*cdf0e10cSrcweir loadSymbol( "FcPatternAddBool" ); 364*cdf0e10cSrcweir m_pFcPatternAddCharSet = (FcBool(*)(FcPattern*,const char*,const FcCharSet *)) 365*cdf0e10cSrcweir loadSymbol( "FcPatternAddCharSet" ); 366*cdf0e10cSrcweir m_pFcPatternAddString = (FcBool(*)(FcPattern*,const char*,const FcChar8*)) 367*cdf0e10cSrcweir loadSymbol( "FcPatternAddString" ); 368*cdf0e10cSrcweir m_pFcPatternDel = (FcBool(*)(FcPattern*,const char*)) 369*cdf0e10cSrcweir loadSymbol( "FcPatternDel" ); 370*cdf0e10cSrcweir 371*cdf0e10cSrcweir m_pFcFreeTypeCharIndex = (FT_UInt(*)(FT_Face,FcChar32)) 372*cdf0e10cSrcweir loadSymbol( "FcFreeTypeCharIndex" ); 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir m_nFcVersion = FcGetVersion(); 375*cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 1) 376*cdf0e10cSrcweir fprintf( stderr,"FC_VERSION = %05d\n", m_nFcVersion ); 377*cdf0e10cSrcweir #endif 378*cdf0e10cSrcweir // make minimum version configurable 379*cdf0e10cSrcweir const char* pMinFcVersion = getenv( "SAL_MIN_FC_VERSION"); 380*cdf0e10cSrcweir if( pMinFcVersion ) 381*cdf0e10cSrcweir { 382*cdf0e10cSrcweir const int nMinFcVersion = atoi( pMinFcVersion ); 383*cdf0e10cSrcweir if( m_nFcVersion < nMinFcVersion ) 384*cdf0e10cSrcweir m_pFcInit = NULL; 385*cdf0e10cSrcweir } 386*cdf0e10cSrcweir 387*cdf0e10cSrcweir if( ! ( 388*cdf0e10cSrcweir m_pFcInit && 389*cdf0e10cSrcweir m_pFcGetVersion && 390*cdf0e10cSrcweir m_pFcConfigGetCurrent && 391*cdf0e10cSrcweir m_pFcObjectSetVaBuild && 392*cdf0e10cSrcweir m_pFcObjectSetDestroy && 393*cdf0e10cSrcweir m_pFcPatternCreate && 394*cdf0e10cSrcweir m_pFcPatternDestroy && 395*cdf0e10cSrcweir m_pFcFontList && 396*cdf0e10cSrcweir m_pFcConfigGetFonts && 397*cdf0e10cSrcweir m_pFcFontSetCreate && 398*cdf0e10cSrcweir m_pFcCharSetCreate && 399*cdf0e10cSrcweir m_pFcCharSetAddChar && 400*cdf0e10cSrcweir m_pFcCharSetHasChar && 401*cdf0e10cSrcweir m_pFcCharSetDestroy && 402*cdf0e10cSrcweir m_pFcFontSetDestroy && 403*cdf0e10cSrcweir m_pFcFontSetAdd && 404*cdf0e10cSrcweir m_pFcPatternReference && 405*cdf0e10cSrcweir m_pFcPatternGetCharSet && 406*cdf0e10cSrcweir m_pFcPatternGetString && 407*cdf0e10cSrcweir m_pFcPatternGetInteger && 408*cdf0e10cSrcweir m_pFcPatternGetDouble && 409*cdf0e10cSrcweir m_pFcPatternGetBool && 410*cdf0e10cSrcweir m_pFcConfigAppFontAddFile && 411*cdf0e10cSrcweir m_pFcConfigAppFontAddDir && 412*cdf0e10cSrcweir m_pFcConfigParseAndLoad && 413*cdf0e10cSrcweir m_pFcFontMatch && 414*cdf0e10cSrcweir m_pFcDefaultSubstitute && 415*cdf0e10cSrcweir m_pFcConfigSubstitute && 416*cdf0e10cSrcweir m_pFcPatternDuplicate && 417*cdf0e10cSrcweir m_pFcPatternAddInteger && 418*cdf0e10cSrcweir m_pFcPatternAddDouble && 419*cdf0e10cSrcweir m_pFcPatternAddCharSet && 420*cdf0e10cSrcweir m_pFcPatternAddBool && 421*cdf0e10cSrcweir m_pFcPatternAddString && 422*cdf0e10cSrcweir m_pFcPatternDel 423*cdf0e10cSrcweir ) ) 424*cdf0e10cSrcweir { 425*cdf0e10cSrcweir osl_unloadModule( (oslModule)m_pLib ); 426*cdf0e10cSrcweir m_pLib = NULL; 427*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 428*cdf0e10cSrcweir fprintf( stderr, "not all needed symbols were found in libfontconfig\n" ); 429*cdf0e10cSrcweir #endif 430*cdf0e10cSrcweir return; 431*cdf0e10cSrcweir } 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir FcInit(); 435*cdf0e10cSrcweir if( ! FcConfigGetCurrent() ) 436*cdf0e10cSrcweir { 437*cdf0e10cSrcweir osl_unloadModule( (oslModule)m_pLib ); 438*cdf0e10cSrcweir m_pLib = NULL; 439*cdf0e10cSrcweir } 440*cdf0e10cSrcweir } 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir void FontCfgWrapper::addFontSet( FcSetName eSetName ) 443*cdf0e10cSrcweir { 444*cdf0e10cSrcweir #ifdef ENABLE_FONTCONFIG 445*cdf0e10cSrcweir /* 446*cdf0e10cSrcweir add only acceptable outlined fonts to our config, 447*cdf0e10cSrcweir for future fontconfig use 448*cdf0e10cSrcweir */ 449*cdf0e10cSrcweir FcFontSet* pOrig = FcConfigGetFonts( FcConfigGetCurrent(), eSetName ); 450*cdf0e10cSrcweir if( !pOrig ) 451*cdf0e10cSrcweir return; 452*cdf0e10cSrcweir 453*cdf0e10cSrcweir // filter the font sets to remove obsolete or duplicate faces 454*cdf0e10cSrcweir for( int i = 0; i < pOrig->nfont; ++i ) 455*cdf0e10cSrcweir { 456*cdf0e10cSrcweir FcPattern* pOrigPattern = pOrig->fonts[i]; 457*cdf0e10cSrcweir // #i115131# ignore non-outline fonts 458*cdf0e10cSrcweir FcBool bOutline = FcFalse; 459*cdf0e10cSrcweir FcResult eOutRes = FcPatternGetBool( pOrigPattern, FC_OUTLINE, 0, &bOutline ); 460*cdf0e10cSrcweir if( (eOutRes != FcResultMatch) || (bOutline == FcFalse) ) 461*cdf0e10cSrcweir continue; 462*cdf0e10cSrcweir // create a pattern to find eventually better alternatives 463*cdf0e10cSrcweir FcPattern* pBetterPattern = pOrigPattern; 464*cdf0e10cSrcweir if( m_nFcVersion > 20400 ) // #i115204# avoid trouble with old FC versions 465*cdf0e10cSrcweir { 466*cdf0e10cSrcweir FcPattern* pTestPattern = FcPatternDuplicate( pOrigPattern ); 467*cdf0e10cSrcweir FcPatternAddBool( pTestPattern, FC_OUTLINE, FcTrue ); 468*cdf0e10cSrcweir // TODO: ignore all attributes that are not interesting for finding dupes 469*cdf0e10cSrcweir // e.g. by using pattern->ImplFontAttr->pattern conversion 470*cdf0e10cSrcweir FcPatternDel( pTestPattern, FC_FONTVERSION ); 471*cdf0e10cSrcweir FcPatternDel( pTestPattern, FC_CHARSET ); 472*cdf0e10cSrcweir FcPatternDel( pTestPattern, FC_FILE ); 473*cdf0e10cSrcweir // find the font face for the dupe-search pattern 474*cdf0e10cSrcweir FcResult eFcResult = FcResultMatch; 475*cdf0e10cSrcweir pBetterPattern = FcFontMatch( FcConfigGetCurrent(), pTestPattern, &eFcResult ); 476*cdf0e10cSrcweir FcPatternDestroy( pTestPattern ); 477*cdf0e10cSrcweir if( eFcResult != FcResultMatch ) 478*cdf0e10cSrcweir continue; 479*cdf0e10cSrcweir // #i115131# double check results and eventually ignore them 480*cdf0e10cSrcweir eOutRes = FcPatternGetBool( pBetterPattern, FC_OUTLINE, 0, &bOutline ); 481*cdf0e10cSrcweir if( (eOutRes != FcResultMatch) || (bOutline == FcFalse) ) 482*cdf0e10cSrcweir continue; 483*cdf0e10cSrcweir } 484*cdf0e10cSrcweir // insert best found pattern for the dupe-search pattern 485*cdf0e10cSrcweir // TODO: skip inserting patterns that are already known in the target fontset 486*cdf0e10cSrcweir FcPatternReference( pBetterPattern ); 487*cdf0e10cSrcweir FcFontSetAdd( m_pOutlineSet, pBetterPattern ); 488*cdf0e10cSrcweir } 489*cdf0e10cSrcweir 490*cdf0e10cSrcweir // TODO?: FcFontSetDestroy( pOrig ); 491*cdf0e10cSrcweir #else 492*cdf0e10cSrcweir (void)eSetName; // prevent compiler warning about unused parameter 493*cdf0e10cSrcweir #endif 494*cdf0e10cSrcweir } 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir FcFontSet* FontCfgWrapper::getFontSet() 497*cdf0e10cSrcweir { 498*cdf0e10cSrcweir #ifdef ENABLE_FONTCONFIG 499*cdf0e10cSrcweir if( !m_pOutlineSet ) 500*cdf0e10cSrcweir { 501*cdf0e10cSrcweir m_pOutlineSet = FcFontSetCreate(); 502*cdf0e10cSrcweir addFontSet( FcSetSystem ); 503*cdf0e10cSrcweir if( m_nFcVersion > 20400 ) // #i85462# prevent crashes 504*cdf0e10cSrcweir addFontSet( FcSetApplication ); 505*cdf0e10cSrcweir } 506*cdf0e10cSrcweir #endif 507*cdf0e10cSrcweir 508*cdf0e10cSrcweir return m_pOutlineSet; 509*cdf0e10cSrcweir } 510*cdf0e10cSrcweir 511*cdf0e10cSrcweir FontCfgWrapper::~FontCfgWrapper() 512*cdf0e10cSrcweir { 513*cdf0e10cSrcweir if( m_pOutlineSet ) 514*cdf0e10cSrcweir FcFontSetDestroy( m_pOutlineSet ); 515*cdf0e10cSrcweir if( m_pLib ) 516*cdf0e10cSrcweir osl_unloadModule( (oslModule)m_pLib ); 517*cdf0e10cSrcweir } 518*cdf0e10cSrcweir 519*cdf0e10cSrcweir static FontCfgWrapper* pOneInstance = NULL; 520*cdf0e10cSrcweir 521*cdf0e10cSrcweir FontCfgWrapper& FontCfgWrapper::get() 522*cdf0e10cSrcweir { 523*cdf0e10cSrcweir if( ! pOneInstance ) 524*cdf0e10cSrcweir pOneInstance = new FontCfgWrapper(); 525*cdf0e10cSrcweir return *pOneInstance; 526*cdf0e10cSrcweir } 527*cdf0e10cSrcweir 528*cdf0e10cSrcweir void FontCfgWrapper::release() 529*cdf0e10cSrcweir { 530*cdf0e10cSrcweir if( pOneInstance ) 531*cdf0e10cSrcweir { 532*cdf0e10cSrcweir delete pOneInstance; 533*cdf0e10cSrcweir pOneInstance = NULL; 534*cdf0e10cSrcweir } 535*cdf0e10cSrcweir } 536*cdf0e10cSrcweir 537*cdf0e10cSrcweir #ifdef ENABLE_FONTCONFIG 538*cdf0e10cSrcweir namespace 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir typedef std::pair<FcChar8*, FcChar8*> lang_and_family; 541*cdf0e10cSrcweir 542*cdf0e10cSrcweir class localizedsorter 543*cdf0e10cSrcweir { 544*cdf0e10cSrcweir rtl::OLocale maLoc; 545*cdf0e10cSrcweir public: 546*cdf0e10cSrcweir localizedsorter(rtl_Locale* pLoc) : maLoc(pLoc) {} 547*cdf0e10cSrcweir FcChar8* bestname(const std::vector<lang_and_family> &families); 548*cdf0e10cSrcweir }; 549*cdf0e10cSrcweir 550*cdf0e10cSrcweir FcChar8* localizedsorter::bestname(const std::vector<lang_and_family> &families) 551*cdf0e10cSrcweir { 552*cdf0e10cSrcweir FcChar8* candidate = families.begin()->second; 553*cdf0e10cSrcweir rtl::OString sLangMatch(rtl::OUStringToOString(maLoc.getLanguage().toAsciiLowerCase(), RTL_TEXTENCODING_UTF8)); 554*cdf0e10cSrcweir rtl::OString sFullMatch = sLangMatch; 555*cdf0e10cSrcweir sFullMatch += OString('-'); 556*cdf0e10cSrcweir sFullMatch += rtl::OUStringToOString(maLoc.getCountry().toAsciiLowerCase(), RTL_TEXTENCODING_UTF8); 557*cdf0e10cSrcweir 558*cdf0e10cSrcweir std::vector<lang_and_family>::const_iterator aEnd = families.end(); 559*cdf0e10cSrcweir bool alreadyclosematch = false; 560*cdf0e10cSrcweir for( std::vector<lang_and_family>::const_iterator aIter = families.begin(); aIter != aEnd; ++aIter ) 561*cdf0e10cSrcweir { 562*cdf0e10cSrcweir const char *pLang = (const char*)aIter->first; 563*cdf0e10cSrcweir if( rtl_str_compare( pLang, sFullMatch.getStr() ) == 0) 564*cdf0e10cSrcweir { 565*cdf0e10cSrcweir // both language and country match 566*cdf0e10cSrcweir candidate = aIter->second; 567*cdf0e10cSrcweir break; 568*cdf0e10cSrcweir } 569*cdf0e10cSrcweir else if( alreadyclosematch ) 570*cdf0e10cSrcweir continue; 571*cdf0e10cSrcweir else if( rtl_str_compare( pLang, sLangMatch.getStr()) == 0) 572*cdf0e10cSrcweir { 573*cdf0e10cSrcweir // just the language matches 574*cdf0e10cSrcweir candidate = aIter->second; 575*cdf0e10cSrcweir alreadyclosematch = true; 576*cdf0e10cSrcweir } 577*cdf0e10cSrcweir else if( rtl_str_compare( pLang, "en") == 0) 578*cdf0e10cSrcweir { 579*cdf0e10cSrcweir // fallback to the english family name 580*cdf0e10cSrcweir candidate = aIter->second; 581*cdf0e10cSrcweir } 582*cdf0e10cSrcweir } 583*cdf0e10cSrcweir return candidate; 584*cdf0e10cSrcweir } 585*cdf0e10cSrcweir } 586*cdf0e10cSrcweir 587*cdf0e10cSrcweir FcResult FontCfgWrapper::FamilyFromPattern(FcPattern* pPattern, FcChar8 **family) 588*cdf0e10cSrcweir { 589*cdf0e10cSrcweir FcChar8 *origfamily; 590*cdf0e10cSrcweir FcResult eFamilyRes = FcPatternGetString( pPattern, FC_FAMILY, 0, &origfamily ); 591*cdf0e10cSrcweir *family = origfamily; 592*cdf0e10cSrcweir 593*cdf0e10cSrcweir if( eFamilyRes == FcResultMatch) 594*cdf0e10cSrcweir { 595*cdf0e10cSrcweir FcChar8* familylang = NULL; 596*cdf0e10cSrcweir if (FcPatternGetString( pPattern, FC_FAMILYLANG, 0, &familylang ) == FcResultMatch) 597*cdf0e10cSrcweir { 598*cdf0e10cSrcweir std::vector< lang_and_family > lang_and_families; 599*cdf0e10cSrcweir lang_and_families.push_back(lang_and_family(familylang, *family)); 600*cdf0e10cSrcweir int k = 1; 601*cdf0e10cSrcweir while (1) 602*cdf0e10cSrcweir { 603*cdf0e10cSrcweir if (FcPatternGetString( pPattern, FC_FAMILYLANG, k, &familylang ) != FcResultMatch) 604*cdf0e10cSrcweir break; 605*cdf0e10cSrcweir if (FcPatternGetString( pPattern, FC_FAMILY, k, family ) != FcResultMatch) 606*cdf0e10cSrcweir break; 607*cdf0e10cSrcweir lang_and_families.push_back(lang_and_family(familylang, *family)); 608*cdf0e10cSrcweir ++k; 609*cdf0e10cSrcweir } 610*cdf0e10cSrcweir 611*cdf0e10cSrcweir //possible to-do, sort by UILocale instead of process locale 612*cdf0e10cSrcweir rtl_Locale* pLoc; 613*cdf0e10cSrcweir osl_getProcessLocale(&pLoc); 614*cdf0e10cSrcweir localizedsorter aSorter(pLoc); 615*cdf0e10cSrcweir *family = aSorter.bestname(lang_and_families); 616*cdf0e10cSrcweir 617*cdf0e10cSrcweir std::vector<lang_and_family>::const_iterator aEnd = lang_and_families.end(); 618*cdf0e10cSrcweir for (std::vector<lang_and_family>::const_iterator aIter = lang_and_families.begin(); aIter != aEnd; ++aIter) 619*cdf0e10cSrcweir { 620*cdf0e10cSrcweir const char *candidate = (const char*)(aIter->second); 621*cdf0e10cSrcweir if (rtl_str_compare(candidate, (const char*)(*family)) != 0) 622*cdf0e10cSrcweir m_aFontNameToLocalized[OString(candidate)] = OString((const char*)(*family)); 623*cdf0e10cSrcweir } 624*cdf0e10cSrcweir if (rtl_str_compare((const char*)origfamily, (const char*)(*family)) != 0) 625*cdf0e10cSrcweir m_aLocalizedToCanonical[OString((const char*)(*family))] = OString((const char*)origfamily); 626*cdf0e10cSrcweir } 627*cdf0e10cSrcweir } 628*cdf0e10cSrcweir 629*cdf0e10cSrcweir return eFamilyRes; 630*cdf0e10cSrcweir } 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir /* 633*cdf0e10cSrcweir * PrintFontManager::initFontconfig 634*cdf0e10cSrcweir */ 635*cdf0e10cSrcweir bool PrintFontManager::initFontconfig() 636*cdf0e10cSrcweir { 637*cdf0e10cSrcweir FontCfgWrapper& rWrapper = FontCfgWrapper::get(); 638*cdf0e10cSrcweir if( ! rWrapper.isValid() ) 639*cdf0e10cSrcweir return false; 640*cdf0e10cSrcweir return true; 641*cdf0e10cSrcweir } 642*cdf0e10cSrcweir 643*cdf0e10cSrcweir namespace 644*cdf0e10cSrcweir { 645*cdf0e10cSrcweir weight::type convertWeight(int weight) 646*cdf0e10cSrcweir { 647*cdf0e10cSrcweir // set weight 648*cdf0e10cSrcweir if( weight <= FC_WEIGHT_THIN ) 649*cdf0e10cSrcweir return weight::Thin; 650*cdf0e10cSrcweir else if( weight <= FC_WEIGHT_ULTRALIGHT ) 651*cdf0e10cSrcweir return weight::UltraLight; 652*cdf0e10cSrcweir else if( weight <= FC_WEIGHT_LIGHT ) 653*cdf0e10cSrcweir return weight::Light; 654*cdf0e10cSrcweir else if( weight <= FC_WEIGHT_BOOK ) 655*cdf0e10cSrcweir return weight::SemiLight; 656*cdf0e10cSrcweir else if( weight <= FC_WEIGHT_NORMAL ) 657*cdf0e10cSrcweir return weight::Normal; 658*cdf0e10cSrcweir else if( weight <= FC_WEIGHT_MEDIUM ) 659*cdf0e10cSrcweir return weight::Medium; 660*cdf0e10cSrcweir else if( weight <= FC_WEIGHT_SEMIBOLD ) 661*cdf0e10cSrcweir return weight::SemiBold; 662*cdf0e10cSrcweir else if( weight <= FC_WEIGHT_BOLD ) 663*cdf0e10cSrcweir return weight::Bold; 664*cdf0e10cSrcweir else if( weight <= FC_WEIGHT_ULTRABOLD ) 665*cdf0e10cSrcweir return weight::UltraBold; 666*cdf0e10cSrcweir return weight::Black; 667*cdf0e10cSrcweir } 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir italic::type convertSlant(int slant) 670*cdf0e10cSrcweir { 671*cdf0e10cSrcweir // set italic 672*cdf0e10cSrcweir if( slant == FC_SLANT_ITALIC ) 673*cdf0e10cSrcweir return italic::Italic; 674*cdf0e10cSrcweir else if( slant == FC_SLANT_OBLIQUE ) 675*cdf0e10cSrcweir return italic::Oblique; 676*cdf0e10cSrcweir return italic::Upright; 677*cdf0e10cSrcweir } 678*cdf0e10cSrcweir 679*cdf0e10cSrcweir pitch::type convertSpacing(int spacing) 680*cdf0e10cSrcweir { 681*cdf0e10cSrcweir // set pitch 682*cdf0e10cSrcweir if( spacing == FC_MONO || spacing == FC_CHARCELL ) 683*cdf0e10cSrcweir return pitch::Fixed; 684*cdf0e10cSrcweir return pitch::Variable; 685*cdf0e10cSrcweir } 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir width::type convertWidth(int width) 688*cdf0e10cSrcweir { 689*cdf0e10cSrcweir if (width == FC_WIDTH_ULTRACONDENSED) 690*cdf0e10cSrcweir return width::UltraCondensed; 691*cdf0e10cSrcweir else if (width == FC_WIDTH_EXTRACONDENSED) 692*cdf0e10cSrcweir return width::ExtraCondensed; 693*cdf0e10cSrcweir else if (width == FC_WIDTH_CONDENSED) 694*cdf0e10cSrcweir return width::Condensed; 695*cdf0e10cSrcweir else if (width == FC_WIDTH_SEMICONDENSED) 696*cdf0e10cSrcweir return width::SemiCondensed; 697*cdf0e10cSrcweir else if (width == FC_WIDTH_SEMIEXPANDED) 698*cdf0e10cSrcweir return width::SemiExpanded; 699*cdf0e10cSrcweir else if (width == FC_WIDTH_EXPANDED) 700*cdf0e10cSrcweir return width::Expanded; 701*cdf0e10cSrcweir else if (width == FC_WIDTH_EXTRAEXPANDED) 702*cdf0e10cSrcweir return width::ExtraExpanded; 703*cdf0e10cSrcweir else if (width == FC_WIDTH_ULTRAEXPANDED) 704*cdf0e10cSrcweir return width::UltraExpanded; 705*cdf0e10cSrcweir return width::Normal; 706*cdf0e10cSrcweir } 707*cdf0e10cSrcweir } 708*cdf0e10cSrcweir 709*cdf0e10cSrcweir int PrintFontManager::countFontconfigFonts( std::hash_map<rtl::OString, int, rtl::OStringHash>& o_rVisitedPaths ) 710*cdf0e10cSrcweir { 711*cdf0e10cSrcweir int nFonts = 0; 712*cdf0e10cSrcweir 713*cdf0e10cSrcweir FontCfgWrapper& rWrapper = FontCfgWrapper::get(); 714*cdf0e10cSrcweir if( !rWrapper.isValid() ) 715*cdf0e10cSrcweir return 0; 716*cdf0e10cSrcweir 717*cdf0e10cSrcweir FcFontSet* pFSet = rWrapper.getFontSet(); 718*cdf0e10cSrcweir if( pFSet ) 719*cdf0e10cSrcweir { 720*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 721*cdf0e10cSrcweir fprintf( stderr, "found %d entries in fontconfig fontset\n", pFSet->nfont ); 722*cdf0e10cSrcweir #endif 723*cdf0e10cSrcweir for( int i = 0; i < pFSet->nfont; i++ ) 724*cdf0e10cSrcweir { 725*cdf0e10cSrcweir FcChar8* file = NULL; 726*cdf0e10cSrcweir FcChar8* family = NULL; 727*cdf0e10cSrcweir FcChar8* style = NULL; 728*cdf0e10cSrcweir int slant = 0; 729*cdf0e10cSrcweir int weight = 0; 730*cdf0e10cSrcweir int spacing = 0; 731*cdf0e10cSrcweir int nCollectionEntry = -1; 732*cdf0e10cSrcweir FcBool outline = false; 733*cdf0e10cSrcweir 734*cdf0e10cSrcweir FcResult eFileRes = rWrapper.FcPatternGetString( pFSet->fonts[i], FC_FILE, 0, &file ); 735*cdf0e10cSrcweir FcResult eFamilyRes = rWrapper.FamilyFromPattern( pFSet->fonts[i], &family ); 736*cdf0e10cSrcweir FcResult eStyleRes = rWrapper.FcPatternGetString( pFSet->fonts[i], FC_STYLE, 0, &style ); 737*cdf0e10cSrcweir FcResult eSlantRes = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_SLANT, 0, &slant ); 738*cdf0e10cSrcweir FcResult eWeightRes = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_WEIGHT, 0, &weight ); 739*cdf0e10cSrcweir FcResult eSpacRes = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_SPACING, 0, &spacing ); 740*cdf0e10cSrcweir FcResult eOutRes = rWrapper.FcPatternGetBool( pFSet->fonts[i], FC_OUTLINE, 0, &outline ); 741*cdf0e10cSrcweir FcResult eIndexRes = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_INDEX, 0, &nCollectionEntry ); 742*cdf0e10cSrcweir 743*cdf0e10cSrcweir if( eFileRes != FcResultMatch || eFamilyRes != FcResultMatch || eOutRes != FcResultMatch ) 744*cdf0e10cSrcweir continue; 745*cdf0e10cSrcweir 746*cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 2) 747*cdf0e10cSrcweir fprintf( stderr, "found font \"%s\" in file %s\n" 748*cdf0e10cSrcweir " weight = %d, slant = %d, style = \"%s\"\n" 749*cdf0e10cSrcweir " spacing = %d, outline = %d\n" 750*cdf0e10cSrcweir , family, file 751*cdf0e10cSrcweir , eWeightRes == FcResultMatch ? weight : -1 752*cdf0e10cSrcweir , eSpacRes == FcResultMatch ? slant : -1 753*cdf0e10cSrcweir , eStyleRes == FcResultMatch ? (const char*) style : "<nil>" 754*cdf0e10cSrcweir , eSpacRes == FcResultMatch ? spacing : -1 755*cdf0e10cSrcweir , eOutRes == FcResultMatch ? outline : -1 756*cdf0e10cSrcweir ); 757*cdf0e10cSrcweir #endif 758*cdf0e10cSrcweir 759*cdf0e10cSrcweir // OSL_ASSERT(eOutRes != FcResultMatch || outline); 760*cdf0e10cSrcweir 761*cdf0e10cSrcweir // only outline fonts are usable to psprint anyway 762*cdf0e10cSrcweir if( eOutRes == FcResultMatch && ! outline ) 763*cdf0e10cSrcweir continue; 764*cdf0e10cSrcweir 765*cdf0e10cSrcweir // see if this font is already cached 766*cdf0e10cSrcweir // update attributes 767*cdf0e10cSrcweir std::list< PrintFont* > aFonts; 768*cdf0e10cSrcweir OString aDir, aBase, aOrgPath( (sal_Char*)file ); 769*cdf0e10cSrcweir splitPath( aOrgPath, aDir, aBase ); 770*cdf0e10cSrcweir 771*cdf0e10cSrcweir o_rVisitedPaths[aDir] = 1; 772*cdf0e10cSrcweir 773*cdf0e10cSrcweir int nDirID = getDirectoryAtom( aDir, true ); 774*cdf0e10cSrcweir if( ! m_pFontCache->getFontCacheFile( nDirID, aBase, aFonts ) ) 775*cdf0e10cSrcweir { 776*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 2 777*cdf0e10cSrcweir fprintf( stderr, "file %s not cached\n", aBase.getStr() ); 778*cdf0e10cSrcweir #endif 779*cdf0e10cSrcweir // not known, analyze font file to get attributes 780*cdf0e10cSrcweir // not described by fontconfig (e.g. alias names, PSName) 781*cdf0e10cSrcweir std::list< OString > aDummy; 782*cdf0e10cSrcweir analyzeFontFile( nDirID, aBase, aDummy, aFonts ); 783*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 784*cdf0e10cSrcweir if( aFonts.empty() ) 785*cdf0e10cSrcweir fprintf( stderr, "Warning: file \"%s\" is unusable to psprint\n", aOrgPath.getStr() ); 786*cdf0e10cSrcweir #endif 787*cdf0e10cSrcweir } 788*cdf0e10cSrcweir if( aFonts.empty() ) 789*cdf0e10cSrcweir { 790*cdf0e10cSrcweir // TODO: remove fonts unusable to psprint from fontset 791*cdf0e10cSrcweir continue; 792*cdf0e10cSrcweir } 793*cdf0e10cSrcweir 794*cdf0e10cSrcweir int nFamilyName = m_pAtoms->getAtom( ATOM_FAMILYNAME, OStringToOUString( OString( (sal_Char*)family ), RTL_TEXTENCODING_UTF8 ), sal_True ); 795*cdf0e10cSrcweir PrintFont* pUpdate = aFonts.front(); 796*cdf0e10cSrcweir std::list<PrintFont*>::const_iterator second_font = aFonts.begin(); 797*cdf0e10cSrcweir ++second_font; 798*cdf0e10cSrcweir if( second_font != aFonts.end() ) // more than one font 799*cdf0e10cSrcweir { 800*cdf0e10cSrcweir // a collection entry, get the correct index 801*cdf0e10cSrcweir if( eIndexRes == FcResultMatch && nCollectionEntry != -1 ) 802*cdf0e10cSrcweir { 803*cdf0e10cSrcweir for( std::list< PrintFont* >::iterator it = aFonts.begin(); it != aFonts.end(); ++it ) 804*cdf0e10cSrcweir { 805*cdf0e10cSrcweir if( (*it)->m_eType == fonttype::TrueType && 806*cdf0e10cSrcweir static_cast<TrueTypeFontFile*>(*it)->m_nCollectionEntry == nCollectionEntry ) 807*cdf0e10cSrcweir { 808*cdf0e10cSrcweir pUpdate = *it; 809*cdf0e10cSrcweir break; 810*cdf0e10cSrcweir } 811*cdf0e10cSrcweir } 812*cdf0e10cSrcweir // update collection entry 813*cdf0e10cSrcweir // additional entries will be created in the cache 814*cdf0e10cSrcweir // if this is a new index (that is if the loop above 815*cdf0e10cSrcweir // ran to the end of the list) 816*cdf0e10cSrcweir if( pUpdate->m_eType == fonttype::TrueType ) // sanity check, this should always be the case here 817*cdf0e10cSrcweir static_cast<TrueTypeFontFile*>(pUpdate)->m_nCollectionEntry = nCollectionEntry; 818*cdf0e10cSrcweir } 819*cdf0e10cSrcweir else 820*cdf0e10cSrcweir { 821*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 822*cdf0e10cSrcweir fprintf( stderr, "multiple fonts for file, but no index in fontconfig pattern ! (index res = %d collection entry = %d\nfile will not be used\n", eIndexRes, nCollectionEntry ); 823*cdf0e10cSrcweir #endif 824*cdf0e10cSrcweir // we have found more than one font in this file 825*cdf0e10cSrcweir // but fontconfig will not tell us which index is meant 826*cdf0e10cSrcweir // -> something is in disorder, do not use this font 827*cdf0e10cSrcweir pUpdate = NULL; 828*cdf0e10cSrcweir } 829*cdf0e10cSrcweir } 830*cdf0e10cSrcweir 831*cdf0e10cSrcweir if( pUpdate ) 832*cdf0e10cSrcweir { 833*cdf0e10cSrcweir // set family name 834*cdf0e10cSrcweir if( pUpdate->m_nFamilyName != nFamilyName ) 835*cdf0e10cSrcweir { 836*cdf0e10cSrcweir #if 0 // fontconfig prefers nameid=16 for the family name which is all fine 837*cdf0e10cSrcweir // but Writer suffers from #i79878# 838*cdf0e10cSrcweir // the only reasonable workaround for now is to use the classic nameid=1 839*cdf0e10cSrcweir pUpdate->m_aAliases.remove( pUpdate->m_nFamilyName ); 840*cdf0e10cSrcweir pUpdate->m_aAliases.push_back( pUpdate->m_nFamilyName ); 841*cdf0e10cSrcweir pUpdate->m_aAliases.remove( nFamilyName ); 842*cdf0e10cSrcweir pUpdate->m_nFamilyName = nFamilyName; 843*cdf0e10cSrcweir #endif 844*cdf0e10cSrcweir } 845*cdf0e10cSrcweir if( eWeightRes == FcResultMatch ) 846*cdf0e10cSrcweir pUpdate->m_eWeight = convertWeight(weight); 847*cdf0e10cSrcweir if( eSpacRes == FcResultMatch ) 848*cdf0e10cSrcweir pUpdate->m_ePitch = convertSpacing(spacing); 849*cdf0e10cSrcweir if( eSlantRes == FcResultMatch ) 850*cdf0e10cSrcweir pUpdate->m_eItalic = convertSlant(slant); 851*cdf0e10cSrcweir if( eStyleRes == FcResultMatch ) 852*cdf0e10cSrcweir { 853*cdf0e10cSrcweir pUpdate->m_aStyleName = OStringToOUString( OString( (sal_Char*)style ), RTL_TEXTENCODING_UTF8 ); 854*cdf0e10cSrcweir } 855*cdf0e10cSrcweir 856*cdf0e10cSrcweir // update font cache 857*cdf0e10cSrcweir m_pFontCache->updateFontCacheEntry( pUpdate, false ); 858*cdf0e10cSrcweir // sort into known fonts 859*cdf0e10cSrcweir fontID aFont = m_nNextFontID++; 860*cdf0e10cSrcweir m_aFonts[ aFont ] = pUpdate; 861*cdf0e10cSrcweir m_aFontFileToFontID[ aBase ].insert( aFont ); 862*cdf0e10cSrcweir nFonts++; 863*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 2 864*cdf0e10cSrcweir fprintf( stderr, "inserted font %s as fontID %d\n", family, aFont ); 865*cdf0e10cSrcweir #endif 866*cdf0e10cSrcweir } 867*cdf0e10cSrcweir // clean up the fonts we did not put into the list 868*cdf0e10cSrcweir for( std::list< PrintFont* >::iterator it = aFonts.begin(); it != aFonts.end(); ++it ) 869*cdf0e10cSrcweir { 870*cdf0e10cSrcweir if( *it != pUpdate ) 871*cdf0e10cSrcweir { 872*cdf0e10cSrcweir m_pFontCache->updateFontCacheEntry( *it, false ); // prepare a cache entry for a collection item 873*cdf0e10cSrcweir delete *it; 874*cdf0e10cSrcweir } 875*cdf0e10cSrcweir } 876*cdf0e10cSrcweir } 877*cdf0e10cSrcweir } 878*cdf0e10cSrcweir 879*cdf0e10cSrcweir // how does one get rid of the config ? 880*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 881*cdf0e10cSrcweir fprintf( stderr, "inserted %d fonts from fontconfig\n", nFonts ); 882*cdf0e10cSrcweir #endif 883*cdf0e10cSrcweir return nFonts; 884*cdf0e10cSrcweir } 885*cdf0e10cSrcweir 886*cdf0e10cSrcweir void PrintFontManager::deinitFontconfig() 887*cdf0e10cSrcweir { 888*cdf0e10cSrcweir FontCfgWrapper::release(); 889*cdf0e10cSrcweir } 890*cdf0e10cSrcweir 891*cdf0e10cSrcweir int PrintFontManager::FreeTypeCharIndex( void *pFace, sal_uInt32 aChar ) 892*cdf0e10cSrcweir { 893*cdf0e10cSrcweir FontCfgWrapper& rWrapper = FontCfgWrapper::get(); 894*cdf0e10cSrcweir return rWrapper.isValid() ? rWrapper.FcFreeTypeCharIndex( (FT_Face)pFace, aChar ) : 0; 895*cdf0e10cSrcweir } 896*cdf0e10cSrcweir 897*cdf0e10cSrcweir bool PrintFontManager::addFontconfigDir( const rtl::OString& rDirName ) 898*cdf0e10cSrcweir { 899*cdf0e10cSrcweir FontCfgWrapper& rWrapper = FontCfgWrapper::get(); 900*cdf0e10cSrcweir if( ! rWrapper.isValid() ) 901*cdf0e10cSrcweir return false; 902*cdf0e10cSrcweir 903*cdf0e10cSrcweir // workaround for a stability problems in older FC versions 904*cdf0e10cSrcweir // when handling application specifc fonts 905*cdf0e10cSrcweir const int nVersion = rWrapper.FcGetVersion(); 906*cdf0e10cSrcweir if( nVersion <= 20400 ) 907*cdf0e10cSrcweir return false; 908*cdf0e10cSrcweir const char* pDirName = (const char*)rDirName.getStr(); 909*cdf0e10cSrcweir bool bDirOk = (rWrapper.FcConfigAppFontAddDir( rWrapper.FcConfigGetCurrent(), (FcChar8*)pDirName ) == FcTrue); 910*cdf0e10cSrcweir 911*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 912*cdf0e10cSrcweir fprintf( stderr, "FcConfigAppFontAddDir( \"%s\") => %d\n", pDirName, bDirOk ); 913*cdf0e10cSrcweir #endif 914*cdf0e10cSrcweir 915*cdf0e10cSrcweir if( !bDirOk ) 916*cdf0e10cSrcweir return false; 917*cdf0e10cSrcweir 918*cdf0e10cSrcweir // load dir-specific fc-config file too if available 919*cdf0e10cSrcweir const rtl::OString aConfFileName = rDirName + "/fc_local.conf"; 920*cdf0e10cSrcweir FILE* pCfgFile = fopen( aConfFileName.getStr(), "rb" ); 921*cdf0e10cSrcweir if( pCfgFile ) 922*cdf0e10cSrcweir { 923*cdf0e10cSrcweir fclose( pCfgFile); 924*cdf0e10cSrcweir bool bCfgOk = rWrapper.FcConfigParseAndLoad( rWrapper.FcConfigGetCurrent(), 925*cdf0e10cSrcweir (FcChar8*)aConfFileName.getStr(), FcTrue ); 926*cdf0e10cSrcweir if( !bCfgOk ) 927*cdf0e10cSrcweir fprintf( stderr, "FcConfigParseAndLoad( \"%s\") => %d\n", aConfFileName.getStr(), bCfgOk ); 928*cdf0e10cSrcweir } 929*cdf0e10cSrcweir 930*cdf0e10cSrcweir return true; 931*cdf0e10cSrcweir } 932*cdf0e10cSrcweir 933*cdf0e10cSrcweir static void addtopattern(FontCfgWrapper& rWrapper, FcPattern *pPattern, 934*cdf0e10cSrcweir italic::type eItalic, weight::type eWeight, width::type eWidth, pitch::type ePitch) 935*cdf0e10cSrcweir { 936*cdf0e10cSrcweir if( eItalic != italic::Unknown ) 937*cdf0e10cSrcweir { 938*cdf0e10cSrcweir int nSlant = FC_SLANT_ROMAN; 939*cdf0e10cSrcweir switch( eItalic ) 940*cdf0e10cSrcweir { 941*cdf0e10cSrcweir case italic::Italic: nSlant = FC_SLANT_ITALIC;break; 942*cdf0e10cSrcweir case italic::Oblique: nSlant = FC_SLANT_OBLIQUE;break; 943*cdf0e10cSrcweir default: 944*cdf0e10cSrcweir break; 945*cdf0e10cSrcweir } 946*cdf0e10cSrcweir rWrapper.FcPatternAddInteger( pPattern, FC_SLANT, nSlant ); 947*cdf0e10cSrcweir } 948*cdf0e10cSrcweir if( eWeight != weight::Unknown ) 949*cdf0e10cSrcweir { 950*cdf0e10cSrcweir int nWeight = FC_WEIGHT_NORMAL; 951*cdf0e10cSrcweir switch( eWeight ) 952*cdf0e10cSrcweir { 953*cdf0e10cSrcweir case weight::Thin: nWeight = FC_WEIGHT_THIN;break; 954*cdf0e10cSrcweir case weight::UltraLight: nWeight = FC_WEIGHT_ULTRALIGHT;break; 955*cdf0e10cSrcweir case weight::Light: nWeight = FC_WEIGHT_LIGHT;break; 956*cdf0e10cSrcweir case weight::SemiLight: nWeight = FC_WEIGHT_BOOK;break; 957*cdf0e10cSrcweir case weight::Normal: nWeight = FC_WEIGHT_NORMAL;break; 958*cdf0e10cSrcweir case weight::Medium: nWeight = FC_WEIGHT_MEDIUM;break; 959*cdf0e10cSrcweir case weight::SemiBold: nWeight = FC_WEIGHT_SEMIBOLD;break; 960*cdf0e10cSrcweir case weight::Bold: nWeight = FC_WEIGHT_BOLD;break; 961*cdf0e10cSrcweir case weight::UltraBold: nWeight = FC_WEIGHT_ULTRABOLD;break; 962*cdf0e10cSrcweir case weight::Black: nWeight = FC_WEIGHT_BLACK;break; 963*cdf0e10cSrcweir default: 964*cdf0e10cSrcweir break; 965*cdf0e10cSrcweir } 966*cdf0e10cSrcweir rWrapper.FcPatternAddInteger( pPattern, FC_WEIGHT, nWeight ); 967*cdf0e10cSrcweir } 968*cdf0e10cSrcweir if( eWidth != width::Unknown ) 969*cdf0e10cSrcweir { 970*cdf0e10cSrcweir int nWidth = FC_WIDTH_NORMAL; 971*cdf0e10cSrcweir switch( eWidth ) 972*cdf0e10cSrcweir { 973*cdf0e10cSrcweir case width::UltraCondensed: nWidth = FC_WIDTH_ULTRACONDENSED;break; 974*cdf0e10cSrcweir case width::ExtraCondensed: nWidth = FC_WIDTH_EXTRACONDENSED;break; 975*cdf0e10cSrcweir case width::Condensed: nWidth = FC_WIDTH_CONDENSED;break; 976*cdf0e10cSrcweir case width::SemiCondensed: nWidth = FC_WIDTH_SEMICONDENSED;break; 977*cdf0e10cSrcweir case width::Normal: nWidth = FC_WIDTH_NORMAL;break; 978*cdf0e10cSrcweir case width::SemiExpanded: nWidth = FC_WIDTH_SEMIEXPANDED;break; 979*cdf0e10cSrcweir case width::Expanded: nWidth = FC_WIDTH_EXPANDED;break; 980*cdf0e10cSrcweir case width::ExtraExpanded: nWidth = FC_WIDTH_EXTRAEXPANDED;break; 981*cdf0e10cSrcweir case width::UltraExpanded: nWidth = FC_WIDTH_ULTRACONDENSED;break; 982*cdf0e10cSrcweir default: 983*cdf0e10cSrcweir break; 984*cdf0e10cSrcweir } 985*cdf0e10cSrcweir rWrapper.FcPatternAddInteger( pPattern, FC_WIDTH, nWidth ); 986*cdf0e10cSrcweir } 987*cdf0e10cSrcweir if( ePitch != pitch::Unknown ) 988*cdf0e10cSrcweir { 989*cdf0e10cSrcweir int nSpacing = FC_PROPORTIONAL; 990*cdf0e10cSrcweir switch( ePitch ) 991*cdf0e10cSrcweir { 992*cdf0e10cSrcweir case pitch::Fixed: nSpacing = FC_MONO;break; 993*cdf0e10cSrcweir case pitch::Variable: nSpacing = FC_PROPORTIONAL;break; 994*cdf0e10cSrcweir default: 995*cdf0e10cSrcweir break; 996*cdf0e10cSrcweir } 997*cdf0e10cSrcweir rWrapper.FcPatternAddInteger( pPattern, FC_SPACING, nSpacing ); 998*cdf0e10cSrcweir if (nSpacing == FC_MONO) 999*cdf0e10cSrcweir rWrapper.FcPatternAddString( pPattern, FC_FAMILY, (FcChar8*)"monospace"); 1000*cdf0e10cSrcweir } 1001*cdf0e10cSrcweir } 1002*cdf0e10cSrcweir 1003*cdf0e10cSrcweir rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName, 1004*cdf0e10cSrcweir rtl::OUString& rMissingCodes, const rtl::OString &rLangAttrib, 1005*cdf0e10cSrcweir italic::type &rItalic, weight::type &rWeight, 1006*cdf0e10cSrcweir width::type &rWidth, pitch::type &rPitch) const 1007*cdf0e10cSrcweir { 1008*cdf0e10cSrcweir rtl::OUString aName; 1009*cdf0e10cSrcweir FontCfgWrapper& rWrapper = FontCfgWrapper::get(); 1010*cdf0e10cSrcweir if( ! rWrapper.isValid() ) 1011*cdf0e10cSrcweir return aName; 1012*cdf0e10cSrcweir 1013*cdf0e10cSrcweir // build pattern argument for fontconfig query 1014*cdf0e10cSrcweir FcPattern* pPattern = rWrapper.FcPatternCreate(); 1015*cdf0e10cSrcweir 1016*cdf0e10cSrcweir // Prefer scalable fonts 1017*cdf0e10cSrcweir rWrapper.FcPatternAddBool( pPattern, FC_SCALABLE, FcTrue ); 1018*cdf0e10cSrcweir 1019*cdf0e10cSrcweir const rtl::OString aTargetName = rtl::OUStringToOString( rFontName, RTL_TEXTENCODING_UTF8 ); 1020*cdf0e10cSrcweir const FcChar8* pTargetNameUtf8 = (FcChar8*)aTargetName.getStr(); 1021*cdf0e10cSrcweir rWrapper.FcPatternAddString( pPattern, FC_FAMILY, pTargetNameUtf8 ); 1022*cdf0e10cSrcweir 1023*cdf0e10cSrcweir const FcChar8* pLangAttribUtf8 = (FcChar8*)rLangAttrib.getStr(); 1024*cdf0e10cSrcweir if( rLangAttrib.getLength() ) 1025*cdf0e10cSrcweir rWrapper.FcPatternAddString( pPattern, FC_LANG, pLangAttribUtf8 ); 1026*cdf0e10cSrcweir 1027*cdf0e10cSrcweir // Add required Unicode characters, if any 1028*cdf0e10cSrcweir if ( rMissingCodes.getLength() ) 1029*cdf0e10cSrcweir { 1030*cdf0e10cSrcweir FcCharSet *unicodes = rWrapper.FcCharSetCreate(); 1031*cdf0e10cSrcweir for( sal_Int32 nStrIndex = 0; nStrIndex < rMissingCodes.getLength(); ) 1032*cdf0e10cSrcweir { 1033*cdf0e10cSrcweir // also handle unicode surrogates 1034*cdf0e10cSrcweir const sal_uInt32 nCode = rMissingCodes.iterateCodePoints( &nStrIndex ); 1035*cdf0e10cSrcweir rWrapper.FcCharSetAddChar( unicodes, nCode ); 1036*cdf0e10cSrcweir } 1037*cdf0e10cSrcweir rWrapper.FcPatternAddCharSet( pPattern, FC_CHARSET, unicodes); 1038*cdf0e10cSrcweir rWrapper.FcCharSetDestroy( unicodes ); 1039*cdf0e10cSrcweir } 1040*cdf0e10cSrcweir 1041*cdf0e10cSrcweir addtopattern(rWrapper, pPattern, rItalic, rWeight, rWidth, rPitch); 1042*cdf0e10cSrcweir 1043*cdf0e10cSrcweir // query fontconfig for a substitute 1044*cdf0e10cSrcweir rWrapper.FcConfigSubstitute( rWrapper.FcConfigGetCurrent(), pPattern, FcMatchPattern ); 1045*cdf0e10cSrcweir rWrapper.FcDefaultSubstitute( pPattern ); 1046*cdf0e10cSrcweir 1047*cdf0e10cSrcweir // process the result of the fontconfig query 1048*cdf0e10cSrcweir FcResult eResult = FcResultNoMatch; 1049*cdf0e10cSrcweir FcFontSet* pFontSet = rWrapper.getFontSet(); 1050*cdf0e10cSrcweir FcPattern* pResult = rWrapper.FcFontSetMatch( rWrapper.FcConfigGetCurrent(), &pFontSet, 1, pPattern, &eResult ); 1051*cdf0e10cSrcweir rWrapper.FcPatternDestroy( pPattern ); 1052*cdf0e10cSrcweir 1053*cdf0e10cSrcweir FcFontSet* pSet = NULL; 1054*cdf0e10cSrcweir if( pResult ) 1055*cdf0e10cSrcweir { 1056*cdf0e10cSrcweir pSet = rWrapper.FcFontSetCreate(); 1057*cdf0e10cSrcweir // info: destroying the pSet destroys pResult implicitly 1058*cdf0e10cSrcweir // since pResult was "added" to pSet 1059*cdf0e10cSrcweir rWrapper.FcFontSetAdd( pSet, pResult ); 1060*cdf0e10cSrcweir } 1061*cdf0e10cSrcweir 1062*cdf0e10cSrcweir if( pSet ) 1063*cdf0e10cSrcweir { 1064*cdf0e10cSrcweir if( pSet->nfont > 0 ) 1065*cdf0e10cSrcweir { 1066*cdf0e10cSrcweir //extract the closest match 1067*cdf0e10cSrcweir FcChar8* family = NULL; 1068*cdf0e10cSrcweir FcResult eFileRes = rWrapper.FcPatternGetString( pSet->fonts[0], FC_FAMILY, 0, &family ); 1069*cdf0e10cSrcweir 1070*cdf0e10cSrcweir // get the family name 1071*cdf0e10cSrcweir if( eFileRes == FcResultMatch ) 1072*cdf0e10cSrcweir { 1073*cdf0e10cSrcweir OString sFamily((sal_Char*)family); 1074*cdf0e10cSrcweir std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash >::const_iterator aI = rWrapper.m_aFontNameToLocalized.find(sFamily); 1075*cdf0e10cSrcweir if (aI != rWrapper.m_aFontNameToLocalized.end()) 1076*cdf0e10cSrcweir sFamily = aI->second; 1077*cdf0e10cSrcweir aName = rtl::OStringToOUString( sFamily, RTL_TEXTENCODING_UTF8 ); 1078*cdf0e10cSrcweir 1079*cdf0e10cSrcweir 1080*cdf0e10cSrcweir int val = 0; 1081*cdf0e10cSrcweir if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_WEIGHT, 0, &val)) 1082*cdf0e10cSrcweir rWeight = convertWeight(val); 1083*cdf0e10cSrcweir if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_SLANT, 0, &val)) 1084*cdf0e10cSrcweir rItalic = convertSlant(val); 1085*cdf0e10cSrcweir if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_SPACING, 0, &val)) 1086*cdf0e10cSrcweir rPitch = convertSpacing(val); 1087*cdf0e10cSrcweir if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_WIDTH, 0, &val)) 1088*cdf0e10cSrcweir rWidth = convertWidth(val); 1089*cdf0e10cSrcweir } 1090*cdf0e10cSrcweir 1091*cdf0e10cSrcweir // update rMissingCodes by removing resolved unicodes 1092*cdf0e10cSrcweir if( rMissingCodes.getLength() > 0 ) 1093*cdf0e10cSrcweir { 1094*cdf0e10cSrcweir sal_uInt32* pRemainingCodes = (sal_uInt32*)alloca( rMissingCodes.getLength() * sizeof(sal_uInt32) ); 1095*cdf0e10cSrcweir int nRemainingLen = 0; 1096*cdf0e10cSrcweir FcCharSet* unicodes; 1097*cdf0e10cSrcweir if( !rWrapper.FcPatternGetCharSet( pSet->fonts[0], FC_CHARSET, 0, &unicodes ) ) 1098*cdf0e10cSrcweir { 1099*cdf0e10cSrcweir for( sal_Int32 nStrIndex = 0; nStrIndex < rMissingCodes.getLength(); ) 1100*cdf0e10cSrcweir { 1101*cdf0e10cSrcweir // also handle unicode surrogates 1102*cdf0e10cSrcweir const sal_uInt32 nCode = rMissingCodes.iterateCodePoints( &nStrIndex ); 1103*cdf0e10cSrcweir if( rWrapper.FcCharSetHasChar( unicodes, nCode ) != FcTrue ) 1104*cdf0e10cSrcweir pRemainingCodes[ nRemainingLen++ ] = nCode; 1105*cdf0e10cSrcweir } 1106*cdf0e10cSrcweir } 1107*cdf0e10cSrcweir rMissingCodes = OUString( pRemainingCodes, nRemainingLen ); 1108*cdf0e10cSrcweir } 1109*cdf0e10cSrcweir } 1110*cdf0e10cSrcweir 1111*cdf0e10cSrcweir rWrapper.FcFontSetDestroy( pSet ); 1112*cdf0e10cSrcweir } 1113*cdf0e10cSrcweir 1114*cdf0e10cSrcweir return aName; 1115*cdf0e10cSrcweir } 1116*cdf0e10cSrcweir 1117*cdf0e10cSrcweir bool PrintFontManager::getFontOptions( 1118*cdf0e10cSrcweir const FastPrintFontInfo& rInfo, int nSize, void (*subcallback)(void*), 1119*cdf0e10cSrcweir ImplFontOptions& rOptions) const 1120*cdf0e10cSrcweir { 1121*cdf0e10cSrcweir #ifndef ENABLE_FONTCONFIG 1122*cdf0e10cSrcweir (void)rInfo;(void)nSize;(void)subcallback;(void)rOptions; 1123*cdf0e10cSrcweir return false; 1124*cdf0e10cSrcweir #else // ENABLE_FONTCONFIG 1125*cdf0e10cSrcweir FontCfgWrapper& rWrapper = FontCfgWrapper::get(); 1126*cdf0e10cSrcweir if( ! rWrapper.isValid() ) 1127*cdf0e10cSrcweir return false; 1128*cdf0e10cSrcweir 1129*cdf0e10cSrcweir FcConfig* pConfig = rWrapper.FcConfigGetCurrent(); 1130*cdf0e10cSrcweir FcPattern* pPattern = rWrapper.FcPatternCreate(); 1131*cdf0e10cSrcweir 1132*cdf0e10cSrcweir OString sFamily = OUStringToOString( rInfo.m_aFamilyName, RTL_TEXTENCODING_UTF8 ); 1133*cdf0e10cSrcweir 1134*cdf0e10cSrcweir std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash >::const_iterator aI = rWrapper.m_aLocalizedToCanonical.find(sFamily); 1135*cdf0e10cSrcweir if (aI != rWrapper.m_aLocalizedToCanonical.end()) 1136*cdf0e10cSrcweir sFamily = aI->second; 1137*cdf0e10cSrcweir if( sFamily.getLength() ) 1138*cdf0e10cSrcweir rWrapper.FcPatternAddString( pPattern, FC_FAMILY, (FcChar8*)sFamily.getStr() ); 1139*cdf0e10cSrcweir 1140*cdf0e10cSrcweir addtopattern(rWrapper, pPattern, rInfo.m_eItalic, rInfo.m_eWeight, rInfo.m_eWidth, rInfo.m_ePitch); 1141*cdf0e10cSrcweir rWrapper.FcPatternAddDouble( pPattern, FC_PIXEL_SIZE, nSize); 1142*cdf0e10cSrcweir 1143*cdf0e10cSrcweir FcBool embitmap = true, antialias = true, autohint = true, hinting = true; 1144*cdf0e10cSrcweir int hintstyle = FC_HINT_FULL; 1145*cdf0e10cSrcweir 1146*cdf0e10cSrcweir rWrapper.FcConfigSubstitute( pConfig, pPattern, FcMatchPattern ); 1147*cdf0e10cSrcweir if (subcallback) subcallback(pPattern); 1148*cdf0e10cSrcweir rWrapper.FcDefaultSubstitute( pPattern ); 1149*cdf0e10cSrcweir 1150*cdf0e10cSrcweir FcResult eResult = FcResultNoMatch; 1151*cdf0e10cSrcweir FcFontSet* pFontSet = rWrapper.getFontSet(); 1152*cdf0e10cSrcweir FcPattern* pResult = rWrapper.FcFontSetMatch( pConfig, &pFontSet, 1, pPattern, &eResult ); 1153*cdf0e10cSrcweir if( pResult ) 1154*cdf0e10cSrcweir { 1155*cdf0e10cSrcweir FcFontSet* pSet = rWrapper.FcFontSetCreate(); 1156*cdf0e10cSrcweir rWrapper.FcFontSetAdd( pSet, pResult ); 1157*cdf0e10cSrcweir if( pSet->nfont > 0 ) 1158*cdf0e10cSrcweir { 1159*cdf0e10cSrcweir FcResult eEmbeddedBitmap = rWrapper.FcPatternGetBool(pSet->fonts[0], 1160*cdf0e10cSrcweir FC_EMBEDDED_BITMAP, 0, &embitmap); 1161*cdf0e10cSrcweir FcResult eAntialias = rWrapper.FcPatternGetBool(pSet->fonts[0], 1162*cdf0e10cSrcweir FC_ANTIALIAS, 0, &antialias); 1163*cdf0e10cSrcweir FcResult eAutoHint = rWrapper.FcPatternGetBool(pSet->fonts[0], 1164*cdf0e10cSrcweir FC_AUTOHINT, 0, &autohint); 1165*cdf0e10cSrcweir FcResult eHinting = rWrapper.FcPatternGetBool(pSet->fonts[0], 1166*cdf0e10cSrcweir FC_HINTING, 0, &hinting); 1167*cdf0e10cSrcweir /*FcResult eHintStyle =*/ rWrapper.FcPatternGetInteger( pSet->fonts[0], 1168*cdf0e10cSrcweir FC_HINT_STYLE, 0, &hintstyle); 1169*cdf0e10cSrcweir 1170*cdf0e10cSrcweir if( eEmbeddedBitmap == FcResultMatch ) 1171*cdf0e10cSrcweir rOptions.meEmbeddedBitmap = embitmap ? EMBEDDEDBITMAP_TRUE : EMBEDDEDBITMAP_FALSE; 1172*cdf0e10cSrcweir if( eAntialias == FcResultMatch ) 1173*cdf0e10cSrcweir rOptions.meAntiAlias = antialias ? ANTIALIAS_TRUE : ANTIALIAS_FALSE; 1174*cdf0e10cSrcweir if( eAutoHint == FcResultMatch ) 1175*cdf0e10cSrcweir rOptions.meAutoHint = autohint ? AUTOHINT_TRUE : AUTOHINT_FALSE; 1176*cdf0e10cSrcweir if( eHinting == FcResultMatch ) 1177*cdf0e10cSrcweir rOptions.meHinting = hinting ? HINTING_TRUE : HINTING_FALSE; 1178*cdf0e10cSrcweir switch (hintstyle) 1179*cdf0e10cSrcweir { 1180*cdf0e10cSrcweir case FC_HINT_NONE: rOptions.meHintStyle = HINT_NONE; break; 1181*cdf0e10cSrcweir case FC_HINT_SLIGHT: rOptions.meHintStyle = HINT_SLIGHT; break; 1182*cdf0e10cSrcweir case FC_HINT_MEDIUM: rOptions.meHintStyle = HINT_MEDIUM; break; 1183*cdf0e10cSrcweir default: // fall through 1184*cdf0e10cSrcweir case FC_HINT_FULL: rOptions.meHintStyle = HINT_FULL; break; 1185*cdf0e10cSrcweir } 1186*cdf0e10cSrcweir } 1187*cdf0e10cSrcweir // info: destroying the pSet destroys pResult implicitly 1188*cdf0e10cSrcweir // since pResult was "added" to pSet 1189*cdf0e10cSrcweir rWrapper.FcFontSetDestroy( pSet ); 1190*cdf0e10cSrcweir } 1191*cdf0e10cSrcweir 1192*cdf0e10cSrcweir // cleanup 1193*cdf0e10cSrcweir rWrapper.FcPatternDestroy( pPattern ); 1194*cdf0e10cSrcweir 1195*cdf0e10cSrcweir // TODO: return true only if non-default font options are set 1196*cdf0e10cSrcweir const bool bOK = (pResult != NULL); 1197*cdf0e10cSrcweir return bOK; 1198*cdf0e10cSrcweir #endif 1199*cdf0e10cSrcweir } 1200*cdf0e10cSrcweir 1201*cdf0e10cSrcweir bool PrintFontManager::matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale ) 1202*cdf0e10cSrcweir { 1203*cdf0e10cSrcweir FontCfgWrapper& rWrapper = FontCfgWrapper::get(); 1204*cdf0e10cSrcweir if( ! rWrapper.isValid() ) 1205*cdf0e10cSrcweir return false; 1206*cdf0e10cSrcweir 1207*cdf0e10cSrcweir FcConfig* pConfig = rWrapper.FcConfigGetCurrent(); 1208*cdf0e10cSrcweir FcPattern* pPattern = rWrapper.FcPatternCreate(); 1209*cdf0e10cSrcweir 1210*cdf0e10cSrcweir OString aLangAttrib; 1211*cdf0e10cSrcweir // populate pattern with font characteristics 1212*cdf0e10cSrcweir if( rLocale.Language.getLength() ) 1213*cdf0e10cSrcweir { 1214*cdf0e10cSrcweir OUStringBuffer aLang(6); 1215*cdf0e10cSrcweir aLang.append( rLocale.Language ); 1216*cdf0e10cSrcweir if( rLocale.Country.getLength() ) 1217*cdf0e10cSrcweir { 1218*cdf0e10cSrcweir aLang.append( sal_Unicode('-') ); 1219*cdf0e10cSrcweir aLang.append( rLocale.Country ); 1220*cdf0e10cSrcweir } 1221*cdf0e10cSrcweir aLangAttrib = OUStringToOString( aLang.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ); 1222*cdf0e10cSrcweir } 1223*cdf0e10cSrcweir if( aLangAttrib.getLength() ) 1224*cdf0e10cSrcweir rWrapper.FcPatternAddString( pPattern, FC_LANG, (FcChar8*)aLangAttrib.getStr() ); 1225*cdf0e10cSrcweir 1226*cdf0e10cSrcweir OString aFamily = OUStringToOString( rInfo.m_aFamilyName, RTL_TEXTENCODING_UTF8 ); 1227*cdf0e10cSrcweir if( aFamily.getLength() ) 1228*cdf0e10cSrcweir rWrapper.FcPatternAddString( pPattern, FC_FAMILY, (FcChar8*)aFamily.getStr() ); 1229*cdf0e10cSrcweir 1230*cdf0e10cSrcweir addtopattern(rWrapper, pPattern, rInfo.m_eItalic, rInfo.m_eWeight, rInfo.m_eWidth, rInfo.m_ePitch); 1231*cdf0e10cSrcweir 1232*cdf0e10cSrcweir rWrapper.FcConfigSubstitute( pConfig, pPattern, FcMatchPattern ); 1233*cdf0e10cSrcweir rWrapper.FcDefaultSubstitute( pPattern ); 1234*cdf0e10cSrcweir FcResult eResult = FcResultNoMatch; 1235*cdf0e10cSrcweir FcFontSet *pFontSet = rWrapper.getFontSet(); 1236*cdf0e10cSrcweir FcPattern* pResult = rWrapper.FcFontSetMatch( pConfig, &pFontSet, 1, pPattern, &eResult ); 1237*cdf0e10cSrcweir bool bSuccess = false; 1238*cdf0e10cSrcweir if( pResult ) 1239*cdf0e10cSrcweir { 1240*cdf0e10cSrcweir FcFontSet* pSet = rWrapper.FcFontSetCreate(); 1241*cdf0e10cSrcweir rWrapper.FcFontSetAdd( pSet, pResult ); 1242*cdf0e10cSrcweir if( pSet->nfont > 0 ) 1243*cdf0e10cSrcweir { 1244*cdf0e10cSrcweir //extract the closest match 1245*cdf0e10cSrcweir FcChar8* file = NULL; 1246*cdf0e10cSrcweir FcResult eFileRes = rWrapper.FcPatternGetString( pSet->fonts[0], FC_FILE, 0, &file ); 1247*cdf0e10cSrcweir if( eFileRes == FcResultMatch ) 1248*cdf0e10cSrcweir { 1249*cdf0e10cSrcweir OString aDir, aBase, aOrgPath( (sal_Char*)file ); 1250*cdf0e10cSrcweir splitPath( aOrgPath, aDir, aBase ); 1251*cdf0e10cSrcweir int nDirID = getDirectoryAtom( aDir, true ); 1252*cdf0e10cSrcweir fontID aFont = findFontFileID( nDirID, aBase ); 1253*cdf0e10cSrcweir if( aFont > 0 ) 1254*cdf0e10cSrcweir bSuccess = getFontFastInfo( aFont, rInfo ); 1255*cdf0e10cSrcweir } 1256*cdf0e10cSrcweir } 1257*cdf0e10cSrcweir // info: destroying the pSet destroys pResult implicitly 1258*cdf0e10cSrcweir // since pResult was "added" to pSet 1259*cdf0e10cSrcweir rWrapper.FcFontSetDestroy( pSet ); 1260*cdf0e10cSrcweir } 1261*cdf0e10cSrcweir 1262*cdf0e10cSrcweir // cleanup 1263*cdf0e10cSrcweir rWrapper.FcPatternDestroy( pPattern ); 1264*cdf0e10cSrcweir 1265*cdf0e10cSrcweir return bSuccess; 1266*cdf0e10cSrcweir } 1267*cdf0e10cSrcweir 1268*cdf0e10cSrcweir #else // ENABLE_FONTCONFIG not defined 1269*cdf0e10cSrcweir 1270*cdf0e10cSrcweir bool PrintFontManager::initFontconfig() 1271*cdf0e10cSrcweir { 1272*cdf0e10cSrcweir return false; 1273*cdf0e10cSrcweir } 1274*cdf0e10cSrcweir 1275*cdf0e10cSrcweir int PrintFontManager::countFontconfigFonts( std::hash_map<rtl::OString, int, rtl::OStringHash>& ) 1276*cdf0e10cSrcweir { 1277*cdf0e10cSrcweir return 0; 1278*cdf0e10cSrcweir } 1279*cdf0e10cSrcweir 1280*cdf0e10cSrcweir void PrintFontManager::deinitFontconfig() 1281*cdf0e10cSrcweir {} 1282*cdf0e10cSrcweir 1283*cdf0e10cSrcweir bool PrintFontManager::addFontconfigDir( const rtl::OString& ) 1284*cdf0e10cSrcweir { 1285*cdf0e10cSrcweir return false; 1286*cdf0e10cSrcweir } 1287*cdf0e10cSrcweir 1288*cdf0e10cSrcweir bool PrintFontManager::matchFont( FastPrintFontInfo&, const com::sun::star::lang::Locale& ) 1289*cdf0e10cSrcweir { 1290*cdf0e10cSrcweir return false; 1291*cdf0e10cSrcweir } 1292*cdf0e10cSrcweir 1293*cdf0e10cSrcweir int PrintFontManager::FreeTypeCharIndex( void*, sal_uInt32 ) 1294*cdf0e10cSrcweir { 1295*cdf0e10cSrcweir return 0; 1296*cdf0e10cSrcweir } 1297*cdf0e10cSrcweir 1298*cdf0e10cSrcweir rtl::OUString PrintFontManager::Substitute( const rtl::OUString&, 1299*cdf0e10cSrcweir rtl::OUString&, const rtl::OString&, italic::type, weight::type, width::type, pitch::type) const 1300*cdf0e10cSrcweir { 1301*cdf0e10cSrcweir rtl::OUString aName; 1302*cdf0e10cSrcweir return aName; 1303*cdf0e10cSrcweir } 1304*cdf0e10cSrcweir 1305*cdf0e10cSrcweir #endif // ENABLE_FONTCONFIG 1306*cdf0e10cSrcweir 1307