mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-31 13:56:54 -06:00
#617: point joins equal to the layer's no longer count as point styles (SVG keeps a plain stroke)
This commit is contained in:
@@ -468,9 +468,9 @@ impl VectorNetwork {
|
||||
start_dir(&self.outward(seg, at_a)?)
|
||||
}
|
||||
|
||||
/// Whether any point has a stroke cap or join of its own.
|
||||
pub fn has_point_styles(&self) -> bool {
|
||||
self.vertices.iter().any(|v| v.cap.is_some() || v.join.is_some())
|
||||
/// Whether any point has a stroke cap of its own or a join other than the layer's `layer_join`.
|
||||
pub fn has_point_styles(&self, layer_join: StrokeJoin) -> bool {
|
||||
self.vertices.iter().any(|v| v.cap.is_some() || v.join.is_some_and(|j| j != layer_join))
|
||||
}
|
||||
|
||||
/// The fill path: every region's loops.
|
||||
|
||||
@@ -20,8 +20,7 @@ impl Styled {
|
||||
/// shortcut: dashed, variable-width and brush strokes keep the layer's caps and joins at every point; stroke them run by run too if asked for.
|
||||
/// Joins equal to the layer do not require styled runs; stored overrides remain unchanged.
|
||||
pub(crate) fn new(net: &VectorNetwork, props: &StrokeProps) -> Option<Styled> {
|
||||
let styled = net.vertices.iter().any(|v| v.cap.is_some() || v.join.is_some_and(|join| join != props.join));
|
||||
if !styled || !props.dashes.is_empty() || props.profile().is_some() || props.brush.is_some() {
|
||||
if !net.has_point_styles(props.join) || !props.dashes.is_empty() || props.profile().is_some() || props.brush.is_some() {
|
||||
return None;
|
||||
}
|
||||
let mut net = net.rounded().unwrap_or_else(|| net.clone());
|
||||
|
||||
@@ -155,7 +155,7 @@ pub fn stroke_area(n: &Node, path: &BezPath, closed: bool) -> Arc<BezPath> {
|
||||
props.dashes.len().hash(&mut h);
|
||||
// Points' own caps and joins (vector networks).
|
||||
let net = match &n.kind {
|
||||
NodeKind::Vector { network } if network.has_point_styles() => Some(network),
|
||||
NodeKind::Vector { network } if network.has_point_styles(props.join) => Some(network),
|
||||
_ => None,
|
||||
};
|
||||
for v in net.map(|n| n.vertices.as_slice()).unwrap_or_default() {
|
||||
|
||||
@@ -638,7 +638,7 @@ impl W<'_> {
|
||||
|| k.brush.is_some()
|
||||
|| k.cap_start.is_arrow()
|
||||
|| k.cap_end.is_arrow()
|
||||
|| matches!(&n.kind, NodeKind::Vector { network } if network.has_point_styles())
|
||||
|| matches!(&n.kind, NodeKind::Vector { network } if network.has_point_styles(k.join))
|
||||
|| !(w.is_finite() && w > 0.0)
|
||||
{
|
||||
return None;
|
||||
|
||||
@@ -115,3 +115,28 @@ fn text_run_fill_survives_live_text_export() {
|
||||
assert!(svg.contains("#000000"), "{svg}");
|
||||
assert!(svg.contains("fill=\"#00FF00\"") && svg.contains(">b</tspan>") && svg.contains(">a</tspan>"), "{svg}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn point_joins_equal_to_the_layer_join_keep_a_plain_stroke() {
|
||||
use figcraft_doc::{StrokeJoin, VectorNetwork};
|
||||
use figcraft_geom::kurbo::Point;
|
||||
let svg_with = |join: StrokeJoin| {
|
||||
let mut network = VectorNetwork::from_points(&[Point::new(0.0, 0.0), Point::new(50.0, 50.0), Point::new(100.0, 0.0)], false);
|
||||
for v in &mut network.vertices {
|
||||
v.join = Some(StrokeJoin::Miter);
|
||||
}
|
||||
if let Some(v) = network.vertices.get_mut(1) {
|
||||
v.join = Some(join);
|
||||
}
|
||||
let mut d = Document::new("t");
|
||||
let p = d.first_page().unwrap();
|
||||
let v = d.create(p, NodeKind::Vector { network }, "V", 0.0, 0.0, 100.0, 50.0).unwrap();
|
||||
let n = d.get_mut(v).unwrap();
|
||||
n.strokes = vec![Paint::solid(Color::from_hex("000000").unwrap())];
|
||||
n.stroke.weight = 2.0;
|
||||
n.stroke.join = StrokeJoin::Miter;
|
||||
export_svg(&d, &[v], &SvgOptions::default()).unwrap()
|
||||
};
|
||||
assert!(svg_with(StrokeJoin::Miter).contains("stroke-width=\"2\""), "equal joins stay a stroke");
|
||||
assert!(!svg_with(StrokeJoin::Round).contains("stroke-width="), "a differing join is drawn as an outline");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user