X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Ftranslators%2FFreetype.c;h=2a1c798f858f58d4c085e875eba625fa28325f96;hb=da1f843588c8bd2b2c7cc74a5b4ffff8d57ab712;hp=adef007b716a10d1804c87c008043a2b0e182015;hpb=da638c8e64a289bb525066cd356d0dd5149e26ea;p=org.ibex.core.git diff --git a/src/org/ibex/translators/Freetype.c b/src/org/ibex/translators/Freetype.c index adef007..2a1c798 100644 --- a/src/org/ibex/translators/Freetype.c +++ b/src/org/ibex/translators/Freetype.c @@ -1 +1,107 @@ // Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL] + +#include +#include + +/* 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. + + The VM will pause after initialization. When unpaused, it expects + that: + + user_info[0] = ptr to font byte stream in memory + user_info[1] = length of font stream + user_info[2] = unicode index of first glyph to render + user_info[3] = unicode index of last glyph to render + user_info[4] = point size to render in + + The VM will then iterate over the requested glyphs, performing the + following actions for each glyph: + + - render the glyph + - store the address of the glyph bitmap in user_info[5] + - store the width of the glyph bitmap in user_info[6] + - store the height of the glyph bitmap in user_info[7] + - store the font's ascender into user_info[8] + - store the font's height into user_info[9] + - store the glyph's ascender into user_info[10] + - store the glyph's advance into user_info[11] + + The VM will then pause after each glyph. The VM should not be + unpaused after the last glyph until the next glyph set has been + configured in user_info (ie it does not pause twice). + +*/ + +extern char *user_info[1024]; + +#define FT_Check(expr) do { \ + if((expr) != 0) { \ + errprint(#expr " failed\n"); \ + exit(EXIT_FAILURE); \ + } \ +} while(0) + +#define max(a, b) ((a) > (b) ? (a) : (b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) + +static int errprint(const char *s) { + int l = strlen(s); + int n; + while(l) { + n = write(STDERR_FILENO,s,l); + if(n < 0) return n; + l -= n; + s += n; + } + return 0; +} + +extern void _pause(); + +int freetype_main() { + 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(;;) { + + _pause(); + FT_Check(FT_Set_Char_Size(face, 0, ((int)user_info[4]) * 64, 72, 72)); + for(charcode = (int)user_info[2]; charcode <= (int)user_info[3]; charcode++) { + + 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[5] = (char*)face->glyph->bitmap.buffer; + user_info[6] = (char*)face->glyph->bitmap.width; + user_info[7] = (char*)face->glyph->bitmap.rows; + user_info[8] = (char*)(face->size->metrics.ascender >> 6); + user_info[9] = (char*)((-1 * face->size->metrics.descender) >> 6); + user_info[10] = (char*)(face->glyph->metrics.horiBearingY >> 6); + user_info[11] = (char*)(face->glyph->advance.x >> 6); + + } + } +} + + +// Kerning code; add back in later +/* +if (old_glyph_index != -1) { + if (FT_HAS_KERNING(face)) { + FT_Check(FT_Get_Kerning(face, old_glyph_index, glyph_index, 0, &kerning)); + x += kerning.x >> 6; + } else { + x += face->glyph->advance.x >> 6; + } +} +old_glyph_index = glyph_index; +*/