File Coverage

Make.xs
Criterion Covered Total %
statement 7 36 19.4
branch 0 54 0.0
condition n/a
subroutine n/a
pod n/a
total 7 90 7.7


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             #include "pdfmake.h"
7             #include "pdfmake_buf.h"
8             #include "pdfmake_writer.h"
9             #include "pdfmake_doc.h"
10             #include "pdfmake_meta.h"
11             #include "pdfmake_page.h"
12             #include "pdfmake_content.h"
13             #include "pdfmake_parser.h"
14             #include "pdfmake_arena.h"
15             #include "pdfmake_reader.h"
16             #include "pdfmake_image.h"
17             #include "pdfmake_font.h"
18             #include "pdfmake_interpreter.h"
19             #include "pdfmake_textract.h"
20             #include "pdfmake_edit.h"
21             #include "pdfmake_import.h"
22             #include "pdfmake_ocg.h"
23             #include "pdfmake_attach.h"
24             #include "pdfmake_tag.h"
25             #include "pdfmake_redact.h"
26             #include "pdfmake_color_mgmt.h"
27             #include "pdfmake_annot.h"
28             #include "pdfmake_outline.h"
29             #include "pdfmake_action.h"
30             #include "pdfmake_crypt.h"
31             #include "pdfmake_form.h"
32             #include "pdfmake_watermark.h"
33             #include "pdfmake_signature.h"
34             #include "pdfmake_x509.h"
35             #include "pdfmake_pkcs12.h"
36             #include "pdfmake_linear.h"
37             #include "pdfmake_image_render.h"
38             #include "pdfmake_custom_ops.h"
39             #include "pdfmake_filter.h"
40              
41             /* -------------------------------------------------------------------------
42             * Render API forward declarations
43             * ------------------------------------------------------------------------- */
44             typedef struct pdfmake_render_ctx {
45             uint32_t *pixels;
46             int width;
47             int height;
48             int stride;
49             } pdfmake_render_ctx_t;
50              
51             typedef pdfmake_render_ctx_t* PDF__Make__Render;
52              
53             typedef enum {
54             PDFMAKE_RENDER_OK = 0,
55             PDFMAKE_RENDER_ERR_NULL,
56             PDFMAKE_RENDER_ERR_MEMORY,
57             PDFMAKE_RENDER_ERR_INVALID,
58             PDFMAKE_RENDER_ERR_OVERFLOW,
59             PDFMAKE_RENDER_ERR_EMPTY_PATH,
60             } pdfmake_render_err_t;
61              
62             typedef int pdfmake_line_cap_t;
63             typedef int pdfmake_line_join_t;
64             typedef int pdfmake_fill_rule_t;
65              
66             typedef struct {
67             double a, b, c, d, e, f;
68             } pdfmake_matrix_t;
69              
70             pdfmake_render_ctx_t *pdfmake_render_create(int width, int height);
71             void pdfmake_render_destroy(pdfmake_render_ctx_t *ctx);
72             void pdfmake_render_clear(pdfmake_render_ctx_t *ctx, pdfmake_color_t color);
73             pdfmake_render_err_t pdfmake_render_save(pdfmake_render_ctx_t *ctx);
74             pdfmake_render_err_t pdfmake_render_restore(pdfmake_render_ctx_t *ctx);
75             void pdfmake_render_set_fill_color(pdfmake_render_ctx_t *ctx, double r, double g, double b, double a);
76             void pdfmake_render_set_stroke_color(pdfmake_render_ctx_t *ctx, double r, double g, double b, double a);
77             void pdfmake_render_set_line_width(pdfmake_render_ctx_t *ctx, double width);
78             void pdfmake_render_set_line_cap(pdfmake_render_ctx_t *ctx, pdfmake_line_cap_t cap);
79             void pdfmake_render_set_line_join(pdfmake_render_ctx_t *ctx, pdfmake_line_join_t join);
80             void pdfmake_render_set_miter_limit(pdfmake_render_ctx_t *ctx, double limit);
81             pdfmake_render_err_t pdfmake_render_set_dash(pdfmake_render_ctx_t *ctx, double *array, size_t count, double phase);
82             void pdfmake_render_set_fill_rule(pdfmake_render_ctx_t *ctx, pdfmake_fill_rule_t rule);
83             void pdfmake_render_translate(pdfmake_render_ctx_t *ctx, double tx, double ty);
84             void pdfmake_render_scale(pdfmake_render_ctx_t *ctx, double sx, double sy);
85             void pdfmake_render_rotate(pdfmake_render_ctx_t *ctx, double angle);
86             void pdfmake_render_set_matrix(pdfmake_render_ctx_t *ctx, pdfmake_matrix_t *m);
87             pdfmake_render_err_t pdfmake_render_move_to(pdfmake_render_ctx_t *ctx, double x, double y);
88             pdfmake_render_err_t pdfmake_render_line_to(pdfmake_render_ctx_t *ctx, double x, double y);
89             pdfmake_render_err_t pdfmake_render_curve_to(pdfmake_render_ctx_t *ctx, double x1, double y1, double x2, double y2, double x3, double y3);
90             pdfmake_render_err_t pdfmake_render_close_path(pdfmake_render_ctx_t *ctx);
91             pdfmake_render_err_t pdfmake_render_rect(pdfmake_render_ctx_t *ctx, double x, double y, double w, double h);
92             void pdfmake_render_new_path(pdfmake_render_ctx_t *ctx);
93             pdfmake_render_err_t pdfmake_render_fill(pdfmake_render_ctx_t *ctx);
94             pdfmake_render_err_t pdfmake_render_fill_preserve(pdfmake_render_ctx_t *ctx);
95             pdfmake_render_err_t pdfmake_render_stroke(pdfmake_render_ctx_t *ctx);
96             pdfmake_render_err_t pdfmake_render_clip(pdfmake_render_ctx_t *ctx);
97             void pdfmake_render_reset_clip(pdfmake_render_ctx_t *ctx);
98             uint32_t pdfmake_render_get_pixel(pdfmake_render_ctx_t *ctx, int x, int y);
99              
100             #ifndef PDFMAKE_FILL_NONZERO
101             #define PDFMAKE_FILL_NONZERO 0
102             #endif
103             #ifndef PDFMAKE_FILL_EVENODD
104             #define PDFMAKE_FILL_EVENODD 1
105             #endif
106              
107             /* -------------------------------------------------------------------------
108             * Render-page API forward declarations
109             * ------------------------------------------------------------------------- */
110             typedef enum {
111             PDFMAKE_SCALE_NEAREST = 0,
112             PDFMAKE_SCALE_BILINEAR = 1,
113             PDFMAKE_SCALE_BICUBIC = 2,
114             } pdfmake_scale_mode_t;
115              
116             typedef struct pdfmake_render_opts {
117             double dpi;
118             double scale;
119             pdfmake_scale_mode_t scale_mode;
120             int antialias;
121             double flatness;
122             pdfmake_rotation_t rotation;
123             uint32_t background;
124             double clip_x, clip_y;
125             double clip_width, clip_height;
126             int use_clip;
127             int render_text;
128             int render_images;
129             int render_vectors;
130             int render_annotations;
131             int show_text_bounds;
132             int show_image_bounds;
133             int show_clip_regions;
134             } pdfmake_render_opts_t;
135              
136             typedef struct pdfmake_page_render {
137             uint32_t *pixels;
138             int width;
139             int height;
140             int stride;
141             double page_width;
142             double page_height;
143             double effective_dpi;
144             int text_objects;
145             int path_objects;
146             int image_objects;
147             double render_time_ms;
148             int error_count;
149             char error_msg[256];
150             } pdfmake_page_render_t;
151              
152             void pdfmake_render_opts_init(pdfmake_render_opts_t *opts);
153             pdfmake_err_t pdfmake_render_page_to_pixels(pdfmake_reader_t *reader, int page_num, const pdfmake_render_opts_t *opts, pdfmake_page_render_t *result);
154             pdfmake_err_t pdfmake_render_page_region(pdfmake_reader_t *reader, int page_num, double region_x, double region_y, double region_w, double region_h, const pdfmake_render_opts_t *opts, pdfmake_page_render_t *result);
155             void pdfmake_page_render_free(pdfmake_page_render_t *result);
156             void pdfmake_page_get_render_size(pdfmake_reader_t *reader, int page_num, double dpi, int *width, int *height);
157              
158             /* Missing prototype in header, implemented in src/pdfmake_image_scale.c */
159             pdfmake_imgr_err_t pdfmake_decoded_image_resize(
160             pdfmake_decoded_image_t *img,
161             int new_w, int new_h,
162             pdfmake_interp_mode_t mode,
163             pdfmake_arena_t *arena);
164              
165             /* Shared helper for render_page.xs */
166 0           static void hv_to_render_opts(pTHX_ HV *hv, pdfmake_render_opts_t *opts)
167             {
168             SV **sv;
169              
170 0           pdfmake_render_opts_init(opts);
171              
172 0 0         if (!hv) return;
173              
174 0 0         if ((sv = hv_fetchs(hv, "dpi", 0)) && SvOK(*sv)) {
    0          
175 0           opts->dpi = SvNV(*sv);
176             }
177 0 0         if ((sv = hv_fetchs(hv, "scale", 0)) && SvOK(*sv)) {
    0          
178 0           opts->scale = SvNV(*sv);
179             }
180 0 0         if ((sv = hv_fetchs(hv, "scale_mode", 0)) && SvOK(*sv)) {
    0          
181 0           opts->scale_mode = (pdfmake_scale_mode_t)SvIV(*sv);
182             }
183 0 0         if ((sv = hv_fetchs(hv, "antialias", 0)) && SvOK(*sv)) {
    0          
184 0           opts->antialias = SvIV(*sv);
185             }
186 0 0         if ((sv = hv_fetchs(hv, "flatness", 0)) && SvOK(*sv)) {
    0          
187 0           opts->flatness = SvNV(*sv);
188             }
189 0 0         if ((sv = hv_fetchs(hv, "rotation", 0)) && SvOK(*sv)) {
    0          
190 0           opts->rotation = (pdfmake_rotation_t)SvIV(*sv);
191             }
192 0 0         if ((sv = hv_fetchs(hv, "background", 0)) && SvOK(*sv)) {
    0          
193 0           opts->background = (uint32_t)SvUV(*sv);
194             }
195 0 0         if ((sv = hv_fetchs(hv, "render_text", 0)) && SvOK(*sv)) {
    0          
196 0           opts->render_text = SvIV(*sv);
197             }
198 0 0         if ((sv = hv_fetchs(hv, "render_images", 0)) && SvOK(*sv)) {
    0          
199 0           opts->render_images = SvIV(*sv);
200             }
201 0 0         if ((sv = hv_fetchs(hv, "render_vectors", 0)) && SvOK(*sv)) {
    0          
202 0           opts->render_vectors = SvIV(*sv);
203             }
204 0 0         if ((sv = hv_fetchs(hv, "render_annotations", 0)) && SvOK(*sv)) {
    0          
205 0           opts->render_annotations = SvIV(*sv);
206             }
207 0 0         if ((sv = hv_fetchs(hv, "show_text_bounds", 0)) && SvOK(*sv)) {
    0          
208 0           opts->show_text_bounds = SvIV(*sv);
209             }
210 0 0         if ((sv = hv_fetchs(hv, "show_image_bounds", 0)) && SvOK(*sv)) {
    0          
211 0           opts->show_image_bounds = SvIV(*sv);
212             }
213             }
214              
215             /* XOP descriptors — registered once in main BOOT, used by all modules */
216             static XOP pdfmake_chain_xop;
217             static XOP pdfmake_getter_xop;
218              
219             /* Writer wrapper struct for XS binding. */
220             typedef struct {
221             pdfmake_buf_t buf;
222             } pdfmake_writer_xs_t;
223              
224             /* Arena wrapper struct - owns the arena. */
225             typedef struct {
226             pdfmake_arena_t *arena;
227             } pdfmake_arena_xs_t;
228              
229             /* Parser wrapper struct - owns parser, keeps buffer alive. */
230             typedef struct {
231             pdfmake_parser_t *parser;
232             SV *bytes_sv; /* Keep input buffer alive for parser */
233             pdfmake_doc_t *doc; /* Parsed document (NULL until parsed) */
234             int parsed; /* Whether parse() has been called */
235             } pdfmake_parser_xs_t;
236              
237             /* Reader wrapper struct - owns reader, references parser. */
238             typedef struct {
239             pdfmake_reader_t *reader;
240             SV *parser_sv; /* SV ref to parser to keep it alive */
241             } pdfmake_reader_xs_t;
242              
243             /* Reader page wrapper - references reader. */
244             typedef struct {
245             pdfmake_reader_page_t *page;
246             SV *reader_sv; /* SV ref to reader to keep it alive */
247             } pdfmake_reader_page_xs_t;
248              
249             /* Obj wrapper struct - holds arena and pointer to obj in arena. */
250             typedef struct {
251             pdfmake_arena_xs_t *arena_xs; /* Ref to arena wrapper (kept alive via SV) */
252             SV *arena_sv; /* SV ref to arena to prevent GC */
253             pdfmake_obj_t *obj; /* Pointer to obj allocated in arena */
254             } pdfmake_obj_xs_t;
255             /* Encryption context wrapper. */
256             typedef struct {
257             pdfmake_crypt_ctx_t ctx;
258             } pdfmake_crypt_xs_t;
259              
260             MODULE = PDF::Make PACKAGE = PDF::Make
261             PROTOTYPES: ENABLE
262              
263             const char *
264             version()
265             CODE:
266 3           RETVAL = pdfmake_version();
267             OUTPUT:
268             RETVAL
269              
270             BOOT:
271             {
272             /* Register custom op XOPs */
273 90           PDFMAKE_REGISTER_XOP(pdfmake_chain_xop, pp_pdfmake_chain,
274             "pdfmake_chain", "PDF::Make chainable method");
275 90           PDFMAKE_REGISTER_XOP(pdfmake_getter_xop, pp_pdfmake_getter,
276             "pdfmake_getter", "PDF::Make struct getter");
277              
278             /* Register additional XOPs */
279             static XOP pdfmake_meta_xop;
280 90           PDFMAKE_REGISTER_XOP(pdfmake_meta_xop, pp_pdfmake_meta,
281             "pdfmake_meta", "PDF::Make metadata getter/setter");
282             static XOP pdfmake_indirect_xop;
283 90           PDFMAKE_REGISTER_XOP(pdfmake_indirect_xop, pp_pdfmake_indirect_getter,
284             "pdfmake_indirect", "PDF::Make indirect getter");
285             static XOP pdfmake_typetest_xop;
286 90           PDFMAKE_REGISTER_XOP(pdfmake_typetest_xop, pp_pdfmake_typetest,
287             "pdfmake_typetest", "PDF::Make type test");
288             static XOP pdfmake_arena_ctor_xop;
289 90           PDFMAKE_REGISTER_XOP(pdfmake_arena_ctor_xop, pp_pdfmake_arena_ctor,
290             "pdfmake_arena_ctor", "PDF::Make arena constructor");
291              
292             /* Per-module BOOT sections register their own getters, constants,
293             * and chain dispatch tables via INCLUDE: directives below */
294             }
295              
296             INCLUDE: xs/writer.xs
297             INCLUDE: xs/document.xs
298             INCLUDE: xs/page.xs
299             INCLUDE: xs/canvas.xs
300             INCLUDE: xs/parser.xs
301             INCLUDE: xs/arena.xs
302             INCLUDE: xs/obj.xs
303             INCLUDE: xs/reader.xs
304             INCLUDE: xs/image.xs
305             INCLUDE: xs/font.xs
306             INCLUDE: xs/extract.xs
307             INCLUDE: xs/outline.xs
308             INCLUDE: xs/action.xs
309             INCLUDE: xs/crypt.xs
310             INCLUDE: xs/form.xs
311             INCLUDE: xs/layer.xs
312             INCLUDE: xs/attach.xs
313             INCLUDE: xs/tag.xs
314             INCLUDE: xs/redact.xs
315             INCLUDE: xs/color.xs
316             INCLUDE: xs/watermark.xs
317             INCLUDE: xs/signature.xs
318             INCLUDE: xs/linear.xs
319             INCLUDE: xs/render.xs
320             INCLUDE: xs/render_page.xs
321             INCLUDE: xs/image_render.xs
322             INCLUDE: xs/import.xs
323             INCLUDE: xs/filter.xs