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
freetypemodinit(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
Face_haschar(void * fp)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
Face_loadglyph(void * fp)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
Freetype_newface(void * fp)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
Freetype_newmemface(void * fp)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
Face_setcharsize(void * fp)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
Face_settransform(void * fp)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
freeface(Heap * h,int swept)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*
ckface(Freetype_Face * 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