File Coverage

include/in_ops.h
Criterion Covered Total %
statement 239 367 65.1
branch 47 88 53.4
condition n/a
subroutine n/a
pod n/a
total 286 455 62.8


line stmt bran cond sub pod time code
1             /*
2             * in_ops.h - Custom ops + peephole optimizer for Colouring::In::XS
3             *
4             * Replaces entersub calls with lightweight custom ops at compile time.
5             * Requires in.h (which pulls in colouring.h) already included.
6             */
7              
8             #ifndef COLOURING_IN_OPS_H
9             #define COLOURING_IN_OPS_H
10              
11             /* compat for pre-5.22 perls */
12             #ifndef OpHAS_SIBLING
13             # define OpHAS_SIBLING(o) ((o)->op_sibling != NULL)
14             #endif
15             #ifndef OpSIBLING
16             # define OpSIBLING(o) ((o)->op_sibling)
17             #endif
18              
19             /* ══════════════════════════════════════════════════════════════════
20             * pp functions — one per method
21             * ══════════════════════════════════════════════════════════════════ */
22              
23             /* ── Format ops (self → string) ───────────────────────────────── */
24              
25 11           static OP * pp_colouring_toHEX(pTHX) {
26 11           dSP;
27 11           I32 ax = POPMARK;
28 11           SV **mark = PL_stack_base + ax;
29 11           I32 items = (I32)(SP - mark);
30 11           SV * self = *(mark + 1);
31 11           int force_long = 0;
32             colouring_rgba_t c;
33             char css[8];
34              
35 11 100         if (items > 2) {
36 5           SV * fl = *(mark + 2);
37 5           force_long = SvTRUE(fl);
38             }
39              
40 11           SP = mark;
41 11           c = xs_extract_rgba(self);
42 11           colouring_fmt_hex(c, css, sizeof(css), force_long);
43 11           PUSHs(sv_2mortal(newSVpvn(css, strlen(css))));
44 11           PUTBACK;
45 11           return NORMAL;
46             }
47              
48 9           static OP * pp_colouring_toRGB(pTHX) {
49 9           dSP;
50 9           I32 ax = POPMARK;
51 9           SV **mark = PL_stack_base + ax;
52 9           SV * self = *(mark + 1);
53             colouring_rgba_t c;
54             SV * alpha_sv;
55              
56 9           SP = mark;
57 9           c = xs_extract_rgba(self);
58 9           alpha_sv = *hv_fetch((HV*)SvRV(self), "alpha", 5, 0);
59 9 50         if (numIs(alpha_sv) && SvIV(alpha_sv) != 1) {
    50          
60             char css[32];
61 0           colouring_fmt_rgba(c, css, sizeof(css));
62 0           PUSHs(sv_2mortal(newSVpvn(css, strlen(css))));
63             } else {
64             char css[24];
65 9           colouring_fmt_rgb(c, css, sizeof(css));
66 9           PUSHs(sv_2mortal(newSVpvn(css, strlen(css))));
67             }
68 9           PUTBACK;
69 9           return NORMAL;
70             }
71              
72 44           static OP * pp_colouring_toRGBA(pTHX) {
73 44           dSP;
74 44           I32 ax = POPMARK;
75 44           SV **mark = PL_stack_base + ax;
76 44           SV * self = *(mark + 1);
77             colouring_rgba_t c;
78             char css[32];
79              
80 44           SP = mark;
81 44           c = xs_extract_rgba(self);
82 44           colouring_fmt_rgba(c, css, sizeof(css));
83 44           PUSHs(sv_2mortal(newSVpvn(css, strlen(css))));
84 44           PUTBACK;
85 44           return NORMAL;
86             }
87              
88 12           static OP * pp_colouring_toHSL(pTHX) {
89 12           dSP;
90 12           I32 ax = POPMARK;
91 12           SV **mark = PL_stack_base + ax;
92 12           SV * self = *(mark + 1);
93             colouring_rgba_t c;
94             colouring_hsl_t hsl;
95             char css[30];
96              
97 12           SP = mark;
98 12           c = xs_extract_rgba(self);
99 12           hsl = colouring_rgb2hsl(c.r, c.g, c.b, c.a);
100 12           colouring_fmt_hsl(hsl, css, sizeof(css));
101 12           PUSHs(sv_2mortal(newSVpvn(css, strlen(css))));
102 12           PUTBACK;
103 12           return NORMAL;
104             }
105              
106 8           static OP * pp_colouring_toHSV(pTHX) {
107 8           dSP;
108 8           I32 ax = POPMARK;
109 8           SV **mark = PL_stack_base + ax;
110 8           SV * self = *(mark + 1);
111             colouring_rgba_t c;
112             colouring_hsv_t hsv;
113             char css[30];
114              
115 8           SP = mark;
116 8           c = xs_extract_rgba(self);
117 8           hsv = colouring_rgb2hsv(c.r, c.g, c.b);
118 8           colouring_fmt_hsv(hsv, css, sizeof(css));
119 8           PUSHs(sv_2mortal(newSVpvn(css, strlen(css))));
120 8           PUTBACK;
121 8           return NORMAL;
122             }
123              
124 17           static OP * pp_colouring_toCSS(pTHX) {
125 17           dSP;
126 17           I32 ax = POPMARK;
127 17           SV **mark = PL_stack_base + ax;
128 17           SV * self = *(mark + 1);
129             colouring_rgba_t c;
130              
131 17           SP = mark;
132 17           c = xs_extract_rgba(self);
133 17 100         if (c.a == 1.0) {
134             char css[8];
135 16           colouring_fmt_hex(c, css, sizeof(css), 0);
136 16           PUSHs(sv_2mortal(newSVpvn(css, strlen(css))));
137             } else {
138             char css[32];
139 1           colouring_fmt_rgba(c, css, sizeof(css));
140 1           PUSHs(sv_2mortal(newSVpvn(css, strlen(css))));
141             }
142 17           PUTBACK;
143 17           return NORMAL;
144             }
145              
146 5           static OP * pp_colouring_toTerm(pTHX) {
147 5           dSP;
148 5           I32 ax = POPMARK;
149 5           SV **mark = PL_stack_base + ax;
150 5           SV * self = *(mark + 1);
151             colouring_rgba_t c;
152             char css[16];
153              
154 5           SP = mark;
155 5           c = xs_extract_rgba(self);
156 5           colouring_fmt_term(c, css, sizeof(css));
157 5           PUSHs(sv_2mortal(newSVpvn(css, strlen(css))));
158 5           PUTBACK;
159 5           return NORMAL;
160             }
161              
162 5           static OP * pp_colouring_toOnTerm(pTHX) {
163 5           dSP;
164 5           I32 ax = POPMARK;
165 5           SV **mark = PL_stack_base + ax;
166 5           SV * self = *(mark + 1);
167             colouring_rgba_t c;
168             char css[20];
169              
170 5           SP = mark;
171 5           c = xs_extract_rgba(self);
172 5           colouring_fmt_on_term(c, css, sizeof(css));
173 5           PUSHs(sv_2mortal(newSVpvn(css, strlen(css))));
174 5           PUTBACK;
175 5           return NORMAL;
176             }
177              
178             /* ── Manipulation ops (self, amount → new object) ─────────────── */
179              
180 4           static OP * pp_colouring_lighten(pTHX) {
181 4           dSP;
182 4           I32 ax = POPMARK;
183 4           SV **mark = PL_stack_base + ax;
184 4           I32 items = (I32)(SP - mark);
185 4           SV * colour = *(mark + 1);
186 4           SV * amt_sv = *(mark + 2);
187 4           SV * class = xs_class_sv();
188             double amount;
189 4           int relative = 0;
190             colouring_rgba_t c;
191              
192 4 100         if (items > 3) {
193 3           SV * rel = *(mark + 3);
194 3 50         if (SvOK(rel) && strEQ(SvPV_nolen(rel), "relative")) relative = 1;
    100          
195             }
196              
197 4           SP = mark;
198 4           amount = colouring_depercent(SvPV_nolen(amt_sv));
199 4           colour = xs_ensure_obj(class, colour);
200 4           c = xs_extract_rgba(colour);
201 4           c = colouring_lighten(c.r, c.g, c.b, c.a, amount, relative);
202 4           PUSHs(sv_2mortal(xs_rgba_to_obj(class, c)));
203 4           PUTBACK;
204 4           return NORMAL;
205             }
206              
207 3           static OP * pp_colouring_darken(pTHX) {
208 3           dSP;
209 3           I32 ax = POPMARK;
210 3           SV **mark = PL_stack_base + ax;
211 3           I32 items = (I32)(SP - mark);
212 3           SV * colour = *(mark + 1);
213 3           SV * amt_sv = *(mark + 2);
214 3           SV * class = xs_class_sv();
215             double amount;
216 3           int relative = 0;
217             colouring_rgba_t c;
218              
219 3 100         if (items > 3) {
220 2           SV * rel = *(mark + 3);
221 2 50         if (SvOK(rel) && strEQ(SvPV_nolen(rel), "relative")) relative = 1;
    100          
222             }
223              
224 3           SP = mark;
225 3           amount = colouring_depercent(SvPV_nolen(amt_sv));
226 3           colour = xs_ensure_obj(class, colour);
227 3           c = xs_extract_rgba(colour);
228 3           c = colouring_darken(c.r, c.g, c.b, c.a, amount, relative);
229 3           PUSHs(sv_2mortal(xs_rgba_to_obj(class, c)));
230 3           PUTBACK;
231 3           return NORMAL;
232             }
233              
234 0           static OP * pp_colouring_fade(pTHX) {
235 0           dSP;
236 0           I32 ax = POPMARK;
237 0           SV **mark = PL_stack_base + ax;
238 0           SV * colour = *(mark + 1);
239 0           SV * amt_sv = *(mark + 2);
240 0           SV * class = xs_class_sv();
241             double amount;
242             colouring_rgba_t c;
243              
244 0           SP = mark;
245 0           amount = colouring_depercent(SvPV_nolen(amt_sv));
246 0           colour = xs_ensure_obj(class, colour);
247 0           c = xs_extract_rgba(colour);
248 0           c = colouring_fade(c.r, c.g, c.b, c.a, amount);
249 0           PUSHs(sv_2mortal(xs_rgba_to_obj(class, c)));
250 0           PUTBACK;
251 0           return NORMAL;
252             }
253              
254 3           static OP * pp_colouring_fadeout(pTHX) {
255 3           dSP;
256 3           I32 ax = POPMARK;
257 3           SV **mark = PL_stack_base + ax;
258 3           I32 items = (I32)(SP - mark);
259 3           SV * colour = *(mark + 1);
260 3           SV * amt_sv = *(mark + 2);
261 3           SV * class = xs_class_sv();
262             double amount;
263 3           int relative = 0;
264             colouring_rgba_t c;
265              
266 3 100         if (items > 3) {
267 2           SV * rel = *(mark + 3);
268 2 50         if (SvOK(rel) && strEQ(SvPV_nolen(rel), "relative")) relative = 1;
    100          
269             }
270              
271 3           SP = mark;
272 3           amount = colouring_depercent(SvPV_nolen(amt_sv));
273 3           colour = xs_ensure_obj(class, colour);
274 3           c = xs_extract_rgba(colour);
275 3           c = colouring_fadeout(c.r, c.g, c.b, c.a, amount, relative);
276 3           PUSHs(sv_2mortal(xs_rgba_to_obj(class, c)));
277 3           PUTBACK;
278 3           return NORMAL;
279             }
280              
281 3           static OP * pp_colouring_fadein(pTHX) {
282 3           dSP;
283 3           I32 ax = POPMARK;
284 3           SV **mark = PL_stack_base + ax;
285 3           I32 items = (I32)(SP - mark);
286 3           SV * colour = *(mark + 1);
287 3           SV * amt_sv = *(mark + 2);
288 3           SV * class = xs_class_sv();
289             double amount;
290 3           int relative = 0;
291             colouring_rgba_t c;
292              
293 3 100         if (items > 3) {
294 2           SV * rel = *(mark + 3);
295 2 50         if (SvOK(rel) && strEQ(SvPV_nolen(rel), "relative")) relative = 1;
    100          
296             }
297              
298 3           SP = mark;
299 3           amount = colouring_depercent(SvPV_nolen(amt_sv));
300 3           colour = xs_ensure_obj(class, colour);
301 3           c = xs_extract_rgba(colour);
302 3           c = colouring_fadein(c.r, c.g, c.b, c.a, amount, relative);
303 3           PUSHs(sv_2mortal(xs_rgba_to_obj(class, c)));
304 3           PUTBACK;
305 3           return NORMAL;
306             }
307              
308 0           static OP * pp_colouring_saturate(pTHX) {
309 0           dSP;
310 0           I32 ax = POPMARK;
311 0           SV **mark = PL_stack_base + ax;
312 0           I32 items = (I32)(SP - mark);
313 0           SV * colour = *(mark + 1);
314 0           SV * amt_sv = *(mark + 2);
315 0           SV * class = xs_class_sv();
316             double amount;
317 0           int relative = 0;
318             colouring_rgba_t c;
319              
320 0 0         if (items > 3) {
321 0           SV * rel = *(mark + 3);
322 0 0         if (SvOK(rel) && strEQ(SvPV_nolen(rel), "relative")) relative = 1;
    0          
323             }
324              
325 0           SP = mark;
326 0           amount = colouring_depercent(SvPV_nolen(amt_sv));
327 0           colour = xs_ensure_obj(class, colour);
328 0           c = xs_extract_rgba(colour);
329 0           c = colouring_saturate(c.r, c.g, c.b, c.a, amount, relative);
330 0           PUSHs(sv_2mortal(xs_rgba_to_obj(class, c)));
331 0           PUTBACK;
332 0           return NORMAL;
333             }
334              
335 0           static OP * pp_colouring_desaturate(pTHX) {
336 0           dSP;
337 0           I32 ax = POPMARK;
338 0           SV **mark = PL_stack_base + ax;
339 0           I32 items = (I32)(SP - mark);
340 0           SV * colour = *(mark + 1);
341 0           SV * amt_sv = *(mark + 2);
342 0           SV * class = xs_class_sv();
343             double amount;
344 0           int relative = 0;
345             colouring_rgba_t c;
346              
347 0 0         if (items > 3) {
348 0           SV * rel = *(mark + 3);
349 0 0         if (SvOK(rel) && strEQ(SvPV_nolen(rel), "relative")) relative = 1;
    0          
350             }
351              
352 0           SP = mark;
353 0           amount = colouring_depercent(SvPV_nolen(amt_sv));
354 0           colour = xs_ensure_obj(class, colour);
355 0           c = xs_extract_rgba(colour);
356 0           c = colouring_desaturate(c.r, c.g, c.b, c.a, amount, relative);
357 0           PUSHs(sv_2mortal(xs_rgba_to_obj(class, c)));
358 0           PUTBACK;
359 0           return NORMAL;
360             }
361              
362 0           static OP * pp_colouring_greyscale(pTHX) {
363 0           dSP;
364 0           I32 ax = POPMARK;
365 0           SV **mark = PL_stack_base + ax;
366 0           SV * colour = *(mark + 1);
367 0           SV * class = xs_class_sv();
368             colouring_rgba_t c;
369              
370 0           SP = mark;
371 0           colour = xs_ensure_obj(class, colour);
372 0           c = xs_extract_rgba(colour);
373 0           c = colouring_greyscale(c.r, c.g, c.b, c.a);
374 0           PUSHs(sv_2mortal(xs_rgba_to_obj(class, c)));
375 0           PUTBACK;
376 0           return NORMAL;
377             }
378              
379             /* ── Mix-family ops (self, colour2[, weight] → new object) ────── */
380              
381 0           static OP * pp_colouring_mix(pTHX) {
382 0           dSP;
383 0           I32 ax = POPMARK;
384 0           SV **mark = PL_stack_base + ax;
385 0           I32 items = (I32)(SP - mark);
386 0           SV * colour1 = *(mark + 1);
387 0           SV * colour2 = *(mark + 2);
388 0           SV * class = xs_class_sv();
389 0           int weight = 50;
390             colouring_rgba_t c1, c2, out;
391              
392 0 0         if (items > 3) {
393 0           SV * w = *(mark + 3);
394 0 0         if (SvOK(w) && SvIV(w) != 0) weight = SvIV(w);
    0          
395             }
396              
397 0           SP = mark;
398 0           colour1 = xs_ensure_obj(class, colour1);
399 0           colour2 = xs_ensure_obj(class, colour2);
400 0           c1 = xs_extract_rgba(colour1);
401 0           c2 = xs_extract_rgba(colour2);
402 0           out = colouring_mix(c1, c2, weight);
403 0           PUSHs(sv_2mortal(xs_rgba_to_obj(class, out)));
404 0           PUTBACK;
405 0           return NORMAL;
406             }
407              
408 0           static OP * pp_colouring_tint(pTHX) {
409 0           dSP;
410 0           I32 ax = POPMARK;
411 0           SV **mark = PL_stack_base + ax;
412 0           I32 items = (I32)(SP - mark);
413 0           SV * colour = *(mark + 1);
414 0           SV * class = xs_class_sv();
415 0           int weight = 50;
416             colouring_rgba_t c, out;
417              
418 0 0         if (items > 2) {
419 0           SV * w = *(mark + 2);
420 0 0         if (SvOK(w) && SvIV(w) != 0) weight = SvIV(w);
    0          
421             }
422              
423 0           SP = mark;
424 0           colour = xs_ensure_obj(class, colour);
425 0           c = xs_extract_rgba(colour);
426 0           out = colouring_tint(c, weight);
427 0           PUSHs(sv_2mortal(xs_rgba_to_obj(class, out)));
428 0           PUTBACK;
429 0           return NORMAL;
430             }
431              
432 0           static OP * pp_colouring_shade(pTHX) {
433 0           dSP;
434 0           I32 ax = POPMARK;
435 0           SV **mark = PL_stack_base + ax;
436 0           I32 items = (I32)(SP - mark);
437 0           SV * colour = *(mark + 1);
438 0           SV * class = xs_class_sv();
439 0           int weight = 50;
440             colouring_rgba_t c, out;
441              
442 0 0         if (items > 2) {
443 0           SV * w = *(mark + 2);
444 0 0         if (SvOK(w) && SvIV(w) != 0) weight = SvIV(w);
    0          
445             }
446              
447 0           SP = mark;
448 0           colour = xs_ensure_obj(class, colour);
449 0           c = xs_extract_rgba(colour);
450 0           out = colouring_shade(c, weight);
451 0           PUSHs(sv_2mortal(xs_rgba_to_obj(class, out)));
452 0           PUTBACK;
453 0           return NORMAL;
454             }
455              
456             /* ── Accessor op ──────────────────────────────────────────────── */
457              
458 22           static OP * pp_colouring_colour(pTHX) {
459 22           dSP;
460 22           I32 ax = POPMARK;
461 22           SV **mark = PL_stack_base + ax;
462 22           SV * self = *(mark + 1);
463 22           AV * colour = (AV*)SvRV(*hv_fetch((HV*)SvRV(self), "colour", 6, 0));
464 22           int len = av_len(colour);
465             int i;
466              
467 22           SP = mark;
468 22 50         EXTEND(SP, len + 1);
    50          
469 88 100         for (i = 0; i <= len; i++) {
470 66           PUSHs(sv_2mortal(newSVsv(*av_fetch(colour, i, 0))));
471             }
472 22           PUTBACK;
473 22           return NORMAL;
474             }
475              
476             /* ══════════════════════════════════════════════════════════════════
477             * XOP descriptors (Perl 5.14+)
478             * ══════════════════════════════════════════════════════════════════ */
479              
480             #if PERL_VERSION >= 14
481              
482             static XOP xop_toHEX;
483             static XOP xop_toRGB;
484             static XOP xop_toRGBA;
485             static XOP xop_toHSL;
486             static XOP xop_toHSV;
487             static XOP xop_toCSS;
488             static XOP xop_toTerm;
489             static XOP xop_toOnTerm;
490             static XOP xop_lighten;
491             static XOP xop_darken;
492             static XOP xop_fade;
493             static XOP xop_fadeout;
494             static XOP xop_fadein;
495             static XOP xop_saturate;
496             static XOP xop_desaturate;
497             static XOP xop_greyscale;
498             static XOP xop_mix;
499             static XOP xop_tint;
500             static XOP xop_shade;
501             static XOP xop_colour;
502              
503             #endif /* PERL_VERSION >= 14 */
504              
505             /* ══════════════════════════════════════════════════════════════════
506             * Op dispatch table — maps method name → pp function
507             * ══════════════════════════════════════════════════════════════════ */
508              
509             typedef struct {
510             const char *name;
511             Perl_ppaddr_t pp;
512             } colouring_op_entry_t;
513              
514             static colouring_op_entry_t colouring_op_table[] = {
515             { "toHEX", pp_colouring_toHEX },
516             { "toRGB", pp_colouring_toRGB },
517             { "toRGBA", pp_colouring_toRGBA },
518             { "toHSL", pp_colouring_toHSL },
519             { "toHSV", pp_colouring_toHSV },
520             { "toCSS", pp_colouring_toCSS },
521             { "toTerm", pp_colouring_toTerm },
522             { "toOnTerm", pp_colouring_toOnTerm },
523             { "lighten", pp_colouring_lighten },
524             { "darken", pp_colouring_darken },
525             { "fade", pp_colouring_fade },
526             { "fadeout", pp_colouring_fadeout },
527             { "fadein", pp_colouring_fadein },
528             { "saturate", pp_colouring_saturate },
529             { "desaturate", pp_colouring_desaturate },
530             { "greyscale", pp_colouring_greyscale },
531             { "mix", pp_colouring_mix },
532             { "tint", pp_colouring_tint },
533             { "shade", pp_colouring_shade },
534             { "colour", pp_colouring_colour },
535             { NULL, NULL }
536             };
537              
538             #define COLOURING_OP_COUNT 20
539              
540             /* ══════════════════════════════════════════════════════════════════
541             * Peephole optimizer — replace entersub with custom ops
542             * ══════════════════════════════════════════════════════════════════ */
543              
544             static peep_t colouring_prev_peep = NULL;
545              
546             /* Walk an optree looking for entersub ops that call our methods,
547             * and replace them with the corresponding custom op. */
548 13128           static void colouring_peep(pTHX_ OP *o) {
549 13128           OP *orig = o;
550              
551             /* chain to any previous peep first */
552 13128 50         if (colouring_prev_peep)
553 13128           colouring_prev_peep(aTHX_ o);
554              
555 306212 100         for (; o; o = o->op_next) {
556             OP *cv_op, *method_op, *first;
557             const char *methname;
558             STRLEN methlen;
559             int i;
560              
561 293084 100         if (o->op_type != OP_ENTERSUB)
562 287607           continue;
563 8847 100         if (!(o->op_flags & OPf_STACKED))
564 162           continue;
565              
566             /* Find the last child of entersub — should be the method op */
567 8685           first = cUNOPo->op_first;
568 8685 50         if (!first)
569 0           continue;
570              
571             /* Walk to last sibling */
572 8685           cv_op = first;
573 24611 100         while (OpHAS_SIBLING(cv_op))
574 15926 50         cv_op = OpSIBLING(cv_op);
575              
576             /* We want OP_METHOD_NAMED */
577 8685 100         if (cv_op->op_type != OP_METHOD_NAMED)
578 3208           continue;
579              
580             /* Get the method name */
581             #if PERL_VERSION >= 22
582 5477           methname = SvPV_const(cMETHOPx_meth(cv_op), methlen);
583             #else
584             methname = SvPV_const(cSVOPx(cv_op)->op_sv, methlen);
585             #endif
586              
587             /* Look up in our dispatch table */
588 114213 100         for (i = 0; i < COLOURING_OP_COUNT; i++) {
589 108796 100         if (strEQ(methname, colouring_op_table[i].name)) {
590             /* Replace the entersub with our custom op */
591 60           o->op_ppaddr = colouring_op_table[i].pp;
592 60           break;
593             }
594             }
595             }
596 13128           }
597              
598             /* ══════════════════════════════════════════════════════════════════
599             * Registration — call from BOOT
600             * ══════════════════════════════════════════════════════════════════ */
601              
602             #define COLOURING_REGISTER_XOP(xop_var, name_str, pp_fn) \
603             XopENTRY_set(&xop_var, xop_name, name_str); \
604             XopENTRY_set(&xop_var, xop_desc, "colouring " name_str); \
605             XopENTRY_set(&xop_var, xop_class, OA_UNOP); \
606             Perl_custom_op_register(aTHX_ pp_fn, &xop_var)
607              
608 18           static void colouring_register_ops(pTHX) {
609             #if PERL_VERSION >= 14
610 18           COLOURING_REGISTER_XOP(xop_toHEX, "toHEX", pp_colouring_toHEX);
611 18           COLOURING_REGISTER_XOP(xop_toRGB, "toRGB", pp_colouring_toRGB);
612 18           COLOURING_REGISTER_XOP(xop_toRGBA, "toRGBA", pp_colouring_toRGBA);
613 18           COLOURING_REGISTER_XOP(xop_toHSL, "toHSL", pp_colouring_toHSL);
614 18           COLOURING_REGISTER_XOP(xop_toHSV, "toHSV", pp_colouring_toHSV);
615 18           COLOURING_REGISTER_XOP(xop_toCSS, "toCSS", pp_colouring_toCSS);
616 18           COLOURING_REGISTER_XOP(xop_toTerm, "toTerm", pp_colouring_toTerm);
617 18           COLOURING_REGISTER_XOP(xop_toOnTerm, "toOnTerm", pp_colouring_toOnTerm);
618 18           COLOURING_REGISTER_XOP(xop_lighten, "lighten", pp_colouring_lighten);
619 18           COLOURING_REGISTER_XOP(xop_darken, "darken", pp_colouring_darken);
620 18           COLOURING_REGISTER_XOP(xop_fade, "fade", pp_colouring_fade);
621 18           COLOURING_REGISTER_XOP(xop_fadeout, "fadeout", pp_colouring_fadeout);
622 18           COLOURING_REGISTER_XOP(xop_fadein, "fadein", pp_colouring_fadein);
623 18           COLOURING_REGISTER_XOP(xop_saturate, "saturate", pp_colouring_saturate);
624 18           COLOURING_REGISTER_XOP(xop_desaturate, "desaturate", pp_colouring_desaturate);
625 18           COLOURING_REGISTER_XOP(xop_greyscale, "greyscale", pp_colouring_greyscale);
626 18           COLOURING_REGISTER_XOP(xop_mix, "mix", pp_colouring_mix);
627 18           COLOURING_REGISTER_XOP(xop_tint, "tint", pp_colouring_tint);
628 18           COLOURING_REGISTER_XOP(xop_shade, "shade", pp_colouring_shade);
629 18           COLOURING_REGISTER_XOP(xop_colour, "colour", pp_colouring_colour);
630             #endif
631              
632             /* Install peephole optimizer */
633 18           colouring_prev_peep = PL_peepp;
634 18           PL_peepp = colouring_peep;
635 18           }
636              
637             #endif /* COLOURING_IN_OPS_H */