File Coverage

xs/watermark.xs
Criterion Covered Total %
statement 239 441 54.2
branch 207 500 41.4
condition n/a
subroutine n/a
pod n/a
total 446 941 47.4


line stmt bran cond sub pod time code
1             ##############################################################################
2             # Watermark XS bindings
3             ##############################################################################
4              
5             MODULE = PDF::Make PACKAGE = PDF::Make::Watermark
6             PROTOTYPES: ENABLE
7              
8             pdfmake_watermark_t *
9             text(class, text_sv, ...)
10             const char *class
11             SV *text_sv
12             PREINIT:
13             pdfmake_watermark_opts_t opts;
14             const char *text;
15             int i;
16             CODE:
17             PERL_UNUSED_VAR(class);
18 27 100         if (!SvOK(text_sv) || SvCUR(text_sv) == 0)
    100          
19 2           croak("Text required");
20              
21 25           text = SvPV_nolen(text_sv);
22 25 50         if (!text || !*text)
    50          
23 0           croak("Text required");
24              
25 25           pdfmake_watermark_opts_init(&opts);
26              
27 54 100         for (i = 2; i < items; i += 2) {
28             const char *key;
29             SV *val;
30             const char *pos;
31              
32 30 50         if (i + 1 >= items) break;
33 30           key = SvPV_nolen(ST(i));
34 30           val = ST(i + 1);
35              
36 30 100         if (strEQ(key, "position")) {
37 20 50         if (!SvOK(val)) {
38 0           opts.position = PDFMAKE_WM_POS_CENTER;
39 20 100         } else if (SvIOK(val) || SvNOK(val)) {
    50          
40 1           opts.position = (pdfmake_wm_position_t)SvIV(val);
41             } else {
42 19           pos = SvPV_nolen(val);
43 19 100         if (strEQ(pos, "center")) opts.position = PDFMAKE_WM_POS_CENTER;
44 17 100         else if (strEQ(pos, "diagonal")) opts.position = PDFMAKE_WM_POS_DIAGONAL;
45 14 100         else if (strEQ(pos, "tile")) opts.position = PDFMAKE_WM_POS_TILE;
46 12 100         else if (strEQ(pos, "custom")) opts.position = PDFMAKE_WM_POS_CUSTOM;
47 11 100         else if (strEQ(pos, "top_left")) opts.position = PDFMAKE_WM_POS_TOP_LEFT;
48 10 100         else if (strEQ(pos, "top_center")) opts.position = PDFMAKE_WM_POS_TOP_CENTER;
49 9 100         else if (strEQ(pos, "top_right")) opts.position = PDFMAKE_WM_POS_TOP_RIGHT;
50 7 100         else if (strEQ(pos, "bottom_left")) opts.position = PDFMAKE_WM_POS_BOTTOM_LEFT;
51 5 100         else if (strEQ(pos, "bottom_center")) opts.position = PDFMAKE_WM_POS_BOTTOM_CENTER;
52 4 100         else if (strEQ(pos, "bottom_right")) opts.position = PDFMAKE_WM_POS_BOTTOM_RIGHT;
53 3 100         else if (strEQ(pos, "left_center")) opts.position = PDFMAKE_WM_POS_LEFT_CENTER;
54 2 100         else if (strEQ(pos, "right_center")) opts.position = PDFMAKE_WM_POS_RIGHT_CENTER;
55 1           else croak("Unknown position: %s", pos);
56             }
57             }
58 10 100         else if (strEQ(key, "opacity")) {
59 2           opts.opacity = SvNV(val);
60             }
61 8 100         else if (strEQ(key, "rotation")) {
62 1           opts.rotation = SvNV(val);
63             }
64 7 100         else if (strEQ(key, "scale")) {
65 1           opts.scale = SvNV(val);
66             }
67 6 50         else if (strEQ(key, "x_offset")) {
68 0           opts.x_offset = SvNV(val);
69             }
70 6 50         else if (strEQ(key, "y_offset")) {
71 0           opts.y_offset = SvNV(val);
72             }
73 6 100         else if (strEQ(key, "overlay")) {
74 1           opts.as_overlay = SvIV(val);
75             }
76 5 100         else if (strEQ(key, "font")) {
77 1           opts.font_name = SvPV_nolen(val);
78             }
79 4 100         else if (strEQ(key, "size")) {
80 1           opts.font_size = SvNV(val);
81             }
82 3 100         else if (strEQ(key, "color")) {
83 1 50         if (SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVAV) {
    50          
84 1           AV *av = (AV*)SvRV(val);
85 1 50         if (av_len(av) >= 2) {
86 1           opts.color[0] = SvNV(*av_fetch(av, 0, 0));
87 1           opts.color[1] = SvNV(*av_fetch(av, 1, 0));
88 1           opts.color[2] = SvNV(*av_fetch(av, 2, 0));
89             }
90             }
91             }
92 2 100         else if (strEQ(key, "tile_spacing_x")) {
93 1           opts.tile_spacing_x = SvNV(val);
94             }
95 1 50         else if (strEQ(key, "tile_spacing_y")) {
96 1           opts.tile_spacing_y = SvNV(val);
97             }
98             }
99              
100 24           RETVAL = pdfmake_watermark_text(NULL, text, &opts);
101 24 50         if (!RETVAL)
102 0           croak("PDF::Make::Watermark: failed to create text watermark");
103             OUTPUT:
104             RETVAL
105              
106             pdfmake_watermark_t *
107             image(class, image_obj, ...)
108             const char *class
109             UV image_obj
110             PREINIT:
111             pdfmake_watermark_opts_t opts;
112             int i;
113 4           double width = 0.0;
114 4           double height = 0.0;
115 4           int have_width = 0;
116 4           int have_height = 0;
117             CODE:
118             PERL_UNUSED_VAR(class);
119 4 100         if (!image_obj)
120 1           croak("Image object required");
121              
122 3           pdfmake_watermark_opts_init(&opts);
123              
124 9 100         for (i = 2; i < items; i += 2) {
125             const char *key;
126             SV *val;
127             const char *pos;
128              
129 6 50         if (i + 1 >= items) break;
130 6           key = SvPV_nolen(ST(i));
131 6           val = ST(i + 1);
132              
133 6 100         if (strEQ(key, "width")) {
134 2           width = SvNV(val);
135 2           have_width = 1;
136             }
137 4 100         else if (strEQ(key, "height")) {
138 1           height = SvNV(val);
139 1           have_height = 1;
140             }
141 3 100         else if (strEQ(key, "position")) {
142 1 50         if (!SvOK(val)) {
143 0           opts.position = PDFMAKE_WM_POS_CENTER;
144 1 50         } else if (SvIOK(val) || SvNOK(val)) {
    50          
145 0           opts.position = (pdfmake_wm_position_t)SvIV(val);
146             } else {
147 1           pos = SvPV_nolen(val);
148 1 50         if (strEQ(pos, "center")) opts.position = PDFMAKE_WM_POS_CENTER;
149 0 0         else if (strEQ(pos, "diagonal")) opts.position = PDFMAKE_WM_POS_DIAGONAL;
150 0 0         else if (strEQ(pos, "tile")) opts.position = PDFMAKE_WM_POS_TILE;
151 0 0         else if (strEQ(pos, "custom")) opts.position = PDFMAKE_WM_POS_CUSTOM;
152 0 0         else if (strEQ(pos, "top_left")) opts.position = PDFMAKE_WM_POS_TOP_LEFT;
153 0 0         else if (strEQ(pos, "top_center")) opts.position = PDFMAKE_WM_POS_TOP_CENTER;
154 0 0         else if (strEQ(pos, "top_right")) opts.position = PDFMAKE_WM_POS_TOP_RIGHT;
155 0 0         else if (strEQ(pos, "bottom_left")) opts.position = PDFMAKE_WM_POS_BOTTOM_LEFT;
156 0 0         else if (strEQ(pos, "bottom_center")) opts.position = PDFMAKE_WM_POS_BOTTOM_CENTER;
157 0 0         else if (strEQ(pos, "bottom_right")) opts.position = PDFMAKE_WM_POS_BOTTOM_RIGHT;
158 0 0         else if (strEQ(pos, "left_center")) opts.position = PDFMAKE_WM_POS_LEFT_CENTER;
159 0 0         else if (strEQ(pos, "right_center")) opts.position = PDFMAKE_WM_POS_RIGHT_CENTER;
160 0           else croak("Unknown position: %s", pos);
161             }
162             }
163 2 100         else if (strEQ(key, "opacity")) {
164 1           opts.opacity = SvNV(val);
165             }
166 1 50         else if (strEQ(key, "rotation")) {
167 0           opts.rotation = SvNV(val);
168             }
169 1 50         else if (strEQ(key, "scale")) {
170 1           opts.scale = SvNV(val);
171             }
172 0 0         else if (strEQ(key, "x_offset")) {
173 0           opts.x_offset = SvNV(val);
174             }
175 0 0         else if (strEQ(key, "y_offset")) {
176 0           opts.y_offset = SvNV(val);
177             }
178 0 0         else if (strEQ(key, "overlay")) {
179 0           opts.as_overlay = SvIV(val);
180             }
181 0 0         else if (strEQ(key, "tile_spacing_x")) {
182 0           opts.tile_spacing_x = SvNV(val);
183             }
184 0 0         else if (strEQ(key, "tile_spacing_y")) {
185 0           opts.tile_spacing_y = SvNV(val);
186             }
187             }
188              
189 3 100         if (!have_width)
190 1           croak("Width required for image watermark");
191 2 100         if (!have_height)
192 1           croak("Height required for image watermark");
193              
194 1           RETVAL = pdfmake_watermark_image(NULL, (uint32_t)image_obj, width, height, &opts);
195 1 50         if (!RETVAL)
196 0           croak("PDF::Make::Watermark: failed to create image watermark");
197             OUTPUT:
198             RETVAL
199              
200             pdfmake_watermark_t *
201             _new_text(class, doc, text, ...)
202             const char *class
203             SV *doc
204             const char *text
205             PREINIT:
206             pdfmake_watermark_opts_t opts;
207             int i;
208             CODE:
209             PERL_UNUSED_VAR(doc);
210             PERL_UNUSED_VAR(class);
211 0           pdfmake_watermark_opts_init(&opts);
212            
213             /* Parse optional hash arguments */
214 0 0         for (i = 3; i < items; i += 2) {
215 0 0         if (i + 1 >= items) break;
216 0           const char *key = SvPV_nolen(ST(i));
217 0           SV *val = ST(i + 1);
218            
219 0 0         if (strEQ(key, "position")) {
220 0           opts.position = (pdfmake_wm_position_t)SvIV(val);
221             }
222 0 0         else if (strEQ(key, "opacity")) {
223 0           opts.opacity = SvNV(val);
224             }
225 0 0         else if (strEQ(key, "rotation")) {
226 0           opts.rotation = SvNV(val);
227             }
228 0 0         else if (strEQ(key, "scale")) {
229 0           opts.scale = SvNV(val);
230             }
231 0 0         else if (strEQ(key, "x_offset")) {
232 0           opts.x_offset = SvNV(val);
233             }
234 0 0         else if (strEQ(key, "y_offset")) {
235 0           opts.y_offset = SvNV(val);
236             }
237 0 0         else if (strEQ(key, "overlay")) {
238 0           opts.as_overlay = SvIV(val);
239             }
240 0 0         else if (strEQ(key, "font")) {
241 0           opts.font_name = SvPV_nolen(val);
242             }
243 0 0         else if (strEQ(key, "size")) {
244 0           opts.font_size = SvNV(val);
245             }
246 0 0         else if (strEQ(key, "color")) {
247 0 0         if (SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVAV) {
    0          
248 0           AV *av = (AV*)SvRV(val);
249 0 0         if (av_len(av) >= 2) {
250 0           opts.color[0] = SvNV(*av_fetch(av, 0, 0));
251 0           opts.color[1] = SvNV(*av_fetch(av, 1, 0));
252 0           opts.color[2] = SvNV(*av_fetch(av, 2, 0));
253             }
254             }
255             }
256 0 0         else if (strEQ(key, "tile_spacing_x")) {
257 0           opts.tile_spacing_x = SvNV(val);
258             }
259 0 0         else if (strEQ(key, "tile_spacing_y")) {
260 0           opts.tile_spacing_y = SvNV(val);
261             }
262             }
263            
264 0           RETVAL = pdfmake_watermark_text(NULL, text, &opts);
265 0 0         if (!RETVAL)
266 0           croak("PDF::Make::Watermark: failed to create text watermark");
267             OUTPUT:
268             RETVAL
269              
270             pdfmake_watermark_t *
271             _new_image(class, doc, image_obj, width, height, ...)
272             const char *class
273             SV *doc
274             UV image_obj
275             double width
276             double height
277             PREINIT:
278             pdfmake_watermark_opts_t opts;
279             int i;
280             CODE:
281             PERL_UNUSED_VAR(doc);
282             PERL_UNUSED_VAR(class);
283 0           pdfmake_watermark_opts_init(&opts);
284            
285             /* Parse optional hash arguments */
286 0 0         for (i = 5; i < items; i += 2) {
287 0 0         if (i + 1 >= items) break;
288 0           const char *key = SvPV_nolen(ST(i));
289 0           SV *val = ST(i + 1);
290            
291 0 0         if (strEQ(key, "position")) {
292 0           opts.position = (pdfmake_wm_position_t)SvIV(val);
293             }
294 0 0         else if (strEQ(key, "opacity")) {
295 0           opts.opacity = SvNV(val);
296             }
297 0 0         else if (strEQ(key, "rotation")) {
298 0           opts.rotation = SvNV(val);
299             }
300 0 0         else if (strEQ(key, "scale")) {
301 0           opts.scale = SvNV(val);
302             }
303 0 0         else if (strEQ(key, "x_offset")) {
304 0           opts.x_offset = SvNV(val);
305             }
306 0 0         else if (strEQ(key, "y_offset")) {
307 0           opts.y_offset = SvNV(val);
308             }
309 0 0         else if (strEQ(key, "overlay")) {
310 0           opts.as_overlay = SvIV(val);
311             }
312 0 0         else if (strEQ(key, "tile_spacing_x")) {
313 0           opts.tile_spacing_x = SvNV(val);
314             }
315 0 0         else if (strEQ(key, "tile_spacing_y")) {
316 0           opts.tile_spacing_y = SvNV(val);
317             }
318             }
319            
320 0           RETVAL = pdfmake_watermark_image(NULL, (uint32_t)image_obj, width, height, &opts);
321 0 0         if (!RETVAL)
322 0           croak("PDF::Make::Watermark: failed to create image watermark");
323             OUTPUT:
324             RETVAL
325              
326             void
327             DESTROY(self)
328             pdfmake_watermark_t *self
329             CODE:
330 25           pdfmake_watermark_free(self);
331              
332             const char *
333             type(self)
334             pdfmake_watermark_t *self
335             CODE:
336 2 100         RETVAL = (self->type == PDFMAKE_WM_TYPE_TEXT) ? "text" : "image";
337             OUTPUT:
338             RETVAL
339              
340             const char *
341             text_content(self)
342             pdfmake_watermark_t *self
343             CODE:
344 1 50         if (self->type == PDFMAKE_WM_TYPE_TEXT)
345 1 50         RETVAL = self->data.text.text ? self->data.text.text : "";
346             else
347 0           RETVAL = "";
348             OUTPUT:
349             RETVAL
350              
351             int
352             position(self)
353             pdfmake_watermark_t *self
354             CODE:
355 7 50         RETVAL = self->opts.position;
356             OUTPUT:
357             RETVAL
358              
359             double
360             opacity(self)
361             pdfmake_watermark_t *self
362             CODE:
363 3 50         RETVAL = self->opts.opacity;
364             OUTPUT:
365             RETVAL
366              
367             double
368             rotation(self)
369             pdfmake_watermark_t *self
370             CODE:
371 1 50         RETVAL = self->opts.rotation;
372             OUTPUT:
373             RETVAL
374              
375             double
376             scale(self)
377             pdfmake_watermark_t *self
378             CODE:
379 2 50         RETVAL = self->opts.scale;
380             OUTPUT:
381             RETVAL
382              
383             double
384             x_offset(self)
385             pdfmake_watermark_t *self
386             CODE:
387 0 0         RETVAL = self->opts.x_offset;
388             OUTPUT:
389             RETVAL
390              
391             double
392             y_offset(self)
393             pdfmake_watermark_t *self
394             CODE:
395 0 0         RETVAL = self->opts.y_offset;
396             OUTPUT:
397             RETVAL
398              
399             int
400             overlay(self)
401             pdfmake_watermark_t *self
402             CODE:
403 2 50         RETVAL = self->opts.as_overlay;
404             OUTPUT:
405             RETVAL
406              
407             const char *
408             font(self)
409             pdfmake_watermark_t *self
410             CODE:
411 2 50         RETVAL = self->opts.font_name ? self->opts.font_name : "Helvetica-Bold";
412             OUTPUT:
413             RETVAL
414              
415             double
416             size(self)
417             pdfmake_watermark_t *self
418             CODE:
419 2 50         RETVAL = self->opts.font_size;
420             OUTPUT:
421             RETVAL
422              
423             SV *
424             color(self)
425             pdfmake_watermark_t *self
426             PREINIT:
427             AV *av;
428             CODE:
429 1           av = newAV();
430 1           av_push(av, newSVnv(self->opts.color[0]));
431 1           av_push(av, newSVnv(self->opts.color[1]));
432 1           av_push(av, newSVnv(self->opts.color[2]));
433 1           RETVAL = newRV_noinc((SV*)av);
434             OUTPUT:
435             RETVAL
436              
437             double
438             width(self)
439             pdfmake_watermark_t *self
440             CODE:
441 1 50         if (self->type == PDFMAKE_WM_TYPE_IMAGE)
442 1           RETVAL = self->data.image.width;
443             else
444 0           RETVAL = self->data.text.text_width;
445             OUTPUT:
446             RETVAL
447              
448             double
449             height(self)
450             pdfmake_watermark_t *self
451             CODE:
452 1 50         if (self->type == PDFMAKE_WM_TYPE_IMAGE)
453 1           RETVAL = self->data.image.height;
454             else
455 0           RETVAL = self->data.text.text_height;
456             OUTPUT:
457             RETVAL
458              
459             double
460             tile_spacing_x(self)
461             pdfmake_watermark_t *self
462             CODE:
463 1 50         RETVAL = self->opts.tile_spacing_x;
464             OUTPUT:
465             RETVAL
466              
467             double
468             tile_spacing_y(self)
469             pdfmake_watermark_t *self
470             CODE:
471 1 50         RETVAL = self->opts.tile_spacing_y;
472             OUTPUT:
473             RETVAL
474              
475             UV
476             image_obj(self)
477             pdfmake_watermark_t *self
478             CODE:
479 1 50         if (self->type == PDFMAKE_WM_TYPE_IMAGE)
480 1           RETVAL = (UV)self->data.image.image_obj;
481             else
482 0           RETVAL = 0;
483             OUTPUT:
484             RETVAL
485              
486             ##############################################################################
487             # Stamp XS bindings
488             ##############################################################################
489              
490             MODULE = PDF::Make PACKAGE = PDF::Make::Stamp
491             PROTOTYPES: ENABLE
492              
493             pdfmake_stamp_t *
494             text(class, format_sv, ...)
495             const char *class
496             SV *format_sv
497             PREINIT:
498             pdfmake_stamp_opts_t opts;
499             const char *format;
500             int i;
501             CODE:
502             PERL_UNUSED_VAR(class);
503 7 50         if (!SvOK(format_sv))
504 0           croak("Format string required");
505              
506 7           format = SvPV_nolen(format_sv);
507 7           pdfmake_stamp_opts_init(&opts);
508              
509 14 100         for (i = 2; i < items; i += 2) {
510             const char *key;
511             SV *val;
512             const char *pos;
513              
514 8 50         if (i + 1 >= items) break;
515 8           key = SvPV_nolen(ST(i));
516 8           val = ST(i + 1);
517              
518 8 100         if (strEQ(key, "position")) {
519 3 50         if (!SvOK(val)) {
520 0           opts.position = PDFMAKE_WM_POS_BOTTOM_CENTER;
521 3 100         } else if (SvIOK(val) || SvNOK(val)) {
    50          
522 1           opts.position = (pdfmake_stamp_position_t)SvIV(val);
523             } else {
524 2           pos = SvPV_nolen(val);
525 2 50         if (strEQ(pos, "center")) opts.position = PDFMAKE_WM_POS_CENTER;
526 2 50         else if (strEQ(pos, "diagonal")) opts.position = PDFMAKE_WM_POS_DIAGONAL;
527 2 50         else if (strEQ(pos, "tile")) opts.position = PDFMAKE_WM_POS_TILE;
528 2 50         else if (strEQ(pos, "custom")) opts.position = PDFMAKE_WM_POS_CUSTOM;
529 2 50         else if (strEQ(pos, "top_left")) opts.position = PDFMAKE_WM_POS_TOP_LEFT;
530 2 50         else if (strEQ(pos, "top_center")) opts.position = PDFMAKE_WM_POS_TOP_CENTER;
531 2 50         else if (strEQ(pos, "top_right")) opts.position = PDFMAKE_WM_POS_TOP_RIGHT;
532 2 50         else if (strEQ(pos, "bottom_left")) opts.position = PDFMAKE_WM_POS_BOTTOM_LEFT;
533 2 50         else if (strEQ(pos, "bottom_center")) opts.position = PDFMAKE_WM_POS_BOTTOM_CENTER;
534 2 100         else if (strEQ(pos, "bottom_right")) opts.position = PDFMAKE_WM_POS_BOTTOM_RIGHT;
535 1 50         else if (strEQ(pos, "left_center")) opts.position = PDFMAKE_WM_POS_LEFT_CENTER;
536 1 50         else if (strEQ(pos, "right_center")) opts.position = PDFMAKE_WM_POS_RIGHT_CENTER;
537 1           else croak("Unknown position: %s", pos);
538             }
539             }
540 5 100         else if (strEQ(key, "margin_x") || strEQ(key, "margin")) {
    50          
541 1           opts.margin_x = SvNV(val);
542             }
543 4 100         else if (strEQ(key, "margin_y")) {
544 1           opts.margin_y = SvNV(val);
545             }
546 3 100         else if (strEQ(key, "font")) {
547 1           opts.font_name = SvPV_nolen(val);
548             }
549 2 100         else if (strEQ(key, "size")) {
550 1           opts.font_size = SvNV(val);
551             }
552 1 50         else if (strEQ(key, "color")) {
553 1 50         if (SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVAV) {
    50          
554 1           AV *av = (AV*)SvRV(val);
555 1 50         if (av_len(av) >= 2) {
556 1           opts.color[0] = SvNV(*av_fetch(av, 0, 0));
557 1           opts.color[1] = SvNV(*av_fetch(av, 1, 0));
558 1           opts.color[2] = SvNV(*av_fetch(av, 2, 0));
559             }
560             }
561             }
562             }
563              
564 6           RETVAL = pdfmake_stamp_text(NULL, format, &opts);
565 6 50         if (!RETVAL)
566 0           croak("PDF::Make::Stamp: failed to create text stamp");
567             OUTPUT:
568             RETVAL
569              
570             pdfmake_stamp_t *
571             bates(class, ...)
572             const char *class
573             PREINIT:
574             pdfmake_stamp_opts_t opts;
575 3           const char *prefix = "";
576 3           const char *suffix = "";
577 3           int start = 1;
578 3           int digits = 6;
579             int i;
580             CODE:
581             PERL_UNUSED_VAR(class);
582 3           pdfmake_stamp_opts_init(&opts);
583              
584 15 100         for (i = 1; i < items; i += 2) {
585             const char *key;
586             SV *val;
587             const char *pos;
588              
589 12 50         if (i + 1 >= items) break;
590 12           key = SvPV_nolen(ST(i));
591 12           val = ST(i + 1);
592              
593 12 100         if (strEQ(key, "prefix")) {
594 3           prefix = SvPV_nolen(val);
595             }
596 9 100         else if (strEQ(key, "suffix")) {
597 2           suffix = SvPV_nolen(val);
598             }
599 7 100         else if (strEQ(key, "start")) {
600 3           start = SvIV(val);
601             }
602 4 100         else if (strEQ(key, "digits")) {
603 3           digits = SvIV(val);
604             }
605 1 50         else if (strEQ(key, "position")) {
606 1 50         if (!SvOK(val)) {
607 0           opts.position = PDFMAKE_WM_POS_BOTTOM_RIGHT;
608 1 50         } else if (SvIOK(val) || SvNOK(val)) {
    50          
609 0           opts.position = (pdfmake_stamp_position_t)SvIV(val);
610             } else {
611 1           pos = SvPV_nolen(val);
612 1 50         if (strEQ(pos, "center")) opts.position = PDFMAKE_WM_POS_CENTER;
613 1 50         else if (strEQ(pos, "diagonal")) opts.position = PDFMAKE_WM_POS_DIAGONAL;
614 1 50         else if (strEQ(pos, "tile")) opts.position = PDFMAKE_WM_POS_TILE;
615 1 50         else if (strEQ(pos, "custom")) opts.position = PDFMAKE_WM_POS_CUSTOM;
616 1 50         else if (strEQ(pos, "top_left")) opts.position = PDFMAKE_WM_POS_TOP_LEFT;
617 1 50         else if (strEQ(pos, "top_center")) opts.position = PDFMAKE_WM_POS_TOP_CENTER;
618 1 50         else if (strEQ(pos, "top_right")) opts.position = PDFMAKE_WM_POS_TOP_RIGHT;
619 1 50         else if (strEQ(pos, "bottom_left")) opts.position = PDFMAKE_WM_POS_BOTTOM_LEFT;
620 1 50         else if (strEQ(pos, "bottom_center")) opts.position = PDFMAKE_WM_POS_BOTTOM_CENTER;
621 1 50         else if (strEQ(pos, "bottom_right")) opts.position = PDFMAKE_WM_POS_BOTTOM_RIGHT;
622 0 0         else if (strEQ(pos, "left_center")) opts.position = PDFMAKE_WM_POS_LEFT_CENTER;
623 0 0         else if (strEQ(pos, "right_center")) opts.position = PDFMAKE_WM_POS_RIGHT_CENTER;
624 0           else croak("Unknown position: %s", pos);
625             }
626             }
627 0 0         else if (strEQ(key, "margin_x") || strEQ(key, "margin")) {
    0          
628 0           opts.margin_x = SvNV(val);
629             }
630 0 0         else if (strEQ(key, "margin_y")) {
631 0           opts.margin_y = SvNV(val);
632             }
633 0 0         else if (strEQ(key, "font")) {
634 0           opts.font_name = SvPV_nolen(val);
635             }
636 0 0         else if (strEQ(key, "size")) {
637 0           opts.font_size = SvNV(val);
638             }
639 0 0         else if (strEQ(key, "color")) {
640 0 0         if (SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVAV) {
    0          
641 0           AV *av = (AV*)SvRV(val);
642 0 0         if (av_len(av) >= 2) {
643 0           opts.color[0] = SvNV(*av_fetch(av, 0, 0));
644 0           opts.color[1] = SvNV(*av_fetch(av, 1, 0));
645 0           opts.color[2] = SvNV(*av_fetch(av, 2, 0));
646             }
647             }
648             }
649             }
650              
651 3           RETVAL = pdfmake_stamp_bates(NULL, prefix, start, digits, suffix, &opts);
652 3 50         if (!RETVAL)
653 0           croak("PDF::Make::Stamp: failed to create Bates stamp");
654             OUTPUT:
655             RETVAL
656              
657             pdfmake_stamp_t *
658             _new_text(class, doc, format, ...)
659             const char *class
660             SV *doc
661             const char *format
662             PREINIT:
663             pdfmake_stamp_opts_t opts;
664             int i;
665             CODE:
666             PERL_UNUSED_VAR(doc);
667             PERL_UNUSED_VAR(class);
668 0           pdfmake_stamp_opts_init(&opts);
669            
670             /* Parse optional hash arguments */
671 0 0         for (i = 3; i < items; i += 2) {
672 0 0         if (i + 1 >= items) break;
673 0           const char *key = SvPV_nolen(ST(i));
674 0           SV *val = ST(i + 1);
675            
676 0 0         if (strEQ(key, "position")) {
677 0           opts.position = (pdfmake_stamp_position_t)SvIV(val);
678             }
679 0 0         else if (strEQ(key, "margin_x") || strEQ(key, "margin")) {
    0          
680 0           opts.margin_x = SvNV(val);
681             }
682 0 0         else if (strEQ(key, "margin_y")) {
683 0           opts.margin_y = SvNV(val);
684             }
685 0 0         else if (strEQ(key, "font")) {
686 0           opts.font_name = SvPV_nolen(val);
687             }
688 0 0         else if (strEQ(key, "size")) {
689 0           opts.font_size = SvNV(val);
690             }
691 0 0         else if (strEQ(key, "color")) {
692 0 0         if (SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVAV) {
    0          
693 0           AV *av = (AV*)SvRV(val);
694 0 0         if (av_len(av) >= 2) {
695 0           opts.color[0] = SvNV(*av_fetch(av, 0, 0));
696 0           opts.color[1] = SvNV(*av_fetch(av, 1, 0));
697 0           opts.color[2] = SvNV(*av_fetch(av, 2, 0));
698             }
699             }
700             }
701             }
702            
703             /* If margin was set but margin_y wasn't explicitly set, use same value */
704             /* This handles the common case of margin => 36 setting both */
705            
706 0           RETVAL = pdfmake_stamp_text(NULL, format, &opts);
707 0 0         if (!RETVAL)
708 0           croak("PDF::Make::Stamp: failed to create text stamp");
709             OUTPUT:
710             RETVAL
711              
712             pdfmake_stamp_t *
713             _new_bates(class, doc, ...)
714             const char *class
715             SV *doc
716             PREINIT:
717             pdfmake_stamp_opts_t opts;
718 0           const char *prefix = "";
719 0           const char *suffix = "";
720 0           int start = 1;
721 0           int digits = 6;
722             int i;
723             CODE:
724             PERL_UNUSED_VAR(doc);
725             PERL_UNUSED_VAR(class);
726 0           pdfmake_stamp_opts_init(&opts);
727            
728             /* Parse optional hash arguments */
729 0 0         for (i = 2; i < items; i += 2) {
730 0 0         if (i + 1 >= items) break;
731 0           const char *key = SvPV_nolen(ST(i));
732 0           SV *val = ST(i + 1);
733            
734 0 0         if (strEQ(key, "prefix")) {
735 0           prefix = SvPV_nolen(val);
736             }
737 0 0         else if (strEQ(key, "suffix")) {
738 0           suffix = SvPV_nolen(val);
739             }
740 0 0         else if (strEQ(key, "start")) {
741 0           start = SvIV(val);
742             }
743 0 0         else if (strEQ(key, "digits")) {
744 0           digits = SvIV(val);
745             }
746 0 0         else if (strEQ(key, "position")) {
747 0           opts.position = (pdfmake_stamp_position_t)SvIV(val);
748             }
749 0 0         else if (strEQ(key, "margin_x") || strEQ(key, "margin")) {
    0          
750 0           opts.margin_x = SvNV(val);
751             }
752 0 0         else if (strEQ(key, "margin_y")) {
753 0           opts.margin_y = SvNV(val);
754             }
755 0 0         else if (strEQ(key, "font")) {
756 0           opts.font_name = SvPV_nolen(val);
757             }
758 0 0         else if (strEQ(key, "size")) {
759 0           opts.font_size = SvNV(val);
760             }
761 0 0         else if (strEQ(key, "color")) {
762 0 0         if (SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVAV) {
    0          
763 0           AV *av = (AV*)SvRV(val);
764 0 0         if (av_len(av) >= 2) {
765 0           opts.color[0] = SvNV(*av_fetch(av, 0, 0));
766 0           opts.color[1] = SvNV(*av_fetch(av, 1, 0));
767 0           opts.color[2] = SvNV(*av_fetch(av, 2, 0));
768             }
769             }
770             }
771             }
772            
773 0           RETVAL = pdfmake_stamp_bates(NULL, prefix, start, digits, suffix, &opts);
774 0 0         if (!RETVAL)
775 0           croak("PDF::Make::Stamp: failed to create Bates stamp");
776             OUTPUT:
777             RETVAL
778              
779             void
780             DESTROY(self)
781             pdfmake_stamp_t *self
782             CODE:
783 9           pdfmake_stamp_free(self);
784              
785             const char *
786             type(self)
787             pdfmake_stamp_t *self
788             CODE:
789 2 100         RETVAL = (self->type == PDFMAKE_WM_STAMP_TEXT) ? "text" : "bates";
790             OUTPUT:
791             RETVAL
792              
793             const char *
794             type_name(self)
795             pdfmake_stamp_t *self
796             CODE:
797 0 0         RETVAL = (self->type == PDFMAKE_WM_STAMP_TEXT) ? "text" : "bates";
798             OUTPUT:
799             RETVAL
800              
801             const char *
802             format(self)
803             pdfmake_stamp_t *self
804             CODE:
805 1 50         if (self->type == PDFMAKE_WM_STAMP_TEXT)
806 1 50         RETVAL = self->data.text.format ? self->data.text.format : "";
807             else
808 0           RETVAL = "";
809             OUTPUT:
810             RETVAL
811              
812             const char *
813             prefix(self)
814             pdfmake_stamp_t *self
815             CODE:
816 1 50         if (self->type == PDFMAKE_WM_STAMP_BATES)
817 1 50         RETVAL = self->data.bates.prefix ? self->data.bates.prefix : "";
818             else
819 0           RETVAL = "";
820             OUTPUT:
821             RETVAL
822              
823             const char *
824             suffix(self)
825             pdfmake_stamp_t *self
826             CODE:
827 1 50         if (self->type == PDFMAKE_WM_STAMP_BATES)
828 1 50         RETVAL = self->data.bates.suffix ? self->data.bates.suffix : "";
829             else
830 0           RETVAL = "";
831             OUTPUT:
832             RETVAL
833              
834             int
835             start(self)
836             pdfmake_stamp_t *self
837             CODE:
838 1 50         if (self->type == PDFMAKE_WM_STAMP_BATES)
839 1           RETVAL = self->data.bates.start_number;
840             else
841 0           RETVAL = 0;
842             OUTPUT:
843             RETVAL
844              
845             int
846             digits(self)
847             pdfmake_stamp_t *self
848             CODE:
849 1 50         if (self->type == PDFMAKE_WM_STAMP_BATES)
850 1           RETVAL = self->data.bates.digits;
851             else
852 0           RETVAL = 0;
853             OUTPUT:
854             RETVAL
855              
856             int
857             position(self)
858             pdfmake_stamp_t *self
859             CODE:
860 3 50         RETVAL = self->opts.position;
861             OUTPUT:
862             RETVAL
863              
864             double
865             margin_x(self)
866             pdfmake_stamp_t *self
867             CODE:
868 2 50         RETVAL = self->opts.margin_x;
869             OUTPUT:
870             RETVAL
871              
872             double
873             margin_y(self)
874             pdfmake_stamp_t *self
875             CODE:
876 1 50         RETVAL = self->opts.margin_y;
877             OUTPUT:
878             RETVAL
879              
880             const char *
881             font(self)
882             pdfmake_stamp_t *self
883             CODE:
884 2 50         RETVAL = self->opts.font_name ? self->opts.font_name : "Helvetica";
885             OUTPUT:
886             RETVAL
887              
888             double
889             size(self)
890             pdfmake_stamp_t *self
891             CODE:
892 2 50         RETVAL = self->opts.font_size;
893             OUTPUT:
894             RETVAL
895              
896             SV *
897             color(self)
898             pdfmake_stamp_t *self
899             PREINIT:
900             AV *av;
901             CODE:
902 1           av = newAV();
903 1           av_push(av, newSVnv(self->opts.color[0]));
904 1           av_push(av, newSVnv(self->opts.color[1]));
905 1           av_push(av, newSVnv(self->opts.color[2]));
906 1           RETVAL = newRV_noinc((SV*)av);
907             OUTPUT:
908             RETVAL
909              
910             void
911             reset(self)
912             pdfmake_stamp_t *self
913             CODE:
914 1 50         if (self->type == PDFMAKE_WM_STAMP_BATES)
915 1           self->data.bates.current_number = self->data.bates.start_number;
916              
917             SV *
918             next_bates(self)
919             pdfmake_stamp_t *self
920             PREINIT:
921             char *text;
922             CODE:
923 4 50         if (self->type != PDFMAKE_WM_STAMP_BATES)
924 0           XSRETURN_UNDEF;
925            
926 4           text = pdfmake_stamp_expand_bates(
927 4           self->data.bates.prefix,
928             self->data.bates.current_number,
929             self->data.bates.digits,
930 4           self->data.bates.suffix
931             );
932 4           self->data.bates.current_number++;
933            
934 4 50         if (text) {
935 4           RETVAL = newSVpv(text, 0);
936 4           free(text);
937             } else {
938 0           XSRETURN_UNDEF;
939             }
940             OUTPUT:
941             RETVAL
942              
943             SV *
944             expand(self, page_num, total_pages, ...)
945             pdfmake_stamp_t *self
946             int page_num
947             int total_pages
948             PREINIT:
949             char *text;
950 2           const char *filename = NULL;
951             CODE:
952 2 50         if (items > 3)
953 0           filename = SvPV_nolen(ST(3));
954            
955 2 50         if (self->type == PDFMAKE_WM_STAMP_BATES) {
956 0           text = pdfmake_stamp_expand_bates(
957 0           self->data.bates.prefix,
958             self->data.bates.current_number,
959             self->data.bates.digits,
960 0           self->data.bates.suffix
961             );
962 0           self->data.bates.current_number++;
963             } else {
964 2           text = pdfmake_stamp_expand_format(
965 2           self->data.text.format,
966             page_num,
967             total_pages,
968             filename
969             );
970             }
971            
972 2 50         if (text) {
973 2           RETVAL = newSVpv(text, 0);
974 2           free(text);
975             } else {
976 0           XSRETURN_UNDEF;
977             }
978             OUTPUT:
979             RETVAL
980              
981             ##############################################################################
982             # Document watermark/stamp methods
983             ##############################################################################
984              
985             MODULE = PDF::Make PACKAGE = PDF::Make::Document
986              
987             void
988             add_watermark(self, wm)
989             pdfmake_doc_t *self
990             pdfmake_watermark_t *wm
991             CODE:
992 2 50         if (pdfmake_doc_add_watermark(self, wm) != PDFMAKE_OK)
993 0           croak("PDF::Make::Document::add_watermark: failed");
994              
995             void
996             apply_stamp(self, stamp)
997             pdfmake_doc_t *self
998             pdfmake_stamp_t *stamp
999             CODE:
1000 2 50         if (pdfmake_doc_add_stamp(self, stamp) != PDFMAKE_OK)
1001 0           croak("PDF::Make::Document::apply_stamp: failed");
1002              
1003              
1004             BOOT:
1005             {
1006 90           HV *stash = gv_stashpv("PDF::Make::Watermark", GV_ADD);
1007 90 50         PDFMAKE_REGISTER_GETTER(stash, "position", pdfmake_watermark_t, opts.position, PDFMAKE_FIELD_INT);
    50          
1008 90 50         PDFMAKE_REGISTER_GETTER(stash, "opacity", pdfmake_watermark_t, opts.opacity, PDFMAKE_FIELD_DOUBLE);
    50          
1009 90 50         PDFMAKE_REGISTER_GETTER(stash, "rotation", pdfmake_watermark_t, opts.rotation, PDFMAKE_FIELD_DOUBLE);
    50          
1010 90 50         PDFMAKE_REGISTER_GETTER(stash, "scale", pdfmake_watermark_t, opts.scale, PDFMAKE_FIELD_DOUBLE);
    50          
1011 90 50         PDFMAKE_REGISTER_GETTER(stash, "x_offset", pdfmake_watermark_t, opts.x_offset, PDFMAKE_FIELD_DOUBLE);
    50          
1012 90 50         PDFMAKE_REGISTER_GETTER(stash, "y_offset", pdfmake_watermark_t, opts.y_offset, PDFMAKE_FIELD_DOUBLE);
    50          
1013 90 50         PDFMAKE_REGISTER_GETTER(stash, "overlay", pdfmake_watermark_t, opts.as_overlay, PDFMAKE_FIELD_INT);
    50          
1014 90 50         PDFMAKE_REGISTER_GETTER(stash, "font_size", pdfmake_watermark_t, opts.font_size, PDFMAKE_FIELD_DOUBLE);
    0          
1015 90 50         PDFMAKE_REGISTER_GETTER(stash, "tile_spacing_x", pdfmake_watermark_t, opts.tile_spacing_x, PDFMAKE_FIELD_DOUBLE);
    50          
1016 90 50         PDFMAKE_REGISTER_GETTER(stash, "tile_spacing_y", pdfmake_watermark_t, opts.tile_spacing_y, PDFMAKE_FIELD_DOUBLE);
    50          
1017             }