Skip to content

Instantly share code, notes, and snippets.

@sameer
Created March 8, 2024 18:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sameer/c40a7fefccc739a2098205ec33f72aaf to your computer and use it in GitHub Desktop.
Save sameer/c40a7fefccc739a2098205ec33f72aaf to your computer and use it in GitHub Desktop.
const RECT_TAG_NAME: &str = "rect";
const CIRCLE_TAG_NAME: &str = "circle";
const ELLIPSE_TAG_NAME: &str = "ellipse";
const LINE_TAG_NAME: &str = "line";
RECT_TAG_NAME => {
let x = self.length_attr_to_user_units(&node, "x").unwrap_or(0.);
let y = self.length_attr_to_user_units(&node, "y").unwrap_or(0.);
let width = self.length_attr_to_user_units(&node, "width");
let height = self.length_attr_to_user_units(&node, "height");
let rx = self.length_attr_to_user_units(&node, "rx").unwrap_or(0.);
let ry = self.length_attr_to_user_units(&node, "ry").unwrap_or(0.);
let has_radius = rx > 0. && ry > 0.;
match (width, height) {
(Some(width), Some(height)) => {
self.comment(&node);
let path = vec![
MoveTo {
abs: true,
x: x + rx,
y,
},
HorizontalLineTo {
abs: true,
x: x + width - rx,
},
EllipticalArc {
abs: true,
rx,
ry,
x_axis_rotation: 0.,
large_arc: false,
sweep: true,
x: x + width,
y: y + ry,
},
VerticalLineTo {
abs: true,
y: y + height - ry,
},
EllipticalArc {
abs: true,
rx,
ry,
x_axis_rotation: 0.,
large_arc: false,
sweep: true,
x: x + width - rx,
y: y + height,
},
HorizontalLineTo {
abs: true,
x: x + rx,
},
EllipticalArc {
abs: true,
rx,
ry,
x_axis_rotation: 0.,
large_arc: false,
sweep: true,
x,
y: y + height - ry,
},
VerticalLineTo {
abs: true,
y: y + ry,
},
EllipticalArc {
abs: true,
rx,
ry,
x_axis_rotation: 0.,
large_arc: false,
sweep: true,
x: x + rx,
y,
},
ClosePath { abs: true },
];
apply_path(
&mut self.terrarium,
path.into_iter()
.filter(|p| has_radius || !matches!(p, EllipticalArc { .. })),
)
}
_other => {
warn!("Invalid rectangle node: {node:?}");
}
}
}
CIRCLE_TAG_NAME | ELLIPSE_TAG_NAME => {
let cx = self.length_attr_to_user_units(&node, "cx").unwrap_or(0.);
let cy = self.length_attr_to_user_units(&node, "cy").unwrap_or(0.);
let r = self.length_attr_to_user_units(&node, "r").unwrap_or(0.);
let rx = self.length_attr_to_user_units(&node, "rx").unwrap_or(r);
let ry = self.length_attr_to_user_units(&node, "ry").unwrap_or(r);
if rx > 0. && ry > 0. {
self.comment(&node);
let path = std::iter::once(MoveTo {
abs: true,
x: cx + rx,
y: cy,
})
.chain(
[(cx, cy + ry), (cx - rx, cy), (cx, cy - ry), (cx + rx, cy)]
.into_iter()
.map(|(x, y)| EllipticalArc {
abs: true,
rx,
ry,
x_axis_rotation: 0.,
large_arc: false,
sweep: true,
x,
y,
}),
)
.chain(std::iter::once(ClosePath { abs: true }));
apply_path(&mut self.terrarium, path);
} else {
warn!("Invalid {} node: {node:?}", node.tag_name().name());
}
}
LINE_TAG_NAME => {
let x1 = self.length_attr_to_user_units(&node, "x1");
let y1 = self.length_attr_to_user_units(&node, "y1");
let x2 = self.length_attr_to_user_units(&node, "x2");
let y2 = self.length_attr_to_user_units(&node, "y2");
match (x1, y1, x2, y2) {
(Some(x1), Some(y1), Some(x2), Some(y2)) => {
self.comment(&node);
let path = vec![
MoveTo {
abs: true,
x: x1,
y: y1,
},
LineTo {
abs: true,
x: x2,
y: y2,
},
];
apply_path(&mut self.terrarium, path.into_iter());
}
_other => {
warn!("Invalid line node: {node:?}");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment