mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-07-07 15:55:00 +00:00
Remove trailing zeros in rendered SVG path output
This commit is contained in:
parent
8dfdc2b98f
commit
1e62af88cd
4 changed files with 44 additions and 17 deletions
|
@ -155,7 +155,10 @@ impl LayoutHolder for PathTool {
|
|||
})
|
||||
.tooltip(colinear_handles_tooltip)
|
||||
.widget_holder();
|
||||
let colinear_handles_label = TextLabel::new("Colinear Handles").tooltip(colinear_handles_tooltip).widget_holder();
|
||||
let colinear_handles_label = TextLabel::new("Colinear Handles")
|
||||
.disabled(self.tool_data.selection_status.is_none())
|
||||
.tooltip(colinear_handles_tooltip)
|
||||
.widget_holder();
|
||||
|
||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row {
|
||||
widgets: vec![
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use super::*;
|
||||
use utils::format_point;
|
||||
|
||||
use std::fmt::Write;
|
||||
|
||||
/// Functionality relating to core `Bezier` operations, such as constructors and `abs_diff_eq`.
|
||||
|
@ -122,32 +124,38 @@ impl Bezier {
|
|||
pub fn write_curve_argument(&self, svg: &mut String) -> std::fmt::Result {
|
||||
match self.handles {
|
||||
BezierHandles::Linear => svg.push_str(SVG_ARG_LINEAR),
|
||||
BezierHandles::Quadratic { handle } => write!(svg, "{SVG_ARG_QUADRATIC}{:.6},{:.6}", handle.x, handle.y)?,
|
||||
BezierHandles::Cubic { handle_start, handle_end } => write!(svg, "{SVG_ARG_CUBIC}{:.6},{:.6} {:.6},{:.6}", handle_start.x, handle_start.y, handle_end.x, handle_end.y)?,
|
||||
BezierHandles::Quadratic { handle } => {
|
||||
format_point(svg, SVG_ARG_QUADRATIC, handle.x, handle.y)?;
|
||||
}
|
||||
BezierHandles::Cubic { handle_start, handle_end } => {
|
||||
format_point(svg, SVG_ARG_CUBIC, handle_start.x, handle_start.y)?;
|
||||
format_point(svg, " ", handle_end.x, handle_end.y)?;
|
||||
}
|
||||
}
|
||||
write!(svg, " {:.6},{:.6}", self.end.x, self.end.y)
|
||||
format_point(svg, " ", self.end.x, self.end.y)
|
||||
}
|
||||
|
||||
/// Return the string argument used to create the lines connecting handles to endpoints in an SVG `path`
|
||||
pub(crate) fn svg_handle_line_argument(&self) -> Option<String> {
|
||||
let mut result = String::new();
|
||||
|
||||
match self.handles {
|
||||
BezierHandles::Linear => None,
|
||||
BezierHandles::Linear => {}
|
||||
BezierHandles::Quadratic { handle } => {
|
||||
let handle_line = format!("{SVG_ARG_LINEAR}{:.6} {:.6}", handle.x, handle.y);
|
||||
Some(format!(
|
||||
"{SVG_ARG_MOVE}{:.6} {:.6} {handle_line} {SVG_ARG_MOVE}{:.6} {:.6} {handle_line}",
|
||||
self.start.x, self.start.y, self.end.x, self.end.y
|
||||
))
|
||||
let _ = format_point(&mut result, SVG_ARG_MOVE, self.start.x, self.start.y);
|
||||
let _ = format_point(&mut result, SVG_ARG_LINEAR, handle.x, handle.y);
|
||||
let _ = format_point(&mut result, SVG_ARG_MOVE, self.end.x, self.end.y);
|
||||
let _ = format_point(&mut result, SVG_ARG_LINEAR, handle.x, handle.y);
|
||||
}
|
||||
BezierHandles::Cubic { handle_start, handle_end } => {
|
||||
let handle_start_line = format!("{SVG_ARG_LINEAR}{:.6} {:.6}", handle_start.x, handle_start.y);
|
||||
let handle_end_line = format!("{SVG_ARG_LINEAR}{} {}", handle_end.x, handle_end.y);
|
||||
Some(format!(
|
||||
"{SVG_ARG_MOVE}{:.6} {:.6} {handle_start_line} {SVG_ARG_MOVE}{:.6} {:.6} {handle_end_line}",
|
||||
self.start.x, self.start.y, self.end.x, self.end.y
|
||||
))
|
||||
let _ = format_point(&mut result, SVG_ARG_MOVE, self.start.x, self.start.y);
|
||||
let _ = format_point(&mut result, SVG_ARG_LINEAR, handle_start.x, handle_start.y);
|
||||
let _ = format_point(&mut result, SVG_ARG_MOVE, self.end.x, self.end.y);
|
||||
let _ = format_point(&mut result, SVG_ARG_LINEAR, handle_end.x, handle_end.y);
|
||||
}
|
||||
}
|
||||
|
||||
(!result.is_empty()).then_some(result)
|
||||
}
|
||||
|
||||
/// Appends to the `svg` mutable string with an SVG shape representation of the curve.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::*;
|
||||
use crate::consts::*;
|
||||
use crate::utils::format_point;
|
||||
|
||||
use glam::DVec2;
|
||||
use std::fmt::Write;
|
||||
|
@ -163,8 +164,10 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
|||
if self.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let start = transform.transform_point2(self[0].anchor);
|
||||
write!(svg, "{SVG_ARG_MOVE}{:.6},{:.6}", start.x, start.y)?;
|
||||
format_point(svg, SVG_ARG_MOVE, start.x, start.y)?;
|
||||
|
||||
for bezier in self.iter() {
|
||||
bezier.apply_transformation(|pos| transform.transform_point2(pos)).write_curve_argument(svg)?;
|
||||
svg.push(' ');
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::consts::{MAX_ABSOLUTE_DIFFERENCE, STRICT_MAX_ABSOLUTE_DIFFERENCE};
|
|||
use crate::{ManipulatorGroup, Subpath};
|
||||
|
||||
use glam::{BVec2, DMat2, DVec2};
|
||||
use std::fmt::Write;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
/// A structure which can be used to reference a particular point along a `Bezier`.
|
||||
|
@ -294,6 +295,18 @@ pub fn compute_circular_subpath_details<PointId: crate::Identifier>(left: DVec2,
|
|||
)
|
||||
}
|
||||
|
||||
pub fn format_point(svg: &mut String, prefix: &str, x: f64, y: f64) -> std::fmt::Result {
|
||||
write!(svg, "{prefix}{:.6}", x)?;
|
||||
let trimmed_length = svg.trim_end_matches('0').trim_end_matches('.').len();
|
||||
svg.truncate(trimmed_length);
|
||||
|
||||
write!(svg, ",{:.6}", y)?;
|
||||
let trimmed_length = svg.trim_end_matches('0').trim_end_matches('.').len();
|
||||
svg.truncate(trimmed_length);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue