File Coverage

lib/Colouring/In/XS.xs
Criterion Covered Total %
statement 106 161 65.8
branch 29 108 26.8
condition n/a
subroutine n/a
pod n/a
total 135 269 50.1


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5              
6             /* Route fatal errors through Perl's croak() */
7             #define COLOURING_FATAL(msg) croak("%s", (msg))
8              
9             #include "in.h"
10             #include "in_ops.h"
11              
12             MODULE = Colouring::In::XS PACKAGE = Colouring::In::XS
13             PROTOTYPES: ENABLE
14             FALLBACK: TRUE
15              
16             void
17             set_messages(...)
18             CODE:
19 1 50         SV * msgs = (items > 0) ? ST(items - 1) : NULL;
20 1 50         if (msgs && SvROK(msgs) && SvTYPE(SvRV(msgs)) == SVt_PVHV) {
    50          
    50          
21 1           SvREFCNT_dec(MESSAGES_REF);
22 1           MESSAGES_REF = newRV_inc(SvRV(msgs));
23             }
24              
25             SV *
26             new(...)
27             CODE:
28             SV * colour;
29             SV * a;
30 10027 50         if (items < 2)
31 0           croak("Usage: %s->new(colour [, alpha])", COLOURING_CLASS);
32 10027           colour = ST(1);
33 10027 100         a = (items > 2) && SvOK(ST(2)) ? ST(2) : sv_2mortal(newSViv(1));
    100          
34 10027           RETVAL = xs_new_color(ST(0), colour, a);
35             OUTPUT:
36             RETVAL
37              
38             SV *
39             rgb(self, red, green, blue, ...)
40             SV * self
41             SV * red
42             SV * green
43             SV * blue
44             CODE:
45 1           double r = xs_scaled(red, 255);
46 1           double g = xs_scaled(green, 255);
47 1           double b = xs_scaled(blue, 255);
48 1           AV * colour = newAV();
49 1 50         double a = colouring_clamp(items > 4 ? SvNV(ST(4)) : 1, 1);
50 1           av_push(colour, newSVnv(r));
51 1           av_push(colour, newSVnv(g));
52 1           av_push(colour, newSVnv(b));
53 1           RETVAL = xs_new_color(self, newRV_noinc((SV*)colour), newSVnv(a));
54             OUTPUT:
55             RETVAL
56              
57             SV *
58             rgba(self, red, green, blue, ...)
59             SV * self
60             SV * red
61             SV * green
62             SV * blue
63             CODE:
64 0           double r = xs_scaled(red, 255);
65 0           double g = xs_scaled(green, 255);
66 0           double b = xs_scaled(blue, 255);
67 0           AV * colour = newAV();
68 0 0         double a = colouring_clamp(items > 4 ? SvNV(ST(4)) : 1, 1);
69 0           av_push(colour, newSVnv(r));
70 0           av_push(colour, newSVnv(g));
71 0           av_push(colour, newSVnv(b));
72 0           RETVAL = xs_new_color(self, newRV_noinc((SV*)colour), newSVnv(a));
73             OUTPUT:
74             RETVAL
75              
76             SV *
77             hsl(self, h, s, l, ...)
78             SV * self
79             SV * h
80             SV * s
81             SV * l
82             CODE:
83 1 50         double a = colouring_clamp(items > 4 ? SvNV(ST(4)) : 1, 1);
84 1           colouring_rgba_t c = colouring_hsl2rgb(SvNV(h), SvNV(s), SvNV(l), a);
85 1           RETVAL = xs_rgba_to_obj(self, c);
86             OUTPUT:
87             RETVAL
88              
89             SV *
90             hsla(self, h, s, l, ...)
91             SV * self
92             SV * h
93             SV * s
94             SV * l
95             CODE:
96 0 0         double a = colouring_clamp(items > 4 ? SvNV(ST(4)) : 1, 1);
97 0           colouring_rgba_t c = colouring_hsl2rgb(SvNV(h), SvNV(s), SvNV(l), a);
98 0           RETVAL = xs_rgba_to_obj(self, c);
99             OUTPUT:
100             RETVAL
101              
102             SV *
103             toCSS(self, ...)
104             SV * self
105             CODE:
106 0 0         int r = items > 1 ? SvIV(ST(1)) : 0;
107 0 0         int s = items > 2 ? SvIV(ST(2)) : 0;
108 0           colouring_rgba_t c = xs_extract_rgba(self);
109 0           double alpha = colouring_round(c.a, r);
110 0 0         if (alpha == 1) {
111             char css[8];
112 0           colouring_fmt_hex(c, css, sizeof(css), s);
113 0           RETVAL = newSVpvn(css, strlen(css));
114             } else {
115             char css[32];
116 0           colouring_fmt_rgba(c, css, sizeof(css));
117 0           RETVAL = newSVpvn(css, strlen(css));
118             }
119             OVERLOAD: \"\"
120             OUTPUT:
121             RETVAL
122              
123             SV *
124             toTerm(self)
125             SV * self
126             CODE:
127             char css[16];
128 0           colouring_rgba_t c = xs_extract_rgba(self);
129 0           colouring_fmt_term(c, css, sizeof(css));
130 0           RETVAL = newSVpvn(css, strlen(css));
131             OUTPUT:
132             RETVAL
133              
134             SV *
135             toOnTerm(self)
136             SV * self
137             CODE:
138             char css[20];
139 0           colouring_rgba_t c = xs_extract_rgba(self);
140 0           colouring_fmt_on_term(c, css, sizeof(css));
141 0           RETVAL = newSVpvn(css, strlen(css));
142             OUTPUT:
143             RETVAL
144              
145             SV *
146             toRGB(self, ...)
147             SV * self
148             CODE:
149 0           colouring_rgba_t c = xs_extract_rgba(self);
150 0           SV * alpha_sv = *hv_fetch((HV*)SvRV(self), "alpha", 5, 0);
151 0 0         if (numIs(alpha_sv) && SvIV(alpha_sv) != 1) {
    0          
152             char css[32];
153 0           colouring_fmt_rgba(c, css, sizeof(css));
154 0           RETVAL = newSVpvn(css, strlen(css));
155             } else {
156             char css[24];
157 0           colouring_fmt_rgb(c, css, sizeof(css));
158 0           RETVAL = newSVpvn(css, strlen(css));
159             }
160             OUTPUT:
161             RETVAL
162              
163             SV *
164             toRGBA(self, ...)
165             SV * self
166             CODE:
167             char css[32];
168 0           colouring_rgba_t c = xs_extract_rgba(self);
169 0           colouring_fmt_rgba(c, css, sizeof(css));
170 0           RETVAL = newSVpvn(css, strlen(css));
171             OUTPUT:
172             RETVAL
173              
174             SV *
175             toHEX(self, ...)
176             SV * self
177             CODE:
178             char css[8];
179 0           colouring_rgba_t c = xs_extract_rgba(self);
180 0           int force_long = (items > 1)
181 0 0         && SvTRUE(ST(1))
182 0 0         && SvTYPE(ST(1)) == SVt_IV;
    0          
