diff --git a/modules/juce_graphics/native/juce_freetype_Fonts.cpp b/modules/juce_graphics/native/juce_freetype_Fonts.cpp index 2c34fa9e07..9c4a3cc249 100644 --- a/modules/juce_graphics/native/juce_freetype_Fonts.cpp +++ b/modules/juce_graphics/native/juce_freetype_Fonts.cpp @@ -154,28 +154,19 @@ public: //============================================================================== StringArray findAllFamilyNames() const { - StringArray s; + std::set 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 diff --git a/modules/juce_graphics/native/juce_linux_Fonts.cpp b/modules/juce_graphics/native/juce_linux_Fonts.cpp index c982a7a3bf..474b136f3f 100644 --- a/modules/juce_graphics/native/juce_linux_Fonts.cpp +++ b/modules/juce_graphics/native/juce_linux_Fonts.cpp @@ -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 - 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); }