1
2 package org.xwt;
3 import org.xwt.translators.*;
4 import org.xwt.util.*;
5 import org.xwt.js.*;
6 import java.util.*;
7
8 public class Glyph {
9 public char c;
10 public int max_ascent;
11 public int max_descent;
12 public int baseline;
13 public int advance;
14 public int pointsize;
15 public Picture p;
16 public Res res;
17 public boolean rendered = false;
18
19
20 private static Cache glyphCache = new Cache();
21
22 private static Queue glyphsToBeRendered = new Queue(255);
23 private static Freetype freetype = new Freetype();
24
25 private static Scheduler.Task glyphRenderingTask = new Scheduler.Task() {
26 public Object call(Object arg) {
27 Glyph g = (Glyph)glyphsToBeRendered.remove(false);
28 if (g == null) return null;
29 if (g.p != null) return null;
30 Log.log(Glyph.class, "rendering glyph " + g.c);
31 freetype.renderGlyph(g.res, g);
32 g.rendered = true;
33 Scheduler.add(this);
34 return null;
35 }
36 };
37
38
49 public static long rasterizeGlyphs(final Res res, final int pointsize, final String text, PixelBuffer pb, int textcolor,
50 int x, int y, int cx1, int cy1, int cx2, int cy2, final Callback callback) {
51 boolean ret = true;
52 int width = 0;
53 int height = 0;
54 for(int i=0; i<text.length(); i++) {
55 final char c = text.charAt(i);
56 Glyph g = (Glyph)glyphCache.get(res, new Integer((((int)c) << 16) | pointsize));
57 if (g == null) {
58 g = new Glyph();
59 g.c = c;
60 g.pointsize = pointsize;
61 g.res = res;
62 glyphCache.put(res, new Integer((((int)c) << 16) | pointsize), g);
63 glyphsToBeRendered.prepend(g);
64 }
65 if (g.rendered && ret) {
66 if (pb != null && g.p != null)
67 pb.drawPictureAlphaOnly(g.p, x, y + g.max_ascent - g.baseline, cx1, cy1, cx2, cy2, textcolor);
68 x += g.advance;
69 width += g.advance;
70 height = java.lang.Math.max(height, g.max_ascent + g.max_descent);
71 } else {
72 glyphsToBeRendered.prepend(g);
73 Scheduler.add(glyphRenderingTask);
74 ret = false;
75 }
76 }
77 if (!ret) Scheduler.add(new Scheduler.Task() { public Object call(Object arg) {
78 for(int i=0; i<text.length(); i++) {
79 Glyph g = (Glyph)glyphCache.get(res, new Integer((((int)text.charAt(i)) << 16) | pointsize));
80 if (g == null || !g.rendered) {
81 Scheduler.add(this);
82 return null;
83 }
84 }
85 callback.call(null);
86 return null;
87 }});
88
89 if (ret) return ((long)width << 16) | (long)height;
90 for(int i=32; i<128; i++) {
91 Glyph g = (Glyph)glyphCache.get(res, new Integer((i << 16) | pointsize));
92 if (g == null) {
93 g = new Glyph();
94 g.c = (char)i;
95 g.pointsize = pointsize;
96 g.res = res;
97 glyphCache.put(res, new Integer((i << 16) | pointsize), g);
98 glyphsToBeRendered.append(g);
99 }
100 }
101 return -1;
102 }
103 }
104