183 0           colouring_fmt_hex(c, css, sizeof(css), force_long);
184 0           RETVAL = newSVpvn(css, strlen(css));
185             OUTPUT:
186             RETVAL
187              
188             SV *
189             toHSL(self)
190             SV * self
191             CODE:
192             char css[30];
193 0           colouring_rgba_t c = xs_extract_rgba(self);
194 0           colouring_hsl_t hsl = colouring_rgb2hsl(c.r, c.g, c.b, c.a);
195 0           colouring_fmt_hsl(hsl, css, sizeof(css));
196 0           RETVAL = newSVpvn(css, strlen(css));
197             OUTPUT:
198             RETVAL
199              
200             SV *
201             toHSV(self)
202             SV * self
203             CODE:
204             char css[30];
205 0           colouring_rgba_t c = xs_extract_rgba(self);
206 0           colouring_hsv_t hsv = colouring_rgb2hsv(c.r, c.g, c.b);
207 0           colouring_fmt_hsv(hsv, css, sizeof(css));
208 0           RETVAL = newSVpvn(css, strlen(css));
209             OUTPUT:
210             RETVAL
211              
212             SV *
213             lighten(colour, amt, ...)
214             SV * colour
215             SV * amt
216             CODE:
217 7           SV * class = sv_2mortal(newSVpv("Colouring::In::XS", 17));
218 7 50         int relative = items > 2 && SvOK(ST(2)) && strcmp(SvPV_nolen(ST(2)), "relative") == 0;
    0          
    0          
