feat: introduce SVG-based complex vector shapes
- Added `SvgShape` variant to `VectorShape` in `hcie-protocol`, allowing for SVG rendering of complex shapes. - Updated serialization to skip old shape variants for backward compatibility. - Implemented SVG generation functions in `svg_templates.rs` for various shapes (arrow, star, rhombus, etc.). - Created `svg_render.rs` to parse SVG strings and tessellate paths using `usvg`. - Modified rendering logic in `hcie-vector` to handle `SvgShape` and integrate with existing shape rendering. - Updated shape creation API in `hcie-engine-api` to support SVG shapes. - Enhanced property editing and shape synchronization in both `hcie-egui-app` and `hcie-iced-app` to accommodate new SVG shapes. - Added comprehensive documentation for new features and changes.
This commit is contained in:
@@ -415,6 +415,39 @@ pub struct Engine {
|
||||
std::sync::Arc<std::sync::Mutex<Vec<crate::stroke_cache::PendingHistoryItem>>>,
|
||||
}
|
||||
|
||||
/// Create a `VectorShape::SvgShape` from a shape kind name and parameter map.
|
||||
///
|
||||
/// The `kind` string must be one of: "arrow", "star", "rhombus", "cylinder",
|
||||
/// "heart", "bubble", "gear", "cross", "crescent", "bolt", "arrow4".
|
||||
///
|
||||
/// Shape-specific parameters (e.g. `points`, `inner_radius`, `thick`) are passed
|
||||
/// via `params`.
|
||||
pub fn create_vector_shape(
|
||||
kind: &str,
|
||||
x1: f32,
|
||||
y1: f32,
|
||||
x2: f32,
|
||||
y2: f32,
|
||||
params: &std::collections::HashMap<String, f32>,
|
||||
) -> VectorShape {
|
||||
let svg = hcie_vector::svg_templates::create_svg(kind, params);
|
||||
VectorShape::SvgShape {
|
||||
x1,
|
||||
y1,
|
||||
x2,
|
||||
y2,
|
||||
kind: kind.to_string(),
|
||||
svg,
|
||||
stroke: 2.0,
|
||||
color: [0, 0, 0, 255],
|
||||
fill_color: [255, 255, 255, 255],
|
||||
fill: true,
|
||||
angle: 0.0,
|
||||
opacity: 1.0,
|
||||
hardness: 1.0,
|
||||
}
|
||||
}
|
||||
|
||||
impl Engine {
|
||||
/// Create a new engine with a default transparent document.
|
||||
///
|
||||
@@ -4038,6 +4071,14 @@ fn set_shape_color(
|
||||
*color = stroke_color;
|
||||
*fc = fill_color;
|
||||
}
|
||||
SvgShape {
|
||||
color,
|
||||
fill_color: fc,
|
||||
..
|
||||
} => {
|
||||
*color = stroke_color;
|
||||
*fc = fill_color;
|
||||
}
|
||||
FreePath {
|
||||
color,
|
||||
fill_color: fc,
|
||||
@@ -4147,6 +4188,12 @@ fn move_shape(
|
||||
*x2 += dx;
|
||||
*y2 += dy;
|
||||
}
|
||||
SvgShape { x1, y1, x2, y2, .. } => {
|
||||
*x1 += dx;
|
||||
*y1 += dy;
|
||||
*x2 += dx;
|
||||
*y2 += dy;
|
||||
}
|
||||
FreePath { pts, .. } => {
|
||||
for p in pts.iter_mut() {
|
||||
p[0] += dx;
|
||||
@@ -4279,6 +4326,14 @@ fn scale_shape(shape: &mut hcie_protocol::VectorShape, scale_x: f32, scale_y: f3
|
||||
*x2 = cx + (*x2 - cx) * scale_x;
|
||||
*y2 = cy + (*y2 - cy) * scale_y;
|
||||
}
|
||||
SvgShape { x1, y1, x2, y2, .. } => {
|
||||
let cx = (*x1 + *x2) / 2.0;
|
||||
let cy = (*y1 + *y2) / 2.0;
|
||||
*x1 = cx + (*x1 - cx) * scale_x;
|
||||
*y1 = cy + (*y1 - cy) * scale_y;
|
||||
*x2 = cx + (*x2 - cx) * scale_x;
|
||||
*y2 = cy + (*y2 - cy) * scale_y;
|
||||
}
|
||||
FreePath { pts, .. } => {
|
||||
if pts.is_empty() {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user