1 #include "freetype/freetype.h" 2 #include "freetype.h" 3 4 static char* fterrstr(int); 5 6 char* 7 ftnewface(char *path, int index, FTface *f, FTfaceinfo *finfo) 8 { 9 FT_Library ft_lib; 10 FT_Face ft_face; 11 char *err; 12 13 err = fterrstr(FT_Init_FreeType(&ft_lib)); 14 if (err != nil) 15 return err; 16 17 err = fterrstr(FT_New_Face(ft_lib, path, index, &ft_face)); 18 if (err != nil) { 19 FT_Done_FreeType(ft_lib); 20 return err; 21 } 22 23 f->ft_lib = ft_lib; 24 f->ft_face = ft_face; 25 finfo->nfaces = ft_face->num_faces; 26 finfo->index = ft_face->face_index; 27 finfo->style = ft_face->style_flags; 28 finfo->height = (FT_MulFix(ft_face->height, ft_face->size->metrics.y_scale)+32)/64; 29 finfo->ascent = (FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale)+32)/64; 30 finfo->familyname = ft_face->family_name; 31 finfo->stylename = ft_face->style_name; 32 return nil; 33 } 34 35 char* 36 ftloadmemface(void *buf, int nbytes, int index, FTface *f, FTfaceinfo *finfo) 37 { 38 USED(buf); 39 USED(f); 40 USED(finfo); 41 return "not implemented"; 42 } 43 44 char* 45 ftsetcharsize(FTface f, int pt, int hdpi, int vdpi, FTfaceinfo *finfo) 46 { 47 FT_Face ft_face = f.ft_face; 48 char *err; 49 50 err = fterrstr(FT_Set_Char_Size(ft_face, 0, pt, hdpi, vdpi)); 51 if (err != nil) 52 return err; 53 finfo->height = (FT_MulFix(ft_face->height, ft_face->size->metrics.y_scale)+32)/64; 54 finfo->ascent = (FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale)+32)/64; 55 return nil; 56 } 57 58 void 59 ftsettransform(FTface f, FTmatrix *m, FTvector *v) 60 { 61 /* FTMatrix and FTVector are compatible with FT_Matrix and FT_Vector */ 62 FT_Set_Transform(f.ft_face, (FT_Matrix*)m, (FT_Vector*)v); 63 } 64 65 int 66 fthaschar(FTface f, int c) 67 { 68 return FT_Get_Char_Index(f.ft_face, c) != 0; 69 } 70 71 char* 72 ftloadglyph(FTface f, int ix, FTglyph *g) 73 { 74 FT_Face ft_face = f.ft_face; 75 FT_GlyphSlot ft_glyph; 76 char *err; 77 78 ix = FT_Get_Char_Index(ft_face, ix); 79 err = fterrstr(FT_Load_Glyph(ft_face, ix, FT_LOAD_NO_BITMAP|FT_LOAD_RENDER|FT_LOAD_CROP_BITMAP)); 80 if (err != nil) 81 return err; 82 83 ft_glyph = ft_face->glyph; 84 g->top = ft_glyph->bitmap_top; 85 g->left = ft_glyph->bitmap_left; 86 g->height = ft_glyph->bitmap.rows; 87 g->width = ft_glyph->bitmap.width; 88 g->advx = ft_glyph->advance.x; 89 g->advy = ft_glyph->advance.y; 90 g->bpr = ft_glyph->bitmap.pitch; 91 g->bitmap = ft_glyph->bitmap.buffer; 92 return nil; 93 } 94 95 void 96 ftdoneface(FTface f) 97 { 98 if (f.ft_face != nil) 99 FT_Done_Face(f.ft_face); 100 if (f.ft_lib != nil) 101 FT_Done_FreeType(f.ft_lib); 102 } 103 104 /* 105 * get the freetype error strings 106 */ 107 108 typedef struct FTerr FTerr; 109 struct FTerr { 110 int code; 111 char* text; 112 }; 113 114 #define FT_NOERRORDEF_(l,c,t) 115 #define FT_ERRORDEF_(l,c,t) c,t, 116 117 static FTerr fterrs[] = { 118 #include "freetype/fterrdef.h" 119 -1, "", 120 }; 121 122 static char* 123 fterrstr(int code) 124 { 125 int i; 126 if (code == 0) 127 return nil; 128 for (i = 0; fterrs[i].code > 0; i++) { 129 if (fterrs[i].code == code) 130 return fterrs[i].text; 131 } 132 return "unknown FreeType error"; 133 } 134 135