219 7           double amount = colouring_depercent(SvPV_nolen(amt));
220             colouring_rgba_t c;
221 7           colour = xs_ensure_obj(class, colour);
222 7           c = xs_extract_rgba(colour);
223 7           c = colouring_lighten(c.r, c.g, c.b, c.a, amount, relative);
224 7           RETVAL = xs_rgba_to_obj(class, c);
225             OUTPUT:
226             RETVAL
227              
228             SV *
229             darken(colour, amt, ...)
230             SV * colour
231             SV * amt
232             CODE:
233 8           SV * class = sv_2mortal(newSVpv("Colouring::In::XS", 17));
234 8 50         int relative = items > 2 && SvOK(ST(2)) && strcmp(SvPV_nolen(ST(2)), "relative") == 0;
    0          
    0          
235 8           double amount = colouring_depercent(SvPV_nolen(amt));
236             colouring_rgba_t c;
237 8           colour = xs_ensure_obj(class, colour);
238 8           c = xs_extract_rgba(colour);
239 8           c = colouring_darken(c.r, c.g, c.b, c.a, amount, relative);
240 8           RETVAL = xs_rgba_to_obj(class, c);
241             OUTPUT:
242             RETVAL
243              
244             SV *
245             fade(colour, amt, ...)
246             SV * colour
247             SV * amt
248             CODE:
249 12           SV * class = sv_2mortal(newSVpv("Colouring::In::XS", 17));
250 12           double amount = colouring_depercent(SvPV_nolen(amt));
251             colouring_rgba_t c;
252 12           colour = xs_ensure_obj(class, colour);
253 12           c = xs_extract_rgba(colour);
254 12           c = colouring_fade(c.r, c.g, c.b, c.a, amount);
255 12           RETVAL = xs_rgba_to_obj(class, c);
256             OUTPUT:
257             RETVAL
258              
259             SV *
260             fadeout(colour, amt, ...)
261             SV * colour
262             SV * amt
263             CODE:
264 11           SV * class = sv_2mortal(newSVpv("Colouring::In::XS", 17));
265 11 50         int relative = items > 2 && SvOK(ST(2)) && strcmp(SvPV_nolen(ST(2)), "relative") == 0;
    0          
    0          
266 11           double amount = colouring_depercent(SvPV_nolen(amt));
267             colouring_rgba_t c;
268 11           colour = xs_ensure_obj(class, colour);
269 11           c = xs_extract_rgba(colour);
270 11           c = colouring_fadeout(c.r, c.g, c.b, c.a, amount, relative);
271 11           RETVAL = xs_rgba_to_obj(class, c);
272             OUTPUT:
273             RETVAL
274              
275             SV *
276             fadein(colour, amt, ...)
277             SV * colour
278             SV * amt
279             CODE:
280 11           SV * class = sv_2mortal(newSVpv("Colouring::In::XS", 17));
281 11 50         int relative = items > 2 && SvOK(ST(2)) && strcmp(SvPV_nolen(ST(2)), "relative") == 0;
    0          
    0          
