freetype fixes
authorbrian <brian@brianweb.net>
Wed, 14 Apr 2004 01:08:53 +0000 (01:08 +0000)
committerbrian <brian@brianweb.net>
Wed, 14 Apr 2004 01:08:53 +0000 (01:08 +0000)
darcs-hash:20040414010853-24bed-ad5d47a11a86eebba68ace9f67110276b9e44276.gz

Makefile
src/org/ibex/graphics/Font.java
src/org/ibex/graphics/Freetype.c

index 469f066..e8f2eb2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -149,7 +149,7 @@ build/class/org/ibex/util/MIPSApps.class: build/mips/mipsapps.mips .install_nest
        mkdir -p build/java/org/ibex/util
        @echo -e "\n\033[1mtranslating        .mips -> .class:  $<\033[0m"
        java -cp upstream/nestedvm/build:upstream/nestedvm/upstream/build/bcel-5.1/bcel-5.1.jar \
-               org.xwt.mips.Compiler org.ibex.translators.MIPSApps $< -outfile $@
+               org.xwt.mips.Compiler org.ibex.util.MIPSApps $< -outfile $@
 #-o onepage,pagesize=8m
 
 compile: .compile
@@ -325,8 +325,8 @@ build/mips/mipsapps.mips: build/mips/org/ibex/graphics/Freetype.c.o build/mips/o
        upstream/install/bin/mips-unknown-elf-gcc \
                --static \
                -march=mips1 \
-               -T upstream/mips/org/xwt/mips/linker.ld \
-               -L upstream/mips/build/org/xwt/mips/ \
+               -T upstream/nestedvm/src/org/xwt/mips/linker.ld \
+               -L upstream/nestedvm/build/org/xwt/mips/ \
                -L upstream/freetype-2.1.4/src/objs \
                -L upstream/libmspack-20030726/build-mips-unknown-elf/ \
                -o $@ \
index 47ba25b..6df9899 100644 (file)
@@ -6,6 +6,7 @@ import java.util.Hashtable;
 import org.ibex.js.*;
 import org.xwt.mips.*;
 import org.ibex.plat.*;
+import org.xwt.mips.Runtime;
 
 // FEATURE: this could be cleaner
 /** encapsulates a single font (a set of Glyphs) */
