path.odin (13365B)
1 // This file is part of Blend2D project <https://blend2d.com> 2 // 3 // See blend2d.h or LICENSE.md for license and copyright information 4 // SPDX-License-Identifier: Zlib 5 package blend2d 6 7 import "core:c" 8 9 when ODIN_OS == .Windows { 10 foreign import lib "blend2d.lib" 11 } else when ODIN_OS == .Darwin { 12 foreign import lib "libblend2d.a" 13 } else when ODIN_OS == .Linux { 14 foreign import lib "libblend2d.a" 15 } 16 17 18 //! Path command. 19 PathCmd :: enum u32 { 20 //! Move-to command (starts a new figure). 21 MOVE = 0, 22 23 //! On-path command (interpreted as line-to or the end of a curve). 24 ON = 1, 25 26 //! Quad-to control point. 27 QUAD = 2, 28 29 //! Conic-to control point 30 CONIC = 3, 31 32 //! Cubic-to control point (always used as a pair of commands). 33 CUBIC = 4, 34 35 //! Close path. 36 CLOSE = 5, 37 38 //! Conic weight. 39 //! 40 //! \note This is not a point. This is a pair of values from which only the first (x) is used to represent weight 41 //! as used by conic curve. The other value (y) is always set to NaN by Blend2D, but can be arbitrary as it has 42 //! no meaning. 43 WEIGHT = 6, 44 45 //! Maximum value of `BLPathCmd`. 46 MAX_VALUE = 6, 47 FORCE_UINT = 4294967295, 48 } 49 50 //! Path command (never stored in path). 51 PathCmdExtra :: enum u32 { 52 //! Used by `BLPath::set_vertex_at` to preserve the current command value. 53 BL_PATH_CMD_PRESERVE = 4294967295, 54 } 55 56 //! Path flags. 57 PathFlags :: enum u32 { 58 //! No flags. 59 NO_FLAGS = 0, 60 61 //! Path is empty (no commands or close commands only). 62 FLAG_EMPTY = 1, 63 64 //! Path contains multiple figures. 65 FLAG_MULTIPLE = 2, 66 67 //! Path contains one or more quad curves. 68 FLAG_QUADS = 4, 69 70 //! Path contains one or more conic curves. 71 FLAG_CONICS = 8, 72 73 //! Path contains one or more cubic curves. 74 FLAG_CUBICS = 16, 75 76 //! Path is invalid. 77 FLAG_INVALID = 1073741824, 78 79 //! Flags are dirty (not reflecting the current status). 80 FLAG_DIRTY = 2147483648, 81 FLAG_FORCE_UINT = 4294967295, 82 } 83 84 //! Path reversal mode. 85 PathReverseMode :: enum u32 { 86 //! Reverse each figure and their order as well (default). 87 COMPLETE = 0, 88 89 //! Reverse each figure separately (keeps their order). 90 SEPARATE = 1, 91 92 //! Maximum value of `BLPathReverseMode`. 93 MAX_VALUE = 1, 94 FORCE_UINT = 4294967295, 95 } 96 97 //! Stroke join type. 98 StrokeJoin :: enum u32 { 99 //! Miter-join possibly clipped at `miter_limit` [default]. 100 MITER_CLIP = 0, 101 102 //! Miter-join or bevel-join depending on miter_limit condition. 103 MITER_BEVEL = 1, 104 105 //! Miter-join or round-join depending on miter_limit condition. 106 MITER_ROUND = 2, 107 108 //! Bevel-join. 109 BEVEL = 3, 110 111 //! Round-join. 112 ROUND = 4, 113 114 //! Maximum value of `BLStrokeJoin`. 115 MAX_VALUE = 4, 116 FORCE_UINT = 4294967295, 117 } 118 119 //! Position of a stroke-cap. 120 StrokeCapPosition :: enum u32 { 121 //! Start of the path. 122 START = 0, 123 124 //! End of the path. 125 END = 1, 126 127 //! Maximum value of `BLStrokeCapPosition`. 128 MAX_VALUE = 1, 129 FORCE_UINT = 4294967295, 130 } 131 132 //! A presentation attribute defining the shape to be used at the end of open sub-paths. 133 StrokeCap :: enum u32 { 134 //! Butt cap [default]. 135 BUTT = 0, 136 137 //! Square cap. 138 SQUARE = 1, 139 140 //! Round cap. 141 ROUND = 2, 142 143 //! Round cap reversed. 144 ROUND_REV = 3, 145 146 //! Triangle cap. 147 TRIANGLE = 4, 148 149 //! Triangle cap reversed. 150 TRIANGLE_REV = 5, 151 152 //! Maximum value of `BLStrokeCap`. 153 MAX_VALUE = 5, 154 FORCE_UINT = 4294967295, 155 } 156 157 //! Stroke transform order. 158 StrokeTransformOrder :: enum u32 { 159 //! Transform after stroke => `Transform(Stroke(Input))` [default]. 160 AFTER = 0, 161 162 //! Transform before stroke => `Stroke(Transform(Input))`. 163 BEFORE = 1, 164 165 //! Maximum value of `BLStrokeTransformOrder`. 166 MAX_VALUE = 1, 167 FORCE_UINT = 4294967295, 168 } 169 170 //! Mode that specifies how curves are approximated to line segments. 171 FlattenMode :: enum u32 { 172 //! Use default mode (decided by Blend2D). 173 DEFAULT = 0, 174 175 //! Recursive subdivision flattening. 176 RECURSIVE = 1, 177 178 //! Maximum value of `BLFlattenMode`. 179 MAX_VALUE = 1, 180 FORCE_UINT = 4294967295, 181 } 182 183 //! Mode that specifies how to construct offset curves. 184 OffsetMode :: enum u32 { 185 //! Use default mode (decided by Blend2D). 186 DEFAULT = 0, 187 188 //! Iterative offset construction. 189 ITERATIVE = 1, 190 191 //! Maximum value of `BLOffsetMode`. 192 MAX_VALUE = 1, 193 FORCE_UINT = 4294967295, 194 } 195 196 //! Options used to describe how geometry is approximated. 197 //! 198 //! This struct cannot be simply zeroed and then passed to functions that accept approximation options. 199 //! Use `bl_default_approximation_options` to setup defaults and then alter values you want to change. 200 //! 201 //! Example of using `BLApproximationOptions`: 202 //! 203 //! ``` 204 //! // Initialize with defaults first. 205 //! BLApproximationOptions approx = bl_default_approximation_options; 206 //! 207 //! // Override values you want to change. 208 //! approx.simplify_tolerance = 0.02; 209 //! 210 //! // ... now safely use approximation options in your code ... 211 //! ``` 212 ApproximationOptions :: struct { 213 //! Specifies how curves are flattened, see \ref BLFlattenMode. 214 flatten_mode: u8, 215 216 //! Specifies how curves are offsetted (used by stroking), see \ref BLOffsetMode. 217 offset_mode: u8, 218 219 //! Reserved for future use, must be zero. 220 reserved_flags: [6]u8, 221 222 //! Tolerance used to flatten curves. 223 flatten_tolerance: f64, 224 225 //! Tolerance used to approximate cubic curves with quadratic curves. 226 simplify_tolerance: f64, 227 228 //! Curve offsetting parameter, exact meaning depends on `offset_mode`. 229 offset_parameter: f64, 230 } 231 232 //! 2D vector path view provides pointers to vertex and command data along with their size. 233 PathView :: struct { 234 command_data: ^u8, 235 vertex_data: ^Point, 236 size: c.size_t, 237 } 238 239 //! Optional callback that can be used to consume a path data. 240 PathSinkFunc :: proc "c" (path: ^PathCore, info: rawptr, user_data: rawptr) -> Result 241 242 //! This is a sink that is used by path offsetting. This sink consumes both `a` and `b` offsets of the path. The sink 243 //! will be called for each figure and is responsible for joining these paths. If the paths are not closed then the 244 //! sink must insert start cap, then join `b`, and then insert end cap. 245 //! 246 //! The sink must also clean up the paths as this is not done by the offsetter. The reason is that in case the `a` path 247 //! is the output path you can just keep it and insert `b` path into it (clearing only `b` path after each call). 248 PathStrokeSinkFunc :: proc "c" (a: ^PathCore, b: ^PathCore, _c: ^PathCore, input_start: c.size_t, input_end: c.size_t, user_data: rawptr) -> Result 249 250 //! 2D vector path [C API]. 251 PathCore :: struct { 252 _d: ObjectDetail, 253 } 254 255 @(default_calling_convention="c", link_prefix="bl_") 256 foreign lib { 257 path_init :: proc(self: ^PathCore) -> Result --- 258 path_init_move :: proc(self: ^PathCore, other: ^PathCore) -> Result --- 259 path_init_weak :: proc(self: ^PathCore, other: ^PathCore) -> Result --- 260 path_destroy :: proc(self: ^PathCore) -> Result --- 261 path_reset :: proc(self: ^PathCore) -> Result --- 262 path_get_size :: proc(self: ^PathCore) -> c.size_t --- 263 path_get_capacity :: proc(self: ^PathCore) -> c.size_t --- 264 path_get_command_data :: proc(self: ^PathCore) -> ^u8 --- 265 path_get_vertex_data :: proc(self: ^PathCore) -> ^Point --- 266 path_clear :: proc(self: ^PathCore) -> Result --- 267 path_shrink :: proc(self: ^PathCore) -> Result --- 268 path_reserve :: proc(self: ^PathCore, n: c.size_t) -> Result --- 269 path_modify_op :: proc(self: ^PathCore, op: ModifyOp, n: c.size_t, cmd_data_out: ^^u8, vtx_data_out: ^^Point) -> Result --- 270 path_assign_move :: proc(self: ^PathCore, other: ^PathCore) -> Result --- 271 path_assign_weak :: proc(self: ^PathCore, other: ^PathCore) -> Result --- 272 path_assign_deep :: proc(self: ^PathCore, other: ^PathCore) -> Result --- 273 path_set_vertex_at :: proc(self: ^PathCore, index: c.size_t, cmd: u32, x: f64, y: f64) -> Result --- 274 path_move_to :: proc(self: ^PathCore, x0: f64, y0: f64) -> Result --- 275 path_line_to :: proc(self: ^PathCore, x1: f64, y1: f64) -> Result --- 276 path_poly_to :: proc(self: ^PathCore, poly: ^Point, count: c.size_t) -> Result --- 277 path_quad_to :: proc(self: ^PathCore, x1: f64, y1: f64, x2: f64, y2: f64) -> Result --- 278 path_conic_to :: proc(self: ^PathCore, x1: f64, y1: f64, x2: f64, y2: f64, w: f64) -> Result --- 279 path_cubic_to :: proc(self: ^PathCore, x1: f64, y1: f64, x2: f64, y2: f64, x3: f64, y3: f64) -> Result --- 280 path_smooth_quad_to :: proc(self: ^PathCore, x2: f64, y2: f64) -> Result --- 281 path_smooth_cubic_to :: proc(self: ^PathCore, x2: f64, y2: f64, x3: f64, y3: f64) -> Result --- 282 path_arc_to :: proc(self: ^PathCore, x: f64, y: f64, rx: f64, ry: f64, start: f64, sweep: f64, force_move_to: i32) -> Result --- 283 path_arc_quadrant_to :: proc(self: ^PathCore, x1: f64, y1: f64, x2: f64, y2: f64) -> Result --- 284 path_elliptic_arc_to :: proc(self: ^PathCore, rx: f64, ry: f64, xAxisRotation: f64, large_arc_flag: i32, sweep_flag: i32, x1: f64, y1: f64) -> Result --- 285 path_close :: proc(self: ^PathCore) -> Result --- 286 path_add_geometry :: proc(self: ^PathCore, geometry_type: GeometryType, geometry_data: rawptr, m: ^Matrix2D, dir: GeometryDirection) -> Result --- 287 path_add_box_i :: proc(self: ^PathCore, box: ^BoxI, dir: GeometryDirection) -> Result --- 288 path_add_box_d :: proc(self: ^PathCore, box: ^Box, dir: GeometryDirection) -> Result --- 289 path_add_rect_i :: proc(self: ^PathCore, rect: ^RectI, dir: GeometryDirection) -> Result --- 290 path_add_rect_d :: proc(self: ^PathCore, rect: ^Rect, dir: GeometryDirection) -> Result --- 291 path_add_path :: proc(self: ^PathCore, other: ^PathCore, range: ^Range) -> Result --- 292 path_add_translated_path :: proc(self: ^PathCore, other: ^PathCore, range: ^Range, p: ^Point) -> Result --- 293 path_add_transformed_path :: proc(self: ^PathCore, other: ^PathCore, range: ^Range, m: ^Matrix2D) -> Result --- 294 path_add_reversed_path :: proc(self: ^PathCore, other: ^PathCore, range: ^Range, reverse_mode: PathReverseMode) -> Result --- 295 path_add_stroked_path :: proc(self: ^PathCore, other: ^PathCore, range: ^Range, options: ^StrokeOptionsCore, approx: ^ApproximationOptions) -> Result --- 296 path_remove_range :: proc(self: ^PathCore, range: ^Range) -> Result --- 297 path_translate :: proc(self: ^PathCore, range: ^Range, p: ^Point) -> Result --- 298 path_transform :: proc(self: ^PathCore, range: ^Range, m: ^Matrix2D) -> Result --- 299 path_fit_to :: proc(self: ^PathCore, range: ^Range, rect: ^Rect, fit_flags: u32) -> Result --- 300 path_equals :: proc(a: ^PathCore, b: ^PathCore) -> i32 --- 301 path_get_info_flags :: proc(self: ^PathCore, flags_out: ^u32) -> Result --- 302 path_get_control_box :: proc(self: ^PathCore, box_out: ^Box) -> Result --- 303 path_get_bounding_box :: proc(self: ^PathCore, box_out: ^Box) -> Result --- 304 path_get_figure_range :: proc(self: ^PathCore, index: c.size_t, range_out: ^Range) -> Result --- 305 path_get_last_vertex :: proc(self: ^PathCore, vtx_out: ^Point) -> Result --- 306 path_get_closest_vertex :: proc(self: ^PathCore, p: ^Point, max_distance: f64, index_out: ^c.size_t, distance_out: ^f64) -> Result --- 307 path_hit_test :: proc(self: ^PathCore, p: ^Point, fill_rule: FillRule) -> HitTest --- 308 } 309 310 //! Stroke options [C API]. 311 StrokeOptionsCore :: struct { 312 using _: struct #raw_union { 313 using _: struct { 314 start_cap: u8, 315 end_cap: u8, 316 join: u8, 317 transform_order: u8, 318 reserved: [4]u8, 319 }, 320 321 caps: [2]u8, 322 hints: u64, 323 }, 324 325 width: f64, 326 miter_limit: f64, 327 dash_offset: f64, 328 dash_array: ArrayCore, 329 } 330 331 @(default_calling_convention="c", link_prefix="bl_") 332 foreign lib { 333 stroke_options_init :: proc(self: ^StrokeOptionsCore) -> Result --- 334 stroke_options_init_move :: proc(self: ^StrokeOptionsCore, other: ^StrokeOptionsCore) -> Result --- 335 stroke_options_init_weak :: proc(self: ^StrokeOptionsCore, other: ^StrokeOptionsCore) -> Result --- 336 stroke_options_destroy :: proc(self: ^StrokeOptionsCore) -> Result --- 337 stroke_options_reset :: proc(self: ^StrokeOptionsCore) -> Result --- 338 stroke_options_equals :: proc(a: ^StrokeOptionsCore, b: ^StrokeOptionsCore) -> i32 --- 339 stroke_options_assign_move :: proc(self: ^StrokeOptionsCore, other: ^StrokeOptionsCore) -> Result --- 340 stroke_options_assign_weak :: proc(self: ^StrokeOptionsCore, other: ^StrokeOptionsCore) -> Result --- 341 path_stroke_to_sink :: proc(self: ^PathCore, range: ^Range, stroke_options: ^StrokeOptionsCore, approximation_options: ^ApproximationOptions, a: ^PathCore, b: ^PathCore, _c: ^PathCore, sink: PathStrokeSinkFunc, user_data: rawptr) -> Result --- 342 } 343 344 //! 2D vector path [Impl]. 345 PathImpl :: struct { 346 //! Union of either raw path-data or their `view`. 347 using _: struct #raw_union { 348 using _: struct { 349 //! Command data 350 command_data: ^u8, 351 352 //! Vertex data. 353 vertex_data: ^Point, 354 355 //! Vertex/command count. 356 size: c.size_t, 357 }, 358 359 //! Path data as view. 360 view: PathView, 361 }, 362 363 //! Path vertex/command capacity. 364 capacity: c.size_t, 365 366 //! Path flags related to caching. 367 flags: u32, 368 } 369