tons of stuff
[nestedvm.git] / src / tests / FreeTypeDemo.java
1 package tests;
2
3 import org.ibex.nestedvm.Runtime;
4 import org.ibex.nestedvm.Interpreter;
5
6 import javax.swing.*;
7 import java.awt.*;
8 import java.awt.image.*;
9 import java.awt.event.*;
10 import java.io.*;
11
12 public class FreeTypeDemo {
13     private JFrame frame;
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();
20     private View view;
21     private Image image;
22     
23     private Runnable renderThread;
24     private String theText;
25     private boolean renderNeeded;
26     
27     private String name;
28     private Runtime rt;
29     
30     int renderAddr;
31     int stringAddr;
32     int stringSize;
33     
34     public static void main(String[] argv) throws Exception {
35         new FreeTypeDemo(argv);
36     }
37     
38     public FreeTypeDemo(String[] argv) throws Exception {
39         if(argv.length >= 2 && argv[1].startsWith("int")) {
40             name = "Interpreter";
41             rt = new Interpreter("build/FreeTypeDemoHelper.mips");
42         } else {
43             rt = (Runtime) Class.forName("tests.FreeTypeDemoHelper").newInstance();
44             name = "Compiler";
45         }
46         
47         rt.start(new String[]{ "freetype.mips"});
48         if(rt.execute()) throw new Error("freetype.mips exited");
49
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);
54         
55         rt.setUserInfo(0,fontAddr);
56         rt.setUserInfo(1,font.length);
57
58         renderAddr = rt.malloc(OURWIDTH*OURHEIGHT);
59         if(renderAddr == 0) throw new Error("malloc() failed");
60         
61         if(rt.execute()) throw new Error("freetype.mips exited (" + rt.getUserInfo(1) +")");
62
63         createImage();
64         
65         frame = new JFrame("FreeTypeDemo - " + name);
66         frame.setSize(OURWIDTH,OURHEIGHT);
67         view = new View();
68         frame.getContentPane().add(view,BorderLayout.CENTER);
69         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
70         frame.show();
71         view.requestFocus();
72         renderThread = new Runnable() {
73             public void run() {
74                 try {
75                     for(;;) {
76                          synchronized(this) { while(!renderNeeded) wait(); renderNeeded = false; }
77                         renderText(theText==null ? "" : theText);
78                     }
79                 } catch(Exception e) { throw new Error(e); }
80             }
81         };
82         new Thread(renderThread).start();
83         keyPress('\n');
84     }
85    
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);
96     }
97     private void renderText(String s) {
98         try {
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;
106             }
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);
113             createImage();
114             view.repaint();
115         } catch(Exception e) {
116             throw new Error(e);
117         }
118     }
119     
120     private void keyPress(char c) {
121         if(c == '\n' || c == '\r') {
122             sb.setLength(0);
123             theText = "Press any key";
124         } else if(c == '+' || c == '-') {
125             size += (c=='+'?1:-1) * 8;
126             System.out.println("New size: " + size);
127         } else {
128             sb.append(c);
129             theText = sb.toString();
130         }
131         synchronized(renderThread) { renderNeeded = true; renderThread.notify(); }
132     }
133                 
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);
137         }
138         public View() {
139             addKeyListener(new KeyAdapter() {
140                 public void keyTyped(KeyEvent e) {
141                     keyPress(e.getKeyChar());
142                 }
143             });
144             setPreferredSize(new Dimension(OURWIDTH,OURHEIGHT));
145         }
146     }
147     private static class InputStreamToByteArray {
148
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 {
153             int pos = 0;
154             while (true) {
155                 int numread = is.read(workspace, pos, workspace.length - pos);
156                 if (numread == -1) break;
157                 else if (pos + numread < workspace.length) pos += numread;
158                 else {
159                     pos += numread;
160                     byte[] temp = new byte[workspace.length * 2];
161                     System.arraycopy(workspace, 0, temp, 0, workspace.length);
162                     workspace = temp;
163                 }
164             }
165             byte[] ret = new byte[pos];
166             System.arraycopy(workspace, 0, ret, 0, pos);
167             return ret;
168         }
169     }
170 }
171