X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2FFont.java;h=dc4f41e84080ce8be5073ed478ce1aacd527948b;hb=9c2602143956cd39ecf5ef4c9eb31f5f56b5bd66;hp=0de820410e388f25dd79983236270bdb69a56222;hpb=1ab599d574a6739e6d1c6685fb65bfddf20137ea;p=org.ibex.core.git diff --git a/src/org/xwt/Font.java b/src/org/xwt/Font.java index 0de8204..dc4f41e 100644 --- a/src/org/xwt/Font.java +++ b/src/org/xwt/Font.java @@ -6,34 +6,40 @@ import org.xwt.js.*; import java.util.*; import java.io.*; +/** encapsulates a single font (a set of Glyphs) */ public class Font { - private Font(Res res, int pointsize) { this.res = res; this.pointsize = pointsize; } + private Font(Stream res, int pointsize) { this.res = res; this.pointsize = pointsize; } - public final int pointsize; - public final Res res; - public int max_ascent; - public int max_descent; + private static boolean glyphRenderingTaskIsScheduled = false; + + public final int pointsize; ///< the size of the font + public final Stream res; ///< the resource from which this font was loaded + public int max_ascent; ///< the maximum ascent, in pixels + public int max_descent; ///< the maximum descent, in pixels boolean latinCharsPreloaded = false; ///< true if a request to preload ASCII 32-127 has begun - Glyph[] glyphs = new Glyph[65535]; - - public static class Glyph { - public Glyph(char c, Font f) { this.c = c; font = f; } - public char c; - public int baseline; // within the picture, this is the y-coordinate of the baseline - public int advance; // amount to increment the x-coordinate - public Picture p; + Glyph[] glyphs = new Glyph[65535]; ///< the glyphs that comprise this font + + public abstract static class Glyph { + protected Glyph(Font font, char c) { this.font = font; this.c = c; } public final Font font; + public final char c; + public int baseline; ///< within the alphamask, this is the y-coordinate of the baseline + public int advance; ///< amount to increment the x-coordinate + public boolean isLoaded = false; ///< true iff the glyph is loaded + public byte[] alphaChannel = null; + public int width = -1; ///< the width of the glyph + public int height = -1; ///< the height of the glyph + public byte[] data = null; } // Statics ////////////////////////////////////////////////////////////////////// private static final Freetype freetype = new Freetype(); - private static Cache sizeCache = new Cache(100); static final Queue glyphsToBeRendered = new Queue(255); private static Cache fontCache = new Cache(100); - public static Font getFont(Res res, int pointsize) { + public static Font getFont(Stream res, int pointsize) { Font ret = (Font)fontCache.get(res, new Integer(pointsize)); if (ret == null) fontCache.put(res, new Integer(pointsize), ret = new Font(res, pointsize)); return ret; @@ -43,52 +49,63 @@ public class Font { // Methods ////////////////////////////////////////////////////////////////////// /** - * If the glyphs of text are not yet loaded, spawn a - * Task to load them and invoke callback. + * Rasterize the glyphs of text. * - * returns the width (in the high-order int) and height (in the - * low-order int) of the string's rasterization, or -1 if some - * glyphs are not loaded. + * If all the glyphs of text are not yet loaded, + * spawn a Task to load them and then invoke callback. If all + * the glyphs are loaded, rasterize them to the + * PixelBuffer (if non-null). + * + * @returns (width<<32)|height if all glyphs are loaded; else -1 */ public long rasterizeGlyphs(final String text, PixelBuffer pb, int textcolor, int x, int y, int cx1, int cy1, int cx2, int cy2, final Scheduler.Task callback) { boolean encounteredUnrenderedGlyph = false; - int width = 0; - int height = 0; + int width = 0, height = 0; for(int i=0; i>> 32) & 0xffffffff); } public int textheight(String s) { return (int)(textsize(s) & 0xffffffffL); } public long textsize(String s) { @@ -101,10 +118,12 @@ public class Font { static final Scheduler.Task glyphRenderingTask = new Scheduler.Task() { public void perform() { Glyph g = (Glyph)glyphsToBeRendered.remove(false); - if (g == null) return; - if (g.p != null) { perform(); return; } - Log.log(Glyph.class, "rendering glyph " + g.c); - try { freetype.renderGlyph(g); } catch (IOException e) { Log.log(Freetype.class, e); } - Scheduler.add(this); + if (g == null) { glyphRenderingTaskIsScheduled = false; return; } + if (g.isLoaded) { perform(); /* tailcall to the next glyph */ return; } + //Log.info(Glyph.class, "rendering glyph " + g.c); + try { freetype.renderGlyph(g); } catch (IOException e) { Log.info(Freetype.class, e); } + g.isLoaded = true; + Scheduler.add(this); // keep ourselves in the queue until there are no glyphs to render + glyphRenderingTaskIsScheduled = true; } }; }