]> git.imager.perl.org - imager.git/blob - FT2/FT2.xs
631b14770359a255874ce5a5ee992ccd59027232
[imager.git] / FT2 / FT2.xs
1 #define PERL_NO_GET_CONTEXT
2 #ifdef __cplusplus
3 extern "C" {
4 #endif
5 #include "EXTERN.h"
6 #include "perl.h"
7 #include "XSUB.h"
8 #include "imext.h"
9 #include "imperl.h"
10 #include "imft2.h"
11
12 DEFINE_IMAGER_CALLBACKS;
13
14 MODULE = Imager::Font::FT2  PACKAGE = Imager::Font::FT2x     PREFIX=FT2_
15
16 #define FT2_DESTROY(font) i_ft2_destroy(font)
17
18 void
19 FT2_DESTROY(font)
20         Imager::Font::FT2x font
21
22 int
23 FT2_CLONE_SKIP(...)
24     CODE:
25         (void)items;
26         RETVAL = 1;
27     OUTPUT:
28         RETVAL
29
30 MODULE = Imager::Font::FT2  PACKAGE = Imager::Font::FT2
31
32 Imager::Font::FT2x
33 i_ft2_new(name, index)
34         char *name
35         int index
36
37 const char *
38 i_ft2_version(runtime)
39         int runtime
40     PREINIT:
41         char buf[100];
42     CODE:
43         if (!i_ft2_version(runtime, buf, sizeof(buf))) {
44           XSRETURN_EMPTY;
45         }
46         RETVAL = buf;
47     OUTPUT:
48         RETVAL
49
50 undef_int
51 i_ft2_setdpi(font, xdpi, ydpi)
52         Imager::Font::FT2x font
53         int xdpi
54         int ydpi
55
56 void
57 i_ft2_getdpi(font)
58         Imager::Font::FT2x font
59       PREINIT:
60         int xdpi, ydpi;
61       CODE:
62         if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
63           EXTEND(SP, 2);
64           PUSHs(sv_2mortal(newSViv(xdpi)));
65           PUSHs(sv_2mortal(newSViv(ydpi)));
66         }
67
68 undef_int
69 i_ft2_sethinting(font, hinting)
70         Imager::Font::FT2x font
71         int hinting
72
73 undef_int
74 i_ft2_settransform(font, matrix)
75         Imager::Font::FT2x font
76       PREINIT:
77         double matrix[6];
78         int len;
79         AV *av;
80         SV *sv1;
81         int i;
82       CODE:
83         if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
84           croak("i_ft2_settransform: parameter 2 must be an array ref\n");
85         av=(AV*)SvRV(ST(1));
86         len=av_len(av)+1;
87         if (len > 6)
88           len = 6;
89         for (i = 0; i < len; ++i) {
90           sv1=(*(av_fetch(av,i,0)));
91           matrix[i] = SvNV(sv1);
92         }
93         for (; i < 6; ++i)
94           matrix[i] = 0;
95         RETVAL = i_ft2_settransform(font, matrix);
96       OUTPUT:
97         RETVAL
98
99 void
100 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
101         Imager::Font::FT2x font
102         double cheight
103         double cwidth
104         SV *text_sv
105         int utf8
106       PREINIT:
107         i_img_dim bbox[BOUNDING_BOX_COUNT];
108         int i;
109         char *text;
110         STRLEN text_len;
111         int rc;
112       PPCODE:
113         text = SvPV(text_sv, text_len);
114 #ifdef SvUTF8
115         if (SvUTF8(text_sv))
116           utf8 = 1;
117 #endif
118         rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
119         if (rc) {
120           EXTEND(SP, rc);
121           for (i = 0; i < rc; ++i)
122             PUSHs(sv_2mortal(newSViv(bbox[i])));
123         }
124
125 void
126 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
127         Imager::Font::FT2x font
128         double cheight
129         double cwidth
130         char *text
131         int vlayout
132         int utf8
133       PREINIT:
134         i_img_dim bbox[8];
135         int i;
136       PPCODE:
137 #ifdef SvUTF8
138         if (SvUTF8(ST(3)))
139           utf8 = 1;
140 #endif
141         if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
142                          utf8, bbox)) {
143           EXTEND(SP, 8);
144           for (i = 0; i < 8; ++i)
145             PUSHs(sv_2mortal(newSViv(bbox[i])));
146         }
147
148 undef_int
149 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
150         Imager::Font::FT2x font
151         Imager::ImgRaw im
152         i_img_dim tx
153         i_img_dim ty
154         Imager::Color cl
155         double cheight
156         double cwidth
157         int align
158         int aa
159         int vlayout
160         int utf8
161       PREINIT:
162         char *text;
163         STRLEN len;
164       CODE:
165 #ifdef SvUTF8
166         if (SvUTF8(ST(7))) {
167           utf8 = 1;
168         }
169 #endif
170         text = SvPV(ST(7), len);
171         RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
172                             len, align, aa, vlayout, utf8);
173       OUTPUT:
174         RETVAL
175
176 undef_int
177 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text_sv, align, aa, vlayout, utf8)
178         Imager::Font::FT2x font
179         Imager::ImgRaw im
180         i_img_dim tx
181         i_img_dim ty
182         int channel
183         double cheight
184         double cwidth
185         SV *text_sv
186         int align
187         int aa
188         int vlayout
189         int utf8
190       PREINIT:
191         char const *text;
192         STRLEN len;
193       CODE:
194 #ifdef SvUTF8
195         if (SvUTF8(ST(7)))
196           utf8 = 1;
197 #endif
198         text = SvPV(text_sv, len);
199         RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
200                           len, align, aa, vlayout, 1);
201       OUTPUT:
202         RETVAL
203
204 void
205 ft2_transform_box(font, x0, x1, x2, x3)
206         Imager::Font::FT2x font
207         i_img_dim x0
208         i_img_dim x1
209         i_img_dim x2
210         i_img_dim x3
211       PREINIT:
212         i_img_dim box[4];
213       PPCODE:
214         box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
215         ft2_transform_box(font, box);
216           EXTEND(SP, 4);
217           PUSHs(sv_2mortal(newSViv(box[0])));
218           PUSHs(sv_2mortal(newSViv(box[1])));
219           PUSHs(sv_2mortal(newSViv(box[2])));
220           PUSHs(sv_2mortal(newSViv(box[3])));
221
222 void
223 i_ft2_has_chars(handle, text_sv, utf8)
224         Imager::Font::FT2x handle
225         SV  *text_sv
226         int utf8
227       PREINIT:
228         char *text;
229         STRLEN len;
230         char *work;
231         size_t count;
232         size_t i;
233       PPCODE:
234 #ifdef SvUTF8
235         if (SvUTF8(text_sv))
236           utf8 = 1;
237 #endif
238         text = SvPV(text_sv, len);
239         work = mymalloc(len);
240         count = i_ft2_has_chars(handle, text, len, utf8, work);
241         if (GIMME_V == G_ARRAY) {
242           EXTEND(SP, count);
243           for (i = 0; i < count; ++i) {
244             PUSHs(boolSV(work[i]));
245           }
246         }
247         else {
248           EXTEND(SP, 1);
249           PUSHs(sv_2mortal(newSVpv(work, count)));
250         }
251         myfree(work);
252
253 void
254 i_ft2_face_name(handle)
255         Imager::Font::FT2x handle
256       PREINIT:
257         char name[255];
258         size_t len;
259       PPCODE:
260         len = i_ft2_face_name(handle, name, sizeof(name));
261         if (len) {
262           EXTEND(SP, 1);
263           PUSHs(sv_2mortal(newSVpv(name, 0)));
264         }
265
266 undef_int
267 i_ft2_can_face_name()
268
269 void
270 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
271         Imager::Font::FT2x handle
272         SV *text_sv
273         int utf8
274         int reliable_only
275       PREINIT:
276         char const *text;
277         STRLEN work_len;
278         size_t len;
279         char name[255];
280       PPCODE:
281 #ifdef SvUTF8
282         if (SvUTF8(text_sv))
283           utf8 = 1;
284 #endif
285         text = SvPV(text_sv, work_len);
286         len = work_len;
287         while (len) {
288           unsigned long ch;
289           if (utf8) {
290             ch = i_utf8_advance(&text, &len);
291             if (ch == ~0UL) {
292               i_push_error(0, "invalid UTF8 character");
293               break;
294             }
295           }
296           else {
297             ch = *text++;
298             --len;
299           }
300           EXTEND(SP, 1);
301           if (i_ft2_glyph_name(handle, ch, name, sizeof(name), 
302                                          reliable_only)) {
303             PUSHs(sv_2mortal(newSVpv(name, 0)));
304           }
305           else {
306             PUSHs(&PL_sv_undef);
307           } 
308         }
309
310 int
311 i_ft2_can_do_glyph_names()
312
313 int
314 i_ft2_face_has_glyph_names(handle)
315         Imager::Font::FT2x handle
316
317 int
318 i_ft2_is_multiple_master(handle)
319         Imager::Font::FT2x handle
320
321 void
322 i_ft2_get_multiple_masters(handle)
323         Imager::Font::FT2x handle
324       PREINIT:
325         i_font_mm mm;
326         int i;
327       PPCODE:
328         if (i_ft2_get_multiple_masters(handle, &mm)) {
329           EXTEND(SP, 2+mm.num_axis);
330           PUSHs(sv_2mortal(newSViv(mm.num_axis)));
331           PUSHs(sv_2mortal(newSViv(mm.num_designs)));
332           for (i = 0; i < mm.num_axis; ++i) {
333             AV *av = newAV();
334             SV *sv;
335             av_extend(av, 3);
336             sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
337             SvREFCNT_inc(sv);
338             av_store(av, 0, sv);
339             sv = newSViv(mm.axis[i].minimum);
340             SvREFCNT_inc(sv);
341             av_store(av, 1, sv);
342             sv = newSViv(mm.axis[i].maximum);
343             SvREFCNT_inc(sv);
344             av_store(av, 2, sv);
345             PUSHs(newRV_noinc((SV *)av));
346           }
347         }
348
349 undef_int
350 i_ft2_set_mm_coords(handle, ...)
351         Imager::Font::FT2x handle
352       PROTOTYPE: DISABLE
353       PREINIT:
354         long *coords;
355         int ix_coords, i;
356       CODE:
357         /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
358            transfer the array manually */
359         ix_coords = items-1;
360         coords = mymalloc(sizeof(long) * ix_coords);
361         for (i = 0; i < ix_coords; ++i) {
362           coords[i] = (long)SvIV(ST(1+i));
363         }
364         RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
365         myfree(coords);
366       OUTPUT:
367         RETVAL
368
369
370 BOOT:
371         PERL_INITIALIZE_IMAGER_CALLBACKS;
372         i_ft2_start();