Skip to main content

Crate clipper2c_sys

Crate clipper2c_sys 

Source
Expand description

Raw Rust FFI bindings to the Clipper2 C++ polygon clipping and offsetting library by Angus Johnson — the canonical implementation. The library’s C++ source is vendored into this crate; see the repository README for the rationale and credit details.

§You probably want clipper2 instead

Almost every item here is unsafe, requires manual memory management, and exposes raw C pointer types. The high-level clipper2 crate wraps these with a safe Rust API and is the recommended way to do polygon clipping from Rust. Reach for clipper2c-sys directly only when you need to interop with code that already operates on the C ABI.

§Memory model

All non-trivial types in this crate are opaque handles. The C++ side owns the storage; Rust code only sees *mut ClipperX pointers and never reads or writes struct fields directly. The lifecycle of every opaque object is:

  1. Ask clipper_X_size() how many bytes the C++ object needs.
  2. Allocate that many bytes via clipper_allocate.
  3. Pass the buffer to a constructor like clipper_X(mem). Internally this is C++ placement-new — no extra allocation occurs.
  4. Use the resulting *mut ClipperX as a handle to all clipper_X_* operations.
  5. Release with clipper_delete_X(handle) (runs the C++ destructor and frees the clipper_allocate buffer) or clipper_destruct_X(handle) (destructor only — caller frees the buffer themselves through the matching allocator).

Memory from clipper_allocate must be released through the matching clipper_delete_X (or destructed and freed via the same allocator). Mixing with libc::free or Rust’s allocator is undefined behaviour.

§_64 (i64) vs _D (f64) variants

Every clipping type comes in two flavours that look superficially similar but use different Rust numeric types:

SuffixRust coordinate typeUpstream C++ typeExample
_64i64 (signed 64-bit integer)int64_tClipperPoint64 (x: i64, y: i64)
_Df64 (64-bit IEEE-754 float)doubleClipperPointD (x: f64, y: f64)

§Why both exist

The clipping engine is implemented exclusively on int64_t. Integer arithmetic and comparisons are exact, so the engine’s handling of coincident edges and shared vertices is deterministic. Floating-point rounding around bit-different-but-mathematically-equal values would otherwise produce different topology depending on input order.

  • _64 types are the engine’s native interface. Your i64 coordinates pass through unchanged. No transformation, no rounding.
  • _D types are a convenience wrapper for f64 data. On input, each coordinate is multiplied by a scale factor s = 2^⌈log₂(10^precision)⌉ (default precision = 2s = 128), rounded to i64, fed to the engine. Outputs are divided by s and returned as f64. The round-trip quantises results to a grid of step 1/s ≈ 10^-precision.

§Which preserves your data

  • _64 round-trips bit-exactly (same i64 values out as in).
  • _D does not — output values are rounded to the integer grid defined by the precision setting. The round-trip is not the identity. This is benign for typical CAD or vector-graphics use, but matters if you depend on invariants like “feeding the same shape back must give bit-identical coordinates”.

§Other tradeoffs

  • Precision floor on _D. Quantisation step is ~10^-precision (default ~0.01). Max supported precision is 8 decimal digits (CLIPPER2_MAX_DEC_PRECISION).
  • Range. Integer coordinates must satisfy |c| ≤ INT64_MAX/4 (≈ 2.3 × 10¹⁸). For _D, the same bound applies after scaling, so high-magnitude values at high precision can hit a range error well before the raw f64 runs out of bits.
  • Performance. _D adds a multiply on every input coordinate and a divide on every output. For hot-path work, prefer _64 and pre-scale once if your data sits on a known integer grid.

Reach for _D when your geometry is already f64 and the quantisation is acceptable. Reach for _64 when your data fits an integer grid or when bit-exact preservation matters.

§Cargo features

  • serde (off by default) — derives Serialize/Deserialize on ClipperPoint64.
  • generate-bindings — regenerate the Rust FFI bindings from the C headers at build time. Off by default; the pre-generated generated/bindings.rs is used otherwise.
  • update-bindings — like generate-bindings, but writes the result back into generated/bindings.rs so the regen output is committed. Use scripts/regenerate-bindings.sh to invoke this with the right LIBCLANG_PATH handling.

Structs§

ClipperClipper64
ClipperClipperD
ClipperClipperOffset
ClipperPath64
ClipperPathD
ClipperPaths64
ClipperPathsD
ClipperPoint64
Coordinate pair in the engine’s native integer (i64) space. Each component must satisfy |c| ≤ INT64_MAX/4 (~2.3 × 10¹⁸); values outside this range produce a range error during a clipping operation.
ClipperPointD
Coordinate pair in floating-point (f64) space. The clipping engine itself runs on integers; ClipperClipperD multiplies each component by its scale factor (s = 128 at the default precision = 2) and rounds to ClipperPoint64 before feeding the engine, so |x × s| and |y × s| must fit ClipperPoint64’s range. Outputs are divided back and quantised to the scaling grid.
ClipperPolyTree64
ClipperPolyTreeD

