e509def0b2
- Introduced new crates for digital brushes, dry media brushes, ink brushes, and paint brushes, each containing various presets. - Updated the menus to include "Paste Special" and "Paste as New Layer" options. - Enhanced the feature scorecard tests to validate selection texture encoding. - Added a regression gate workflow for automated testing on push and pull requests. - Implemented Git hooks for pre-commit checks to ensure code formatting and run tests before commits. - Created a settings file for local configurations.
152 lines
4.4 KiB
Rust
152 lines
4.4 KiB
Rust
//! Digital-native raster, blend, texture, FX, and vector brush descriptors.
|
|
//!
|
|
//! **Purpose:** Separates digital-only tools from traditional-media catalogs. **Logic & Workflow:**
|
|
//! Raster tools return engine `BrushPreset` values; vector tools use a distinct descriptor so they
|
|
//! are never misrouted through the raster brush engine. **Side Effects / Dependencies:** None.
|
|
|
|
use hcie_engine_api::brush::{BrushStyle, BrushTip};
|
|
use hcie_engine_api::BrushPreset;
|
|
|
|
/// Vector-path brush metadata consumed by GUI vector tooling rather than raster drawing.
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub struct VectorBrushPreset {
|
|
/// Stable preset identifier.
|
|
pub id: &'static str,
|
|
/// User-facing preset name.
|
|
pub name: &'static str,
|
|
/// Default path stroke width.
|
|
pub width: f32,
|
|
/// Whether pressure changes path width.
|
|
pub pressure_width: bool,
|
|
/// Input-path smoothing strength in `0..=1`.
|
|
pub smoothing: f32,
|
|
}
|
|
|
|
/// Builds one digital raster preset.
|
|
fn preset(id: &str, name: &str, category: &str, tip: BrushTip) -> BrushPreset {
|
|
BrushPreset {
|
|
id: id.into(),
|
|
name: name.into(),
|
|
category: category.into(),
|
|
style: tip.style,
|
|
tip,
|
|
pressure_size: true,
|
|
pressure_opacity: true,
|
|
pressure_flow: true,
|
|
jitter_position: 0.0,
|
|
jitter_angle: 0.0,
|
|
}
|
|
}
|
|
|
|
/// Returns digital raster, blend, texture, and FX presets.
|
|
pub fn digital_presets() -> Vec<BrushPreset> {
|
|
vec![
|
|
preset(
|
|
"digital_pixel",
|
|
"Pixel / Raster Brush",
|
|
"Digital Raster",
|
|
BrushTip {
|
|
style: BrushStyle::HardRound,
|
|
size: 8.0,
|
|
opacity: 1.0,
|
|
hardness: 1.0,
|
|
spacing: 0.05,
|
|
..BrushTip::default()
|
|
},
|
|
),
|
|
preset(
|
|
"digital_smudge",
|
|
"Smudge / Blender",
|
|
"Digital Blend",
|
|
BrushTip {
|
|
style: BrushStyle::Blender,
|
|
size: 40.0,
|
|
opacity: 0.65,
|
|
hardness: 0.0,
|
|
spacing: 0.05,
|
|
..BrushTip::default()
|
|
},
|
|
),
|
|
preset(
|
|
"digital_stamp",
|
|
"Stamp / Texture",
|
|
"Digital Texture",
|
|
BrushTip {
|
|
style: BrushStyle::Texture,
|
|
size: 48.0,
|
|
opacity: 0.9,
|
|
hardness: 0.8,
|
|
spacing: 0.35,
|
|
jitter_amount: 0.3,
|
|
scatter_amount: 0.6,
|
|
rotation_random: 0.5,
|
|
density: 0.7,
|
|
..BrushTip::default()
|
|
},
|
|
),
|
|
preset(
|
|
"digital_fx_glow",
|
|
"FX Glow",
|
|
"Digital FX",
|
|
BrushTip {
|
|
style: BrushStyle::Glow,
|
|
size: 30.0,
|
|
opacity: 0.8,
|
|
hardness: 0.0,
|
|
spacing: 0.04,
|
|
..BrushTip::default()
|
|
},
|
|
),
|
|
preset(
|
|
"digital_fx_particles",
|
|
"FX Particles",
|
|
"Digital FX",
|
|
BrushTip {
|
|
style: BrushStyle::Spray,
|
|
size: 60.0,
|
|
opacity: 0.7,
|
|
hardness: 0.5,
|
|
spacing: 0.2,
|
|
spray_particle_size: 2.0,
|
|
spray_density: 120,
|
|
..BrushTip::default()
|
|
},
|
|
),
|
|
]
|
|
}
|
|
|
|
/// Returns vector brush descriptors for the vector path subsystem.
|
|
pub fn vector_brush_presets() -> Vec<VectorBrushPreset> {
|
|
vec![
|
|
VectorBrushPreset {
|
|
id: "digital_vector_clean",
|
|
name: "Clean Vector Brush",
|
|
width: 4.0,
|
|
pressure_width: true,
|
|
smoothing: 0.65,
|
|
},
|
|
VectorBrushPreset {
|
|
id: "digital_vector_ink",
|
|
name: "Vector Ink Brush",
|
|
width: 7.0,
|
|
pressure_width: true,
|
|
smoothing: 0.35,
|
|
},
|
|
]
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::{digital_presets, vector_brush_presets};
|
|
|
|
/// Ensures vector tools remain separate from raster brush presets.
|
|
#[test]
|
|
fn digital_catalog_separates_raster_and_vector_tools() {
|
|
assert_eq!(digital_presets().len(), 5);
|
|
assert_eq!(vector_brush_presets().len(), 2);
|
|
assert!(digital_presets()
|
|
.iter()
|
|
.all(|preset| preset.style == preset.tip.style));
|
|
}
|
|
}
|