27#include <com/sun/star/uno/Any.hxx>
28#include <com/sun/star/uno/Sequence.hxx>
29#include <com/sun/star/configuration/theDefaultProvider.hpp>
30#include <com/sun/star/container/XNameAccess.hpp>
33#include <rtl/ustrbuf.hxx>
34#include <osl/diagnose.h>
79 OSL_FAIL(
"unmatched type" );
87 return theDefaultFontConfiguration;
101 {
"nodepath",
Any(OUString(
"/org.openoffice.VCL/DefaultFonts" ))}
105 m_xConfigProvider->createInstanceWithArguments(
"com.sun.star.configuration.ConfigurationAccess",
112 for(
const OUString& rLocaleString : aLocales )
115 OUString aLoc(
LanguageTag( rLocaleString,
true).getBcp47(
false));
117 m_aConfig[ aLoc ].aConfigLocaleString = rLocaleString;
145 std::unordered_map< OUString, LocaleAccess >::const_iterator it =
m_aConfig.find( rBcp47 );
148 if( !it->second.xAccess.is() )
157 it->second.xAccess = xNode;
160 catch (
const NoSuchElementException&)
163 catch (
const WrappedTargetException&)
167 if( it->second.xAccess.is() )
171 if ( it->second.xAccess->hasByName( rType ) )
173 Any aAny = it->second.xAccess->getByName( rType );
177 catch (
const NoSuchElementException&)
180 catch (
const WrappedTargetException&)
206 for (
const auto& rFallback : aFallbacks)
229 if( !aUIFont.isEmpty() )
234 static constexpr OUStringLiteral FALLBACKFONT_UI_SANS =
u"Andale Sans UI;Albany;Albany AMT;Tahoma;Arial Unicode MS;Arial;Nimbus Sans L;Bitstream Vera Sans;gnu-unifont;Interface User;Geneva;WarpSans;Dialog;Swiss;Lucida;Helvetica;Charcoal;Chicago;MS Sans Serif;Helv;Times;Times New Roman;Interface System";
235 static constexpr OUStringLiteral FALLBACKFONT_UI_SANS_LATIN2 =
u"Andale Sans UI;Albany;Albany AMT;Tahoma;Arial Unicode MS;Arial;Nimbus Sans L;Luxi Sans;Bitstream Vera Sans;Interface User;Geneva;WarpSans;Dialog;Swiss;Lucida;Helvetica;Charcoal;Chicago;MS Sans Serif;Helv;Times;Times New Roman;Interface System";
236 static constexpr OUStringLiteral FALLBACKFONT_UI_SANS_ARABIC =
u"Tahoma;Traditional Arabic;Simplified Arabic;Lucidasans;Lucida Sans;Supplement;Andale Sans UI;clearlyU;Interface User;Arial Unicode MS;Lucida Sans Unicode;WarpSans;Geneva;MS Sans Serif;Helv;Dialog;Albany;Lucida;Helvetica;Charcoal;Chicago;Arial;Helmet;Interface System;Sans Serif";
237 static constexpr OUStringLiteral FALLBACKFONT_UI_SANS_THAI =
u"OONaksit;Tahoma;Lucidasans;Arial Unicode MS";
238 static constexpr OUStringLiteral FALLBACKFONT_UI_SANS_KOREAN =
u"Noto Sans KR;Noto Sans CJK KR;Noto Serif KR;Noto Serif CJK KR;Source Han Sans KR;NanumGothic;NanumBarunGothic;NanumBarunGothic YetHangul;KoPubWorld Dotum;Malgun Gothic;Apple SD Gothic Neo;Dotum;DotumChe;Gulim;GulimChe;Batang;BatangChe;Apple Gothic;UnDotum;Baekmuk Gulim;Arial Unicode MS;Lucida Sans Unicode;gnu-unifont;Andale Sans UI";
239 static constexpr OUStringLiteral FALLBACKFONT_UI_SANS_JAPANESE =
u"Noto Sans CJK JP;Noto Sans JP;Source Han Sans;Source Han Sans JP;Yu Gothic UI;Yu Gothic;YuGothic;Hiragino Sans;Hiragino Kaku Gothic ProN;Hiragino Kaku Gothic Pro;Hiragino Kaku Gothic StdN;Meiryo UI;Meiryo;IPAexGothic;IPAPGothic;IPAGothic;MS UI Gothic;MS PGothic;MS Gothic;Osaka;Unifont;gnu-unifont;Arial Unicode MS;Interface System";
240 static constexpr OUStringLiteral FALLBACKFONT_UI_SANS_CHINSIM =
u"Andale Sans UI;Arial Unicode MS;ZYSong18030;AR PL SungtiL GB;AR PL KaitiM GB;SimSun;Lucida Sans Unicode;Fangsong;Hei;Song;Kai;Ming;gnu-unifont;Interface User;";
241 static constexpr OUStringLiteral FALLBACKFONT_UI_SANS_CHINTRD =
u"Andale Sans UI;Arial Unicode MS;AR PL Mingti2L Big5;AR PL KaitiM Big5;Kai;PMingLiU;MingLiU;Ming;Lucida Sans Unicode;gnu-unifont;Interface User;";
243 const OUString aLanguage( aLanguageTag.
getLanguage());
246 if( aLanguage ==
"ar" || aLanguage ==
"he" || aLanguage ==
"iw" )
248 return FALLBACKFONT_UI_SANS_ARABIC;
250 else if ( aLanguage ==
"th" )
252 return FALLBACKFONT_UI_SANS_THAI;
254 else if ( aLanguage ==
"ko" )
256 return FALLBACKFONT_UI_SANS_KOREAN;
258 else if ( aLanguage ==
"ja" )
260 return FALLBACKFONT_UI_SANS_JAPANESE;
262 else if( aLanguage ==
"cs" ||
272 return FALLBACKFONT_UI_SANS_LATIN2;
278 return FALLBACKFONT_UI_SANS_CHINTRD;
280 return FALLBACKFONT_UI_SANS_CHINSIM;
283 return FALLBACKFONT_UI_SANS;
292 static FontSubstConfiguration theFontSubstConfiguration;
293 return theFontSubstConfiguration;
300FontSubstConfiguration::FontSubstConfiguration() :
314 {
"nodepath",
Any(OUString(
"/org.openoffice.VCL/FontSubstitutions" ))}
318 m_xConfigProvider->createInstanceWithArguments(
"com.sun.star.configuration.ConfigurationAccess",
325 for(
const OUString& rLocaleString : aLocales )
328 OUString aLoc(
LanguageTag( rLocaleString,
true).getBcp47(
false));
329 m_aSubst[ aLoc ] = LocaleSubst();
330 m_aSubst[ aLoc ].aConfigLocaleString = rLocaleString;
334 catch (
const Exception&)
351FontSubstConfiguration::~FontSubstConfiguration()
438 "ce",
"monospace",
"oldface",
nullptr,
439 "ps",
"caps",
nullptr,
445struct ImplFontAttrWeightSearchData
475struct ImplFontAttrWidthSearchData
500struct ImplFontAttrTypeSearchData
574 for(; *ppStr; ++ppStr )
576 const char* pStr = *ppStr;
578 while ( (*pNameStr ==
static_cast<sal_Unicode>(
static_cast<unsigned char>(*pStr))) && *pStr )
585 sal_Int32 nLen =
static_cast<sal_Int32
>(pNameStr - rName.getStr());
586 rName = rName.copy(nLen);
594 if( (pNameStr[0]==0xBC31) && (pNameStr[1]==0xBC35) )
596 sal_Int32 nLen = (pNameStr[2]==0x0020) ? 3 : 2;
597 rName = rName.copy(nLen);
606 size_t nStrLen = strlen( pStr );
607 if( nStrLen >= rName.size() )
610 const sal_Unicode* pEndName = rName.data() + rName.size();
612 do if( *(pNameStr++) != *(pStr++) )
621 for(; *ppStr; ++ppStr )
626 rName = rName.copy(0, rName.getLength() - nTrailLen );
636 for(; *ppStr; ++ppStr )
646 rName = rName.copy(0, rName.getLength() - nTrailLen );
661 sal_Int32 nLen =
static_cast<sal_Int32
>(strlen(pStr));
662 sal_Int32
nPos = rName.indexOfAsciiL(pStr, nLen );
666 OUStringBuffer sBuff(rName);
667 sBuff.remove(
nPos, nLen);
668 rName = sBuff.makeStringAndClear();
672void FontSubstConfiguration::getMapName(
const OUString& rOrgName, OUString& rShortName,
676 rShortName = rOrgName;
688 rFamilyName = rShortName;
693 while ( pWeightList->mpStr )
697 if ( (rWeight == WEIGHT_DONTKNOW) || (rWeight == WEIGHT_NORMAL) )
698 rWeight = pWeightList->meWeight;
706 while ( pWidthList->mpStr )
710 if ( (rWidth == WIDTH_DONTKNOW) || (rWidth == WIDTH_NORMAL) )
711 rWidth = pWidthList->meWidth;
730 OUStringBuffer sBuff(rFamilyName);
731 while ( i < sBuff.getLength() )
734 if ( (c >= 0x0030) && (c <= 0x0039) )
743struct StrictStringSort
746 {
return rLeft.
Name.compareTo( rRight.
Name ) < 0; }
831void FontSubstConfiguration::fillSubstVector(
const css::uno::Reference< XNameAccess >& rFont,
832 const OUString& rType,
833 std::vector< OUString >& rSubstVector )
const
837 Any aAny = rFont->getByName( rType );
838 if(
auto pLine = o3tl::tryAccess<OUString>(aAny) )
840 sal_Int32
nLength = pLine->getLength();
844 sal_Int32 nTokens = 0;
851 rSubstVector.clear();
853 rSubstVector.reserve( nTokens );
855 while( nIndex != -1 )
857 OUString aSubst( pLine->getToken( 0,
';', nIndex ) );
858 if( !aSubst.isEmpty() )
860 auto itPair = maSubstHash.insert( aSubst );
862 aSubst = *itPair.first;
863 rSubstVector.push_back( aSubst );
869 catch (
const NoSuchElementException&)
872 catch (
const WrappedTargetException&)
877FontWeight FontSubstConfiguration::getSubstWeight(
const css::uno::Reference< XNameAccess >& rFont,
878 const OUString& rType )
const
883 Any aAny = rFont->getByName( rType );
884 if(
auto pLine = o3tl::tryAccess<OUString>(aAny) )
886 if( !pLine->isEmpty() )
888 for( weight=std::size(
pWeightNames)-1; weight >= 0; weight-- )
889 if( pLine->equalsIgnoreAsciiCaseAscii(
pWeightNames[weight].pName ) )
892 SAL_WARN_IF(weight < 0,
"unotools.config",
"Error: invalid weight " << *pLine);
895 catch (
const NoSuchElementException&)
898 catch (
const WrappedTargetException&)
904FontWidth FontSubstConfiguration::getSubstWidth(
const css::uno::Reference< XNameAccess >& rFont,
905 const OUString& rType )
const
910 Any aAny = rFont->getByName( rType );
911 if(
auto pLine = o3tl::tryAccess<OUString>(aAny) )
913 if( !pLine->isEmpty() )
915 for( width=std::size(
pWidthNames)-1; width >= 0; width-- )
916 if( pLine->equalsIgnoreAsciiCaseAscii(
pWidthNames[width].pName ) )
919 SAL_WARN_IF( width < 0,
"unotools.config",
"Error: invalid width " << *pLine);
922 catch (
const NoSuchElementException&)
925 catch (
const WrappedTargetException&)
931ImplFontAttrs FontSubstConfiguration::getSubstType(
const css::uno::Reference< XNameAccess >& rFont,
932 const OUString& rType )
const
937 Any aAny = rFont->getByName( rType );
938 auto pLine = o3tl::tryAccess<OUString>(aAny);
941 if( pLine->isEmpty() )
944 while( nIndex != -1 )
946 OUString aToken( pLine->getToken( 0,
',', nIndex ) );
947 for(
int k = 0; k < 32; k++ )
948 if( aToken.equalsIgnoreAsciiCaseAscii(
pAttribNames[k] ) )
950 type |= sal_uInt32(1) << k;
956 catch (
const NoSuchElementException&)
959 catch (
const WrappedTargetException&)
966void FontSubstConfiguration::readLocaleSubst(
const OUString& rBcp47 )
const
968 std::unordered_map< OUString, LocaleSubst >::const_iterator it = m_aSubst.find( rBcp47 );
969 if( it == m_aSubst.end() )
972 if( it->second.bConfigRead )
975 it->second.bConfigRead =
true;
982 catch (
const NoSuchElementException&)
985 catch (
const WrappedTargetException&)
992 int nFonts = aFonts.getLength();
994 it->second.aSubstAttributes.reserve( nFonts );
997 static constexpr OUStringLiteral aSubstFontsStr ( u
"SubstFonts" );
998 static constexpr OUStringLiteral aSubstFontsMSStr( u
"SubstFontsMS" );
999 static constexpr OUStringLiteral aSubstWeightStr ( u
"FontWeight" );
1000 static constexpr OUStringLiteral aSubstWidthStr ( u
"FontWidth" );
1001 static constexpr OUStringLiteral aSubstTypeStr ( u
"FontType" );
1002 for(
const OUString& rFontName : aFonts )
1007 Any aAny = xNode->getByName( rFontName );
1010 catch (
const NoSuchElementException&)
1013 catch (
const WrappedTargetException&)
1018 SAL_WARN(
"unotools.config",
"did not get font attributes for " << rFontName);
1024 aAttr.
Name = rFontName;
1025 fillSubstVector( xFont, aSubstFontsStr, aAttr.
Substitutions );
1027 aAttr.
Weight = getSubstWeight( xFont, aSubstWeightStr );
1028 aAttr.
Width = getSubstWidth( xFont, aSubstWidthStr );
1029 aAttr.
Type = getSubstType( xFont, aSubstTypeStr );
1032 it->second.aSubstAttributes.push_back( aAttr );
1034 std::sort( it->second.aSubstAttributes.begin(), it->second.aSubstAttributes.end(), StrictStringSort() );
1037const FontNameAttr* FontSubstConfiguration::getSubstInfo(
const OUString& rFontName )
const
1039 if( rFontName.isEmpty() )
1044 OUString aSearchFont( rFontName.toAsciiLowerCase() );
1046 aSearchAttr.
Name = aSearchFont;
1050 aFallbacks.emplace_back(
"en");
1052 for (
const auto& rFallback : aFallbacks)
1054 std::unordered_map< OUString, LocaleSubst >::const_iterator lang = m_aSubst.find( rFallback );
1055 if( lang != m_aSubst.end() )
1057 if( ! lang->second.bConfigRead )
1058 readLocaleSubst( rFallback );
1061 std::vector< FontNameAttr >::const_iterator it = ::std::lower_bound( lang->second.aSubstAttributes.begin(), lang->second.aSubstAttributes.end(), aSearchAttr, StrictStringSort() );
1062 if( it != lang->second.aSubstAttributes.end())
1067 if( rFoundAttr.
Name.getLength() <= aSearchFont.getLength() )
1068 if( aSearchFont.startsWith( rFoundAttr.
Name))
bool isSystemLocale() const
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
OUString getLanguage() const
const OUString & getBcp47(bool bResolveSystem=true) const
OUString getCountry() const
::std::vector< OUString > getFallbackStrings(bool bIncludeFullBcp47) const
static bool isTraditionalChinese(LanguageType nLang)
static bool isSimplifiedChinese(LanguageType nLang)
SvtSysLocale provides a refcounted single instance of an application wide LocaleDataWrapper and <type...
const LanguageTag & GetUILanguageTag() const
OUString getUserInterfaceFont(const LanguageTag &rLanguageTag) const
std::unordered_map< OUString, LocaleAccess > m_aConfig
OUString getDefaultFont(const LanguageTag &rLanguageTag, DefaultFontType nType) const
css::uno::Reference< css::lang::XMultiServiceFactory > m_xConfigProvider
css::uno::Reference< css::container::XNameAccess > m_xConfigAccess
DefaultFontConfiguration()
OUString tryLocale(const OUString &rBcp47, const OUString &rType) const
~DefaultFontConfiguration()
const ScContentId pTypeList[int(ScContentId::LAST)+1]
const char *const aImplKillTrailingWithExceptionsList[]
const char *const pAttribNames[]
ImplFontAttrWidthSearchData const aImplWidthAttrSearchList[]
const char *const aImplKillTrailingList[]
const enum_convert pWidthNames[]
static const char * getKeyType(DefaultFontType nKeyType)
static bool ImplFindAndErase(OUString &rName, const char *pStr)
static bool ImplKillTrailingWithExceptions(OUString &rName, const char *const *ppStr)
ImplFontAttrWeightSearchData const aImplWeightAttrSearchList[]
static bool ImplKillLeading(OUString &rName, const char *const *ppStr)
ImplFontAttrTypeSearchData const aImplTypeAttrSearchList[]
const enum_convert pWeightNames[]
static bool ImplKillTrailing(OUString &rName, const char *const *ppStr)
const char *const aImplKillLeadingList[]
static sal_Int32 ImplIsTrailing(std::u16string_view rName, const char *pStr)
@ Handwriting
More Handwriting with normal letters.
@ Symbol
Font with symbols.
@ Titling
Only uppercase characters.
@ Typewriter
Like a typewriter: Courier, ...
@ Capitals
Only uppercase characters, but lowercase characters smaller as the uppercase characters.
@ Chancery
Like Zapf Chancery.
@ BrushScript
More Script.
@ OtherStyle
OldStyle, ... so negative points.
@ Script
Handwriting or Script.
uno::Reference< uno::XInterface > m_xConfigAccess
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
LanguageTag maLanguageTag
OUString get(TranslateId sContextAndId, const std::locale &loc)
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
Reference< XComponentContext > getProcessComponentContext()
::std::vector< OUString > MSSubstitutions
::std::vector< OUString > Substitutions
Reference< XMultiServiceFactory > m_xConfigProvider