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