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