This source file includes following definitions.
- toString
- checkMatch
- list
- match
- listFamilies
- openFont
- hasChar
- textExtents1
- textExtents
- encodeChar
- draw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.gnu.emacs;
21
22 import java.io.File;
23
24 import java.util.LinkedList;
25 import java.util.List;
26
27 import android.graphics.Paint;
28 import android.graphics.Rect;
29 import android.graphics.Typeface;
30 import android.graphics.Canvas;
31
32 import android.util.Log;
33
34 public class EmacsSdk7FontDriver extends EmacsFontDriver
35 {
36 private static final String TOFU_STRING = "\uDB3F\uDFFD";
37 private static final String EM_STRING = "m";
38 private static final String TAG = "EmacsSdk7FontDriver";
39
40 protected static final class Sdk7Typeface
41 {
42
43 public Typeface typeface;
44 public Paint typefacePaint;
45 public String familyName;
46 public int slant, width, weight, spacing;
47
48 public
49 Sdk7Typeface (String fileName, Typeface typeface)
50 {
51 String style, testString;
52 int index, measured, i;
53 float[] widths;
54
55 slant = NORMAL;
56 weight = REGULAR;
57 width = UNSPECIFIED;
58 spacing = PROPORTIONAL;
59
60 this.typeface = typeface;
61
62 typefacePaint = new Paint ();
63 typefacePaint.setAntiAlias (true);
64 typefacePaint.setTypeface (typeface);
65
66
67 typefacePaint.setTextSize (10.0f);
68
69
70
71 fileName = fileName.split ("\\.", 2)[0];
72
73
74
75 index = fileName.lastIndexOf ("-");
76
77 if (index > 0)
78 {
79 style = fileName.substring (index + 1, fileName.length ());
80 familyName = fileName.substring (0, index);
81
82
83 if (style.contains ("Thin"))
84 weight = THIN;
85 else if (style.contains ("UltraLight"))
86 weight = ULTRA_LIGHT;
87 else if (style.contains ("SemiLight"))
88 weight = SEMI_LIGHT;
89 else if (style.contains ("Light"))
90 weight = LIGHT;
91 else if (style.contains ("Medium"))
92 weight = MEDIUM;
93 else if (style.contains ("SemiBold"))
94 weight = SEMI_BOLD;
95 else if (style.contains ("ExtraBold"))
96 weight = EXTRA_BOLD;
97 else if (style.contains ("Bold"))
98 weight = BOLD;
99 else if (style.contains ("Black"))
100 weight = BLACK;
101 else if (style.contains ("UltraHeavy"))
102 weight = ULTRA_HEAVY;
103
104
105 if (style.contains ("ReverseOblique"))
106 slant = OBLIQUE;
107 else if (style.contains ("ReverseItalic"))
108 slant = REVERSE_ITALIC;
109 else if (style.contains ("Italic"))
110 slant = ITALIC;
111 else if (style.contains ("Oblique"))
112 slant = OBLIQUE;
113
114
115 if (style.contains ("UltraCondensed"))
116 width = ULTRA_CONDENSED;
117 else if (style.contains ("ExtraCondensed"))
118 width = EXTRA_CONDENSED;
119 else if (style.contains ("SemiCondensed"))
120 width = SEMI_CONDENSED;
121 else if (style.contains ("Condensed"))
122 width = CONDENSED;
123 else if (style.contains ("SemiExpanded"))
124 width = SEMI_EXPANDED;
125 else if (style.contains ("ExtraExpanded"))
126 width = EXTRA_EXPANDED;
127 else if (style.contains ("UltraExpanded"))
128 width = ULTRA_EXPANDED;
129 else if (style.contains ("Expanded"))
130 width = EXPANDED;
131
132
133 testString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
134 widths = new float[testString.length ()];
135
136 measured = typefacePaint.getTextWidths (testString,
137 0, testString.length (),
138 widths);
139 spacing = MONO;
140 for (i = 0; i < measured; ++i)
141 {
142 if (i != 0 && widths[i - 1] != widths[i])
143
144 spacing = PROPORTIONAL;
145 }
146 }
147 else
148 familyName = fileName;
149 }
150
151 @Override
152 public String
153 toString ()
154 {
155 return ("Sdk7Typeface ("
156 + String.valueOf (familyName) + ", "
157 + String.valueOf (slant) + ", "
158 + String.valueOf (width) + ", "
159 + String.valueOf (weight) + ", "
160 + String.valueOf (spacing) + ")");
161 }
162 };
163
164 protected static final class Sdk7FontEntity extends FontEntity
165 {
166
167 public Sdk7Typeface typeface;
168
169 public
170 Sdk7FontEntity (Sdk7Typeface typeface)
171 {
172 foundry = "Google";
173 family = typeface.familyName;
174 adstyle = null;
175 weight = typeface.weight;
176 slant = typeface.slant;
177 spacing = typeface.spacing;
178 width = typeface.width;
179 dpi = Math.round (EmacsService.SERVICE.metrics.scaledDensity * 160f);
180
181 this.typeface = typeface;
182 }
183 };
184
185 protected final class Sdk7FontObject extends FontObject
186 {
187
188 public Sdk7Typeface typeface;
189
190 public
191 Sdk7FontObject (Sdk7Typeface typeface, int pixelSize)
192 {
193 float totalWidth;
194 String testWidth, testString;
195
196 this.typeface = typeface;
197 this.pixelSize = pixelSize;
198
199 family = typeface.familyName;
200 adstyle = null;
201 weight = typeface.weight;
202 slant = typeface.slant;
203 spacing = typeface.spacing;
204 width = typeface.width;
205 dpi = Math.round (EmacsService.SERVICE.metrics.scaledDensity * 160f);
206
207
208 typeface.typefacePaint.setTextSize (pixelSize);
209 ascent
210 = Math.round (-typeface.typefacePaint.ascent ());
211 descent
212 = Math.round (typeface.typefacePaint.descent ());
213
214
215 testString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
216 totalWidth = typeface.typefacePaint.measureText (testString);
217
218 if (totalWidth > 0)
219 avgwidth = Math.round (totalWidth
220 / testString.length ());
221
222
223
224 minWidth = maxWidth = avgwidth;
225
226
227 averageWidth = avgwidth;
228
229
230 totalWidth = typeface.typefacePaint.measureText (" ");
231 spaceWidth = Math.round (totalWidth);
232
233
234 height = ascent + descent;
235 defaultAscent = ascent;
236 }
237 };
238
239 private String[] fontFamilyList;
240 private Sdk7Typeface[] typefaceList;
241 private Sdk7Typeface fallbackTypeface;
242
243 public
244 EmacsSdk7FontDriver ()
245 {
246 int i;
247 File systemFontsDirectory, fontFile;
248 Typeface typeface;
249
250 systemFontsDirectory = new File ("/system/fonts");
251
252 fontFamilyList = systemFontsDirectory.list ();
253
254
255 fontFamilyList = new String[0];
256
257 typefaceList = new Sdk7Typeface[fontFamilyList.length + 3];
258
259
260
261
262
263 for (i = 0; i < fontFamilyList.length; ++i)
264 {
265 fontFile = new File (systemFontsDirectory,
266 fontFamilyList[i]);
267 typeface = Typeface.createFromFile (fontFile);
268 typefaceList[i] = new Sdk7Typeface (fontFile.getName (),
269 typeface);
270 }
271
272
273 fallbackTypeface = new Sdk7Typeface ("monospace",
274 Typeface.MONOSPACE);
275 typefaceList[fontFamilyList.length] = fallbackTypeface;
276
277 fallbackTypeface = new Sdk7Typeface ("Monospace",
278 Typeface.MONOSPACE);
279 typefaceList[fontFamilyList.length + 1] = fallbackTypeface;
280
281 fallbackTypeface = new Sdk7Typeface ("Sans Serif",
282 Typeface.DEFAULT);
283 typefaceList[fontFamilyList.length + 2] = fallbackTypeface;
284 }
285
286 private boolean
287 checkMatch (Sdk7Typeface typeface, FontSpec fontSpec)
288 {
289 if (fontSpec.family != null
290 && !fontSpec.family.equals (typeface.familyName))
291 return false;
292
293 if (fontSpec.slant != null
294 && !fontSpec.weight.equals (typeface.weight))
295 return false;
296
297 if (fontSpec.spacing != null
298 && !fontSpec.spacing.equals (typeface.spacing))
299 return false;
300
301 if (fontSpec.weight != null
302 && !fontSpec.weight.equals (typeface.weight))
303 return false;
304
305 if (fontSpec.width != null
306 && !fontSpec.width.equals (typeface.width))
307 return false;
308
309 return true;
310 }
311
312 @Override
313 public FontEntity[]
314 list (FontSpec fontSpec)
315 {
316 LinkedList<FontEntity> list;
317 int i;
318
319 list = new LinkedList<FontEntity> ();
320
321 for (i = 0; i < typefaceList.length; ++i)
322 {
323 if (checkMatch (typefaceList[i], fontSpec))
324 list.add (new Sdk7FontEntity (typefaceList[i]));
325 }
326
327 return list.toArray (new FontEntity[0]);
328 }
329
330 @Override
331 public FontEntity
332 match (FontSpec fontSpec)
333 {
334 FontEntity[] entities;
335 int i;
336
337 entities = this.list (fontSpec);
338
339 if (entities.length == 0)
340 return new Sdk7FontEntity (fallbackTypeface);
341
342 return entities[0];
343 }
344
345 @Override
346 public String[]
347 listFamilies ()
348 {
349 return fontFamilyList;
350 }
351
352 @Override
353 public FontObject
354 openFont (FontEntity fontEntity, int pixelSize)
355 {
356 return new Sdk7FontObject (((Sdk7FontEntity) fontEntity).typeface,
357 pixelSize);
358 }
359
360 @Override
361 public int
362 hasChar (FontSpec font, char charCode)
363 {
364 float missingGlyphWidth, width;
365 Rect rect1, rect2;
366 Paint paint;
367 Sdk7FontObject fontObject;
368
369 if (font instanceof Sdk7FontObject)
370 {
371 fontObject = (Sdk7FontObject) font;
372 paint = fontObject.typeface.typefacePaint;
373 }
374 else
375 paint = ((Sdk7FontEntity) font).typeface.typefacePaint;
376
377 paint.setTextSize (10);
378
379 if (Character.isWhitespace (charCode))
380 return 1;
381
382 missingGlyphWidth = paint.measureText (TOFU_STRING);
383 width = paint.measureText ("" + charCode);
384
385 if (width == 0f)
386 return 0;
387
388 if (width != missingGlyphWidth)
389 return 1;
390
391 rect1 = new Rect ();
392 rect2 = new Rect ();
393
394 paint.getTextBounds (TOFU_STRING, 0, TOFU_STRING.length (),
395 rect1);
396 paint.getTextBounds ("" + charCode, 0, 1, rect2);
397 return rect1.equals (rect2) ? 0 : 1;
398 }
399
400 private void
401 textExtents1 (Sdk7FontObject font, int code, FontMetrics metrics,
402 Paint paint, Rect bounds)
403 {
404 char[] text;
405
406 text = new char[1];
407 text[0] = (char) code;
408
409 paint.getTextBounds (text, 0, 1, bounds);
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426 metrics.lbearing = (short) bounds.left;
427 metrics.rbearing = (short) bounds.right;
428 metrics.ascent = (short) -bounds.top;
429 metrics.descent = (short) bounds.bottom;
430 metrics.width = (short) paint.measureText ("" + text[0]);
431 }
432
433 @Override
434 public void
435 textExtents (FontObject font, int code[], FontMetrics fontMetrics)
436 {
437 int i;
438 Paint paintCache;
439 Rect boundsCache;
440 Sdk7FontObject fontObject;
441 char[] text;
442 float width;
443
444 fontObject = (Sdk7FontObject) font;
445 paintCache = fontObject.typeface.typefacePaint;
446 paintCache.setTextSize (fontObject.pixelSize);
447 boundsCache = new Rect ();
448
449 if (code.length == 0)
450 {
451 fontMetrics.lbearing = 0;
452 fontMetrics.rbearing = 0;
453 fontMetrics.ascent = 0;
454 fontMetrics.descent = 0;
455 fontMetrics.width = 0;
456 }
457 else if (code.length == 1)
458 textExtents1 ((Sdk7FontObject) font, code[0], fontMetrics,
459 paintCache, boundsCache);
460 else
461 {
462 text = new char[code.length];
463
464 for (i = 0; i < code.length; ++i)
465 text[i] = (char) code[i];
466
467 paintCache.getTextBounds (text, 0, code.length,
468 boundsCache);
469 width = paintCache.measureText (text, 0, code.length);
470
471 fontMetrics.lbearing = (short) boundsCache.left;
472 fontMetrics.rbearing = (short) boundsCache.right;
473 fontMetrics.ascent = (short) -boundsCache.top;
474 fontMetrics.descent = (short) boundsCache.bottom;
475 fontMetrics.width = (short) Math.round (width);
476 }
477 }
478
479 @Override
480 public int
481 encodeChar (FontObject fontObject, char charCode)
482 {
483 return charCode;
484 }
485
486 @Override
487 public int
488 draw (FontObject fontObject, EmacsGC gc, EmacsDrawable drawable,
489 int[] chars, int x, int y, int backgroundWidth,
490 boolean withBackground)
491 {
492 Rect backgroundRect, bounds;
493 Sdk7FontObject sdk7FontObject;
494 char[] charsArray;
495 int i;
496 Canvas canvas;
497 Paint paint;
498
499 sdk7FontObject = (Sdk7FontObject) fontObject;
500 charsArray = new char[chars.length];
501
502 for (i = 0; i < chars.length; ++i)
503 charsArray[i] = (char) chars[i];
504
505 backgroundRect = new Rect ();
506 backgroundRect.top = y - sdk7FontObject.ascent;
507 backgroundRect.left = x;
508 backgroundRect.right = x + backgroundWidth;
509 backgroundRect.bottom = y + sdk7FontObject.descent;
510
511 canvas = drawable.lockCanvas (gc);
512
513 if (canvas == null)
514 return 0;
515
516 paint = gc.gcPaint;
517 paint.setStyle (Paint.Style.FILL);
518
519 if (withBackground)
520 {
521 paint.setColor (gc.background | 0xff000000);
522 canvas.drawRect (backgroundRect, paint);
523 paint.setColor (gc.foreground | 0xff000000);
524 }
525
526 paint.setTextSize (sdk7FontObject.pixelSize);
527 paint.setTypeface (sdk7FontObject.typeface.typeface);
528 paint.setAntiAlias (true);
529 canvas.drawText (charsArray, 0, chars.length, x, y, paint);
530
531 bounds = new Rect ();
532 paint.getTextBounds (charsArray, 0, chars.length, bounds);
533 bounds.offset (x, y);
534 bounds.union (backgroundRect);
535 drawable.damageRect (bounds);
536 paint.setAntiAlias (false);
537 return 1;
538 }
539 };