34 for(
int i = 0;
i < rFontName.getLength();
i++)
38 if ( ((ch >= 0x3040) && (ch <= 0x30FF)) ||
39 ((ch >= 0x3190) && (ch <= 0x319F)) )
40 return ImplFontAttrs::CJK|ImplFontAttrs::CJK_JP;
43 if ( ((ch >= 0xAC00) && (ch <= 0xD7AF)) ||
44 ((ch >= 0xA960) && (ch <= 0xA97F)) ||
45 ((ch >= 0xD7B0) && (ch <= 0xD7FF)) ||
46 ((ch >= 0x3130) && (ch <= 0x318F)) ||
47 ((ch >= 0x1100) && (ch <= 0x11FF)) )
48 return ImplFontAttrs::CJK|ImplFontAttrs::CJK_KR;
51 if ( (ch >= 0x3400) && (ch <= 0x9FFF) )
52 return ImplFontAttrs::CJK|ImplFontAttrs::CJK_TC|ImplFontAttrs::CJK_SC;
55 if ( ((ch >= 0x3000) && (ch <= 0xD7AF)) ||
56 ((ch >= 0xFF00) && (ch <= 0xFFEE)) )
57 return ImplFontAttrs::CJK;
61 return ImplFontAttrs::None;
65 : mbMatchData( false )
66 , mpPreMatchHook( nullptr )
67 , mpFallbackHook( nullptr )
68 , mnFallbackCount( -1 )
104 static const char* aGlyphFallbackList[] = {
107 "arialunicodems",
"cyberbit",
"code2000",
"",
109 "starsymbol",
"opensymbol",
"",
110 "msmincho",
"fzmingti",
"fzheiti",
"ipamincho",
"sazanamimincho",
"kochimincho",
"",
111 "sunbatang",
"sundotum",
"baekmukdotum",
"gulim",
"batang",
"dotum",
"",
112 "hgmincholightj",
"msunglightsc",
"msunglighttc",
"hymyeongjolightk",
"",
113 "tahoma",
"dejavusans",
"timesnewroman",
"liberationsans",
"",
114 "shree",
"mangal",
"",
115 "raavi",
"shruti",
"tunga",
"",
116 "latha",
"gautami",
"kartika",
"vrinda",
"",
117 "shayyalmt",
"naskmt",
"scheherazade",
"",
118 "david",
"nachlieli",
"lucidagrande",
"",
119 "norasi",
"angsanaupc",
"",
123 "padauk",
"pinlonmyanmar",
"",
124 "iskoolapota",
"lklug",
"",
128 bool bHasEudc =
false;
130 int nBestQuality = 0;
131 std::unique_ptr<std::array<PhysicalFontFamily*,MAX_GLYPHFALLBACK>> pFallbackList;
133 for(
const char** ppNames = &aGlyphFallbackList[0];; ++ppNames )
138 if( nBestQuality > 0 )
150 OUString aTokenName( *ppNames, strlen(*ppNames), RTL_TEXTENCODING_UTF8 );
157 if( nBestQuality < pFallbackFont->GetMinQuality() )
162 pFallbackList.reset(
new std::array<PhysicalFontFamily*,MAX_GLYPHFALLBACK>);
164 (*pFallbackList)[ nMaxLevel ] = pFallbackFont;
165 if( !bHasEudc && !nMaxLevel )
166 bHasEudc = !strncmp( *ppNames,
"eudc", 5 );
176 OUString& rMissingCodes,
177 int nFallbackLevel )
const
188 sal_Int32 nStrIndex = 0;
189 while( nStrIndex < rMissingCodes.getLength() )
191 cChar = rMissingCodes.iterateCodePoints( &nStrIndex );
203 int nRemainingLength = 0;
204 std::unique_ptr<sal_UCS4[]>
const pRemainingCodes(
new sal_UCS4[rMissingCodes.getLength()]);
207 while( nStrIndex < rMissingCodes.getLength() )
209 cChar = rMissingCodes.iterateCodePoints( &nStrIndex );
211 if( !bCached || (rFontSelData.
maSearchName != aFontName) )
212 pRemainingCodes[ nRemainingLength++ ] = cChar;
214 rMissingCodes = OUString( pRemainingCodes.get(), nRemainingLength );
218 OUString aOldMissingCodes = rMissingCodes;
234 if (!bSubSetOfFontRequiresPropertyFaking)
240 if( nStrIndex >= aOldMissingCodes.getLength() )
242 cChar = aOldMissingCodes.iterateCodePoints( &nStrIndex );
247 for( nStrIndex = 0; nStrIndex < rMissingCodes.getLength(); )
249 cChar = rMissingCodes.iterateCodePoints( &nStrIndex );
270 pFallbackData = (*mpFallbackList)[ nFallbackLevel ];
273 return pFallbackData;
282 pFoundData->AddFontFace( pNewData );
310 pFoundData = (*it).second.get();
326 for( sal_Int32 nTokenPos = 0; nTokenPos != -1; )
329 if( aFamilyName.isEmpty() )
355 if( nSearchType != ImplFontAttrs::None )
362 eSearchWeight, eSearchWidth, eSearchSlant,
"" );
382 const utl::FontSubstConfiguration& rFontSubst = utl::FontSubstConfiguration::get();
386 const OUString& rSearchName = family.first;
397 const OUString& rSearchFamilyName )
const
400 nSearchType |= ImplFontAttrs::Italic;
403 if( nSearchType == ImplFontAttrs::None
439 if ( nSearchType & ImplFontAttrs::CJK )
442 if( ImplFontAttrs::None == ((nSearchType ^ nMatchType) & ImplFontAttrs::CJK_AllLang) )
443 nTestMatch += 10000000*3;
444 if( nMatchType & ImplFontAttrs::CJK )
445 nTestMatch += 10000000*2;
446 if( nMatchType & ImplFontAttrs::Full )
447 nTestMatch += 10000000;
449 else if ( nMatchType & ImplFontAttrs::CJK )
451 nTestMatch -= 10000000;
455 if( nSearchType & ImplFontAttrs::CTL )
457 if( nMatchType & ImplFontAttrs::CTL )
458 nTestMatch += 10000000*2;
459 if( nMatchType & ImplFontAttrs::Full )
460 nTestMatch += 10000000;
462 else if ( nMatchType & ImplFontAttrs::CTL )
464 nTestMatch -= 10000000;
468 if( nSearchType & ImplFontAttrs::NoneLatin )
470 if( nMatchType & ImplFontAttrs::NoneLatin )
471 nTestMatch += 10000000*2;
472 if( nMatchType & ImplFontAttrs::Full )
473 nTestMatch += 10000000;
477 if ( nSearchType & ImplFontAttrs::Symbol )
479 const OUString& rSearchName = family.first;
481 if ( rSearchName ==
"starsymbol" )
483 nTestMatch += 10000000*6+(10000*3);
485 else if ( rSearchName ==
"opensymbol" )
487 nTestMatch += 10000000*6;
489 else if ( rSearchName ==
"starbats" ||
490 rSearchName ==
"wingdings" ||
491 rSearchName ==
"monotypesorts" ||
492 rSearchName ==
"dingbats" ||
493 rSearchName ==
"zapfdingbats" )
495 nTestMatch += 10000000*5;
499 nTestMatch += 10000000*4;
503 if( nMatchType & ImplFontAttrs::Symbol )
504 nTestMatch += 10000000*2;
505 if( nMatchType & ImplFontAttrs::Full )
506 nTestMatch += 10000000;
511 nTestMatch -= 10000000;
513 else if ( nMatchType & ImplFontAttrs::Symbol )
519 if( !rSearchFamilyName.isEmpty() && (rSearchFamilyName == pData->
GetMatchFamilyName()) )
521 nTestMatch += 1000000*3;
525 if( nSearchType & ImplFontAttrs::AllScript )
527 if( nMatchType & ImplFontAttrs::AllScript )
529 nTestMatch += 1000000*2;
531 if( nSearchType & ImplFontAttrs::AllSubscript )
533 if( ImplFontAttrs::None == ((nSearchType ^ nMatchType) & ImplFontAttrs::AllSubscript) )
534 nTestMatch += 1000000*2;
535 if( ImplFontAttrs::None != ((nSearchType ^ nMatchType) & ImplFontAttrs::BrushScript) )
536 nTestMatch -= 1000000;
539 else if( nMatchType & ImplFontAttrs::AllScript )
541 nTestMatch -= 1000000;
545 if( nSearchType & ImplFontAttrs::Fixed )
547 if( nMatchType & ImplFontAttrs::Fixed )
548 nTestMatch += 1000000*2;
550 if( ImplFontAttrs::None == ((nSearchType ^ nMatchType) & ImplFontAttrs::Typewriter) )
551 nTestMatch += 10000*2;
553 else if( nMatchType & ImplFontAttrs::Fixed )
555 nTestMatch -= 1000000;
559 if( nSearchType & ImplFontAttrs::Special )
561 if( nMatchType & ImplFontAttrs::Special )
565 else if( !(nSearchType & ImplFontAttrs::AllSerifStyle) )
567 if( nMatchType & ImplFontAttrs::Serif )
569 nTestMatch += 1000*2;
571 else if( nMatchType & ImplFontAttrs::SansSerif )
577 else if( (nMatchType & ImplFontAttrs::Special) && !(nSearchType & ImplFontAttrs::Symbol) )
579 nTestMatch -= 1000000;
583 if( nSearchType & ImplFontAttrs::Decorative )
585 if( nMatchType & ImplFontAttrs::Decorative )
589 else if( !(nSearchType & ImplFontAttrs::AllSerifStyle) )
591 if( nMatchType & ImplFontAttrs::Serif )
592 nTestMatch += 1000*2;
593 else if ( nMatchType & ImplFontAttrs::SansSerif )
597 else if( nMatchType & ImplFontAttrs::Decorative )
599 nTestMatch -= 1000000;
603 if( nSearchType & (ImplFontAttrs::Titling | ImplFontAttrs::Capitals) )
605 if( nMatchType & (ImplFontAttrs::Titling | ImplFontAttrs::Capitals) )
607 nTestMatch += 1000000*2;
609 if( ImplFontAttrs::None == ((nSearchType^nMatchType) &
ImplFontAttrs(ImplFontAttrs::Titling | ImplFontAttrs::Capitals)))
611 nTestMatch += 1000000;
613 else if( (nMatchType & (ImplFontAttrs::Titling | ImplFontAttrs::Capitals)) &&
614 (nMatchType & (ImplFontAttrs::Standard | ImplFontAttrs::Default)) )
616 nTestMatch += 1000000;
619 else if( nMatchType & (ImplFontAttrs::Titling | ImplFontAttrs::Capitals) )
621 nTestMatch -= 1000000;
625 if( nSearchType & (ImplFontAttrs::Outline | ImplFontAttrs::Shadow) )
627 if( nMatchType & (ImplFontAttrs::Outline | ImplFontAttrs::Shadow) )
629 nTestMatch += 1000000*2;
631 if( ImplFontAttrs::None == ((nSearchType ^ nMatchType) &
ImplFontAttrs(ImplFontAttrs::Outline | ImplFontAttrs::Shadow)) )
633 nTestMatch += 1000000;
635 else if( (nMatchType & (ImplFontAttrs::Outline | ImplFontAttrs::Shadow)) &&
636 (nMatchType & (ImplFontAttrs::Standard | ImplFontAttrs::Default)) )
638 nTestMatch += 1000000;
641 else if ( nMatchType & (ImplFontAttrs::Outline | ImplFontAttrs::Shadow) )
643 nTestMatch -= 1000000;
648 if( (rSearchFamilyName.getLength() >= 4) &&
656 if( nSearchType & ImplFontAttrs::Serif )
658 if( nMatchType & ImplFontAttrs::Serif )
659 nTestMatch += 1000000*2;
660 else if( nMatchType & ImplFontAttrs::SansSerif )
661 nTestMatch -= 1000000;
665 if( nSearchType & ImplFontAttrs::SansSerif )
667 if( nMatchType & ImplFontAttrs::SansSerif )
668 nTestMatch += 1000000;
669 else if ( nMatchType & ImplFontAttrs::Serif )
670 nTestMatch -= 1000000;
674 if( nSearchType & ImplFontAttrs::Italic )
677 nTestMatch += 1000000*3;
678 if( nMatchType & ImplFontAttrs::Italic )
679 nTestMatch += 1000000;
681 else if( !(nSearchType & ImplFontAttrs::AllScript) &&
682 ((nMatchType & ImplFontAttrs::Italic) ||
685 nTestMatch -= 1000000*2;
693 if( eSearchWidth == eMatchWidth )
694 nTestMatch += 1000000*3;
696 nTestMatch += 1000000;
700 if( eSearchWidth == eMatchWidth )
701 nTestMatch += 1000000*3;
703 nTestMatch += 1000000;
708 nTestMatch -= 1000000;
719 nTestMatch += 1000000;
721 nTestMatch += 1000000;
726 nTestMatch += 1000000;
728 nTestMatch += 1000000;
736 nTestMatch -= 1000000;
741 nTestMatch += 10000*4;
743 nTestMatch -= 10000*4;
746 if( nMatchType & ImplFontAttrs::Standard )
747 nTestMatch += 10000*2;
748 if( nMatchType & ImplFontAttrs::Default )
750 if( nMatchType & ImplFontAttrs::Full )
752 if( nMatchType & ImplFontAttrs::Normal )
756 if( ((nSearchType ^ nMatchType) & ImplFontAttrs::OtherStyle) != ImplFontAttrs::None )
762 if( ImplFontAttrs::None == ((nSearchType ^ nMatchType) & ImplFontAttrs::Rounded) )
766 if( ImplFontAttrs::None == ((nSearchType ^ nMatchType) & ImplFontAttrs::Typewriter) )
770 if( nSearchType & ImplFontAttrs::Gothic )
772 if( nMatchType & ImplFontAttrs::Gothic )
773 nTestMatch += 1000*3;
774 if( nMatchType & ImplFontAttrs::SansSerif )
775 nTestMatch += 1000*2;
779 if( nSearchType & ImplFontAttrs::Schoolbook )
781 if( nMatchType & ImplFontAttrs::Schoolbook )
782 nTestMatch += 1000*3;
783 if( nMatchType & ImplFontAttrs::Serif )
784 nTestMatch += 1000*2;
788 if ( nTestMatch > nBestMatch )
791 nBestMatch = nTestMatch;
792 nBestType = nMatchType;
794 else if( nTestMatch == nBestMatch )
797 if( nMatchType & ImplFontAttrs::Default )
800 nBestType = nMatchType;
802 else if( (nMatchType & ImplFontAttrs::Standard) &&
803 !(nBestType & ImplFontAttrs::Default) )
806 nBestType = nMatchType;
823 OUString aFontname = rDefaults.
getDefaultFont( aLanguageTag, DefaultFontType::SANS_UNICODE );
829 aFontname = rDefaults.
getDefaultFont( aLanguageTag, DefaultFontType::SANS );
834 aFontname = rDefaults.
getDefaultFont( aLanguageTag, DefaultFontType::SERIF );
839 aFontname = rDefaults.
getDefaultFont( aLanguageTag, DefaultFontType::FIXED );
856 if( pData->
GetMatchType() & (ImplFontAttrs::Default|ImplFontAttrs::Standard) )
863 auto it = maPhysicalFontFamilies.begin();
864 if( it != maPhysicalFontFamilies.end() )
865 pFoundData = (*it).second.get();
872 auto xClonedCollection = std::make_shared<PhysicalFontCollection>();
877 xClonedCollection->mbMatchData =
false;
885 return xClonedCollection;
898 return pDeviceFontList;
906 if( pFontFamily !=
nullptr )
911 for(
const auto& rHeight : rHeights )
912 pDeviceFontSizeList->Add( rHeight );
915 return pDeviceFontSizeList;
923 {
"Times New Roman",
"Liberation Serif" },
924 {
"Arial",
"Liberation Sans" },
925 {
"Arial Narrow",
"Liberation Sans Narrow" },
926 {
"Courier New",
"Liberation Mono" },
927 {
"Cambria",
"Caladea" },
928 {
"Calibri",
"Carlito" },
951 if (getenv(
"SAL_NO_FONT_LOOKUP") !=
nullptr)
962 bool bMultiToken =
false;
963 sal_Int32 nTokenPos = 0;
974 OUString aBaseFontName = aSearchName.copy( 0, (nFeat != -1) ? nFeat : aSearchName.getLength() );
978 aSearchName = aBaseFontName;
987 aSearchName.startsWithIgnoreAsciiCase(
"hg" ) )
990 if( aSearchName.startsWithIgnoreAsciiCase(
"hggothicb" ) )
991 aBoldName =
"hggothice";
992 else if( aSearchName.startsWithIgnoreAsciiCase(
"hgpgothicb" ) )
993 aBoldName =
"hgpgothice";
994 else if( aSearchName.startsWithIgnoreAsciiCase(
"hgminchol" ) )
995 aBoldName =
"hgminchob";
996 else if( aSearchName.startsWithIgnoreAsciiCase(
"hgpminchol" ) )
997 aBoldName =
"hgpminchob";
998 else if( aSearchName.equalsIgnoreAsciiCase(
"hgminchob" ) )
999 aBoldName =
"hgminchoe";
1000 else if( aSearchName.equalsIgnoreAsciiCase(
"hgpminchob" ) )
1001 aBoldName =
"hgpminchoe";
1006 aSearchName = aBoldName;
1056 if( nTokenPos == -1)
1066 for( nTokenPos = 0; nTokenPos != -1; )
1095 OUString aSearchShortName;
1096 OUString aSearchFamilyName;
1100 utl::FontSubstConfiguration::getMapName( aSearchName, aSearchShortName, aSearchFamilyName,
1101 eSearchWeight, eSearchWidth, nSearchType );
1105 if ( aSearchShortName != aSearchName )
1115 if ((aSearchName !=
"msmincho") && (aSearchName !=
"msgothic"))
1130 const utl::FontSubstConfiguration& rFontSubst = utl::FontSubstConfiguration::get();
1131 pFontAttr = rFontSubst.getSubstInfo( aSearchName );
1132 if ( !pFontAttr && (aSearchShortName != aSearchName) )
1133 pFontAttr = rFontSubst.getSubstInfo( aSearchShortName );
1134 if ( !pFontAttr && (aSearchFamilyName != aSearchShortName) )
1135 pFontAttr = rFontSubst.getSubstInfo( aSearchFamilyName );
1151 aSearchName =
"OpenSymbol";
1160 while( nTokenPos != -1 )
1168 OUString aTempShortName;
1169 OUString aTempFamilyName;
1173 utl::FontSubstConfiguration::getMapName( aSearchName, aTempShortName, aTempFamilyName,
1174 eTempWeight, eTempWidth, nTempType );
1177 if( aTempShortName != aSearchName )
1190 const utl::FontSubstConfiguration& rFontSubst = utl::FontSubstConfiguration::get();
1191 pTempFontAttr = rFontSubst.getSubstInfo( aSearchName );
1193 if ( !pTempFontAttr && (aTempShortName != aSearchName) )
1194 pTempFontAttr = rFontSubst.getSubstInfo( aTempShortName );
1196 if ( !pTempFontAttr && (aTempFamilyName != aTempShortName) )
1197 pTempFontAttr = rFontSubst.getSubstInfo( aTempFamilyName );
1207 pFontAttr = pTempFontAttr;
1213 nSearchType |= ImplFontAttrs::CJK | ImplFontAttrs::CJK_SC;
1215 nSearchType |= ImplFontAttrs::CJK | ImplFontAttrs::CJK_TC;
1217 nSearchType |= ImplFontAttrs::CJK | ImplFontAttrs::CJK_KR;
1219 nSearchType |= ImplFontAttrs::CJK | ImplFontAttrs::CJK_JP;
1224 nSearchType |= ImplFontAttrs::Symbol;
1229 eSearchWeight, eSearchWidth, rFSD.
GetItalic(), aSearchFamilyName );
1248 if( (nSearchType & ImplFontAttrs::Italic) &&
void Add(PhysicalFontFace *)
PhysicalFontFamily * FindOrCreateFontFamily(const OUString &rFamilyName)
std::unique_ptr< ImplDeviceFontSizeList > GetDeviceFontSizeList(const OUString &rFontName) const
std::unique_ptr< ContentProperties > pData
FontWeight GetMatchWeight() const
PhysicalFontFamily * ImplFindFontFamilyOfDefaultFont() const
void UpdateDevFontList(ImplDeviceFontList &) const
ImplPreMatchFontSubstitution * mpPreMatchHook
PhysicalFontFamily * FindFontFamilyByAttributes(ImplFontAttrs nSearchType, FontWeight, FontWidth, FontItalic, const OUString &rSearchFamily) const
PhysicalFontFamily * GetGlyphFallbackFont(FontSelectPattern &, LogicalFontInstance *pLogicalFont, OUString &rMissingCodes, int nFallbackLevel) const
void ImplInitMatchData() const
bool GetFallbackForUnicode(sal_UCS4, FontWeight eWeight, OUString *pFontName) const
PhysicalFontFamily * FindFontFamilyByTokenNames(const OUString &rTokenStr) const
ImplFontAttrs GetMatchType() const
void InitMatchData(const utl::FontSubstConfiguration &, const OUString &rSearchName)
FontTypeFaces GetTypeFaces() const
void SetFallbackHook(ImplGlyphFallbackFontSubstitution *)
void ImplInitGenericGlyphFallback() const
PhysicalFontFamily * ImplFindFontFamilyBySearchName(const OUString &) const
void SetPreMatchHook(ImplPreMatchFontSubstitution *)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
OUString GetEnglishSearchFontName(const OUString &rInName)
ItalicMatrix maItalicMatrix
std::unique_ptr< std::array< PhysicalFontFamily *, MAX_GLYPHFALLBACK > > mpFallbackList
const OUString & GetMatchFamilyName() const
FontItalic GetItalic() const
static bool FindMetricCompatibleFont(FontSelectPattern &rFontSelData)
OUString getDefaultFont(const LanguageTag &rLanguageTag, DefaultFontType nType) const
abstract base class for physical font faces
FontFamily GetFamilyType() const
void SetWeight(const FontWeight eWeight)
static void CalcType(ImplFontAttrs &rType, FontWeight &rWeight, FontWidth &rWidth, FontFamily eFamily, const utl::FontNameAttr *pFontAttr)
FontWeight GetWeight() const
void IgnoreFallbackForUnicode(sal_UCS4, FontWeight eWeight, std::u16string_view rFontName)
int GetMinQuality() const
OUString StripScriptFromName(const OUString &_aName)
void SetItalic(const FontItalic eItalic)
virtual bool FindFontSubstitute(FontSelectPattern &, LogicalFontInstance *pLogicalFont, OUString &rMissingCodes) const =0
static ImplFontAttrs lcl_IsCJKFont(const OUString &rFontName)
std::unique_ptr< ImplDeviceFontList > GetDeviceFontList() const
~PhysicalFontCollection()
static bool isSimplifiedChinese(LanguageType nLang)
ImplGlyphFallbackFontSubstitution * mpFallbackHook
FontWidth GetMatchWidth() const
static DefaultFontConfiguration & get()
PhysicalFontFamily * FindFontFamily(const OUString &rFontName) const
void UpdateCloneFontList(PhysicalFontCollection &) const
void GetFontHeights(o3tl::sorted_vector< int > &rHeights) const
PhysicalFontFamily * ImplFindFontFamilyBySubstFontAttr(const utl::FontNameAttr &) const
virtual bool FindFontSubstitute(FontSelectPattern &) const =0
static const char FEAT_PREFIX
void ImplFontSubstitute(OUString &rFontName)
const std::vector< std::pair< OUString, OUString > > aMetricCompatibleMap
static bool isKorean(LanguageType nLang)
OUString GetNextFontToken(const OUString &rTokenStr, sal_Int32 &rIndex)
FontWidth GetWidthType() const
bool IsSymbolFont() const
PhysicalFontFamilies maPhysicalFontFamilies
#define MAX_GLYPHFALLBACK
const OUString & GetFamilyName() const
#define LANGUAGE_JAPANESE
void AddFallbackForUnicode(sal_UCS4, FontWeight eWeight, const OUString &rFontName)
::std::vector< OUString > Substitutions
std::shared_ptr< PhysicalFontCollection > Clone() const
static bool isTraditionalChinese(LanguageType nLang)