1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Linux Fonts: Improve default selection mechanism

This commit is contained in:
reuk 2022-08-30 19:25:25 +01:00
parent 98d81bf87a
commit 5a6c8b1d0a
No known key found for this signature in database
GPG key ID: FCB43929F012EE5C
2 changed files with 86 additions and 75 deletions

View file

@ -154,28 +154,19 @@ public:
//==============================================================================
StringArray findAllFamilyNames() const
{
StringArray s;
std::set<String> set;
for (auto* face : faces)
s.addIfNotAlreadyThere (face->family);
set.insert (face->family);
StringArray s;
for (const auto& family : set)
s.add (family);
return s;
}
static int indexOfRegularStyle (const StringArray& styles)
{
int i = styles.indexOf ("Regular", true);
if (i >= 0)
return i;
for (i = 0; i < styles.size(); ++i)
if (! (styles[i].containsIgnoreCase ("Bold") || styles[i].containsIgnoreCase ("Italic")))
return i;
return -1;
}
StringArray findAllTypefaceStyles (const String& family) const
{
StringArray s;
@ -184,12 +175,7 @@ public:
if (face->family == family)
s.addIfNotAlreadyThere (face->style);
// try to get a regular style to be first in the list
auto regular = indexOfRegularStyle (s);
if (regular > 0)
s.strings.swap (0, regular);
// scanFontPaths ensures that regular styles are ordered before other styles
return s;
}
@ -198,9 +184,48 @@ public:
for (auto& path : paths)
{
for (const auto& iter : RangedDirectoryIterator (File::getCurrentWorkingDirectory().getChildFile (path), true))
{
if (iter.getFile().hasFileExtension ("ttf;pfb;pcf;otf"))
scanFont (iter.getFile());
}
}
std::sort (faces.begin(), faces.end(), [] (const auto* a, const auto* b)
{
const auto tie = [] (const KnownTypeface& t)
{
// Used to order styles like "Regular", "Roman" etc. before "Bold", "Italic", etc.
const auto computeStyleNormalcy = [] (const String& style)
{
if (style == "Regular")
return 0;
if (style == "Roman")
return 1;
if (style == "Book")
return 2;
if (style.containsIgnoreCase ("Bold"))
return 3;
if (style.containsIgnoreCase ("Italic"))
return 4;
return 5;
};
return std::make_tuple (t.family,
computeStyleNormalcy (t.style),
t.style,
t.isSansSerif,
t.isMonospaced,
t.faceIndex,
t.file);
};
return tie (*a) < tie (*b);
});
}
void getMonospacedNames (StringArray& monoSpaced) const

View file

