2003/12/28 09:45:29
[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 #if 0
37 /* Use this when org.xwt.mips is updated to the latest org.xwt.mips cvs */
38 extern char *user_info[1024];
39 #else
40 extern char **_user_info;
41 #define user_info _user_info
42 #define _pause emu_pause
43 #endif
44
45 #define FT_Check(expr) do { \
46     if((expr) != 0) { \
47         fprintf(stderr, #expr " failed\n"); \
48         exit(EXIT_FAILURE); \
49     } \
50 } while(0)
51
52 #define max(a, b) ((a) > (b) ? (a) : (b))
53 #define min(a, b) ((a) < (b) ? (a) : (b))
54
55 extern void _pause();
56
57 int freetype_main() {
58     char *fontdata;
59     int glyph_index;
60     short charcode;
61     FT_Library  library;   /* handle to library     */
62     FT_Face     face;      /* handle to face object */
63
64     FT_Check(FT_Init_FreeType(&library));
65     FT_Check(FT_New_Memory_Face(library, user_info[0], (int)user_info[1], 0, &face));
66
67     for(;;) {
68       
69         _pause();
70         FT_Check(FT_Set_Char_Size(face, 0, ((int)user_info[4]) * 64, 72, 72));
71         for(charcode = (int)user_info[2]; charcode <= (int)user_info[3]; charcode++) {
72
73             glyph_index = FT_Get_Char_Index(face, charcode);
74             FT_Check(FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_FORCE_AUTOHINT));
75             FT_Check(FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL));
76
77             user_info[5]  = (char*)face->glyph->bitmap.buffer;
78             user_info[6]  = (char*)face->glyph->bitmap.width;
79             user_info[7]  = (char*)face->glyph->bitmap.rows;
80             user_info[8]  = (char*)(face->size->metrics.ascender >> 6);
81             user_info[9]  = (char*)((-1 * face->size->metrics.descender) >> 6);
82             user_info[10] = (char*)(face->glyph->metrics.horiBearingY >> 6);
83             user_info[11] = (char*)(face->glyph->advance.x >> 6);
84
85         }
86     }
87 }
88
89
90 // Kerning code; add back in later
91 /*
92 if (old_glyph_index != -1) {
93   if (FT_HAS_KERNING(face)) {
94     FT_Check(FT_Get_Kerning(face, old_glyph_index, glyph_index, 0, &kerning));
95     x += kerning.x >> 6;
96   } else {
97     x += face->glyph->advance.x >> 6;
98   }
99 }
100 old_glyph_index = glyph_index;
101 */