]> git.imager.perl.org - imager.git/blob - FT2/FT2.xs
dd934427da56a37568ed84b1412f037865a53f34
[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_sv, vlayout, utf8)
127         Imager::Font::FT2x font
128         double cheight
129         double cwidth
130         SV *text_sv
131         int vlayout
132         int utf8
133       PREINIT:
134         i_img_dim bbox[8];
135         int i;
136         const char *text;
137         STRLEN len;
138       PPCODE:
139         text = SvPV(text_sv, len);
140 #ifdef SvUTF8
141         if (SvUTF8(text_sv))
142           utf8 = 1;
143 #endif
144         if (i_ft2_bbox_r(font, cheight, cwidth, text, len, vlayout,
145                          utf8, bbox)) {
146           EXTEND(SP, 8);
147           for (i = 0; i < 8; ++i)
148             PUSHs(sv_2mortal(newSViv(bbox[i])));
149         }
150
151 undef_int
152 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text_sv, align, aa, vlayout, utf8)
153         Imager::Font::FT2x font
154         Imager::ImgRaw im
155         i_img_dim tx
156         i_img_dim ty
157         Imager::Color cl
158         double cheight
159         double cwidth
160         SV *text_sv
161         int align
162         int aa
163         int vlayout
164         int utf8
165       PREINIT:
166         const char *text;
167         STRLEN len;
168       CODE:
169         text = SvPV(text_sv, len);
170 #ifdef SvUTF8
171         if (SvUTF8(text_sv)) {
172           utf8 = 1;
173         }
174 #endif
175         RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
176                             len, align, aa, vlayout, utf8);
177       OUTPUT:
178         RETVAL
179
180 undef_int
181 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text_sv, align, aa, vlayout, utf8)
182         Imager::Font::FT2x font
183         Imager::ImgRaw im
184         i_img_dim tx
185         i_img_dim ty
186         int channel
187         double cheight
188         double cwidth
189         SV *text_sv
190         int align
191         int aa
192         int vlayout
193         int utf8
194       PREINIT:
195         char const *text;
196         STRLEN len;
197       CODE:
198         text = SvPV(text_sv, len);
199 #ifdef SvUTF8
200         if (SvUTF8(text_sv))
201           utf8 = 1;
202 #endif
203         RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
204                           len, align, aa, vlayout, utf8);
205       OUTPUT:
206         RETVAL
207
208 void
209 ft2_transform_box(font, x0, x1, x2, x3)
210         Imager::Font::FT2x font
211         i_img_dim x0
212         i_img_dim x1
213         i_img_dim x2
214         i_img_dim x3
215       PREINIT:
216         i_img_dim box[4];
217       PPCODE:
218         box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
219         ft2_transform_box(font, box);
220           EXTEND(SP, 4);
221           PUSHs(sv_2mortal(newSViv(box[0])));
222           PUSHs(sv_2mortal(newSViv(box[1])));
223           PUSHs(sv_2mortal(newSViv(box[2])));
224           PUSHs(sv_2mortal(newSViv(box[3])));
225
226 void
227 i_ft2_has_chars(handle, text_sv, utf8)
228         Imager::Font::FT2x handle
229         SV  *text_sv
230         int utf8
231       PREINIT:
232         char *text;
233         STRLEN len;
234         char *work;
235         size_t count;
236         size_t i;
237       PPCODE:
238         text = SvPV(text_sv, len);
239 #ifdef SvUTF8
240         if (SvUTF8(text_sv))
241           utf8 = 1;
242 #endif
243         work = mymalloc(len);
244         count = i_ft2_has_chars(handle, text, len, utf8, work);
245         if (GIMME_V == G_ARRAY) {
246           EXTEND(SP, count);
247           for (i = 0; i < count; ++i) {
248             PUSHs(boolSV(work[i]));
249           }
250         }
251         else {
252           EXTEND(SP, 1);
253           PUSHs(sv_2mortal(newSVpv(work, count)));
254         }
255         myfree(work);
256
257 void
258 i_ft2_face_name(handle)
259         Imager::Font::FT2x handle
260       PREINIT:
261         char name[255];
262         size_t len;
263       PPCODE:
264         len = i_ft2_face_name(handle, name, sizeof(name));
265         if (len) {
266           EXTEND(SP, 1);
267           PUSHs(sv_2mortal(newSVpv(name, 0)));
268         }
269
270 undef_int
271 i_ft2_can_face_name()
272
273 void
274 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
275         Imager::Font::FT2x handle
276         SV *text_sv
277         int utf8
278         int reliable_only
279       PREINIT:
280         char const *text;
281         STRLEN work_len;
282         size_t len;
283         char name[255];
284         SSize_t count = 0;
285       PPCODE:
286         i_clear_error();
287         text = SvPV(text_sv, work_len);
288         len = work_len;
289 #ifdef SvUTF8
290         if (SvUTF8(text_sv))
291           utf8 = 1;
292 #endif
293         while (len) {
294           unsigned long ch;
295           if (utf8) {
296             ch = i_utf8_advance(&text, &len);
297             if (ch == ~0UL) {
298               i_push_error(0, "invalid UTF8 character");
299               XSRETURN_EMPTY;
300             }
301           }
302           else {
303             ch = *text++;
304             --len;
305           }
306           EXTEND(SP, 1);
307           if (i_ft2_glyph_name(handle, ch, name, sizeof(name), 
308                                          reliable_only)) {
309             PUSHs(sv_2mortal(newSVpv(name, 0)));
310           }
311           else {
312             PUSHs(&PL_sv_undef);
313           }
314         }
315
316 int
317 i_ft2_can_do_glyph_names()
318
319 int
320 i_ft2_face_has_glyph_names(handle)
321         Imager::Font::FT2x handle
322
323 int
324 i_ft2_is_multiple_master(handle)
325         Imager::Font::FT2x handle
326
327 void
328 i_ft2_get_multiple_masters(handle)
329         Imager::Font::FT2x handle
330       PREINIT:
331         i_font_mm mm;
332         int i;
333       PPCODE:
334         if (i_ft2_get_multiple_masters(handle, &mm)) {
335           EXTEND(SP, 2+mm.num_axis);
336           PUSHs(sv_2mortal(newSViv(mm.num_axis)));
337           PUSHs(sv_2mortal(newSViv(mm.num_designs)));
338           for (i = 0; i < mm.num_axis; ++i) {
339             AV *av = newAV();
340             SV *sv;
341             av_extend(av, 3);
342             sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
343             SvREFCNT_inc(sv);
344             av_store(av, 0, sv);
345             sv = newSViv(mm.axis[i].minimum);
346             SvREFCNT_inc(sv);
347             av_store(av, 1, sv);
348             sv = newSViv(mm.axis[i].maximum);
349             SvREFCNT_inc(sv);
350             av_store(av, 2, sv);
351             PUSHs(newRV_noinc((SV *)av));
352           }
353         }
354
355 undef_int
356 i_ft2_set_mm_coords(handle, ...)
357         Imager::Font::FT2x handle
358       PROTOTYPE: DISABLE
359       PREINIT:
360         long *coords;
361         int ix_coords, i;
362       CODE:
363         /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
364            transfer the array manually */
365         ix_coords = items-1;
366         coords = mymalloc(sizeof(long) * ix_coords);
367         for (i = 0; i < ix_coords; ++i) {
368           coords[i] = (long)SvIV(ST(1+i));
369         }
370         RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
371         myfree(coords);
372       OUTPUT:
373         RETVAL
374
375
376 BOOT:
377         PERL_INITIALIZE_IMAGER_CALLBACKS;
378         i_ft2_start();