From bef6f784dfa4d62c411fd2ab41b6afa9637fcb63 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Mon, 2 Mar 2026 19:29:24 -0800 Subject: [PATCH 1/2] Remove dead code for now-retired SVG implementation --- .../document/data_panel/data_panel_message_handler.rs | 4 ---- .../graph_operation_message_handler.rs | 1 - node-graph/libraries/rendering/src/render_ext.rs | 4 ---- node-graph/libraries/vector-types/src/vector/style.rs | 11 ----------- node-graph/nodes/vector/src/vector_nodes.rs | 1 - 5 files changed, 21 deletions(-) diff --git a/editor/src/messages/portfolio/document/data_panel/data_panel_message_handler.rs b/editor/src/messages/portfolio/document/data_panel/data_panel_message_handler.rs index b8daed3c91..b0b9bacacb 100644 --- a/editor/src/messages/portfolio/document/data_panel/data_panel_message_handler.rs +++ b/editor/src/messages/portfolio/document/data_panel/data_panel_message_handler.rs @@ -432,10 +432,6 @@ impl TableRowLayout for Vector { TextLabel::new("Stroke Transform").narrow(true).widget_instance(), TextLabel::new(format_transform_matrix(&stroke.transform)).narrow(true).widget_instance(), ]); - table_rows.push(vec![ - TextLabel::new("Stroke Non-Scaling").narrow(true).widget_instance(), - TextLabel::new((if stroke.non_scaling { "Yes" } else { "No" }).to_string()).narrow(true).widget_instance(), - ]); table_rows.push(vec![ TextLabel::new("Stroke Paint Order").narrow(true).widget_instance(), TextLabel::new(stroke.paint_order.to_string()).narrow(true).widget_instance(), diff --git a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs index d0660983c3..1f6ed6fad1 100644 --- a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs +++ b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs @@ -515,7 +515,6 @@ fn apply_usvg_stroke(stroke: &usvg::Stroke, modify_inputs: &mut ModifyInputsCont align: StrokeAlign::Center, paint_order: PaintOrder::StrokeAbove, transform, - non_scaling: false, }) } } diff --git a/node-graph/libraries/rendering/src/render_ext.rs b/node-graph/libraries/rendering/src/render_ext.rs index 3fbaccbe16..f455f719b1 100644 --- a/node-graph/libraries/rendering/src/render_ext.rs +++ b/node-graph/libraries/rendering/src/render_ext.rs @@ -148,10 +148,6 @@ impl RenderExt for Stroke { if let Some(stroke_join_miter_limit) = stroke_join_miter_limit { let _ = write!(&mut attributes, r#" stroke-miterlimit="{stroke_join_miter_limit}""#); } - // Add vector-effect attribute to make strokes non-scaling - if self.non_scaling { - let _ = write!(&mut attributes, r#" vector-effect="non-scaling-stroke""#); - } if paint_order.is_some() { let _ = write!(&mut attributes, r#" style="paint-order: stroke;" "#); } diff --git a/node-graph/libraries/vector-types/src/vector/style.rs b/node-graph/libraries/vector-types/src/vector/style.rs index dc584675b0..b4e942c200 100644 --- a/node-graph/libraries/vector-types/src/vector/style.rs +++ b/node-graph/libraries/vector-types/src/vector/style.rs @@ -309,8 +309,6 @@ pub struct Stroke { #[serde(default = "daffine2_identity")] pub transform: DAffine2, #[serde(default)] - pub non_scaling: bool, - #[serde(default)] pub paint_order: PaintOrder, } @@ -328,7 +326,6 @@ impl std::hash::Hash for Stroke { self.join_miter_limit.to_bits().hash(state); self.align.hash(state); self.transform.to_cols_array().iter().for_each(|x| x.to_bits().hash(state)); - self.non_scaling.hash(state); self.paint_order.hash(state); } } @@ -345,7 +342,6 @@ impl Stroke { join_miter_limit: 4., align: StrokeAlign::Center, transform: DAffine2::IDENTITY, - non_scaling: false, paint_order: PaintOrder::StrokeAbove, } } @@ -364,7 +360,6 @@ impl Stroke { time * self.transform.matrix2 + (1. - time) * other.transform.matrix2, self.transform.translation * time + other.transform.translation * (1. - time), ), - non_scaling: if time < 0.5 { self.non_scaling } else { other.non_scaling }, paint_order: if time < 0.5 { self.paint_order } else { other.paint_order }, } } @@ -462,11 +457,6 @@ impl Stroke { self } - pub fn with_non_scaling(mut self, non_scaling: bool) -> Self { - self.non_scaling = non_scaling; - self - } - pub fn has_renderable_stroke(&self) -> bool { self.weight > 0. && self.color.is_some_and(|color| color.a() != 0.) } @@ -485,7 +475,6 @@ impl Default for Stroke { join_miter_limit: 4., align: StrokeAlign::Center, transform: DAffine2::IDENTITY, - non_scaling: false, paint_order: PaintOrder::default(), } } diff --git a/node-graph/nodes/vector/src/vector_nodes.rs b/node-graph/nodes/vector/src/vector_nodes.rs index 0920d04daf..dc3194c06d 100644 --- a/node-graph/nodes/vector/src/vector_nodes.rs +++ b/node-graph/nodes/vector/src/vector_nodes.rs @@ -211,7 +211,6 @@ where join_miter_limit: miter_limit, align, transform: DAffine2::IDENTITY, - non_scaling: false, paint_order, }; From a07a4586a569554a80f6aa169f2688b5cdb36466 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Mon, 2 Mar 2026 19:34:25 -0800 Subject: [PATCH 2/2] Implement viewport zoom compensation for thickness --- node-graph/libraries/rendering/src/renderer.rs | 5 ++++- node-graph/nodes/gstd/src/render_node.rs | 7 +++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/node-graph/libraries/rendering/src/renderer.rs b/node-graph/libraries/rendering/src/renderer.rs index 36556f5818..fc51b50093 100644 --- a/node-graph/libraries/rendering/src/renderer.rs +++ b/node-graph/libraries/rendering/src/renderer.rs @@ -180,6 +180,8 @@ pub struct RenderParams { pub aligned_strokes: bool, pub override_paint_order: bool, pub artboard_background: Option, + /// Viewport zoom level (document-space scale). Used to compute constant viewport-pixel stroke widths in Outline mode. + pub viewport_zoom: f64, } impl Hash for RenderParams { @@ -197,6 +199,7 @@ impl Hash for RenderParams { self.aligned_strokes.hash(state); self.override_paint_order.hash(state); self.artboard_background.hash(state); + self.viewport_zoom.to_bits().hash(state); } } @@ -1109,7 +1112,7 @@ impl Render for Table { match render_params.render_mode { RenderMode::Outline => { let outline_stroke = kurbo::Stroke { - width: LAYER_OUTLINE_STROKE_WEIGHT, + width: LAYER_OUTLINE_STROKE_WEIGHT / if render_params.viewport_zoom > 0. { render_params.viewport_zoom } else { 1. }, miter_limit: 4., join: Join::Miter, start_cap: Cap::Butt, diff --git a/node-graph/nodes/gstd/src/render_node.rs b/node-graph/nodes/gstd/src/render_node.rs index 735cb4af4a..11a6724b30 100644 --- a/node-graph/nodes/gstd/src/render_node.rs +++ b/node-graph/nodes/gstd/src/render_node.rs @@ -1,16 +1,14 @@ use core_types::table::Table; -use core_types::transform::Footprint; +use core_types::transform::{Footprint, Transform}; use core_types::{CloneVarArgs, ExtractAll, ExtractVarArgs}; use core_types::{Color, Context, Ctx, ExtractFootprint, OwnedContextImpl, WasmNotSend}; use graph_craft::document::value::RenderOutput; pub use graph_craft::document::value::RenderOutputType; pub use graph_craft::wasm_application_io::*; use graphene_application_io::{ApplicationIo, ExportFormat, ImageTexture, RenderConfig}; -use graphic_types::Artboard; -use graphic_types::Graphic; -use graphic_types::Vector; use graphic_types::raster_types::Image; use graphic_types::raster_types::{CPU, Raster}; +use graphic_types::{Artboard, Graphic, Vector}; use rendering::{Render, RenderOutputType as RenderOutputTypeRequest, RenderParams, RenderSvgSegmentList, SvgRender, format_transform_matrix}; use rendering::{RenderMetadata, SvgSegment}; use std::collections::HashMap; @@ -110,6 +108,7 @@ async fn create_context<'a: 'n>( render_output_type, footprint: Footprint::default(), scale: render_config.scale, + viewport_zoom: footprint.decompose_scale().x, ..Default::default() };