1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the Apache Public Source License 2.0 ("the License").
3 // You may not use this file except in compliance with the License.
7 import org.ibex.nestedvm.Runtime;
8 import org.ibex.nestedvm.Interpreter;
12 import java.awt.image.*;
13 import java.awt.event.*;
16 public class FreeTypeDemo {
18 private static final int OURWIDTH=640;
19 private static final int OURHEIGHT=256;
20 private static final int BASELINE=160;
21 private byte[] render = new byte[OURWIDTH*OURHEIGHT];
22 private int size = 72;
23 private StringBuffer sb = new StringBuffer();
27 private Runnable renderThread;
28 private String theText;
29 private boolean renderNeeded;
38 public static void main(String[] argv) throws Exception {
39 new FreeTypeDemo(argv);
42 public FreeTypeDemo(String[] argv) throws Exception {
43 if(argv.length >= 2 && argv[1].startsWith("int")) {
45 rt = new Interpreter("build/FreeTypeDemoHelper.mips");
47 rt = (Runtime) Class.forName("tests.FreeTypeDemoHelper").newInstance();
51 rt.start(new String[]{ "freetype.mips"});
52 if(rt.execute()) throw new Error("freetype.mips exited");
54 byte[] font = InputStreamToByteArray.convert(new FileInputStream(argv[0]));
55 int fontAddr = rt.malloc(font.length);
56 if(fontAddr == 0) throw new Error("malloc() failed");
57 rt.copyout(font,fontAddr,font.length);
59 rt.setUserInfo(0,fontAddr);
60 rt.setUserInfo(1,font.length);
62 renderAddr = rt.malloc(OURWIDTH*OURHEIGHT);
63 if(renderAddr == 0) throw new Error("malloc() failed");
65 if(rt.execute()) throw new Error("freetype.mips exited (" + rt.getUserInfo(1) +")");
69 frame = new JFrame("FreeTypeDemo - " + name);
70 frame.setSize(OURWIDTH,OURHEIGHT);
72 frame.getContentPane().add(view,BorderLayout.CENTER);
73 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
76 renderThread = new Runnable() {
80 synchronized(this) { while(!renderNeeded) wait(); renderNeeded = false; }
81 renderText(theText==null ? "" : theText);
83 } catch(Exception e) { throw new Error(e); }
86 new Thread(renderThread).start();
90 private static ColorModel cmodel = new DirectColorModel(8, 0xff,0xff,0xff);
91 private void createImage() {
92 for(int i=0;i<OURHEIGHT;i++)
93 for(int j=0;j<OURWIDTH;j++)
94 render[i*OURWIDTH+j] = (byte)((~(render[i*OURWIDTH+j]&0xff))&0xff);
95 image = Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(OURWIDTH, OURHEIGHT, cmodel, render, 0, OURWIDTH));
96 MediaTracker mediatracker = new MediaTracker(new Canvas());
97 mediatracker.addImage(image, 1);
98 try { mediatracker.waitForAll(); } catch (InterruptedException e) { }
99 mediatracker.removeImage(image);
101 private void renderText(String s) {
103 byte[] b = (s+"\0").getBytes("UTF-16BE");
104 if(stringSize < b.length) {
105 System.err.println("reallocing the string space");
106 if(stringAddr != 0) rt.free(stringAddr);
107 stringAddr = rt.malloc(b.length*2);
108 if(stringAddr == 0) throw new Error("malloc failed");
109 stringSize = b.length*2;
111 rt.copyout(b,stringAddr,b.length);
112 long start = System.currentTimeMillis();
113 if(rt.call("render",new int[]{stringAddr,size,renderAddr,OURWIDTH,OURHEIGHT,BASELINE})==0)
114 throw new Error("render() failed");
115 System.out.println(name + ": Render of: " + s + " took " + (System.currentTimeMillis()-start) + " ms");
116 rt.copyin(renderAddr,render,render.length);
119 } catch(Exception e) {
124 private void keyPress(char c) {
125 if(c == '\n' || c == '\r') {
127 theText = "Press any key";
128 } else if(c == '+' || c == '-') {
129 size += (c=='+'?1:-1) * 8;
130 System.out.println("New size: " + size);
133 theText = sb.toString();
135 synchronized(renderThread) { renderNeeded = true; renderThread.notify(); }
138 public class View extends JComponent {
139 public void paintComponent(Graphics g) {
140 g.drawImage(image,0,0,OURWIDTH,OURHEIGHT,0,0,OURWIDTH,OURHEIGHT,null);
143 addKeyListener(new KeyAdapter() {
144 public void keyTyped(KeyEvent e) {
145 keyPress(e.getKeyChar());
148 setPreferredSize(new Dimension(OURWIDTH,OURHEIGHT));
151 private static class InputStreamToByteArray {
153 /** scratch space for isToByteArray() */
154 private static byte[] workspace = new byte[16 * 1024];
155 /** Trivial method to completely read an InputStream */
156 public static synchronized byte[] convert(InputStream is) throws IOException {
159 int numread = is.read(workspace, pos, workspace.length - pos);
160 if (numread == -1) break;
161 else if (pos + numread < workspace.length) pos += numread;
164 byte[] temp = new byte[workspace.length * 2];
165 System.arraycopy(workspace, 0, temp, 0, workspace.length);
169 byte[] ret = new byte[pos];
170 System.arraycopy(workspace, 0, ret, 0, pos);