3 import org.ibex.nestedvm.Runtime;
4 import org.ibex.nestedvm.Interpreter;
8 import java.awt.image.*;
9 import java.awt.event.*;
12 public class FreeTypeDemo {
14 private static final int OURWIDTH=640;
15 private static final int OURHEIGHT=256;
16 private static final int BASELINE=160;
17 private byte[] render = new byte[OURWIDTH*OURHEIGHT];
18 private int size = 72;
19 private StringBuffer sb = new StringBuffer();
23 private Runnable renderThread;
24 private String theText;
25 private boolean renderNeeded;
34 public static void main(String[] argv) throws Exception {
35 new FreeTypeDemo(argv);
38 public FreeTypeDemo(String[] argv) throws Exception {
39 if(argv.length >= 2 && argv[1].startsWith("int")) {
41 rt = new Interpreter("build/FreeTypeDemoHelper.mips");
43 rt = (Runtime) Class.forName("tests.FreeTypeDemoHelper").newInstance();
47 rt.start(new String[]{ "freetype.mips"});
48 if(rt.execute()) throw new Error("freetype.mips exited");
50 byte[] font = InputStreamToByteArray.convert(new FileInputStream(argv[0]));
51 int fontAddr = rt.malloc(font.length);
52 if(fontAddr == 0) throw new Error("malloc() failed");
53 rt.copyout(font,fontAddr,font.length);
55 rt.setUserInfo(0,fontAddr);
56 rt.setUserInfo(1,font.length);
58 renderAddr = rt.malloc(OURWIDTH*OURHEIGHT);
59 if(renderAddr == 0) throw new Error("malloc() failed");
61 if(rt.execute()) throw new Error("freetype.mips exited (" + rt.getUserInfo(1) +")");
65 frame = new JFrame("FreeTypeDemo - " + name);
66 frame.setSize(OURWIDTH,OURHEIGHT);
68 frame.getContentPane().add(view,BorderLayout.CENTER);
69 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
72 renderThread = new Runnable() {
76 synchronized(this) { while(!renderNeeded) wait(); renderNeeded = false; }
77 renderText(theText==null ? "" : theText);
79 } catch(Exception e) { throw new Error(e); }
82 new Thread(renderThread).start();
86 private static ColorModel cmodel = new DirectColorModel(8, 0xff,0xff,0xff);
87 private void createImage() {
88 for(int i=0;i<OURHEIGHT;i++)
89 for(int j=0;j<OURWIDTH;j++)
90 render[i*OURWIDTH+j] = (byte)((~(render[i*OURWIDTH+j]&0xff))&0xff);
91 image = Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(OURWIDTH, OURHEIGHT, cmodel, render, 0, OURWIDTH));
92 MediaTracker mediatracker = new MediaTracker(new Canvas());
93 mediatracker.addImage(image, 1);
94 try { mediatracker.waitForAll(); } catch (InterruptedException e) { }
95 mediatracker.removeImage(image);
97 private void renderText(String s) {
99 byte[] b = (s+"\0").getBytes("UTF-16BE");
100 if(stringSize < b.length) {
101 System.err.println("reallocing the string space");
102 if(stringAddr != 0) rt.free(stringAddr);
103 stringAddr = rt.malloc(b.length*2);
104 if(stringAddr == 0) throw new Error("malloc failed");
105 stringSize = b.length*2;
107 rt.copyout(b,stringAddr,b.length);
108 long start = System.currentTimeMillis();
109 if(rt.call("render",new int[]{stringAddr,size,renderAddr,OURWIDTH,OURHEIGHT,BASELINE})==0)
110 throw new Error("render() failed");
111 System.out.println(name + ": Render of: " + s + " took " + (System.currentTimeMillis()-start) + " ms");
112 rt.copyin(renderAddr,render,render.length);
115 } catch(Exception e) {
120 private void keyPress(char c) {
121 if(c == '\n' || c == '\r') {
123 theText = "Press any key";
124 } else if(c == '+' || c == '-') {
125 size += (c=='+'?1:-1) * 8;
126 System.out.println("New size: " + size);
129 theText = sb.toString();
131 synchronized(renderThread) { renderNeeded = true; renderThread.notify(); }
134 public class View extends JComponent {
135 public void paintComponent(Graphics g) {
136 g.drawImage(image,0,0,OURWIDTH,OURHEIGHT,0,0,OURWIDTH,OURHEIGHT,null);
139 addKeyListener(new KeyAdapter() {
140 public void keyTyped(KeyEvent e) {
141 keyPress(e.getKeyChar());
144 setPreferredSize(new Dimension(OURWIDTH,OURHEIGHT));
147 private static class InputStreamToByteArray {
149 /** scratch space for isToByteArray() */
150 private static byte[] workspace = new byte[16 * 1024];
151 /** Trivial method to completely read an InputStream */
152 public static synchronized byte[] convert(InputStream is) throws IOException {
155 int numread = is.read(workspace, pos, workspace.length - pos);
156 if (numread == -1) break;
157 else if (pos + numread < workspace.length) pos += numread;
160 byte[] temp = new byte[workspace.length * 2];
161 System.arraycopy(workspace, 0, temp, 0, workspace.length);
165 byte[] ret = new byte[pos];
166 System.arraycopy(workspace, 0, ret, 0, pos);