1 #ifndef MUPDF_FITZ_PATH_H 2 #define MUPDF_FITZ_PATH_H 3 4 #include "mupdf/fitz/system.h" 5 #include "mupdf/fitz/context.h" 6 #include "mupdf/fitz/geometry.h" 7 8 /** 9 * Vector path buffer. 10 * It can be stroked and dashed, or be filled. 11 * It has a fill rule (nonzero or even_odd). 12 * 13 * When rendering, they are flattened, stroked and dashed straight 14 * into the Global Edge List. 15 */ 16 17 typedef struct fz_path fz_path; 18 19 typedef enum 20 { 21 FZ_LINECAP_BUTT = 0, 22 FZ_LINECAP_ROUND = 1, 23 FZ_LINECAP_SQUARE = 2, 24 FZ_LINECAP_TRIANGLE = 3 25 } fz_linecap; 26 27 typedef enum 28 { 29 FZ_LINEJOIN_MITER = 0, 30 FZ_LINEJOIN_ROUND = 1, 31 FZ_LINEJOIN_BEVEL = 2, 32 FZ_LINEJOIN_MITER_XPS = 3 33 } fz_linejoin; 34 35 typedef struct 36 { 37 int refs; 38 fz_linecap start_cap, dash_cap, end_cap; 39 fz_linejoin linejoin; 40 float linewidth; 41 float miterlimit; 42 float dash_phase; 43 int dash_len; 44 float dash_list[32]; 45 } fz_stroke_state; 46 47 typedef struct 48 { 49 /* Compulsory ones */ 50 void (*moveto)(fz_context *ctx, void *arg, float x, float y); 51 void (*lineto)(fz_context *ctx, void *arg, float x, float y); 52 void (*curveto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2, float x3, float y3); 53 void (*closepath)(fz_context *ctx, void *arg); 54 /* Optional ones */ 55 void (*quadto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2); 56 void (*curvetov)(fz_context *ctx, void *arg, float x2, float y2, float x3, float y3); 57 void (*curvetoy)(fz_context *ctx, void *arg, float x1, float y1, float x3, float y3); 58 void (*rectto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2); 59 } fz_path_walker; 60 61 /** 62 Walk the segments of a path, calling the 63 appropriate callback function from a given set for each 64 segment of the path. 65 66 path: The path to walk. 67 68 walker: The set of callback functions to use. The first 69 4 callback pointers in the set must be non-NULL. The 70 subsequent ones can either be supplied, or can be left 71 as NULL, in which case the top 4 functions will be 72 called as appropriate to simulate them. 73 74 arg: An opaque argument passed in to each callback. 75 76 Exceptions will only be thrown if the underlying callback 77 functions throw them. 78 */ 79 void fz_walk_path(fz_context *ctx, const fz_path *path, const fz_path_walker *walker, void *arg); 80 81 /** 82 Create a new (empty) path structure. 83 */ 84 fz_path *fz_new_path(fz_context *ctx); 85 86 /** 87 Increment the reference count. Returns the same pointer. 88 89 All paths can be kept, regardless of their packing type. 90 91 Never throws exceptions. 92 */ 93 fz_path *fz_keep_path(fz_context *ctx, const fz_path *path); 94 95 /** 96 Decrement the reference count. When the reference count hits 97 zero, free the path. 98 99 All paths can be dropped, regardless of their packing type. 100 Packed paths do not own the blocks into which they are packed 101 so dropping them does not free those blocks. 102 103 Never throws exceptions. 104 */ 105 void fz_drop_path(fz_context *ctx, const fz_path *path); 106 107 /** 108 Minimise the internal storage used by a path. 109 110 As paths are constructed, the internal buffers 111 grow. To avoid repeated reallocations they 112 grow with some spare space. Once a path has 113 been fully constructed, this call allows the 114 excess space to be trimmed. 115 */ 116 void fz_trim_path(fz_context *ctx, fz_path *path); 117 118 /** 119 Return the number of bytes required to pack a path. 120 */ 121 int fz_packed_path_size(const fz_path *path); 122 123 /** 124 Pack a path into the given block. 125 To minimise the size of paths, this function allows them to be 126 packed into a buffer with other information. Paths can be used 127 interchangeably regardless of how they are packed. 128 129 pack: Pointer to a block of data to pack the path into. Should 130 be aligned by the caller to the same alignment as required for 131 a fz_path pointer. 132 133 max: The number of bytes available in the block. 134 If max < sizeof(fz_path) then an exception will 135 be thrown. If max >= the value returned by 136 fz_packed_path_size, then this call will never 137 fail, except in low memory situations with large 138 paths. 139 140 path: The path to pack. 141 142 Returns the number of bytes within the block used. Callers can 143 access the packed path data by casting the value of pack on 144 entry to be a fz_path *. 145 146 Throws exceptions on failure to allocate, or if 147 max < sizeof(fz_path). 148 149 Implementation details: Paths can be 'unpacked', 'flat', or 150 'open'. Standard paths, as created are 'unpacked'. Paths that 151 will pack into less than max bytes will be packed as 'flat', 152 unless they are too large (where large indicates that they 153 exceed some private implementation defined limits, currently 154 including having more than 256 coordinates or commands). 155 156 Large paths are 'open' packed as a header into the given block, 157 plus pointers to other data blocks. 158 159 Users should not have to care about whether paths are 'open' 160 or 'flat' packed. Simply pack a path (if required), and then 161 forget about the details. 162 */ 163 size_t fz_pack_path(fz_context *ctx, uint8_t *pack, size_t max, const fz_path *path); 164 165 /** 166 Clone the data for a path. 167 168 This is used in preference to fz_keep_path when a whole 169 new copy of a path is required, rather than just a shared 170 pointer. This probably indicates that the path is about to 171 be modified. 172 173 path: path to clone. 174 175 Throws exceptions on failure to allocate. 176 */ 177 fz_path *fz_clone_path(fz_context *ctx, fz_path *path); 178 179 /** 180 Return the current point that a path has 181 reached or (0,0) if empty. 182 183 path: path to return the current point of. 184 */ 185 fz_point fz_currentpoint(fz_context *ctx, fz_path *path); 186 187 /** 188 Append a 'moveto' command to a path. 189 This 'opens' a path. 190 191 path: The path to modify. 192 193 x, y: The coordinate to move to. 194 195 Throws exceptions on failure to allocate, or attempting to 196 modify a packed path. 197 */ 198 void fz_moveto(fz_context *ctx, fz_path *path, float x, float y); 199 200 /** 201 Append a 'lineto' command to an open path. 202 203 path: The path to modify. 204 205 x, y: The coordinate to line to. 206 207 Throws exceptions on failure to allocate, or attempting to 208 modify a packed path. 209 */ 210 void fz_lineto(fz_context *ctx, fz_path *path, float x, float y); 211 212 /** 213 Append a 'rectto' command to an open path. 214 215 The rectangle is equivalent to: 216 moveto x0 y0 217 lineto x1 y0 218 lineto x1 y1 219 lineto x0 y1 220 closepath 221 222 path: The path to modify. 223 224 x0, y0: First corner of the rectangle. 225 226 x1, y1: Second corner of the rectangle. 227 228 Throws exceptions on failure to allocate, or attempting to 229 modify a packed path. 230 */ 231 void fz_rectto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1); 232 233 /** 234 Append a 'quadto' command to an open path. (For a 235 quadratic bezier). 236 237 path: The path to modify. 238 239 x0, y0: The control coordinates for the quadratic curve. 240 241 x1, y1: The end coordinates for the quadratic curve. 242 243 Throws exceptions on failure to allocate, or attempting to 244 modify a packed path. 245 */ 246 void fz_quadto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1); 247 248 /** 249 Append a 'curveto' command to an open path. (For a 250 cubic bezier). 251 252 path: The path to modify. 253 254 x0, y0: The coordinates of the first control point for the 255 curve. 256 257 x1, y1: The coordinates of the second control point for the 258 curve. 259 260 x2, y2: The end coordinates for the curve. 261 262 Throws exceptions on failure to allocate, or attempting to 263 modify a packed path. 264 */ 265 void fz_curveto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1, float x2, float y2); 266 267 /** 268 Append a 'curvetov' command to an open path. (For a 269 cubic bezier with the first control coordinate equal to 270 the start point). 271 272 path: The path to modify. 273 274 x1, y1: The coordinates of the second control point for the 275 curve. 276 277 x2, y2: The end coordinates for the curve. 278 279 Throws exceptions on failure to allocate, or attempting to 280 modify a packed path. 281 */ 282 void fz_curvetov(fz_context *ctx, fz_path *path, float x1, float y1, float x2, float y2); 283 284 /** 285 Append a 'curvetoy' command to an open path. (For a 286 cubic bezier with the second control coordinate equal to 287 the end point). 288 289 path: The path to modify. 290 291 x0, y0: The coordinates of the first control point for the 292 curve. 293 294 x2, y2: The end coordinates for the curve (and the second 295 control coordinate). 296 297 Throws exceptions on failure to allocate, or attempting to 298 modify a packed path. 299 */ 300 void fz_curvetoy(fz_context *ctx, fz_path *path, float x0, float y0, float x2, float y2); 301 302 /** 303 Close the current subpath. 304 305 path: The path to modify. 306 307 Throws exceptions on failure to allocate, attempting to modify 308 a packed path, and illegal path closes (i.e. closing a non open 309 path). 310 */ 311 void fz_closepath(fz_context *ctx, fz_path *path); 312 313 /** 314 Transform a path by a given 315 matrix. 316 317 path: The path to modify (must not be a packed path). 318 319 transform: The transform to apply. 320 321 Throws exceptions if the path is packed, or on failure 322 to allocate. 323 */ 324 void fz_transform_path(fz_context *ctx, fz_path *path, fz_matrix transform); 325 326 /** 327 Return a bounding rectangle for a path. 328 329 path: The path to bound. 330 331 stroke: If NULL, the bounding rectangle given is for 332 the filled path. If non-NULL the bounding rectangle 333 given is for the path stroked with the given attributes. 334 335 ctm: The matrix to apply to the path during stroking. 336 337 r: Pointer to a fz_rect which will be used to hold 338 the result. 339 340 Returns r, updated to contain the bounding rectangle. 341 */ 342 fz_rect fz_bound_path(fz_context *ctx, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm); 343 344 /** 345 Given a rectangle (assumed to be the bounding box for a path), 346 expand it to allow for the expansion of the bbox that would be 347 seen by stroking the path with the given stroke state and 348 transform. 349 */ 350 fz_rect fz_adjust_rect_for_stroke(fz_context *ctx, fz_rect rect, const fz_stroke_state *stroke, fz_matrix ctm); 351 352 /** 353 A sane 'default' stroke state. 354 */ 355 extern const fz_stroke_state fz_default_stroke_state; 356 357 /** 358 Create a new (empty) stroke state structure (with no dash 359 data) and return a reference to it. 360 361 Throws exception on failure to allocate. 362 */ 363 fz_stroke_state *fz_new_stroke_state(fz_context *ctx); 364 365 /** 366 Create a new (empty) stroke state structure, with room for 367 dash data of the given length, and return a reference to it. 368 369 len: The number of dash elements to allow room for. 370 371 Throws exception on failure to allocate. 372 */ 373 fz_stroke_state *fz_new_stroke_state_with_dash_len(fz_context *ctx, int len); 374 375 /** 376 Take an additional reference to a stroke state structure. 377 378 No modifications should be carried out on a stroke 379 state to which more than one reference is held, as 380 this can cause race conditions. 381 */ 382 fz_stroke_state *fz_keep_stroke_state(fz_context *ctx, const fz_stroke_state *stroke); 383 384 /** 385 Drop a reference to a stroke state structure, destroying the 386 structure if it is the last reference. 387 */ 388 void fz_drop_stroke_state(fz_context *ctx, const fz_stroke_state *stroke); 389 390 /** 391 Given a reference to a (possibly) shared stroke_state structure, 392 return a reference to an equivalent stroke_state structure 393 that is guaranteed to be unshared (i.e. one that can 394 safely be modified). 395 396 shared: The reference to a (possibly) shared structure 397 to unshare. Ownership of this reference is passed in 398 to this function, even in the case of exceptions being 399 thrown. 400 401 Exceptions may be thrown in the event of failure to 402 allocate if required. 403 */ 404 fz_stroke_state *fz_unshare_stroke_state(fz_context *ctx, fz_stroke_state *shared); 405 406 /** 407 Given a reference to a (possibly) shared stroke_state structure, 408 return a reference to a stroke_state structure (with room for a 409 given amount of dash data) that is guaranteed to be unshared 410 (i.e. one that can safely be modified). 411 412 shared: The reference to a (possibly) shared structure 413 to unshare. Ownership of this reference is passed in 414 to this function, even in the case of exceptions being 415 thrown. 416 417 Exceptions may be thrown in the event of failure to 418 allocate if required. 419 */ 420 fz_stroke_state *fz_unshare_stroke_state_with_dash_len(fz_context *ctx, fz_stroke_state *shared, int len); 421 422 /** 423 Create an identical stroke_state structure and return a 424 reference to it. 425 426 stroke: The stroke state reference to clone. 427 428 Exceptions may be thrown in the event of a failure to 429 allocate. 430 */ 431 fz_stroke_state *fz_clone_stroke_state(fz_context *ctx, fz_stroke_state *stroke); 432 433 #endif 434