MCPcopy Create free account
hub / github.com/alceal/plotlars / simplify_svg_polylines

Function simplify_svg_polylines

crates/plotlars-plotters/src/render/mod.rs:214–256  ·  view source on GitHub ↗

Find every `points="..."` attribute in the SVG and, when the polyline has enough vertices, apply Ramer-Douglas-Peucker to remove redundant ones.

(svg: &mut String)

Source from the content-addressed store, hash-verified

212/// Find every `points="..."` attribute in the SVG and, when the polyline has
213/// enough vertices, apply Ramer-Douglas-Peucker to remove redundant ones.
214fn simplify_svg_polylines(svg: &mut String) {
215 // MIN_POINTS: skip simplification for short polylines (axis ticks, error-bar
216 // caps, scatter markers); RDP overhead outweighs savings below this size.
217 // EPSILON: 0.5 px matches plotters' integer-pixel rounding granularity, so
218 // collinear-after-rounding vertices collapse without altering visible shape.
219 const MIN_POINTS: usize = 20;
220 const EPSILON: f64 = 0.5;
221
222 let mut result = String::with_capacity(svg.len());
223 let mut remaining = svg.as_str();
224 let mut modified = false;
225
226 while let Some(idx) = remaining.find("points=\"") {
227 let prefix_end = idx + 8; // length of `points="`
228 result.push_str(&remaining[..prefix_end]);
229 remaining = &remaining[prefix_end..];
230
231 if let Some(end) = remaining.find('"') {
232 let raw = &remaining[..end];
233 // Cheap pre-check: count separators before parsing. A polyline with
234 // <MIN_POINTS vertices has <MIN_POINTS spaces between coord pairs.
235 let space_count = raw.bytes().filter(|&b| b == b' ').count();
236 if space_count >= MIN_POINTS {
237 let points = parse_svg_points(raw);
238 if points.len() > MIN_POINTS {
239 let simplified = rdp_simplify(&points, EPSILON);
240 result.push_str(&format_svg_points(&simplified));
241 modified = true;
242 } else {
243 result.push_str(raw);
244 }
245 } else {
246 result.push_str(raw);
247 }
248 result.push('"');
249 remaining = &remaining[end + 1..];
250 }
251 }
252 if modified {
253 result.push_str(remaining);
254 *svg = result;
255 }
256}
257
258fn parse_svg_points(s: &str) -> Vec<(f64, f64)> {
259 s.split_whitespace()

Callers 1

smooth_svg_linesFunction · 0.85

Calls 3

parse_svg_pointsFunction · 0.85
rdp_simplifyFunction · 0.85
format_svg_pointsFunction · 0.85

Tested by

no test coverage detected