1 #include <lib9.h> 2 #include <kernel.h> 3 #include "interp.h" 4 #include "isa.h" 5 #include "runt.h" 6 #include "raise.h" 7 #include "freetypemod.h" 8 #include "freetype.h" 9 10 11 typedef struct Face Face; 12 struct Face { 13 Freetype_Face freetypeface; /* limbo part */ 14 FTface ftface; /* private parts */ 15 }; 16 17 Type* TMatrix; 18 Type* TVector; 19 Type* TFace; 20 Type* TGlyph; 21 22 static uchar Matrixmap[] = Freetype_Matrix_map; 23 static uchar Vectormap[] = Freetype_Vector_map; 24 static uchar Facemap[] = Freetype_Face_map; 25 static uchar Glyphmap[] = Freetype_Glyph_map; 26 27 static void freeface(Heap*, int); 28 static Face* ckface(Freetype_Face*); 29 30 void 31 freetypemodinit(void) 32 { 33 builtinmod("$Freetype", Freetypemodtab, Freetypemodlen); 34 TMatrix = dtype(freeheap, sizeof(Freetype_Matrix), Matrixmap, sizeof(Matrixmap)); 35 TVector = dtype(freeheap, sizeof(Freetype_Vector), Vectormap, sizeof(Vectormap)); 36 TFace = dtype(freeface, sizeof(Face), Facemap, sizeof(Facemap)); 37 TGlyph = dtype(freeheap, sizeof(Freetype_Glyph), Glyphmap, sizeof(Glyphmap)); 38 } 39 40 void 41 Face_haschar(void *fp) 42 { 43 F_Face_haschar *f = fp; 44 Face *face; 45 46 *f->ret = 0; 47 face = ckface(f->face); 48 release(); 49 *f->ret = fthaschar(face->ftface, f->c); 50 acquire(); 51 } 52 53 void 54 Face_loadglyph(void *fp) 55 { 56 F_Face_loadglyph *f = fp; 57 Heap *h; 58 Face *face; 59 Freetype_Glyph *g; 60 FTglyph ftg; 61 int n, i, s1bpr, s2bpr; 62 char *err; 63 64 face = ckface(f->face); 65 66 destroy(*f->ret); 67 *f->ret = H; 68 69 release(); 70 err = ftloadglyph(face->ftface, f->c, &ftg); 71 acquire(); 72 if (err != nil) { 73 kwerrstr(err); 74 return; 75 } 76 77 h = heap(TGlyph); 78 if (h == H) { 79 kwerrstr(exNomem); 80 return; 81 } 82 g = H2D(Freetype_Glyph*, h); 83 n = ftg.width*ftg.height; 84 h = heaparray(&Tbyte, n); 85 if (h == H) { 86 destroy(g); 87 kwerrstr(exNomem); 88 return; 89 } 90 g->bitmap = H2D(Array*, h); 91 g->top = ftg.top; 92 g->left = ftg.left; 93 g->height = ftg.height; 94 g->width = ftg.width; 95 g->advance.x = ftg.advx; 96 g->advance.y = ftg.advy; 97 98 s1bpr = ftg.width; 99 s2bpr = ftg.bpr; 100 for (i = 0; i < ftg.height; i++) 101 memcpy(g->bitmap->data+(i*s1bpr), ftg.bitmap+(i*s2bpr), s1bpr); 102 *f->ret = g; 103 } 104 105 void 106 Freetype_newface(void *fp) 107 { 108 F_Freetype_newface *f = fp; 109 Heap *h; 110 Face *face; 111 Freetype_Face *limboface; 112 FTfaceinfo finfo; 113 char *path; 114 char *err; 115 116 destroy(*f->ret); 117 *f->ret = H; 118 119 h = heapz(TFace); 120 if (h == H) { 121 kwerrstr(exNomem); 122 return; 123 } 124 125 face = H2D(Face*, h); 126 limboface = (Freetype_Face*)face; 127 *f->ret = limboface; 128 path = strdup(string2c(f->path)); /* string2c() can call error() */ 129 release(); 130 err = ftnewface(path, f->index, &face->ftface, &finfo); 131 acquire(); 132 free(path); 133 if (err != nil) { 134 *f->ret = H; 135 destroy(face); 136 kwerrstr(err); 137 return; 138 } 139 limboface->nfaces = finfo.nfaces; 140 limboface->index = finfo.index; 141 limboface->style = finfo.style; 142 limboface->height = finfo.height; 143 limboface->ascent = finfo.ascent; 144 limboface->familyname = c2string(finfo.familyname, strlen(finfo.familyname)); 145 limboface->stylename = c2string(finfo.stylename, strlen(finfo.stylename)); 146 *f->ret = limboface; 147 } 148 149 void 150 Freetype_newmemface(void *fp) 151 { 152 F_Freetype_newmemface *f = fp; 153 154 destroy(*f->ret); 155 *f->ret = H; 156 157 kwerrstr("not implemented"); 158 } 159 160 void 161 Face_setcharsize(void *fp) 162 { 163 F_Face_setcharsize *f = fp; 164 Face *face; 165 Freetype_Face *limboface; 166 FTfaceinfo finfo; 167 char *err; 168 169 face = ckface(f->face); 170 limboface = (Freetype_Face*)face; 171 release(); 172 err = ftsetcharsize(face->ftface, f->pts, f->hdpi, f->vdpi, &finfo); 173 acquire(); 174 if (err == nil) { 175 limboface->height = finfo.height; 176 limboface->ascent = finfo.ascent; 177 } 178 retstr(err, f->ret); 179 } 180 181 void 182 Face_settransform(void *fp) 183 { 184 F_Face_settransform *f = fp; 185 FTmatrix *m = nil; 186 FTvector *v = nil; 187 Face *face; 188 189 face = ckface(f->face); 190 191 /* 192 * ftsettransform() has no error return 193 * we have one for consistency - but always nil for now 194 */ 195 destroy(*f->ret); 196 *f->ret = H; 197 198 if (f->m != H) 199 m = (FTmatrix*)(f->m); 200 if (f->v != H) 201 v = (FTvector*)(f->v); 202 release(); 203 ftsettransform(face->ftface, m, v); 204 acquire(); 205 } 206 207 static void 208 freeface(Heap *h, int swept) 209 { 210 Face *face = H2D(Face*, h); 211 212 if (!swept) { 213 destroy(face->freetypeface.familyname); 214 destroy(face->freetypeface.stylename); 215 } 216 release(); 217 ftdoneface(face->ftface); 218 acquire(); 219 memset(&face->ftface, 0, sizeof(face->ftface)); 220 } 221 222 static Face* 223 ckface(Freetype_Face *face) 224 { 225 if (face == nil || face == H) 226 error("nil Face"); 227 if (D2H(face)->t != TFace) 228 error(exType); 229 return (Face*)face; 230 } 231 232