Constants§

ClipperClipType_DIFFERENCE
ClipperClipType_INTERSECTION
ClipperClipType_NONE
ClipperClipType_UNION
ClipperClipType_XOR
ClipperEndType_BUTT_END
ClipperEndType_JOINED_END
ClipperEndType_POLYGON_END
ClipperEndType_ROUND_END
ClipperEndType_SQUARE_END
ClipperFillRule_EVEN_ODD
ClipperFillRule_NEGATIVE
ClipperFillRule_NON_ZERO
ClipperFillRule_POSITIVE
ClipperJoinType_BEVEL_JOIN
ClipperJoinType_MITER_JOIN
ClipperJoinType_ROUND_JOIN
ClipperJoinType_SQUARE_JOIN
ClipperPathType_CLIP
ClipperPathType_SUBJECT
ClipperPointInPolygonResult_IS_INSIDE
ClipperPointInPolygonResult_IS_ON
ClipperPointInPolygonResult_IS_OUTSIDE

Functions§

clipper_allocate
Allocator paired with the clipper_delete_X / clipper_destruct_X family. Returns raw bytes that must then be placement-new constructed by a clipper_X(mem, …) call before use.
clipper_clipper64
Clipper Contsructors
clipper_clipper64_add_clip
clipper_clipper64_add_open_subject
clipper_clipper64_add_subject
Clipper64 Methods
clipper_clipper64_clear
clipper_clipper64_execute
Run the configured boolean operation. Closed-path output is written to closed; if open-path subjects were added via clipper_clipper64_add_open_subject, their offset/intersected portions land in open. Returns 1 on success, 0 on failure.
clipper_clipper64_execute_tree_with_open
Run the configured boolean operation, writing closed-path output as a hierarchical ClipperPolyTree64 and open-path output (from clipper_clipper64_add_open_subject) into the separate ClipperPaths64 open. Use this when you need to know which contours are holes inside which solids — that nesting is lost in the flat output of clipper_clipper64_execute.
clipper_clipper64_get_preserve_collinear
clipper_clipper64_get_reverse_solution
clipper_clipper64_set_preserve_collinear
Clipper64 Setters / Getters
clipper_clipper64_set_reverse_solution
clipper_clipper64_size
clipper_clipperd
clipper_clipperd_add_clip
clipper_clipperd_add_open_subject
clipper_clipperd_add_subject
ClipperD Methods
clipper_clipperd_clear
clipper_clipperd_execute
Decimal-coordinate version of clipper_clipper64_execute.
clipper_clipperd_execute_tree_with_open
Decimal-coordinate version of clipper_clipper64_execute_tree_with_open.
clipper_clipperd_get_preserve_collinear
clipper_clipperd_get_reverse_solution
clipper_clipperd_set_preserve_collinear
ClipperD Setters / Getters
clipper_clipperd_set_reverse_solution
clipper_clipperd_size
clipper_clipperoffset
ClipperOffset Constructors
clipper_clipperoffset_add_path64
ClipperOffset Methods
clipper_clipperoffset_add_paths64
clipper_clipperoffset_clear
clipper_clipperoffset_error_code
clipper_clipperoffset_execute
clipper_clipperoffset_get_arc_tolerance
clipper_clipperoffset_get_miter_limit
clipper_clipperoffset_get_preserve_collinear
clipper_clipperoffset_get_reverse_solution
clipper_clipperoffset_set_arc_tolerance
clipper_clipperoffset_set_miter_limit
ClipperOffset Setters / Getters
clipper_clipperoffset_set_preserve_collinear
clipper_clipperoffset_set_reverse_solution
clipper_clipperoffset_size
clipper_delete_clipper64
clipper_delete_clipperd
clipper_delete_clipperoffset
clipper_delete_path64
clipper_delete_pathd
clipper_delete_paths64
clipper_delete_pathsd
clipper_delete_polytree64
clipper_delete_polytreed
clipper_path64
Path Constructors
clipper_path64_add_point
clipper_path64_area
clipper_path64_get_point
clipper_path64_length
Path Conversions (to C)
clipper_path64_minkowski_diff
Minkowski difference: like clipper_path64_minkowski_sum but translates pattern by -p instead of +p at each vertex of path. For a pattern that is symmetric about the origin (e.g. a centred disc or square) sum and difference produce the same result; the distinction matters as soon as the pattern is asymmetric, where difference is the operation you want for “set of points x such that x + pattern is contained in path” intuitions (robot-footprint configuration space, tool-reachability inside a pocket).
clipper_path64_minkowski_sum
Minkowski sum: sweep the pattern polygon along path, returning the union of all translated copies of pattern placed at every vertex of path. Geometrically this is { a + b | a in pattern, b in path } — useful when you need to grow a shape by an arbitrary polygonal kernel rather than the radius-only kernel that clipper_paths64_inflate offers.
clipper_path64_of_points
clipper_path64_simplify
clipper_path64_size
Bytes required for placement-new construction of a ClipperPath64.
clipper_path64_to_pathd
Path Conversions
clipper_pathd
clipper_pathd_add_point
clipper_pathd_area
clipper_pathd_get_point
clipper_pathd_length
clipper_pathd_minkowski_diff
Decimal-coordinate version of clipper_path64_minkowski_diff. See clipper_pathd_minkowski_sum for the meaning of precision.
clipper_pathd_minkowski_sum
Decimal-coordinate version of clipper_path64_minkowski_sum. The precision argument selects how many fractional digits are preserved when Clipper2 internally scales to integers, runs the algorithm, and scales back; see the crate-level “_64 (i64) vs _D (f64) variants” documentation for the precision / range / quantisation tradeoffs. Two decimal places is upstream’s default.
clipper_pathd_of_points
clipper_pathd_simplify
clipper_pathd_size
clipper_pathd_to_path64
clipper_paths64
clipper_paths64_add_path
clipper_paths64_add_paths
clipper_paths64_area
clipper_paths64_get_path
clipper_paths64_get_point
clipper_paths64_inflate
Path Offsetting
clipper_paths64_length
clipper_paths64_minkowski_diff
Multi-path variant of clipper_path64_minkowski_diff; same shape as clipper_paths64_minkowski_sum.
clipper_paths64_minkowski_sum
Multi-path variant of clipper_path64_minkowski_sum. The pattern is a single path applied to every input path in paths; the per-path results are unioned with fillrule, so this is exactly equivalent to running clipper_path64_minkowski_sum once per input path and unioning the outputs — provided here for the common case of a scene-wide kernel sweep over many polygons.
clipper_paths64_of_paths
clipper_paths64_path_length
clipper_paths64_simplify
clipper_paths64_size
clipper_paths64_to_pathsd
clipper_pathsd
clipper_pathsd_add_path
clipper_pathsd_add_paths
clipper_pathsd_area
clipper_pathsd_get_path
clipper_pathsd_get_point
clipper_pathsd_inflate
clipper_pathsd_length
clipper_pathsd_minkowski_diff
Decimal-coordinate version of clipper_paths64_minkowski_diff. See clipper_pathd_minkowski_sum for the meaning of precision.
clipper_pathsd_minkowski_sum
Decimal-coordinate version of clipper_paths64_minkowski_sum. See clipper_pathd_minkowski_sum for the meaning of precision.
clipper_pathsd_of_paths
clipper_pathsd_path_length
clipper_pathsd_simplify
clipper_pathsd_size
clipper_pathsd_to_paths64
clipper_point_in_path64
clipper_point_in_pathd
clipper_polytree64
PolyTree Constructors
clipper_polytree64_add_child
clipper_polytree64_area
clipper_polytree64_count
clipper_polytree64_get_child
clipper_polytree64_is_hole
clipper_polytree64_parent
PolyTree64 Methods
clipper_polytree64_polygon
clipper_polytree64_size
clipper_polytree64_to_paths
clipper_polytreed
clipper_polytreed_add_child
clipper_polytreed_area
clipper_polytreed_count
clipper_polytreed_get_child
clipper_polytreed_inv_scale
clipper_polytreed_is_hole
clipper_polytreed_parent
PolyTreeD Methods
clipper_polytreed_polygon
clipper_polytreed_set_inv_scale
clipper_polytreed_size
clipper_polytreed_to_paths

