2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
23 ==============================================================================
29 static std::unique_ptr
<XmlElement
> findFontsConfFile()
31 static const char* pathsToSearch
[] = { "/etc/fonts/fonts.conf",
32 "/usr/share/fonts/fonts.conf",
33 "/usr/local/etc/fonts/fonts.conf",
34 "/usr/share/defaults/fonts/fonts.conf" };
36 for (auto* path
: pathsToSearch
)
37 if (auto xml
= parseXML (File (path
)))
43 StringArray
FTTypefaceList::getDefaultFontDirectories()
47 fontDirs
.addTokens (String (CharPointer_UTF8 (getenv ("JUCE_FONT_PATH"))), ";,", "");
48 fontDirs
.removeEmptyStrings (true);
50 if (fontDirs
.isEmpty())
52 if (auto fontsInfo
= findFontsConfFile())
54 for (auto* e
: fontsInfo
->getChildWithTagNameIterator ("dir"))
56 auto fontPath
= e
->getAllSubText().trim();
58 if (fontPath
.isNotEmpty())
60 if (e
->getStringAttribute ("prefix") == "xdg")
62 auto xdgDataHome
= SystemStats::getEnvironmentVariable ("XDG_DATA_HOME", {});
64 if (xdgDataHome
.trimStart().isEmpty())
65 xdgDataHome
= "~/.local/share";
67 fontPath
= File (xdgDataHome
).getChildFile (fontPath
).getFullPathName();
70 fontDirs
.add (fontPath
);
76 if (fontDirs
.isEmpty())
77 fontDirs
.add ("/usr/X11R6/lib/X11/fonts");
79 fontDirs
.removeDuplicates (false);
83 Typeface::Ptr
Typeface::createSystemTypefaceFor (const Font
& font
)
85 return new FreeTypeTypeface (font
);
88 Typeface::Ptr
Typeface::createSystemTypefaceFor (const void* data
, size_t dataSize
)
90 return new FreeTypeTypeface (data
, dataSize
);
93 void Typeface::scanFolderForFonts (const File
& folder
)
95 FTTypefaceList::getInstance()->scanFontPaths (StringArray (folder
.getFullPathName()));
98 StringArray
Font::findAllTypefaceNames()
100 return FTTypefaceList::getInstance()->findAllFamilyNames();
103 StringArray
Font::findAllTypefaceStyles (const String
& family
)
105 return FTTypefaceList::getInstance()->findAllTypefaceStyles (family
);
108 bool TextLayout::createNativeLayout (const AttributedString
&)
113 //==============================================================================
114 struct DefaultFontInfo
116 struct Characteristics
118 explicit Characteristics (String nameIn
) : name (nameIn
) {}
120 Characteristics
withStyle (String styleIn
) const
123 copy
.style
= std::move (styleIn
);
131 : defaultSans (getDefaultSansSerifFontCharacteristics()),
132 defaultSerif (getDefaultSerifFontCharacteristics()),
133 defaultFixed (getDefaultMonospacedFontCharacteristics())
137 Characteristics
getRealFontCharacteristics (const String
& faceName
) const
139 if (faceName
== Font::getDefaultSansSerifFontName()) return defaultSans
;
140 if (faceName
== Font::getDefaultSerifFontName()) return defaultSerif
;
141 if (faceName
== Font::getDefaultMonospacedFontName()) return defaultFixed
;
143 return Characteristics
{ faceName
};
146 Characteristics defaultSans
, defaultSerif
, defaultFixed
;
149 template <typename Range
>
150 static Characteristics
pickBestFont (const StringArray
& names
, Range
&& choicesArray
)
152 for (auto& choice
: choicesArray
)
153 if (names
.contains (choice
.name
, true))
156 for (auto& choice
: choicesArray
)
157 for (auto& name
: names
)
158 if (name
.startsWithIgnoreCase (choice
.name
))
159 return Characteristics
{ name
}.withStyle (choice
.style
);
161 for (auto& choice
: choicesArray
)
162 for (auto& name
: names
)
163 if (name
.containsIgnoreCase (choice
.name
))
164 return Characteristics
{ name
}.withStyle (choice
.style
);
166 return Characteristics
{ names
[0] };
169 static Characteristics
getDefaultSansSerifFontCharacteristics()
171 StringArray allFonts
;
172 FTTypefaceList::getInstance()->getSansSerifNames (allFonts
);
174 static const Characteristics targets
[] { Characteristics
{ "Verdana" },
175 Characteristics
{ "Bitstream Vera Sans" }.withStyle ("Roman"),
176 Characteristics
{ "Luxi Sans" },
177 Characteristics
{ "Liberation Sans" },
178 Characteristics
{ "DejaVu Sans" },
179 Characteristics
{ "Sans" } };
180 return pickBestFont (allFonts
, targets
);
183 static Characteristics
getDefaultSerifFontCharacteristics()
185 StringArray allFonts
;
186 FTTypefaceList::getInstance()->getSerifNames (allFonts
);
188 static const Characteristics targets
[] { Characteristics
{ "Bitstream Vera Serif" }.withStyle ("Roman"),
189 Characteristics
{ "Times" },
190 Characteristics
{ "Nimbus Roman" },
191 Characteristics
{ "Liberation Serif" },
192 Characteristics
{ "DejaVu Serif" },
193 Characteristics
{ "Serif" } };
194 return pickBestFont (allFonts
, targets
);
197 static Characteristics
getDefaultMonospacedFontCharacteristics()
199 StringArray allFonts
;
200 FTTypefaceList::getInstance()->getMonospacedNames (allFonts
);
202 static const Characteristics targets
[] { Characteristics
{ "DejaVu Sans Mono" },
203 Characteristics
{ "Bitstream Vera Sans Mono" }.withStyle ("Roman"),
204 Characteristics
{ "Sans Mono" },
205 Characteristics
{ "Liberation Mono" },
206 Characteristics
{ "Courier" },
207 Characteristics
{ "DejaVu Mono" },
208 Characteristics
{ "Mono" } };
209 return pickBestFont (allFonts
, targets
);
212 JUCE_DECLARE_NON_COPYABLE (DefaultFontInfo
)
215 Typeface::Ptr
Font::getDefaultTypefaceForFont (const Font
& font
)
217 static const DefaultFontInfo defaultInfo
;
221 const auto name
= font
.getTypefaceName();
222 const auto characteristics
= defaultInfo
.getRealFontCharacteristics (name
);
223 f
.setTypefaceName (characteristics
.name
);
225 const auto styles
= findAllTypefaceStyles (name
);
227 if (! styles
.contains (font
.getTypefaceStyle()))
228 f
.setTypefaceStyle (characteristics
.style
);
230 return Typeface::createSystemTypefaceFor (f
);