Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
5.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE 6 technical preview.
  4. Copyright (c) 2020 - Raw Material Software Limited
  5. You may use this code under the terms of the GPL v3
  6. (see www.gnu.org/licenses).
  7. For this technical preview, this file is not subject to commercial licensing.
  8. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  9. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  10. DISCLAIMED.
  11. ==============================================================================
  12. */
  13. namespace juce
  14. {
  15. static std::unique_ptr<XmlElement> findFontsConfFile()
  16. {
  17. static const char* pathsToSearch[] = { "/etc/fonts/fonts.conf",
  18. "/usr/share/fonts/fonts.conf" };
  19. for (auto* path : pathsToSearch)
  20. if (auto xml = parseXML (File (path)))
  21. return xml;
  22. return {};
  23. }
  24. StringArray FTTypefaceList::getDefaultFontDirectories()
  25. {
  26. StringArray fontDirs;
  27. fontDirs.addTokens (String (CharPointer_UTF8 (getenv ("JUCE_FONT_PATH"))), ";,", "");
  28. fontDirs.removeEmptyStrings (true);
  29. if (fontDirs.isEmpty())
  30. {
  31. if (auto fontsInfo = findFontsConfFile())
  32. {
  33. forEachXmlChildElementWithTagName (*fontsInfo, e, "dir")
  34. {
  35. auto fontPath = e->getAllSubText().trim();
  36. if (fontPath.isNotEmpty())
  37. {
  38. if (e->getStringAttribute ("prefix") == "xdg")
  39. {
  40. auto xdgDataHome = SystemStats::getEnvironmentVariable ("XDG_DATA_HOME", {});
  41. if (xdgDataHome.trimStart().isEmpty())
  42. xdgDataHome = "~/.local/share";
  43. fontPath = File (xdgDataHome).getChildFile (fontPath).getFullPathName();
  44. }
  45. fontDirs.add (fontPath);
  46. }
  47. }
  48. }
  49. }
  50. if (fontDirs.isEmpty())
  51. fontDirs.add ("/usr/X11R6/lib/X11/fonts");
  52. fontDirs.removeDuplicates (false);
  53. return fontDirs;
  54. }
  55. Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font)
  56. {
  57. return new FreeTypeTypeface (font);
  58. }
  59. Typeface::Ptr Typeface::createSystemTypefaceFor (const void* data, size_t dataSize)
  60. {
  61. return new FreeTypeTypeface (data, dataSize);
  62. }
  63. void Typeface::scanFolderForFonts (const File& folder)
  64. {
  65. FTTypefaceList::getInstance()->scanFontPaths (StringArray (folder.getFullPathName()));
  66. }
  67. StringArray Font::findAllTypefaceNames()
  68. {
  69. return FTTypefaceList::getInstance()->findAllFamilyNames();
  70. }
  71. StringArray Font::findAllTypefaceStyles (const String& family)
  72. {
  73. return FTTypefaceList::getInstance()->findAllTypefaceStyles (family);
  74. }
  75. bool TextLayout::createNativeLayout (const AttributedString&)
  76. {
  77. return false;
  78. }
  79. //==============================================================================
  80. struct DefaultFontNames
  81. {
  82. DefaultFontNames()
  83. : defaultSans (getDefaultSansSerifFontName()),
  84. defaultSerif (getDefaultSerifFontName()),
  85. defaultFixed (getDefaultMonospacedFontName())
  86. {
  87. }
  88. String getRealFontName (const String& faceName) const
  89. {
  90. if (faceName == Font::getDefaultSansSerifFontName()) return defaultSans;
  91. if (faceName == Font::getDefaultSerifFontName()) return defaultSerif;
  92. if (faceName == Font::getDefaultMonospacedFontName()) return defaultFixed;
  93. return faceName;
  94. }
  95. String defaultSans, defaultSerif, defaultFixed;
  96. private:
  97. static String pickBestFont (const StringArray& names, const char* const* choicesArray)
  98. {
  99. const StringArray choices (choicesArray);
  100. for (auto& choice : choices)
  101. if (names.contains (choice, true))
  102. return choice;
  103. for (auto& choice : choices)
  104. for (auto& name : names)
  105. if (name.startsWithIgnoreCase (choice))
  106. return name;
  107. for (auto& choice : choices)
  108. for (auto& name : names)
  109. if (name.containsIgnoreCase (choice))
  110. return name;
  111. return names[0];
  112. }
  113. static String getDefaultSansSerifFontName()
  114. {
  115. StringArray allFonts;
  116. FTTypefaceList::getInstance()->getSansSerifNames (allFonts);
  117. static const char* targets[] = { "Verdana", "Bitstream Vera Sans", "Luxi Sans",
  118. "Liberation Sans", "DejaVu Sans", "Sans", nullptr };
  119. return pickBestFont (allFonts, targets);
  120. }
  121. static String getDefaultSerifFontName()
  122. {
  123. StringArray allFonts;
  124. FTTypefaceList::getInstance()->getSerifNames (allFonts);
  125. static const char* targets[] = { "Bitstream Vera Serif", "Times", "Nimbus Roman",
  126. "Liberation Serif", "DejaVu Serif", "Serif", nullptr };
  127. return pickBestFont (allFonts, targets);
  128. }
  129. static String getDefaultMonospacedFontName()
  130. {
  131. StringArray allFonts;
  132. FTTypefaceList::getInstance()->getMonospacedNames (allFonts);
  133. static const char* targets[] = { "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Sans Mono",
  134. "Liberation Mono", "Courier", "DejaVu Mono", "Mono", nullptr };
  135. return pickBestFont (allFonts, targets);
  136. }
  137. JUCE_DECLARE_NON_COPYABLE (DefaultFontNames)
  138. };
  139. Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
  140. {
  141. static DefaultFontNames defaultNames;
  142. Font f (font);
  143. f.setTypefaceName (defaultNames.getRealFontName (font.getTypefaceName()));
  144. return Typeface::createSystemTypefaceFor (f);
  145. }
  146. } // namespace juce