44import android .graphics .Color ;
55import android .graphics .Paint ;
66import android .graphics .Bitmap ;
7+ import android .graphics .Rect ;
78import android .graphics .Typeface ;
89import androidx .annotation .Keep ;
910import androidx .annotation .NonNull ;
1415 * by the portable local_glyph_rasterizer.hpp
1516 */
1617@ Keep
17- public class LocalGlyphRasterizer {
18- private final Bitmap bitmap ;
18+ class LocalGlyphRasterizer {
19+
20+ @ Keep
21+ private class GlyphMetrics {
22+ int width ;
23+ int height ;
24+ int top ;
25+ int left ;
26+ int ascender ;
27+ int descender ;
28+ int advance ;
29+ Bitmap glyphBitmap ;
30+ }
31+
32+ @ NonNull
33+ private final GlyphMetrics glyphMetrics ;
34+ @ NonNull
35+ private final Rect bounds ;
1936 @ NonNull
2037 private final Paint paint ;
2138 @ NonNull
2239 private final Canvas canvas ;
2340
2441 LocalGlyphRasterizer () {
25- /*
26- 35x35px dimensions are hardwired to match local_glyph_rasterizer.cpp
27- These dimensions are large enough to draw a 24 point character in the middle
28- of the bitmap (y: 20) with some buffer around the edge
29- */
30- bitmap = Bitmap .createBitmap (35 , 35 , Bitmap .Config .ARGB_8888 );
42+ glyphMetrics = new GlyphMetrics ();
43+ glyphMetrics .glyphBitmap = Bitmap .createBitmap (35 , 35 , Bitmap .Config .ARGB_8888 );
44+
45+ bounds = new Rect ();
3146
3247 paint = new Paint ();
3348 paint .setAntiAlias (true );
3449 paint .setTextSize (24 );
3550
3651 canvas = new Canvas ();
37- canvas .setBitmap (bitmap );
52+ canvas .setBitmap (glyphMetrics . glyphBitmap );
3853 }
3954
4055 /***
41- * Uses Android-native drawing code to rasterize a single glyph
42- * to a square {@link Bitmap} which can be returned to portable
43- * code for transformation into a Signed Distance Field glyph .
56+ * Uses Android-native drawing code to encapsulate the glyph metrics and a raterized
57+ * square {@link Bitmap} to a single structure which can be returned to portable
58+ * code for transformation into the native glyph data structure .
4459 *
4560 * @param fontFamily Font family string to pass to Typeface.create
4661 * @param bold If true, use Typeface.BOLD option
4762 * @param glyphID 16-bit Unicode BMP codepoint to draw
4863 *
49- * @return Return a {@link Bitmap} to be displayed in the requested tile.
64+ * @return Return GlyphMetrics that contains all the necessary information to display
65+ * the character in the requested tile.
5066 */
5167 @ WorkerThread
52- protected Bitmap drawGlyphBitmap (String fontFamily , boolean bold , char glyphID ) {
68+ protected GlyphMetrics getGlyphMetrics (String fontFamily , boolean bold , char glyphID ) {
5369 paint .setTypeface (Typeface .create (fontFamily , bold ? Typeface .BOLD : Typeface .NORMAL ));
70+
71+ // Get font metrics
72+ Paint .FontMetricsInt metrics = paint .getFontMetricsInt ();
73+ glyphMetrics .ascender = Math .abs (metrics .top );
74+ glyphMetrics .descender = Math .abs (metrics .bottom );
75+
76+ String glyph = String .valueOf (glyphID );
77+ paint .getTextBounds (glyph , 0 , 1 , bounds );
78+ glyphMetrics .left = bounds .left ;
79+ glyphMetrics .width = bounds .right - bounds .left ;
80+ glyphMetrics .height = bounds .bottom - bounds .top ;
81+ glyphMetrics .top = Math .abs (bounds .top );
82+ glyphMetrics .advance = Math .round (paint .measureText (glyph , 0 , 1 ));
83+
84+ if (glyphMetrics .width == 0 && glyphMetrics .height == 0 ) {
85+ return glyphMetrics ;
86+ }
87+ // Draw glyph on the canvas with the 3 pixels' boarder padding from the left and top
88+ float x = 3 - bounds .left ;
89+ float y = 3 - bounds .top ;
5490 canvas .drawColor (Color .WHITE );
55- canvas .drawText (String .valueOf (glyphID ), 5 , 25 , paint );
56- return bitmap ;
91+ canvas .drawText (glyph , x , y , paint );
92+
93+ return glyphMetrics ;
5794 }
58- }
95+ }
0 commit comments