f8172d956e27036a88cd6894bfe3c829c4ec328b
[org.ibex.core.git] / src / org / xwt / translators / Freetype.c
1 // Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
2
3 #include <unistd.h>
4 #include <freetype/freetype.h>
5
6 /* NOTE: _user_info is defined in crt0.c. It points to a 4096 byte
7    block of memory that contains 1024 32-bit values that can be set
8    with the setUserInfo() method of MIPSEmu.
9
10    The VM will pause after initialization.  When unpaused, it expects
11    that:
12
13      user_info[0] = ptr to font byte stream in memory
14      user_info[1] = length of font stream
15      user_info[2] = unicode index of first glyph to render
16      user_info[3] = unicode index of last glyph to render
17      user_info[4] = point size to render in
18
19    The VM will then iterate over the requested glyphs, performing the
20    following actions for each glyph:
21    
22      - render the glyph
23      - store the address of the glyph bitmap in user_info[5]
24      - store the width of the glyph bitmap in user_info[6]
25      - store the height of the glyph bitmap in user_info[7]
26      - store the font's ascender into user_info[8]
27      - store the font's height into user_info[9]
28      - store the glyph's ascender into user_info[10]
29      - store the glyph's advance into user_info[11]
30
31    The VM will then pause after each glyph.  The VM should not be
32    unpaused after the last glyph until the next glyph set has been
33    configured in user_info (ie it does not pause twice).
34
35 */
36
37 #if 0
38 /* Use this when org.xwt.mips is updated to the latest org.xwt.mips cvs */
39 extern char *user_info[1024];
40 #else
41 extern char **_user_info;
42 #define user_info _user_info
43 #define _pause emu_pause
44 #endif
45
46 #define FT_Check(expr) do { \
47     if((expr) != 0) { \
48         errprint(#expr " failed\n"); \
49         exit(EXIT_FAILURE); \
50     } \
51 } while(0)
52
53 #define max(a, b) ((a) > (b) ? (a) : (b))
54 #define min(a, b) ((a) < (b) ? (a) : (b))
55
56 static int errprint(const char *s) {
57     int l = strlen(s);
58     int n;
59     while(l) {
60         n = write(STDERR_FILENO,s,l);
61         if(n < 0) return n;
62         l -= n;
63         s += n;
64     }
65     return 0;
66 }
67
68 extern void _pause();
69
70 int freetype_main() {
71     char *fontdata;
72     int glyph_index;
73     short charcode;
74     FT_Library  library;   /* handle to library     */
75     FT_Face     face;      /* handle to face object */
76
77     FT_Check(FT_Init_FreeType(&library));
78     FT_Check(FT_New_Memory_Face(library, user_info[0], (int)user_info[1], 0, &face));
79
80     for(;;) {
81       
82         _pause();
83         FT_Check(FT_Set_Char_Size(face, 0, ((int)user_info[4]) * 64, 72, 72));
84         for(charcode = (int)user_info[2]; charcode <= (int)user_info[3]; charcode++) {
85
86             glyph_index = FT_Get_Char_Index(face, charcode);
87             FT_Check(FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_FORCE_AUTOHINT));
88             FT_Check(FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL));
89
90             user_info[5]  = (char*)face->glyph->bitmap.buffer;
91             user_info[6]  = (char*)face->glyph->bitmap.width;
92             user_info[7]  = (char*)face->glyph->bitmap.rows;
93             user_info[8]  = (char*)(face->size->metrics.ascender >> 6);
94             user_info[9]  = (char*)((-1 * face->size->metrics.descender) >> 6);
95             user_info[10] = (char*)(face->glyph->metrics.horiBearingY >> 6);
96             user_info[11] = (char*)(face->glyph->advance.x >> 6);
97
98         }
99     }
100 }
101
102
103 // Kerning code; add back in later
104 /*
105 if (old_glyph_index != -1) {
106   if (FT_HAS_KERNING(face)) {
107     FT_Check(FT_Get_Kerning(face, old_glyph_index, glyph_index, 0, &kerning));
108     x += kerning.x >> 6;
109   } else {
110     x += face->glyph->advance.x >> 6;
111   }
112 }
113 old_glyph_index = glyph_index;
114 */