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