@ -113,99 +113,85 @@ bool TextLayout::createNativeLayout (const AttributedString&)
//==============================================================================
struct DefaultFontInfo
{
struct Characteristics
{
explicit Characteristics (String nameIn) : name (nameIn) {}
Characteristics withStyle (String styleIn) const
{
auto copy = *this;
copy.style = std::move (styleIn);
return copy;
}
String name, style;
};
DefaultFontInfo()
: defaultSans (getDefaultSansSerifFontCharacteristics()),
defaultSerif (getDefaultSerifFontCharacteristics()),
defaultFixed (getDefaultMonospacedFontCharacteristics())
: defaultSans (getDefaultSansSerifFontName()),
defaultSerif (getDefaultSerifFontName()),
defaultFixed (getDefaultMonospacedFontName())
{
}
Characteristics getRealFontCharacteristics (const String& faceName) const
String getRealFontName (const String& faceName) const
{
if (faceName == Font::getDefaultSansSerifFontName()) return defaultSans;
if (faceName == Font::getDefaultSerifFontName()) return defaultSerif;
if (faceName == Font::getDefaultMonospacedFontName()) return defaultFixed;
return Characteristics { faceName };
return faceName;
}
Characteristics defaultSans, defaultSerif, defaultFixed;
String defaultSans, defaultSerif, defaultFixed;
private:
template <typename Range>
static Characteristics pickBestFont (const StringArray& names, Range&& choicesArray)
static String pickBestFont (const StringArray& names, Range&& choicesArray)
{
for (auto& choice : choicesArray)
if (names.contains (choice.name, true))
if (names.contains (choice, true))
return choice;
for (auto& choice : choicesArray)
for (auto& name : names)
if (name.startsWithIgnoreCase (choice.name))
return Characteristics { name }.withStyle (choice.style);
if (name.startsWithIgnoreCase (choice))
return name;
for (auto& choice : choicesArray)
for (auto& name : names)
if (name.containsIgnoreCase (choice.name))
return Characteristics { name }.withStyle (choice.style);
if (name.containsIgnoreCase (choice))
return name;
return Characteristics { names[0] };
return names[0];
}
static Characteristics getDefaultSansSerifFontCharacteristics()
static String getDefaultSansSerifFontName()
{
StringArray allFonts;
FTTypefaceList::getInstance()->getSansSerifNames (allFonts);
static const Characteristics targets[] { Characteristics { "Verdana" },
Characteristics { "Bitstream Vera Sans" }.withStyle ("Roman"),
Characteristics { "Luxi Sans" },
Characteristics { "Liberation Sans" },
Characteristics { "DejaVu Sans" },
Characteristics { "Sans" } };
static constexpr const char* targets[] { "Verdana",
"Bitstream Vera Sans",
"Luxi Sans",
"Liberation Sans",
"DejaVu Sans",
"Sans" };
return pickBestFont (allFonts, targets);
}
static Characteristics getDefaultSerifFontCharacteristics()
static String getDefaultSerifFontName()
{
StringArray allFonts;
FTTypefaceList::getInstance()->getSerifNames (allFonts);
static const Characteristics targets[] { Characteristics { "Bitstream Vera Serif" }.withStyle ("Roman"),
Characteristics { "Times" },
Characteristics { "Nimbus Roman" },
Characteristics { "Liberation Serif" },
Characteristics { "DejaVu Serif" },
Characteristics { "Serif" } };
static constexpr const char* targets[] { "Bitstream Vera Serif",
"Times",
"Nimbus Roman",
"Liberation Serif",
"DejaVu Serif",
"Serif" };
return pickBestFont (allFonts, targets);
}
static Characteristics getDefaultMonospacedFontCharacteristics()
static String getDefaultMonospacedFontName()
{
StringArray allFonts;
FTTypefaceList::getInstance()->getMonospacedNames (allFonts);
static const Characteristics targets[] { Characteristics { "DejaVu Sans Mono" },
Characteristics { "Bitstream Vera Sans Mono" }.withStyle ("Roman"),
Characteristics { "Sans Mono" },
Characteristics { "Liberation Mono" },
Characteristics { "Courier" },
Characteristics { "DejaVu Mono" },
Characteristics { "Mono" } };
static constexpr const char* targets[] { "DejaVu Sans Mono",
"Bitstream Vera Sans Mono",
"Sans Mono",
"Liberation Mono",
"Courier",
"DejaVu Mono",
"Mono" };
return pickBestFont (allFonts, targets);
}
@ -219,13 +205,13 @@ Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
Font f (font);
const auto name = font.getTypefaceName();
const auto characteristics = defaultInfo.getRealFontCharacteristics (name);
f.setTypefaceName (characteristics.name);
const auto realName = defaultInfo.getRealFontName (name);
f.setTypefaceName (realName);
const auto styles = findAllTypefaceStyles (characteristics.name);
const auto styles = findAllTypefaceStyles (realName);
if (! styles.contains (font.getTypefaceStyle()))
f.setTypefaceStyle (characteristics.style);
f.setTypefaceStyle (styles[0]);
return Typeface::createSystemTypefaceFor (f);
}