Improve the spreadsheet visualization details for VectorData

This commit is contained in:
Keavon Chambers
2025-06-19 18:37:39 -07:00
parent 6111440afd
commit 523cc27523
4 changed files with 110 additions and 33 deletions
+37
View File
@@ -160,6 +160,20 @@ impl core::hash::Hash for Gradient {
}
}
impl std::fmt::Display for Gradient {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let round = |x: f64| (x * 1e3).round() / 1e3;
let stops = self
.stops
.0
.iter()
.map(|(position, color)| format!("[{}%: #{}]", round(position * 100.), color.to_rgba_hex_srgb()))
.collect::<Vec<_>>()
.join(", ");
write!(f, "{} Gradient: {stops}", self.gradient_type)
}
}
impl Gradient {
/// Constructs a new gradient with the colors at 0 and 1 specified.
pub fn new(start: DVec2, start_color: Color, end: DVec2, end_color: Color, transform: DAffine2, gradient_type: GradientType) -> Self {
@@ -308,6 +322,16 @@ pub enum Fill {
Gradient(Gradient),
}
impl std::fmt::Display for Fill {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::None => write!(f, "None"),
Self::Solid(color) => write!(f, "#{} (Alpha: {}%)", color.to_rgb_hex_srgb(), color.a() * 100.),
Self::Gradient(gradient) => write!(f, "{}", gradient),
}
}
}
impl Fill {
/// Construct a new [Fill::Solid] from a [Color].
pub fn solid(color: Color) -> Self {
@@ -752,6 +776,19 @@ impl core::hash::Hash for PathStyle {
}
}
impl std::fmt::Display for PathStyle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let fill = &self.fill;
let stroke = match &self.stroke {
Some(stroke) => format!("#{} (Weight: {} px)", stroke.color.map_or("None".to_string(), |c| c.to_rgba_hex_srgb()), stroke.weight),
None => "None".to_string(),
};
write!(f, "Fill: {fill}\nStroke: {stroke}")
}
}
impl PathStyle {
pub const fn new(stroke: Option<Stroke>, fill: Fill) -> Self {
Self { stroke, fill }
+23 -13
View File
@@ -91,6 +91,19 @@ pub struct VectorData {
pub upstream_graphic_group: Option<GraphicGroupTable>,
}
impl Default for VectorData {
fn default() -> Self {
Self {
style: PathStyle::new(Some(Stroke::new(Some(Color::BLACK), 0.)), super::style::Fill::None),
colinear_manipulators: Vec::new(),
point_domain: PointDomain::new(),
segment_domain: SegmentDomain::new(),
region_domain: RegionDomain::new(),
upstream_graphic_group: None,
}
}
}
impl core::hash::Hash for VectorData {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.point_domain.hash(state);
@@ -450,19 +463,6 @@ impl VectorData {
}
}
impl Default for VectorData {
fn default() -> Self {
Self {
style: PathStyle::new(Some(Stroke::new(Some(Color::BLACK), 0.)), super::style::Fill::None),
colinear_manipulators: Vec::new(),
point_domain: PointDomain::new(),
segment_domain: SegmentDomain::new(),
region_domain: RegionDomain::new(),
upstream_graphic_group: None,
}
}
}
/// A selectable part of a curve, either an anchor (start or end of a bézier) or a handle (doesn't necessarily go through the bézier but influences curvature).
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, DynAny)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@@ -569,6 +569,16 @@ pub struct HandleId {
pub segment: SegmentId,
}
impl std::fmt::Display for HandleId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.ty {
// I haven't checked if "out" and "in" are reversed, or are accurate translations of the "primary" and "end" terms used in the `HandleType` enum, so this naming is an assumption.
HandleType::Primary => write!(f, "{} out", self.segment.inner()),
HandleType::End => write!(f, "{} in", self.segment.inner()),
}
}
}
impl HandleId {
/// Construct a handle for the first handle on a cubic bézier or the only handle on a quadratic bézier.
#[must_use]