282 11           double amount = colouring_depercent(SvPV_nolen(amt));
283             colouring_rgba_t c;
284 11           colour = xs_ensure_obj(class, colour);
285 11           c = xs_extract_rgba(colour);
286 11           c = colouring_fadein(c.r, c.g, c.b, c.a, amount, relative);
287 11           RETVAL = xs_rgba_to_obj(class, c);
288             OUTPUT:
289             RETVAL
290              
291             SV *
292             mix(colour1, colour2, ...)
293             SV * colour1
294             SV * colour2
295             CODE:
296 1           SV * class = sv_2mortal(newSVpv("Colouring::In::XS", 17));
297 1           int weight = 50;
298             colouring_rgba_t c1, c2, out;
299 1 50         if (items > 2 && SvOK(ST(2)) && SvIV(ST(2)) != 0) {
    0          
    0          
300 0           weight = SvIV(ST(2));
301             }
302 1           colour1 = xs_ensure_obj(class, colour1);
303 1           colour2 = xs_ensure_obj(class, colour2);
304 1           c1 = xs_extract_rgba(colour1);
305 1           c2 = xs_extract_rgba(colour2);
306 1           out = colouring_mix(c1, c2, weight);
307 1           RETVAL = xs_rgba_to_obj(class, out);
308             OUTPUT:
309             RETVAL
310              
311             SV *
312             tint(colour, ...)
313             SV * colour
314             CODE:
315 1           SV * class = sv_2mortal(newSVpv("Colouring::In::XS", 17));
316 1           int weight = 50;
317             colouring_rgba_t c, out;
318 1 50         if (items > 1 && SvOK(ST(1)) && SvIV(ST(1)) != 0) {
    0          
    0          
319 0           weight = SvIV(ST(1));
320             }
321 1           colour = xs_ensure_obj(class, colour);
322 1           c = xs_extract_rgba(colour);
323 1           out = colouring_tint(c, weight);
324 1           RETVAL = xs_rgba_to_obj(class, out);
325             OUTPUT:
326             RETVAL
327              
328             SV *
329             shade(colour, ...)
330             SV * colour
331             CODE:
332 1           SV * class = sv_2mortal(newSVpv("Colouring::In::XS", 17));
333 1           int weight = 50;
334             colouring_rgba_t c, out;
335 1 50         if (items > 1 && SvOK(ST(1)) && SvIV(ST(1)) != 0) {
    0          
    0          
336 0           weight = SvIV(ST(1));
337             }
338 1           colour = xs_ensure_obj(class, colour);
339 1           c = xs_extract_rgba(colour);
340 1           out = colouring_shade(c, weight);
341 1           RETVAL = xs_rgba_to_obj(class, out);
342             OUTPUT:
343             RETVAL
344              
345             SV *
346             saturate(colour, amt, ...)
347             SV * colour
348             SV * amt
349             CODE:
350 1           SV * class = sv_2mortal(newSVpv("Colouring::In::XS", 17));
351 1 50         int relative = items > 2 && SvOK(ST(2)) && strcmp(SvPV_nolen(ST(2)), "relative") == 0;
    0          
    0          
352 1           double amount = colouring_depercent(SvPV_nolen(amt));
353             colouring_rgba_t c;
354 1           colour = xs_ensure_obj(class, colour);
355 1           c = xs_extract_rgba(colour);
356 1           c = colouring_saturate(c.r, c.g, c.b, c.a, amount, relative);
357 1           RETVAL = xs_rgba_to_obj(class, c);
358             OUTPUT:
359             RETVAL
360              
361             SV *
362             desaturate(colour, amt, ...)
363             SV * colour
364             SV * amt
365             CODE:
366 2           SV * class = sv_2mortal(newSVpv("Colouring::In::XS", 17));
367 2 50         int relative = items > 2 && SvOK(ST(2)) && strcmp(SvPV_nolen(ST(2)), "relative") == 0;
    0          
    0          
368 2           double amount = colouring_depercent(SvPV_nolen(amt));
369             colouring_rgba_t c;
370 2           colour = xs_ensure_obj(class, colour);
371 2           c = xs_extract_rgba(colour);
372 2           c = colouring_desaturate(c.r, c.g, c.b, c.a, amount, relative);
373 2           RETVAL = xs_rgba_to_obj(class, c);
374             OUTPUT:
375             RETVAL
376              
377             SV *
378             greyscale(colour)
379             SV * colour
380             CODE:
381 1           SV * class = sv_2mortal(newSVpv("Colouring::In::XS", 17));
382             colouring_rgba_t c;
383 1           colour = xs_ensure_obj(class, colour);
384 1           c = xs_extract_rgba(colour);
385 1           c = colouring_greyscale(c.r, c.g, c.b, c.a);
386 1           RETVAL = xs_rgba_to_obj(class, c);
387             OUTPUT:
388             RETVAL
389              
390             void
391             colour(self)
392             SV * self
393             PPCODE:
394             int i;
395 10001           AV * colour = (AV*)SvRV(*hv_fetch((HV*)SvRV(self), "colour", 6, 0));
396 10001           int len = av_len(colour);
397 10001 50         EXTEND(SP, len + 1);
    50          
398 40004 100         for (i = 0; i <= len; i++) {
399 30003           PUSHs(sv_2mortal(newSVsv(*av_fetch(colour, i, 0))));
400             }
401              
402             SV *
403             get_message(msg)
404             SV * msg
405             CODE:
406 4 50         HV * msgs = MESSAGES;
    50          
407             STRLEN klen;
408 4           const char * key = SvPV(msg, klen);
409 4 50         SV ** slot = msgs ? hv_fetch(msgs, key, klen, 0) : NULL;
410 4 50         RETVAL = (slot && *slot) ? newSVsv(*slot) : &PL_sv_undef;
    50          
411             OUTPUT:
412             RETVAL
413              
414             BOOT:
415 19           colouring_register_ops(aTHX);