Type Aliases§

ClipperClipType
Boolean operation kind. NONE is the sentinel default for an unconfigured engine — passing it to clipper_*_execute is undefined. Use INTERSECTION / UNION / DIFFERENCE / XOR for the standard four set operations.
ClipperEndType
Open-path endpoint handling for ClipperOffset. POLYGON_END is the closed-polygon case — no endpoints to inflate. The other variants decide how the start and end of a polyline are extended (listed in enum order): JOINED keeps polylines connected to neighbouring segments, BUTT keeps the line flat at the original endpoint, SQUARE extends one delta past it, ROUND adds a half-circle cap.
ClipperFillRule
Determines which subregions are ‘inside’ when paths self-intersect or overlap. EVEN_ODD toggles inside/outside on every edge crossing. NON_ZERO uses the winding-number sign — the conventional rule for polygons-with-holes data where holes wind opposite to their outer contour. POSITIVE and NEGATIVE only count windings of the matching sign, useful when direction has been baked into the input.
ClipperJoinType
Corner-handling style for ClipperOffset; same shapes as SVG and Cairo stroke joins. SQUARE squares off perpendicular to the corner. BEVEL flattens the corner with a straight cut. ROUND replaces it with a circular arc. MITER extends the offset edges to their intersection, clipped at the configured miter limit.
ClipperPathType
Subject paths are the input geometry being clipped. Clip paths are the mask. The clipping engine combines the two sets according to the chosen ClipperClipType and ClipperFillRule.
ClipperPointInPolygonResult