path_kit/lib.rs
1//! # path-kit
2//!
3//! 基于 Skia PathOps 和 PathKit 的 Rust 路径运算库,提供 safe 的 API 封装。
4//! A Rust path operations library based on Skia PathOps and PathKit with safe API wrappers.
5//!
6//! ## 功能 / Features
7//!
8//! - **路径构建**:[`Path`]、[`PathBuilder`];线段、二次/三次贝塞尔、矩形、椭圆、圆、圆角矩形、RRect
9//! Path construction: [`Path`], [`PathBuilder`]; lines, quad/cubic bezier, rect, oval, circle, round rect, RRect
10//! - **路径布尔运算**:并集、交集、差集、异或
11//! Path boolean operations: union, intersect, difference, xor
12//! - **路径简化、包围盒**:`simplify`, `path.tight_bounds`, `pathops_tight_bounds`
13//! Path simplification and tight bounds computation
14//! - **路径迭代**:按动词遍历 Move/Line/Quad/Cubic/Close
15//! Path iteration over verbs and points
16//! - **描边**:将路径转为描边轮廓
17//! Stroke: convert path to stroked outline
18//!
19//! ## 线程安全 / Thread safety
20//!
21//! 当前未保证 `Send` / `Sync`,请勿跨线程共享 `Path`、`RRect`、`StrokeRec` 等类型。
22//! `Send` / `Sync` are not guaranteed; do not share `Path`, `RRect`, `StrokeRec`, etc. across threads.
23//!
24//! ## 类型概览 / Types
25//!
26//! | 类型 | 说明 |
27//! |------|------|
28//! | [`Path`] | 路径 |
29//! | [`PathBuilder`] | 路径构建器(`SkPathBuilder`,支持 `snapshot` / `detach`) |
30//! | [`Rect`] | 矩形 |
31//! | [`RRect`] | 圆角矩形(支持四角独立半径) |
32//! | [`Point`] | 二维点 |
33//! | [`Direction`] | 绘制方向 Cw/Ccw |
34//! | [`RectCorner`] | 矩形起始角 |
35//! | [`PathOp`] | 布尔运算类型 |
36//! | [`PathFillType`] | 路径填充规则(winding / even-odd / inverse) |
37//! | [`PathVerb`] / [`PathVerbItem`] | 路径动词枚举 / 迭代项 |
38//! | [`PathMeasure`] | 路径测量(长度、位置、切线、段提取) |
39//! | [`OpBuilder`] | 批量路径布尔运算(`SkOpBuilder`) |
40//! | [`path_op`] / [`simplify`] / [`pathops_tight_bounds`] | 两路径布尔运算、简化、pathops 紧密包围盒 |
41//! | [`StrokeRec`] / [`StrokeStyle`] | 描边参数与当前样式快照 |
42//! | [`StrokeCap`] | 线端样式 Butt/Round/Square |
43//! | [`StrokeJoin`] | 转角样式 Miter/Round/Bevel |
44//! | [`Paint`] | 绘图参数(含 Style、Stroke) |
45//! | [`PaintStyle`] | 绘图样式 Fill/Stroke/StrokeAndFill |
46//! | [`CornerPathEffect`] / [`DashPathEffect`] | 圆角 / 虚线路径效果 |
47//! | [`RRectType`] | 圆角矩形分类(与 `SkRRect::Type` 一致) |
48//!
49//! ## 示例 / Examples
50//!
51//! ### 路径布尔运算 / Path boolean ops
52//!
53//! ```rust
54//! use path_kit::{Path, Rect, Direction, RectCorner, PathOp, path_op, OpBuilder};
55//!
56//! let mut path1 = Path::new();
57//! path1.add_rect(&Rect::new(0.0, 0.0, 100.0, 100.0), Direction::Cw, RectCorner::UpperLeft);
58//!
59//! let mut path2 = Path::new();
60//! path2.add_rect(&Rect::new(50.0, 50.0, 150.0, 150.0), Direction::Cw, RectCorner::UpperLeft);
61//!
62//! let union = path_op(&path1, &path2, PathOp::Union).unwrap();
63//!
64//! // 批量运算 / Batch operations (use add_ref to avoid clone when reusing paths)
65//! let result = OpBuilder::new()
66//! .add_ref(&path1, PathOp::Union)
67//! .add_ref(&path2, PathOp::Union)
68//! .resolve()
69//! .unwrap();
70//! ```
71//!
72//! ### 圆角矩形 RRect / Rounded rect with per-corner radii
73//!
74//! ```rust
75//! use path_kit::{Path, Rect, RRect, Radii, Direction, RectCorner};
76//!
77//! // 统一圆角 / Uniform radii
78//! let rr = RRect::from_rect_xy(&Rect::new(0.0, 0.0, 100.0, 50.0), 10.0, 10.0);
79//! let mut path = Path::new();
80//! path.add_rrect(&rr, Direction::Cw);
81//!
82//! // 四角独立半径 / Per-corner radii
83//! let radii = [
84//! Radii { x: 10.0, y: 10.0 },
85//! Radii { x: 20.0, y: 10.0 },
86//! Radii { x: 10.0, y: 20.0 },
87//! Radii { x: 5.0, y: 5.0 },
88//! ];
89//! let rr2 = RRect::from_rect_radii(&Rect::new(0.0, 0.0, 80.0, 60.0), &radii);
90//! path.add_rrect(&rr2, Direction::Ccw);
91//! ```
92//!
93//! ### 路径迭代 / Path iteration
94//!
95//! ```rust
96//! use path_kit::{Path, PathVerbItem};
97//!
98//! let mut path = Path::new();
99//! path.move_to(0.0, 0.0).line_to(100.0, 0.0).line_to(100.0, 100.0).close();
100//!
101//! for item in path.iter(false) {
102//! match item {
103//! PathVerbItem::Move(p) => println!("Move to {:?}", p),
104//! PathVerbItem::Line(from, to) => println!("Line {:?} -> {:?}", from, to),
105//! PathVerbItem::Quad(c, to) => println!("Quad {:?} -> {:?}", c, to),
106//! PathVerbItem::Cubic(c1, c2, to) => println!("Cubic -> {:?}", to),
107//! PathVerbItem::Close => println!("Close"),
108//! _ => {}
109//! }
110//! }
111//! ```
112//!
113//! ### 描边 / Stroke
114//!
115//! ```rust
116//! use path_kit::{Path, StrokeRec};
117//!
118//! let rec = StrokeRec::new_stroke(4.0, false);
119//! let mut path = Path::new();
120//! path.move_to(0.0, 0.0).line_to(100.0, 0.0);
121//! let stroked = rec.apply_to_path(&path).unwrap();
122//! ```
123//!
124//! ### 路径测量 / Path measure
125//!
126//! ```rust
127//! use path_kit::{Path, PathMeasure};
128//!
129//! let mut path = Path::new();
130//! path.move_to(0.0, 0.0).line_to(100.0, 0.0);
131//! let mut measure = PathMeasure::from_path(&path, false, 1.0);
132//! let len = measure.length(); // ~100
133//! let (pos, tan) = measure.pos_tan(50.0).unwrap(); // position & tangent at midpoint
134//! let mut segment = Path::new();
135//! measure.get_segment(25.0, 75.0, &mut segment, true); // extract sub-path
136//! ```
137//!
138//! ### 路径简化与包围盒 / Simplify and bounds
139//!
140//! ```rust
141//! use path_kit::{Path, simplify, pathops_tight_bounds};
142//!
143//! let mut path = Path::new();
144//! path.move_to(0.0, 0.0)
145//! .line_to(100.0, 0.0)
146//! .line_to(100.0, 100.0)
147//! .line_to(50.0, 50.0)
148//! .line_to(0.0, 100.0)
149//! .close();
150//!
151//! let simplified = simplify(&path).unwrap();
152//! let bounds = pathops_tight_bounds(&path).unwrap(); // or path.tight_bounds() for infallible
153//! ```
154
155/// PathKit(Skia PathOps)与 C++ 的 cxx 桥接(仅内部使用)。
156/// PathKit C++ interop via cxx (internal only).
157#[doc(hidden)]
158pub(crate) mod bridge;
159
160mod corner_path_effect;
161mod dash_path_effect;
162mod op_builder;
163mod ops;
164mod path;
165mod path_builder;
166mod path_iter;
167mod path_measure;
168mod path_fill_type;
169mod point;
170mod rect;
171mod rrect;
172mod paint;
173mod stroke_rec;
174
175pub use bridge::ffi::Direction;
176pub use bridge::ffi::PathOp;
177pub use bridge::ffi::RectCorner;
178pub use bridge::ffi::RRectType;
179
180impl Default for Direction {
181 fn default() -> Self {
182 Self::Cw
183 }
184}
185
186impl Default for RectCorner {
187 fn default() -> Self {
188 Self::UpperLeft
189 }
190}
191
192pub use corner_path_effect::CornerPathEffect;
193pub use dash_path_effect::DashPathEffect;
194pub use op_builder::OpBuilder;
195pub use ops::{path_op, pathops_tight_bounds, simplify};
196pub use path::Path;
197pub use path_builder::PathBuilder;
198pub use path_fill_type::PathFillType;
199pub use path_iter::{PathIter, PathVerb, PathVerbItem};
200pub use path_measure::PathMeasure;
201pub use point::Point;
202pub use rect::Rect;
203pub use rrect::{Radii, RRect};
204pub use paint::{Paint, PaintStyle};
205pub use stroke_rec::{StrokeCap, StrokeJoin, StrokeRec, StrokeStyle};
206
207#[cfg(test)]
208mod tests;