#include "freetype/freetype.h" #include "freetype.h" static char* fterrstr(int); char* ftnewface(char *path, int index, FTface *f, FTfaceinfo *finfo) { FT_Library ft_lib; FT_Face ft_face; char *err; err = fterrstr(FT_Init_FreeType(&ft_lib)); if (err != nil) return err; err = fterrstr(FT_New_Face(ft_lib, path, index, &ft_face)); if (err != nil) { FT_Done_FreeType(ft_lib); return err; } f->ft_lib = ft_lib; f->ft_face = ft_face; finfo->nfaces = ft_face->num_faces; finfo->index = ft_face->face_index; finfo->style = ft_face->style_flags; finfo->height = (FT_MulFix(ft_face->height, ft_face->size->metrics.y_scale)+32)/64; finfo->ascent = (FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale)+32)/64; finfo->familyname = ft_face->family_name; finfo->stylename = ft_face->style_name; return nil; } char* ftloadmemface(void *buf, int nbytes, int index, FTface *f, FTfaceinfo *finfo) { USED(buf); USED(f); USED(finfo); return "not implemented"; } char* ftsetcharsize(FTface f, int pt, int hdpi, int vdpi, FTfaceinfo *finfo) { FT_Face ft_face = f.ft_face; char *err; err = fterrstr(FT_Set_Char_Size(ft_face, 0, pt, hdpi, vdpi)); if (err != nil) return err; finfo->height = (FT_MulFix(ft_face->height, ft_face->size->metrics.y_scale)+32)/64; finfo->ascent = (FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale)+32)/64; return nil; } void ftsettransform(FTface f, FTmatrix *m, FTvector *v) { /* FTMatrix and FTVector are compatible with FT_Matrix and FT_Vector */ FT_Set_Transform(f.ft_face, (FT_Matrix*)m, (FT_Vector*)v); } int fthaschar(FTface f, int c) { return FT_Get_Char_Index(f.ft_face, c) != 0; } char* ftloadglyph(FTface f, int ix, FTglyph *g) { FT_Face ft_face = f.ft_face; FT_GlyphSlot ft_glyph; char *err; ix = FT_Get_Char_Index(ft_face, ix); err = fterrstr(FT_Load_Glyph(ft_face, ix, FT_LOAD_NO_BITMAP|FT_LOAD_RENDER|FT_LOAD_CROP_BITMAP)); if (err != nil) return err; ft_glyph = ft_face->glyph; g->top = ft_glyph->bitmap_top; g->left = ft_glyph->bitmap_left; g->height = ft_glyph->bitmap.rows; g->width = ft_glyph->bitmap.width; g->advx = ft_glyph->advance.x; g->advy = ft_glyph->advance.y; g->bpr = ft_glyph->bitmap.pitch; g->bitmap = ft_glyph->bitmap.buffer; return nil; } void ftdoneface(FTface f) { if (f.ft_face != nil) FT_Done_Face(f.ft_face); if (f.ft_lib != nil) FT_Done_FreeType(f.ft_lib); } /* * get the freetype error strings */ typedef struct FTerr FTerr; struct FTerr { int code; char* text; }; #define FT_NOERRORDEF_(l,c,t) #define FT_ERRORDEF_(l,c,t) c,t, static FTerr fterrs[] = { #include "freetype/fterrdef.h" -1, "", }; static char* fterrstr(int code) { int i; if (code == 0) return nil; for (i = 0; fterrs[i].code > 0; i++) { if (fterrs[i].code == code) return fterrs[i].text; } return "unknown FreeType error"; }