@@ -112,52 +113,68 @@ public class Font {
 
     // FEATURE: use streams, not memoryfont's
     // FEATURE: kerning pairs
-    private static int mem_allocated = 0;
-    private static org.xwt.mips.Runtime vm = null;
-    private static Stream loadedStream = null;
+    private static final Runtime rt;
+    private static Stream loadedStream;
+    private static int loadedStreamAddr;
 
-    public static void loadFontByteStream(Stream res) {
+    static {
+        try {
+            rt = (Runtime)Class.forName("org.ibex.util.MIPSApps").newInstance();
+        } catch(Exception e) {
+            throw new Error("Error instansiating freetype");
+        }
+        rt.start(new String[]{"freetype"});
+        rt.execute();
+        rtCheck();
+    }
+    
+    private static void rtCheck() { if(rt.getState() != Runtime.PAUSED) throw new Error("Freetype exited " + rt.exitStatus()); }
+    
+    private static void loadFontByteStream(Stream res) {
+        if(loadedStream == res) return;
+        
         try {
             Log.info(Font.class, "loading font " + res);
-            loadedStream = res;
             InputStream is = Stream.getInputStream(res);
             byte[] fontstream = InputStreamToByteArray.convert(is);
-            vm = (org.xwt.mips.Runtime)Class.forName("org.ibex.util.MIPSApps").newInstance();
-            int baseAddr = vm.sbrk(fontstream.length);
-            vm.copyout(fontstream, baseAddr, fontstream.length);
-            vm.setUserInfo(0, baseAddr);
-            vm.setUserInfo(1, fontstream.length);
-            vm.start(new String[]{ "freetype" });
-            vm.execute();
-            if(vm.getState() == org.xwt.mips.Runtime.DONE) throw new Error("Freetype VM exited: " + vm.exitStatus());
+            rt.free(loadedStreamAddr);
+            loadedStreamAddr = rt.xmalloc(fontstream.length);
+            rt.copyout(fontstream, loadedStreamAddr, fontstream.length);
+            if(rt.call("load_font", loadedStreamAddr, fontstream.length) != 0)
+                throw new RuntimeException("load_font failed"); // FEATURE: better error
+            rtCheck();
+            loadedStream = res;
         } catch (Exception e) {
+            // FEATURE: Better error reporting (thow an exception?)
             Log.info(Font.class, e);
         }
     }
 
-    public static synchronized void renderGlyph(Font.Glyph glyph) throws IOException {
+    private static synchronized void renderGlyph(Font.Glyph glyph) throws IOException {
         try {
             Log.debug(Font.class, "rasterizing glyph " + glyph.c + " of font " + glyph.font);
             if (loadedStream != glyph.font.stream) loadFontByteStream(glyph.font.stream);
-            vm.setUserInfo(2, (int)glyph.c);
-            vm.setUserInfo(3, (int)glyph.c);
-            vm.setUserInfo(4, glyph.font.pointsize);
+            
             long start = System.currentTimeMillis();
-            vm.execute();
-            glyph.font.max_ascent = vm.getUserInfo(8);
-            glyph.font.max_descent = vm.getUserInfo(9);
-            glyph.baseline = vm.getUserInfo(10);
-            glyph.advance = vm.getUserInfo(11);
             
-            glyph.width = vm.getUserInfo(6);
-            glyph.height = vm.getUserInfo(7);
+            rt.call("render",glyph.c,glyph.font.pointsize);
+            rtCheck();
+            
+            glyph.font.max_ascent = rt.getUserInfo(3);
+            glyph.font.max_descent = rt.getUserInfo(4);
+            glyph.baseline = rt.getUserInfo(5);
+            glyph.advance = rt.getUserInfo(6);
+            
+            glyph.width = rt.getUserInfo(1);
+            glyph.height = rt.getUserInfo(2);
             
             glyph.data = new byte[glyph.width * glyph.height];
-            int addr = vm.getUserInfo(5);
-            vm.copyin(addr, glyph.data, glyph.width * glyph.height);
-            glyph.isLoaded = true;
+            int addr = rt.getUserInfo(0);
+            rt.copyin(addr, glyph.data, glyph.width * glyph.height);
             
+            glyph.isLoaded = true;
         } catch (Exception e) {
+            // FEATURE: Better error reporting (thow an exception?)
             Log.info(Font.class, e);
         }
     }
index f65f5c8..4387aec 100644 (file)
@@ -3,8 +3,6 @@
 #include <unistd.h>
 #include <freetype/freetype.h>
 
-char *user_info[1024];
-
 /* NOTE: _user_info is defined in crt0.c. It points to a 4096 byte
    block of memory that contains 1024 32-bit values that can be set
    with the setUserInfo() method of MIPSEmu.
@@ -36,6 +34,24 @@ char *user_info[1024];
 
 */
 
+#if 0
+extern int user_info[1024];
+#else
+/* HACK: This really doesn't belong here... */
+int user_info[1024];
+
+extern int mspack_main();
+int freetype_main();
+
+int main(int argc, char **argv) {
+    if(argc < 1) return 1;
+    if(strcmp(argv[0],"mspack")==0) return mspack_main();
+    if(strcmp(argv[0],"freetype")==0) return freetype_main();
+    return 1;
+}
+#endif
+
+
 #define FT_Check(expr) do { \
     if((expr) != 0) { \
         errprint(#expr " failed\n"); \
@@ -60,15 +76,19 @@ static int errprint(const char *s) {
 
 extern void _pause();
 
+static FT_Library  library;   /* handle to library     */
+static FT_Face     face;      /* handle to face object */
+
 int freetype_main() {
-    char *fontdata;
+    FT_Check(FT_Init_FreeType(&library));
+    _pause();
+    
+    /*char *fontdata;
     int glyph_index;
     short charcode;
-    FT_Library  library;   /* handle to library     */
-    FT_Face     face;      /* handle to face object */
+
 
     FT_Check(FT_Init_FreeType(&library));
-    FT_Check(FT_New_Memory_Face(library, user_info[0], (int)user_info[1], 0, &face));
 
     for(;;) {
       
@@ -89,9 +109,34 @@ int freetype_main() {
             user_info[11] = (char*)(face->glyph->advance.x >> 6);
 
         }
-    }
+    }*/
+}
+
+int load_font(char *buf, int length) __attribute__((section(".text")));
+int load_font(char *buf, int length) {
+    if(face != NULL) FT_Check(FT_Done_Face(face));
+    face = NULL;
+    return FT_New_Memory_Face(library, buf, length, 0, &face);
 }
 
+int render(int charcode, int size) __attribute__((section(".text")));
+int render(int charcode, int size) {
+    int glyph_index;
+    
+    FT_Check(FT_Set_Char_Size(face, 0, size * 64, 72, 72));
+    
+    glyph_index = FT_Get_Char_Index(face, charcode);
+    FT_Check(FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_FORCE_AUTOHINT));
+    FT_Check(FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL));
+    
+    user_info[0]  = (int)face->glyph->bitmap.buffer;
+    user_info[1]  = face->glyph->bitmap.width;
+    user_info[2]  = face->glyph->bitmap.rows;
+    user_info[3]  = face->size->metrics.ascender >> 6;
+    user_info[4]  = (-1 * face->size->metrics.descender) >> 6;
+    user_info[5] = face->glyph->metrics.horiBearingY >> 6;
+    user_info[6] = face->glyph->advance.x >> 6;
+}
 
 // Kerning code; add back in later
 /*
@@ -105,12 +150,3 @@ if (old_glyph_index != -1) {
 }
 old_glyph_index = glyph_index;
 */
-
-
-extern int mspack_main();
-int main(int argc, char **argv) {
-  if(argc < 1) return 1;
-  if(strcmp(argv[0],"mspack")==0) return mspack_main();
-  if(strcmp(argv[0],"freetype")==0) return freetype_main();
-  return 1;
-}