2003/09/19 08:33:47
[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 <freetype/freetype.h>
4
5 /* NOTE: _user_info is defined in crt0.c. It points to a 4096 byte
6    block of memory that contains 1024 32-bit values that can be set
7    with the setUserInfo() method of MIPSEmu.
8
9    The VM will pause after initialization.  When unpaused, it expects
10    that:
11
12      user_info[0] = ptr to font byte stream in memory
13      user_info[1] = length of font stream
14      user_info[2] = unicode index of first glyph to render
15      user_info[3] = unicode index of last glyph to render
16      user_info[4] = point size to render in
17
18    The VM will then iterate over the requested glyphs, performing the
19    following actions for each glyph:
20    
21      - render the glyph
22      - store the address of the glyph bitmap in user_info[5]
23      - store the width of the glyph bitmap in user_info[6]
24      - store the height of the glyph bitmap in user_info[7]
25      - store the font's ascender into user_info[8]
26      - store the font's height into user_info[9]
27      - store the glyph's ascender into user_info[10]
28      - store the glyph's advance into user_info[11]
29
30    The VM will then pause after each glyph.  The VM should not be
31    unpaused after the last glyph until the next glyph set has been
32    configured in user_info (ie it does not pause twice).
33
34 */
35
36 extern char **_user_info;
37
38 FT_Library  library;   /* handle to library     */
39 FT_Face     face;      /* handle to face object */
40
41 #define FT_Check(expr) do { \
42     if((expr) != 0) { \
43         fprintf(stderr, #expr " failed\n"); \
44         exit(EXIT_FAILURE); \
45     } \
46 } while(0)
47
48 #define max(a, b) ((a) > (b) ? (a) : (b))
49 #define min(a, b) ((a) < (b) ? (a) : (b))
50
51 extern void emu_pause();
52
53 int main(int argc, char** argv) {
54     char *fontdata;
55     int glyph_index;
56     short charcode;
57     
58     FT_Check(FT_Init_FreeType(&library));
59     emu_pause();
60
61     for(;;) {
62         FT_Check(FT_New_Memory_Face(library, _user_info[0], (int)_user_info[1], 0, &face));
63         FT_Check(FT_Set_Char_Size(face, 0, ((int)_user_info[4]) * 64, 72, 72));
64
65         for(charcode = (int)_user_info[2]; charcode <= (int)_user_info[3]; charcode++) {
66
67             glyph_index = FT_Get_Char_Index(face, charcode);
68             FT_Check(FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_FORCE_AUTOHINT));
69             FT_Check(FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL));
70
71             _user_info[5]  = (char*)face->glyph->bitmap.buffer;
72             _user_info[6]  = (char*)face->glyph->bitmap.width;
73             _user_info[7]  = (char*)face->glyph->bitmap.rows;
74             _user_info[8]  = (char*)(face->size->metrics.ascender >> 6);
75             _user_info[9]  = (char*)(face->size->metrics.height >> 6);
76             _user_info[10] = (char*)(face->glyph->metrics.horiBearingY >> 6);
77             _user_info[11] = (char*)(face->glyph->advance.x >> 6);
78
79             emu_pause();
80         }
81     }
82 }
83
84
85 // Kerning code; add back in later
86 /*
87 if (old_glyph_index != -1) {
88   if (FT_HAS_KERNING(face)) {
89     FT_Check(FT_Get_Kerning(face, old_glyph_index, glyph_index, 0, &kerning));
90     x += kerning.x >> 6;
91   } else {
92     x += face->glyph->advance.x >> 6;
93   }
94 }
95 old_glyph_index = glyph_index;
96 */