X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Forg%2Fibex%2Fgraphics%2FFreetype.c;h=62a2f7c61199faf9c7ac99bb6f365414439aaa72;hb=2d6763644359578428d56d004b998edd10463a84;hp=f65f5c85af4a538bdcec0fd7c17c9e1eaf816d78;hpb=8e190fb0ff508ccf4962bbfbf8295a431805c12b;p=org.ibex.core.git diff --git a/src/org/ibex/graphics/Freetype.c b/src/org/ibex/graphics/Freetype.c index f65f5c8..62a2f7c 100644 --- a/src/org/ibex/graphics/Freetype.c +++ b/src/org/ibex/graphics/Freetype.c @@ -3,8 +3,6 @@ #include #include -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,92 @@ 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); +} + +// if the path is more than 16k chars long, we're screwed anyways... +static char path[1024 * 16]; +static int pathlen = 0; +static int current_x; +static int current_y; + +static void append(FT_Pos x, FT_Pos y) { + sprintf(path + pathlen, "%d,%d ", x - current_x, y - current_y); + pathlen += strlen(path + pathlen); +} +static int moveto(FT_Vector* to, void* user) { + if (pathlen > 0) { + path[pathlen++] = 'z'; + path[pathlen++] = ' '; } + path[pathlen++] = 'm'; + path[pathlen++] = ' '; + append(to->x, to->y); + current_x = to->x; current_y = to->y; + return 0; +} +static int lineto(FT_Vector* to, void* user) { + path[pathlen++] = 'l'; + path[pathlen++] = ' '; + append(to->x, to->y); + current_x = to->x; current_y = to->y; + return 0; +} +static int conicto(FT_Vector* control, FT_Vector* to, void* user) { + path[pathlen++] = 'q'; + path[pathlen++] = ' '; + append(control->x, control->y); + append(to->x, to->y); + current_x = to->x; current_y = to->y; + return 0; +} +static int cubicto(FT_Vector* control1, FT_Vector* control2, FT_Vector* to, void* user) { + path[pathlen++] = 'c'; + path[pathlen++] = ' '; + append(control1->x, control1->y); + append(control2->x, control2->y); + append(to->x, to->y); + current_x = to->x; current_y = to->y; + return 0; } +static FT_Outline_Funcs buildPath = { &moveto, &lineto, &conicto, &cubicto, 0, 0 }; +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; + + pathlen = 0; current_x = 0; current_y = 0; + FT_Outline_Decompose(&face->glyph->outline, &buildPath, NULL); + path[pathlen++] = 'z'; + path[pathlen++] = ' '; + path[pathlen++] = 'm'; + path[pathlen++] = ' '; + append(0, 0); + path[pathlen++] = ' '; + user_info[7] = (int)&path; + user_info[8] = pathlen; +} // Kerning code; add back in later /* @@ -105,12 +208,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; -}