File Coverage

include/pdfmake_render.h
Criterion Covered Total %
statement 0 23 0.0
branch 0 4 0.0
condition n/a
subroutine n/a
pod n/a
total 0 27 0.0


line stmt bran cond sub pod time code
1             /*
2             * pdfmake_render.h - Path rendering types and context
3             *
4             * Implements PDF path construction and painting operations:
5             * - Path segments: move, line, curve, close
6             * - Fill with non-zero or even-odd winding rules
7             * - Stroke with caps, joins, dashes
8             * - Clipping
9             */
10              
11             #ifndef PDFMAKE_RENDER_H
12             #define PDFMAKE_RENDER_H
13              
14             #include "pdfmake_types.h"
15             #include
16             #include
17              
18             #ifdef __cplusplus
19             extern "C" {
20             #endif
21              
22             /*
23             * Error codes
24             */
25              
26             typedef enum {
27             PDFMAKE_RENDER_OK = 0,
28             PDFMAKE_RENDER_ERR_NULL,
29             PDFMAKE_RENDER_ERR_MEMORY,
30             PDFMAKE_RENDER_ERR_INVALID,
31             PDFMAKE_RENDER_ERR_OVERFLOW,
32             PDFMAKE_RENDER_ERR_EMPTY_PATH,
33             } pdfmake_render_err_t;
34              
35             /*
36             * Point - 2D coordinate
37             */
38              
39             typedef struct pdfmake_point {
40             double x;
41             double y;
42             } pdfmake_point_t;
43              
44             /*
45             * Path segment operations
46             */
47              
48             #ifndef PDFMAKE_PATH_OP_DEFINED
49             #define PDFMAKE_PATH_OP_DEFINED
50             typedef enum {
51             PDFMAKE_PATH_MOVE, /* Move to point (1 point) */
52             PDFMAKE_PATH_LINE, /* Line to point (1 point) */
53             PDFMAKE_PATH_CURVE, /* Cubic bezier (3 control points) */
54             PDFMAKE_PATH_CLOSE, /* Close subpath (0 points) */
55             } pdfmake_path_op_t;
56             #endif
57              
58             /*
59             * Path segment - single path operation with control points
60             */
61              
62             typedef struct pdfmake_path_seg {
63             pdfmake_path_op_t op;
64             pdfmake_point_t pts[3]; /* Up to 3 control points for curves */
65             } pdfmake_path_seg_t;
66              
67             /*
68             * Path - collection of segments forming subpaths
69             */
70              
71             struct pdfmake_path {
72             pdfmake_path_seg_t *segs;
73             size_t seg_count;
74             size_t seg_cap;
75            
76             /* Current point for path construction */
77             pdfmake_point_t current;
78             int has_current;
79            
80             /* Start of current subpath (for close) */
81             pdfmake_point_t subpath_start;
82             int has_subpath;
83             };
84             #ifndef PDFMAKE_PATH_T_DEFINED
85             #define PDFMAKE_PATH_T_DEFINED
86             typedef struct pdfmake_path pdfmake_path_t;
87             #endif
88              
89             /*
90             * Line cap styles (PDF spec 8.4.3.3)
91             */
92              
93             typedef enum {
94             PDFMAKE_CAP_BUTT = 0, /* Square end at endpoint */
95             PDFMAKE_CAP_ROUND = 1, /* Semicircular cap */
96             PDFMAKE_CAP_SQUARE = 2, /* Square cap extending beyond endpoint */
97             } pdfmake_line_cap_t;
98              
99             /*
100             * Line join styles (PDF spec 8.4.3.4)
101             */
102              
103             typedef enum {
104             PDFMAKE_JOIN_MITER = 0, /* Sharp corner (with miter limit) */
105             PDFMAKE_JOIN_ROUND = 1, /* Rounded corner */
106             PDFMAKE_JOIN_BEVEL = 2, /* Beveled corner */
107             } pdfmake_line_join_t;
108              
109             /*
110             * Fill rules (PDF spec 8.5.3.3)
111             */
112              
113             typedef enum {
114             PDFMAKE_FILL_NONZERO = 0, /* Non-zero winding number rule */
115             PDFMAKE_FILL_EVENODD = 1, /* Even-odd rule */
116             } pdfmake_fill_rule_t;
117              
118             /*
119             * Stroke style - all stroke parameters
120             */
121              
122             typedef struct pdfmake_stroke_style {
123             double width;
124             pdfmake_line_cap_t cap;
125             pdfmake_line_join_t join;
126             double miter_limit;
127            
128             /* Dash pattern */
129             double *dash_array;
130             size_t dash_count;
131             double dash_phase;
132             } pdfmake_stroke_style_t;
133              
134             /*
135             * Color - RGBA
136             */
137              
138             typedef struct pdfmake_rgba {
139             double r, g, b, a;
140             } pdfmake_rgba_t;
141              
142             /*
143             * Transformation matrix - [a b c d e f]
144             *
145             * | a b 0 | x' = ax + cy + e
146             * | c d 0 | y' = bx + dy + f
147             * | e f 1 |
148             */
149              
150             typedef struct pdfmake_matrix {
151             double a, b, c, d, e, f;
152             } pdfmake_matrix_t;
153              
154             /*
155             * Render context - maintains graphics state and output buffer
156             */
157              
158             #ifndef PDFMAKE_RENDER_CTX_T_DEFINED
159             #define PDFMAKE_RENDER_CTX_T_DEFINED
160             typedef struct pdfmake_render_ctx pdfmake_render_ctx_t;
161             #endif
162              
163             struct pdfmake_render_ctx {
164             /* Output buffer (RGBA, 8 bits per channel) */
165             uint32_t *pixels;
166             int width;
167             int height;
168             int stride; /* Bytes per row */
169             int owns_buffer; /* 1 if we allocated pixels */
170            
171             /* Current graphics state */
172             pdfmake_matrix_t ctm; /* Current transformation matrix */
173             pdfmake_rgba_t fill_color;
174             pdfmake_rgba_t stroke_color;
175             pdfmake_stroke_style_t stroke_style;
176             pdfmake_fill_rule_t fill_rule;
177            
178             /* Clip mask (8-bit alpha, same dimensions as pixels) */
179             uint8_t *clip_mask;
180             int has_clip;
181            
182             /* Current path being constructed */
183             pdfmake_path_t *path;
184            
185             /* Graphics state stack for save/restore */
186             struct pdfmake_gstate *gstate_stack;
187             int gstate_depth;
188             int gstate_max;
189            
190             /* Flatness tolerance for curve flattening */
191             double flatness;
192            
193             /* Anti-aliasing (0 = off, 1-4 = supersample level) */
194             int antialias;
195             };
196              
197             /*
198             * Saved graphics state
199             */
200              
201             typedef struct pdfmake_gstate {
202             pdfmake_matrix_t ctm;
203             pdfmake_rgba_t fill_color;
204             pdfmake_rgba_t stroke_color;
205             pdfmake_stroke_style_t stroke_style;
206             pdfmake_fill_rule_t fill_rule;
207             uint8_t *clip_mask;
208             int has_clip;
209             double flatness;
210             } pdfmake_gstate_t;
211              
212             /*
213             * Edge for scanline algorithm
214             */
215              
216             typedef struct pdfmake_edge {
217             double y_min; /* Top of edge */
218             double y_max; /* Bottom of edge */
219             double x_at_ymin; /* X at y_min */
220             double slope; /* dx/dy */
221             int direction; /* +1 going up, -1 going down */
222             struct pdfmake_edge *next;
223             } pdfmake_edge_t;
224              
225             /*
226             * Active edge list for scanline fill
227             */
228              
229             typedef struct pdfmake_ael {
230             pdfmake_edge_t *edges;
231             int count;
232             int capacity;
233             } pdfmake_ael_t;
234              
235             /*
236             * =============================================================
237             * Render Context Functions (pdfmake_render.c)
238             * =============================================================
239             */
240              
241             /* Create render context with new buffer */
242             pdfmake_render_ctx_t *pdfmake_render_create(int width, int height);
243              
244             /* Create render context with external buffer */
245             pdfmake_render_ctx_t *pdfmake_render_create_with_buffer(
246             uint32_t *pixels, int width, int height, int stride);
247              
248             /* Destroy render context */
249             void pdfmake_render_destroy(pdfmake_render_ctx_t *ctx);
250              
251             /* Clear buffer to color */
252             void pdfmake_render_clear(pdfmake_render_ctx_t *ctx, pdfmake_rgba_t color);
253              
254             /* Save/restore graphics state */
255             pdfmake_render_err_t pdfmake_render_save(pdfmake_render_ctx_t *ctx);
256             pdfmake_render_err_t pdfmake_render_restore(pdfmake_render_ctx_t *ctx);
257              
258             /* Set colors */
259             void pdfmake_render_set_fill_color(pdfmake_render_ctx_t *ctx,
260             double r, double g, double b, double a);
261             void pdfmake_render_set_stroke_color(pdfmake_render_ctx_t *ctx,
262             double r, double g, double b, double a);
263              
264             /* Set stroke style */
265             void pdfmake_render_set_line_width(pdfmake_render_ctx_t *ctx, double width);
266             void pdfmake_render_set_line_cap(pdfmake_render_ctx_t *ctx, pdfmake_line_cap_t cap);
267             void pdfmake_render_set_line_join(pdfmake_render_ctx_t *ctx, pdfmake_line_join_t join);
268             void pdfmake_render_set_miter_limit(pdfmake_render_ctx_t *ctx, double limit);
269             pdfmake_render_err_t pdfmake_render_set_dash(pdfmake_render_ctx_t *ctx,
270             double *array, size_t count, double phase);
271              
272             /* Set fill rule */
273             void pdfmake_render_set_fill_rule(pdfmake_render_ctx_t *ctx, pdfmake_fill_rule_t rule);
274              
275             /* Set flatness tolerance */
276             void pdfmake_render_set_flatness(pdfmake_render_ctx_t *ctx, double flatness);
277              
278             /* Transformation matrix operations */
279             void pdfmake_render_set_matrix(pdfmake_render_ctx_t *ctx, pdfmake_matrix_t *m);
280             void pdfmake_render_concat_matrix(pdfmake_render_ctx_t *ctx, pdfmake_matrix_t *m);
281             void pdfmake_render_translate(pdfmake_render_ctx_t *ctx, double tx, double ty);
282             void pdfmake_render_scale(pdfmake_render_ctx_t *ctx, double sx, double sy);
283             void pdfmake_render_rotate(pdfmake_render_ctx_t *ctx, double angle);
284              
285             /* Get pixel */
286             uint32_t pdfmake_render_get_pixel(pdfmake_render_ctx_t *ctx, int x, int y);
287              
288             /*
289             * =============================================================
290             * Path Construction Functions (pdfmake_render_path.c)
291             * =============================================================
292             */
293              
294             /* Create/destroy path */
295             pdfmake_path_t *pdfmake_path_create(void);
296             void pdfmake_path_destroy(pdfmake_path_t *path);
297             void pdfmake_path_clear(pdfmake_path_t *path);
298              
299             /* Path construction */
300             pdfmake_render_err_t pdfmake_path_move_to(pdfmake_path_t *path, double x, double y);
301             pdfmake_render_err_t pdfmake_path_line_to(pdfmake_path_t *path, double x, double y);
302             pdfmake_render_err_t pdfmake_path_curve_to(pdfmake_path_t *path,
303             double x1, double y1, double x2, double y2, double x3, double y3);
304             pdfmake_render_err_t pdfmake_path_close(pdfmake_path_t *path);
305             pdfmake_render_err_t pdfmake_path_rect(pdfmake_path_t *path,
306             double x, double y, double w, double h);
307              
308             /* Context path operations */
309             pdfmake_render_err_t pdfmake_render_move_to(pdfmake_render_ctx_t *ctx, double x, double y);
310             pdfmake_render_err_t pdfmake_render_line_to(pdfmake_render_ctx_t *ctx, double x, double y);
311             pdfmake_render_err_t pdfmake_render_curve_to(pdfmake_render_ctx_t *ctx,
312             double x1, double y1, double x2, double y2, double x3, double y3);
313             pdfmake_render_err_t pdfmake_render_close_path(pdfmake_render_ctx_t *ctx);
314             pdfmake_render_err_t pdfmake_render_rect(pdfmake_render_ctx_t *ctx,
315             double x, double y, double w, double h);
316             void pdfmake_render_new_path(pdfmake_render_ctx_t *ctx);
317              
318             /* Path info */
319             int pdfmake_path_is_empty(pdfmake_path_t *path);
320             pdfmake_render_err_t pdfmake_path_get_bounds(pdfmake_path_t *path,
321             double *x_min, double *y_min, double *x_max, double *y_max);
322              
323             /*
324             * =============================================================
325             * Bezier Flattening Functions (pdfmake_render_bezier.c)
326             * =============================================================
327             */
328              
329             /* Flatten cubic bezier to line segments */
330             pdfmake_render_err_t pdfmake_bezier_flatten(
331             pdfmake_point_t p0, pdfmake_point_t p1,
332             pdfmake_point_t p2, pdfmake_point_t p3,
333             double tolerance,
334             pdfmake_path_t *out);
335              
336             /* Flatten entire path (curves -> lines) */
337             pdfmake_path_t *pdfmake_path_flatten(pdfmake_path_t *path, double tolerance);
338              
339             /*
340             * =============================================================
341             * Fill Functions (pdfmake_render_fill.c)
342             * =============================================================
343             */
344              
345             /* Fill current path */
346             pdfmake_render_err_t pdfmake_render_fill(pdfmake_render_ctx_t *ctx);
347              
348             /* Fill and preserve path */
349             pdfmake_render_err_t pdfmake_render_fill_preserve(pdfmake_render_ctx_t *ctx);
350              
351             /* Fill path with specific rule */
352             pdfmake_render_err_t pdfmake_fill_path(
353             pdfmake_render_ctx_t *ctx,
354             pdfmake_path_t *path,
355             pdfmake_fill_rule_t rule);
356              
357             /*
358             * =============================================================
359             * Stroke Functions (pdfmake_render_stroke.c)
360             * =============================================================
361             */
362              
363             /* Stroke current path */
364             pdfmake_render_err_t pdfmake_render_stroke(pdfmake_render_ctx_t *ctx);
365              
366             /* Stroke and preserve path */
367             pdfmake_render_err_t pdfmake_render_stroke_preserve(pdfmake_render_ctx_t *ctx);
368              
369             /* Stroke path with specific style */
370             pdfmake_render_err_t pdfmake_stroke_path(
371             pdfmake_render_ctx_t *ctx,
372             pdfmake_path_t *path,
373             pdfmake_stroke_style_t *style);
374              
375             /* Convert stroke to fill path (for internal use) */
376             pdfmake_path_t *pdfmake_stroke_to_path(
377             pdfmake_path_t *path,
378             pdfmake_stroke_style_t *style);
379              
380             /*
381             * =============================================================
382             * Clipping Functions (pdfmake_render_clip.c)
383             * =============================================================
384             */
385              
386             /* Clip to current path */
387             pdfmake_render_err_t pdfmake_render_clip(pdfmake_render_ctx_t *ctx);
388              
389             /* Clip with specific rule */
390             pdfmake_render_err_t pdfmake_clip_path(
391             pdfmake_render_ctx_t *ctx,
392             pdfmake_path_t *path,
393             pdfmake_fill_rule_t rule);
394              
395             /* Reset clip to full canvas */
396             void pdfmake_render_reset_clip(pdfmake_render_ctx_t *ctx);
397              
398             /*
399             * =============================================================
400             * Matrix Utilities
401             * =============================================================
402             */
403              
404             /* Identity matrix */
405             pdfmake_matrix_t pdfmake_matrix_identity(void);
406              
407             /* Matrix multiplication: result = a * b */
408             pdfmake_matrix_t pdfmake_matrix_multiply(pdfmake_matrix_t *a, pdfmake_matrix_t *b);
409              
410             /* Transform point by matrix */
411             pdfmake_point_t pdfmake_matrix_transform_point(pdfmake_matrix_t *m, pdfmake_point_t p);
412              
413             /* Invert matrix (returns 0 on success, -1 if singular) */
414             int pdfmake_matrix_invert(pdfmake_matrix_t *m, pdfmake_matrix_t *out);
415              
416             /*
417             * =============================================================
418             * Color Utilities
419             * =============================================================
420             */
421              
422             /* Pack RGBA to uint32_t (ARGB format) */
423 0           static PDFMAKE_INLINE uint32_t pdfmake_color_pack(pdfmake_rgba_t c) {
424 0           uint8_t r = (uint8_t)(c.r * 255.0 + 0.5);
425 0           uint8_t g = (uint8_t)(c.g * 255.0 + 0.5);
426 0           uint8_t b = (uint8_t)(c.b * 255.0 + 0.5);
427 0           uint8_t a = (uint8_t)(c.a * 255.0 + 0.5);
428 0           return ((uint32_t)a << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
429             }
430              
431             /* Unpack uint32_t to RGBA */
432             static PDFMAKE_INLINE pdfmake_rgba_t pdfmake_color_unpack(uint32_t packed) {
433             pdfmake_rgba_t c;
434             c.a = ((packed >> 24) & 0xFF) / 255.0;
435             c.r = ((packed >> 16) & 0xFF) / 255.0;
436             c.g = ((packed >> 8) & 0xFF) / 255.0;
437             c.b = (packed & 0xFF) / 255.0;
438             return c;
439             }
440              
441             /* Blend source over destination (Porter-Duff) */
442 0           static PDFMAKE_INLINE uint32_t pdfmake_color_blend(uint32_t dst, uint32_t src) {
443 0           uint32_t sa = (src >> 24) & 0xFF;
444             uint32_t da, sr, sg, sb, dr, dg, db;
445             uint32_t inv_sa, oa, or, og, ob;
446              
447 0 0         if (sa == 0) return dst;
448 0 0         if (sa == 255) return src;
449              
450 0           da = (dst >> 24) & 0xFF;
451 0           sr = (src >> 16) & 0xFF;
452 0           sg = (src >> 8) & 0xFF;
453 0           sb = src & 0xFF;
454 0           dr = (dst >> 16) & 0xFF;
455 0           dg = (dst >> 8) & 0xFF;
456 0           db = dst & 0xFF;
457              
458 0           inv_sa = 255 - sa;
459 0           oa = sa + ((da * inv_sa) >> 8);
460 0           or = sr + ((dr * inv_sa) >> 8);
461 0           og = sg + ((dg * inv_sa) >> 8);
462 0           ob = sb + ((db * inv_sa) >> 8);
463              
464 0           return (oa << 24) | (or << 16) | (og << 8) | ob;
465             }
466              
467             #ifdef __cplusplus
468             }
469             #endif
470              
471             #endif /* PDFMAKE_RENDER_H */