mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-04 16:38:12 +08:00
Apply correct stroke styling with Vello (#1875)
* Apply correct stroke styling in vello * Account for line end caps in clipmask size * apply properties panel improvements * Account for miter limit in Bbox calculation * Fix bounding box for individual layers
This commit is contained in:
@@ -2132,11 +2132,22 @@ pub fn stroke_properties(document_node: &DocumentNode, node_id: NodeId, _context
|
|||||||
|
|
||||||
let color = color_widget(document_node, node_id, color_index, "Color", ColorButton::default(), true);
|
let color = color_widget(document_node, node_id, color_index, "Color", ColorButton::default(), true);
|
||||||
let weight = number_widget(document_node, node_id, weight_index, "Weight", NumberInput::default().unit("px").min(0.), true);
|
let weight = number_widget(document_node, node_id, weight_index, "Weight", NumberInput::default().unit("px").min(0.), true);
|
||||||
|
|
||||||
|
let dash_lengths_val = match &document_node.inputs[dash_lengths_index].as_value() {
|
||||||
|
Some(TaggedValue::VecF64(x)) => x,
|
||||||
|
_ => &vec![],
|
||||||
|
};
|
||||||
let dash_lengths = vec_f64_input(document_node, node_id, dash_lengths_index, "Dash Lengths", TextInput::default().centered(true), true);
|
let dash_lengths = vec_f64_input(document_node, node_id, dash_lengths_index, "Dash Lengths", TextInput::default().centered(true), true);
|
||||||
let dash_offset = number_widget(document_node, node_id, dash_offset_index, "Dash Offset", NumberInput::default().unit("px").min(0.), true);
|
let number_input = NumberInput::default().unit("px").disabled(dash_lengths_val.is_empty());
|
||||||
|
let dash_offset = number_widget(document_node, node_id, dash_offset_index, "Dash Offset", number_input, true);
|
||||||
let line_cap = line_cap_widget(document_node, node_id, line_cap_index, "Line Cap", true);
|
let line_cap = line_cap_widget(document_node, node_id, line_cap_index, "Line Cap", true);
|
||||||
let line_join = line_join_widget(document_node, node_id, line_join_index, "Line Join", true);
|
let line_join = line_join_widget(document_node, node_id, line_join_index, "Line Join", true);
|
||||||
let miter_limit = number_widget(document_node, node_id, miter_limit_index, "Miter Limit", NumberInput::default().min(0.), true);
|
let line_join_val = match &document_node.inputs[line_join_index].as_value() {
|
||||||
|
Some(TaggedValue::LineJoin(x)) => x,
|
||||||
|
_ => &LineJoin::Miter,
|
||||||
|
};
|
||||||
|
let number_input = NumberInput::default().min(0.).disabled(line_join_val != &LineJoin::Miter);
|
||||||
|
let miter_limit = number_widget(document_node, node_id, miter_limit_index, "Miter Limit", number_input, true);
|
||||||
|
|
||||||
vec![
|
vec![
|
||||||
color,
|
color,
|
||||||
|
|||||||
@@ -327,8 +327,10 @@ impl GraphicElementRendered for VectorData {
|
|||||||
|
|
||||||
fn bounding_box(&self, transform: DAffine2) -> Option<[DVec2; 2]> {
|
fn bounding_box(&self, transform: DAffine2) -> Option<[DVec2; 2]> {
|
||||||
let stroke_width = self.style.stroke().map(|s| s.weight()).unwrap_or_default();
|
let stroke_width = self.style.stroke().map(|s| s.weight()).unwrap_or_default();
|
||||||
|
let miter_limit = self.style.stroke().map(|s| s.line_join_miter_limit).unwrap_or(1.);
|
||||||
let scale = transform.decompose_scale();
|
let scale = transform.decompose_scale();
|
||||||
let offset = DVec2::splat(stroke_width * scale.x.max(scale.y) / 2.);
|
// We use the full line width here to account for different styles of line caps
|
||||||
|
let offset = DVec2::splat(stroke_width * scale.x.max(scale.y) * miter_limit);
|
||||||
self.bounding_box_with_transform(transform * self.transform).map(|[a, b]| [a - offset, b + offset])
|
self.bounding_box_with_transform(transform * self.transform).map(|[a, b]| [a - offset, b + offset])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,8 +351,7 @@ impl GraphicElementRendered for VectorData {
|
|||||||
use crate::vector::style::GradientType;
|
use crate::vector::style::GradientType;
|
||||||
use vello::peniko;
|
use vello::peniko;
|
||||||
|
|
||||||
let multiplied_transform = transform * self.transform;
|
let transformed_bounds = GraphicElementRendered::bounding_box(self, transform).unwrap_or_default();
|
||||||
let transformed_bounds = self.bounding_box_with_transform(multiplied_transform).unwrap_or_default();
|
|
||||||
let mut layer = false;
|
let mut layer = false;
|
||||||
|
|
||||||
if self.alpha_blending.opacity < 1. || self.alpha_blending.blend_mode != BlendMode::default() {
|
if self.alpha_blending.opacity < 1. || self.alpha_blending.blend_mode != BlendMode::default() {
|
||||||
@@ -424,10 +425,26 @@ impl GraphicElementRendered for VectorData {
|
|||||||
Some(color) => peniko::Color::rgba(color.r() as f64, color.g() as f64, color.b() as f64, color.a() as f64),
|
Some(color) => peniko::Color::rgba(color.r() as f64, color.g() as f64, color.b() as f64, color.a() as f64),
|
||||||
None => peniko::Color::TRANSPARENT,
|
None => peniko::Color::TRANSPARENT,
|
||||||
};
|
};
|
||||||
|
use crate::vector::style::{LineCap, LineJoin};
|
||||||
|
use vello::kurbo::{Cap, Join};
|
||||||
|
let cap = match stroke.line_cap {
|
||||||
|
LineCap::Butt => Cap::Butt,
|
||||||
|
LineCap::Round => Cap::Round,
|
||||||
|
LineCap::Square => Cap::Square,
|
||||||
|
};
|
||||||
|
let join = match stroke.line_join {
|
||||||
|
LineJoin::Miter => Join::Miter,
|
||||||
|
LineJoin::Bevel => Join::Bevel,
|
||||||
|
LineJoin::Round => Join::Round,
|
||||||
|
};
|
||||||
let stroke = kurbo::Stroke {
|
let stroke = kurbo::Stroke {
|
||||||
width: stroke.weight,
|
width: stroke.weight,
|
||||||
miter_limit: stroke.line_join_miter_limit,
|
miter_limit: stroke.line_join_miter_limit,
|
||||||
..Default::default()
|
join,
|
||||||
|
start_cap: cap,
|
||||||
|
end_cap: cap,
|
||||||
|
dash_pattern: stroke.dash_lengths.into(),
|
||||||
|
dash_offset: stroke.dash_offset,
|
||||||
};
|
};
|
||||||
if stroke.width > 0. {
|
if stroke.width > 0. {
|
||||||
scene.stroke(&stroke, kurbo_transform, color, None, &path);
|
scene.stroke(&stroke, kurbo_transform, color, None, &path);
|
||||||
|
|||||||
Reference in New Issue
Block a user