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