File Coverage

Shaper.xs
Criterion Covered Total %
statement 57 85 67.0
branch 17 30 56.6
condition n/a
subroutine n/a
pod n/a
total 74 115 64.3


line stmt bran cond sub pod time code
1             // XS glue for harfbuzz library.
2             //
3             // As conventional this is not documented :) .
4              
5             #define PERL_NO_GET_CONTEXT
6             #include "EXTERN.h"
7             #include "perl.h"
8             #include "XSUB.h"
9             #include "stdint.h"
10             #include
11             #include
12             #include
13             #include
14              
15             typedef const char * bytestring_t;
16             typedef const char * bytestring_nolen_t;
17              
18             MODULE = HarfBuzz::Shaper PACKAGE = HarfBuzz::Shaper
19             PROTOTYPES: ENABLE
20              
21             SV *
22             hb_version_string()
23             INIT:
24             const char *p;
25             CODE:
26 5           p = hb_version_string();
27 5           RETVAL = newSVpv(p, strlen(p));
28             OUTPUT:
29             RETVAL
30              
31             hb_buffer_t *
32             hb_buffer_create()
33              
34             void
35             hb_buffer_clear_contents( hb_buffer_t *buf )
36              
37             void
38             hb_buffer_reset( hb_buffer_t *buf )
39              
40             void
41             hb_buffer_add_utf8(hb_buffer_t *buf, bytestring_t s, size_t length(s), unsigned int offset=0, size_t len=-1)
42              
43             hb_blob_t *
44             hb_blob_create_from_file( bytestring_nolen_t s )
45              
46             void
47             hb_blob_destroy(hb_blob_t *blob)
48              
49             hb_face_t *
50             hb_face_create(hb_blob_t *blob, int index)
51              
52             hb_font_t *
53             hb_font_create(hb_face_t *face)
54              
55             void
56             hb_ot_font_set_funcs(hb_font_t *font)
57              
58             void
59             hb_font_set_scale( hb_font_t *font, int xscale, int yscale)
60              
61             void
62             hb_font_set_ptem( hb_font_t *font, float pt )
63              
64             int
65             hb_buffer_set_language( hb_buffer_t *buf, bytestring_t s, size_t length(s) )
66             PREINIT:
67             hb_language_t lang;
68             CODE:
69 0           lang = hb_language_from_string(s, XSauto_length_of_s);
70 0 0         if ( lang ) {
71 0           hb_buffer_set_language( buf, lang );
72 0           RETVAL = 1;
73             }
74             else
75 0           XSRETURN_UNDEF;
76             OUTPUT:
77             RETVAL
78              
79             SV *
80             hb_buffer_get_language( hb_buffer_t *buf )
81             PREINIT:
82             hb_language_t lang;
83             const char *s;
84             CODE:
85 0           lang = hb_buffer_get_language(buf);
86 0           s = hb_language_to_string(lang);
87 0           RETVAL = newSVpvn(s, strlen(s));
88             OUTPUT:
89             RETVAL
90              
91             int
92             hb_buffer_set_script( hb_buffer_t *buf, bytestring_t s, size_t length(s) )
93             PREINIT:
94             hb_script_t script;
95             CODE:
96 0           script = hb_script_from_string(s, XSauto_length_of_s);
97 0 0         if ( script ) {
98 0           hb_buffer_set_script( buf, script );
99 0           RETVAL = 1;
100             }
101             else
102 0           XSRETURN_UNDEF;
103             OUTPUT:
104             RETVAL
105              
106             SV *
107             hb_buffer_get_script( hb_buffer_t *buf )
108             PREINIT:
109             hb_script_t script;
110             hb_tag_t tag;
111             char s[5];
112             CODE:
113 0           script = hb_buffer_get_script(buf);
114 0           tag = hb_script_to_iso15924_tag(script);
115 0           hb_tag_to_string(tag, s);
116 0           RETVAL = newSVpvn(s, 4);
117             OUTPUT:
118             RETVAL
119              
120             int
121             hb_buffer_set_direction( hb_buffer_t *buf, bytestring_t s, size_t length(s) )
122             PREINIT:
123             hb_direction_t dir;
124             CODE:
125 0           dir = hb_direction_from_string(s, XSauto_length_of_s);
126 0 0         if ( dir ) {
127 0           hb_buffer_set_direction( buf, dir );
128 0           RETVAL = 1;
129             }
130             else
131 0           XSRETURN_UNDEF;
132             OUTPUT:
133             RETVAL
134              
135             SV *
136             hb_buffer_get_direction( hb_buffer_t *buf )
137             PREINIT:
138             hb_direction_t dir;
139             const char *s;
140             CODE:
141 0           dir = hb_buffer_get_direction(buf);
142 0           s = hb_direction_to_string(dir);
143 0           RETVAL = newSVpvn(s, strlen(s));
144             OUTPUT:
145             RETVAL
146              
147             void
148             hb_buffer_guess_segment_properties( hb_buffer_t *buf )
149              
150             int
151             hb_buffer_get_length( hb_buffer_t *buf )
152              
153             SV *
154             hb_feature_from_string( SV *sv )
155             PREINIT:
156             STRLEN len;
157             char* s;
158             hb_feature_t f;
159             CODE:
160 4 50         s = SvPVutf8(sv, len);
161 4 50         if ( hb_feature_from_string(s, len, &f) )
162 4           RETVAL = newSVpv((char*)&f,sizeof(f));
163             else
164 0           XSRETURN_UNDEF;
165             OUTPUT:
166             RETVAL
167              
168             void
169             hb_shape( hb_font_t *font, hb_buffer_t *buf )
170             CODE:
171 0           hb_shape( font, buf, NULL, 0 );
172              
173             SV *
174             hb_shaper( hb_font_t *font, hb_buffer_t *buf, SV* feat )
175             INIT:
176             int n;
177             int i;
178             AV* results;
179             char glyphname[32];
180 7           hb_feature_t* features = NULL;
181 7           results = (AV *)sv_2mortal((SV *)newAV());
182             CODE:
183             /* Do we have features? */
184 7 50         if ( (SvROK(feat))
185 7 50         && (SvTYPE(SvRV(feat)) == SVt_PVAV)
186 7 100         && ((n = av_len((AV *)SvRV(feat))) >= 0)) {
187              
188 4           n++; /* top index -> length */
189 4 50         Newx(features, n, hb_feature_t);
190 10 100         for ( i = 0; i < n; i++ ) {
191             hb_feature_t* f;
192 6 50         f = (hb_feature_t*) SvPV_nolen (*av_fetch ((AV*) SvRV(feat), i, 0));
193 6           features[i] = *f;
194             }
195 4           if (0) for ( i = 0; i < n; i++ ) {
196             hb_feature_to_string( &features[i], glyphname, 32 );
197             fprintf( stderr, "feature[%d] = '%s'\n", i, glyphname );
198             }
199             }
200             else {
201 3           features = NULL;
202 3           n = 0;
203             }
204              
205 7           hb_shape( font, buf, features, n );
206 7 100         if ( features ) Safefree(features);
207              
208 7           n = hb_buffer_get_length(buf);
209 7           hb_glyph_position_t *pos = hb_buffer_get_glyph_positions(buf, NULL);
210 7           hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buf, NULL);
211 38 100         for ( i = 0; i < n; i++ ) {
212             HV * rh;
213 31           hb_codepoint_t gid = info[i].codepoint;
214 31           rh = (HV *)sv_2mortal((SV *)newHV());
215 31           hv_store(rh, "ax", 2, newSViv(pos[i].x_advance), 0);
216 31           hv_store(rh, "ay", 2, newSViv(pos[i].y_advance), 0);
217 31           hv_store(rh, "dx", 2, newSViv(pos[i].x_offset), 0);
218 31           hv_store(rh, "dy", 2, newSViv(pos[i].y_offset), 0);
219 31           hv_store(rh, "g", 1, newSViv(gid), 0);
220 31           hb_font_get_glyph_name(font, gid,
221             glyphname, sizeof(glyphname));
222 31           hv_store(rh, "name", 4,
223             newSVpvn(glyphname, strlen(glyphname)), 0);
224 31           av_push(results, newRV_inc((SV *)rh));
225             }
226              
227 7           RETVAL = newRV_inc((SV *)results);
228             OUTPUT:
229             RETVAL
230              
231             SV *
232             hb_buffer_get_extents( hb_font_t *font, hb_buffer_t *buf )
233             INIT:
234             int n;
235             int i;
236             AV* results;
237 2           results = (AV *)sv_2mortal((SV *)newAV());
238             CODE:
239 2           n = hb_buffer_get_length(buf);
240 2           hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buf, NULL);
241 11 100         for ( i = 0; i < n; i++ ) {
242             HV * rh;
243 9           hb_codepoint_t gid = info[i].codepoint;
244 9           rh = (HV *)sv_2mortal((SV *)newHV());
245             hb_glyph_extents_t e;
246 9           hb_font_get_glyph_extents(font, gid, &e);
247 9           hv_store(rh, "g", 1, newSViv(gid), 0);
248 9           hv_store(rh, "x_bearing", 9, newSViv(e.x_bearing), 0);
249 9           hv_store(rh, "y_bearing", 9, newSViv(e.y_bearing), 0);
250 9           hv_store(rh, "width", 5, newSViv(e.width), 0);
251 9           hv_store(rh, "height", 6, newSViv(e.height), 0);
252 9           av_push(results, newRV_inc((SV *)rh));
253             }
254              
255 2           RETVAL = newRV_inc((SV *)results);
256             OUTPUT:
257             RETVAL
258              
259             SV *
260             hb_buffer_get_font_extents( hb_font_t *font, bytestring_t s, size_t length(s) )
261             PREINIT:
262             hb_direction_t dir;
263             INIT:
264             HV* rh;
265 2           rh = (HV *)sv_2mortal((SV *)newHV());
266             CODE:
267 2           dir = hb_direction_from_string(s, XSauto_length_of_s);
268 2 50         if ( !dir )
269 0           XSRETURN_UNDEF;
270              
271             hb_font_extents_t e;
272 2           hb_font_get_extents_for_direction( font, dir, &e );
273 2           hv_store(rh, "ascender", 8, newSViv(e.ascender), 0);
274 2           hv_store(rh, "descender", 9, newSViv(e.descender), 0);
275 2           hv_store(rh, "line_gap", 8, newSViv(e.line_gap), 0);
276              
277 2           RETVAL = newRV_inc((SV *)rh);
278             OUTPUT:
279             RETVAL