PageRenderTime 24ms CodeModel.GetById 36ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/juce_graphics/native/juce_android_Fonts.cpp

https://bitbucket.org/Klinkenstecker/owlsim
C++ | 329 lines | 224 code | 76 blank | 29 comment | 21 complexity | 14902d18998c2af8fc9a65a60201fff9 MD5 | raw file
  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. struct DefaultFontNames
  19. {
  20. DefaultFontNames()
  21. : defaultSans ("sans"),
  22. defaultSerif ("serif"),
  23. defaultFixed ("monospace"),
  24. defaultFallback ("sans")
  25. {
  26. }
  27. String getRealFontName (const String& faceName) const
  28. {
  29. if (faceName == Font::getDefaultSansSerifFontName()) return defaultSans;
  30. if (faceName == Font::getDefaultSerifFontName()) return defaultSerif;
  31. if (faceName == Font::getDefaultMonospacedFontName()) return defaultFixed;
  32. return faceName;
  33. }
  34. String defaultSans, defaultSerif, defaultFixed, defaultFallback;
  35. };
  36. Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
  37. {
  38. static DefaultFontNames defaultNames;
  39. Font f (font);
  40. f.setTypefaceName (defaultNames.getRealFontName (font.getTypefaceName()));
  41. return Typeface::createSystemTypefaceFor (f);
  42. }
  43. //==============================================================================
  44. #if JUCE_USE_FREETYPE
  45. StringArray FTTypefaceList::getDefaultFontDirectories()
  46. {
  47. return StringArray ("/system/fonts");
  48. }
  49. Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font)
  50. {
  51. return new FreeTypeTypeface (font);
  52. }
  53. void Typeface::scanFolderForFonts (const File& folder)
  54. {
  55. FTTypefaceList::getInstance()->scanFontPaths (StringArray (folder.getFullPathName()));
  56. }
  57. StringArray Font::findAllTypefaceNames()
  58. {
  59. return FTTypefaceList::getInstance()->findAllFamilyNames();
  60. }
  61. StringArray Font::findAllTypefaceStyles (const String& family)
  62. {
  63. return FTTypefaceList::getInstance()->findAllTypefaceStyles (family);
  64. }
  65. bool TextLayout::createNativeLayout (const AttributedString&)
  66. {
  67. return false;
  68. }
  69. #else
  70. //==============================================================================
  71. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
  72. STATICMETHOD (create, "create", "(Ljava/lang/String;I)Landroid/graphics/Typeface;") \
  73. STATICMETHOD (createFromFile, "createFromFile", "(Ljava/lang/String;)Landroid/graphics/Typeface;") \
  74. DECLARE_JNI_CLASS (TypefaceClass, "android/graphics/Typeface");
  75. #undef JNI_CLASS_MEMBERS
  76. //==============================================================================
  77. StringArray Font::findAllTypefaceNames()
  78. {
  79. StringArray results;
  80. Array<File> fonts;
  81. File ("/system/fonts").findChildFiles (fonts, File::findFiles, false, "*.ttf");
  82. for (int i = 0; i < fonts.size(); ++i)
  83. results.addIfNotAlreadyThere (fonts.getReference(i).getFileNameWithoutExtension()
  84. .upToLastOccurrenceOf ("-", false, false));
  85. return results;
  86. }
  87. StringArray Font::findAllTypefaceStyles (const String& family)
  88. {
  89. StringArray results ("Regular");
  90. Array<File> fonts;
  91. File ("/system/fonts").findChildFiles (fonts, File::findFiles, false, family + "-*.ttf");
  92. for (int i = 0; i < fonts.size(); ++i)
  93. results.addIfNotAlreadyThere (fonts.getReference(i).getFileNameWithoutExtension()
  94. .fromLastOccurrenceOf ("-", false, false));
  95. return results;
  96. }
  97. const float referenceFontSize = 256.0f;
  98. const float referenceFontToUnits = 1.0f / referenceFontSize;
  99. //==============================================================================
  100. class AndroidTypeface : public Typeface
  101. {
  102. public:
  103. AndroidTypeface (const Font& font)
  104. : Typeface (font.getTypefaceName(), font.getTypefaceStyle()),
  105. ascent (0), descent (0), heightToPointsFactor (1.0f)
  106. {
  107. JNIEnv* const env = getEnv();
  108. const bool isBold = style.contains ("Bold");
  109. const bool isItalic = style.contains ("Italic");
  110. File fontFile (getFontFile (name, style));
  111. if (! fontFile.exists())
  112. fontFile = findFontFile (name, isBold, isItalic);
  113. if (fontFile.exists())
  114. typeface = GlobalRef (env->CallStaticObjectMethod (TypefaceClass, TypefaceClass.createFromFile,
  115. javaString (fontFile.getFullPathName()).get()));
  116. else
  117. typeface = GlobalRef (env->CallStaticObjectMethod (TypefaceClass, TypefaceClass.create,
  118. javaString (getName()).get(),
  119. (isBold ? 1 : 0) + (isItalic ? 2 : 0)));
  120. rect = GlobalRef (env->NewObject (RectClass, RectClass.constructor, 0, 0, 0, 0));
  121. paint = GlobalRef (GraphicsHelpers::createPaint (Graphics::highResamplingQuality));
  122. const LocalRef<jobject> ignored (paint.callObjectMethod (Paint.setTypeface, typeface.get()));
  123. paint.callVoidMethod (Paint.setTextSize, referenceFontSize);
  124. const float fullAscent = std::abs (paint.callFloatMethod (Paint.ascent));
  125. const float fullDescent = paint.callFloatMethod (Paint.descent);
  126. const float totalHeight = fullAscent + fullDescent;
  127. ascent = fullAscent / totalHeight;
  128. descent = fullDescent / totalHeight;
  129. heightToPointsFactor = referenceFontSize / totalHeight;
  130. }
  131. float getAscent() const { return ascent; }
  132. float getDescent() const { return descent; }
  133. float getHeightToPointsFactor() const { return heightToPointsFactor; }
  134. float getStringWidth (const String& text)
  135. {
  136. JNIEnv* env = getEnv();
  137. const int numChars = text.length();
  138. jfloatArray widths = env->NewFloatArray (numChars);
  139. const int numDone = paint.callIntMethod (Paint.getTextWidths, javaString (text).get(), widths);
  140. HeapBlock<jfloat> localWidths (numDone);
  141. env->GetFloatArrayRegion (widths, 0, numDone, localWidths);
  142. env->DeleteLocalRef (widths);
  143. float x = 0;
  144. for (int i = 0; i < numDone; ++i)
  145. x += localWidths[i];
  146. return x * referenceFontToUnits;
  147. }
  148. void getGlyphPositions (const String& text, Array<int>& glyphs, Array<float>& xOffsets)
  149. {
  150. JNIEnv* env = getEnv();
  151. const int numChars = text.length();
  152. jfloatArray widths = env->NewFloatArray (numChars);
  153. const int numDone = paint.callIntMethod (Paint.getTextWidths, javaString (text).get(), widths);
  154. HeapBlock<jfloat> localWidths (numDone);
  155. env->GetFloatArrayRegion (widths, 0, numDone, localWidths);
  156. env->DeleteLocalRef (widths);
  157. String::CharPointerType s (text.getCharPointer());
  158. xOffsets.add (0);
  159. float x = 0;
  160. for (int i = 0; i < numDone; ++i)
  161. {
  162. glyphs.add ((int) s.getAndAdvance());
  163. x += localWidths[i];
  164. xOffsets.add (x * referenceFontToUnits);
  165. }
  166. }
  167. bool getOutlineForGlyph (int /*glyphNumber*/, Path& /*destPath*/)
  168. {
  169. return false;
  170. }
  171. EdgeTable* getEdgeTableForGlyph (int glyphNumber, const AffineTransform& t)
  172. {
  173. JNIEnv* env = getEnv();
  174. jobject matrix = GraphicsHelpers::createMatrix (env, AffineTransform::scale (referenceFontToUnits).followedBy (t));
  175. jintArray maskData = (jintArray) android.activity.callObjectMethod (JuceAppActivity.renderGlyph, (jchar) glyphNumber, paint.get(), matrix, rect.get());
  176. env->DeleteLocalRef (matrix);
  177. const int left = env->GetIntField (rect.get(), RectClass.left);
  178. const int top = env->GetIntField (rect.get(), RectClass.top);
  179. const int right = env->GetIntField (rect.get(), RectClass.right);
  180. const int bottom = env->GetIntField (rect.get(), RectClass.bottom);
  181. const Rectangle<int> bounds (left, top, right - left, bottom - top);
  182. EdgeTable* et = nullptr;
  183. if (! bounds.isEmpty())
  184. {
  185. et = new EdgeTable (bounds);
  186. jint* const maskDataElements = env->GetIntArrayElements (maskData, 0);
  187. const jint* mask = maskDataElements;
  188. for (int y = top; y < bottom; ++y)
  189. {
  190. #if JUCE_LITTLE_ENDIAN
  191. const uint8* const lineBytes = ((const uint8*) mask) + 3;
  192. #else
  193. const uint8* const lineBytes = (const uint8*) mask;
  194. #endif
  195. et->clipLineToMask (left, y, lineBytes, 4, bounds.getWidth());
  196. mask += bounds.getWidth();
  197. }
  198. env->ReleaseIntArrayElements (maskData, maskDataElements, 0);
  199. }
  200. env->DeleteLocalRef (maskData);
  201. return et;
  202. }
  203. GlobalRef typeface, paint, rect;
  204. float ascent, descent, heightToPointsFactor;
  205. private:
  206. static File findFontFile (const String& family,
  207. const bool bold, const bool italic)
  208. {
  209. File file;
  210. if (bold || italic)
  211. {
  212. String suffix;
  213. if (bold) suffix = "Bold";
  214. if (italic) suffix << "Italic";
  215. file = getFontFile (family, suffix);
  216. if (file.exists())
  217. return file;
  218. }
  219. file = getFontFile (family, "Regular");
  220. if (! file.exists())
  221. file = getFontFile (family, String::empty);
  222. return file;
  223. }
  224. static File getFontFile (const String& family, const String& style)
  225. {
  226. String path ("/system/fonts/" + family);
  227. if (style.isNotEmpty())
  228. path << '-' << style;
  229. return File (path + ".ttf");
  230. }
  231. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidTypeface)
  232. };
  233. //==============================================================================
  234. Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font)
  235. {
  236. return new AndroidTypeface (font);
  237. }
  238. void Typeface::scanFolderForFonts (const File&)
  239. {
  240. jassertfalse; // not available unless using FreeType
  241. }
  242. bool TextLayout::createNativeLayout (const AttributedString&)
  243. {
  244. return false;
  245. }
  246. #endif