From 59cc303912ce9b68ba8fcd150e17fb075c889ecf Mon Sep 17 00:00:00 2001 From: Drew Dibble Date: Mon, 9 Nov 2026 15:13:42 -0700 Subject: [PATCH] Canvas redraw: the stack overflow fix's evidence, and two tests' known differences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The parity rows say what the fix covers: a 3D effect on a fill or stroke that builds nothing overflowed the stack with no effect of the object's own too, on the canvas, in Object › Rasterize and in raster exports. - The builds-nothing test says the fill-only difference (a raster effect clipped to the path, cutting Roughen's spikes, when drawn without the 3D effect) is an older bug, not the design. - The traced-shape test says why its area is bounded rather than drawn again: a partial render in outline view differs from the whole by one in alpha on 37 pixels, older than the test and unrelated to the edit. - A doc comment rewrapped. --- crates/render/src/fx/tests.rs | 9 +++++---- crates/render/src/tests/changed.rs | 5 +++++ docs/target-app-parity.md | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/crates/render/src/fx/tests.rs b/crates/render/src/fx/tests.rs index 7bdd8c3c6..974557e50 100644 --- a/crates/render/src/fx/tests.rs +++ b/crates/render/src/fx/tests.rs @@ -911,8 +911,8 @@ fn a_3d_effect_that_builds_nothing_is_measured_alike() { assert_eq!(Renderer::new().bounds_of(&symbols, &n), crate::brush_fx::cull_bounds(&symbols, &n)); } -/// A group with effects of its own that holds an extruded path is measured once for every artboard of a -/// pass: its bounds are kept after the first. +/// A group with effects of its own that holds an extruded path is measured once for every artboard +/// of a pass: its bounds are kept after the first. #[test] fn a_group_holding_3d_art_is_measured_once_a_pass() { let mut d = Document::new(100.0, 100.0); @@ -1752,8 +1752,9 @@ fn an_image_inner_glow_follows_its_visible_pixels() { /// 3D effect, with a raster effect of its own (Drop Shadow, Gaussian Blur) too. An object with /// only a fill and a raster effect draws from that art, where without the 3D effect it draws as a /// path, whose raster effects are clipped to the path's own geometry: there Roughen's spikes are -/// cut off, so the two differ in a few pixels at the edge and match inside the path. Either way -/// the raster effect reaches past what the object draws without it. +/// cut off, so the two differ in a few pixels at the edge and match inside the path. That clipping +/// is a known bug of drawing without the 3D effect, older than this test, not the design. Either +/// way the raster effect reaches past what the object draws without it. #[test] fn a_3d_effect_that_builds_nothing_draws_the_item_as_without_it() { let rough = diff --git a/crates/render/src/tests/changed.rs b/crates/render/src/tests/changed.rs index 67c476ee3..5d6272eca 100644 --- a/crates/render/src/tests/changed.rs +++ b/crates/render/src/tests/changed.rs @@ -615,6 +615,11 @@ fn a_trace_objects_new_first_member_is_its_source() { redraw_traced(&back, &replaced); } +/// Recoloring a traced shape changes only the shape, as the free measure and the renderer that drew +/// the trace object in its view measure it. The area is bounded, not drawn again and compared: in +/// this view (outlines with the source image) a partial render of the outlines differs from the +/// whole by one in alpha on 37 pixels (230 against 229), which is older than this test and has +/// nothing to do with what changed (the recolor changes no pixel in this view). #[test] fn recolouring_a_traced_shape_changes_only_the_shape() { let (old, _, _, shape) = traced("outlinesWithSourceImage"); diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index 49f7d0c9b..8754a12f6 100644 --- a/docs/target-app-parity.md +++ b/docs/target-app-parity.md @@ -41,7 +41,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard | Date | Change | Summary | |---|---|---| -| 2026-11-09 | minor | Canvas: a 3D effect (Extrude & Bevel, Inflate, Rotate, Revolve) changed on type or a group draws again where its art was and is, measured by that art; the canvas measures through its renderer and draws the part with the art it made to measure it. Exports and Object › Rasterize take the solid of 3D type. Fit to Artwork Bounds and per-artboard SVG export measure every artboard through one renderer, building each solid once. A 3D effect on a fill or stroke that builds nothing (Revolve after Roughen), under an effect of the object's own, no longer overflows the stack on the canvas and in Object › Rasterize: the fill or stroke draws as without it. Tests `tests::changed::a_3d_effect_changed_on_type_or_a_group_changes_where_its_solid_was`, `fx::tests::a_renderer_measures_the_art_on_each_artboard_building_each_solid_once`, `canvas::tests::an_edit_to_a_3d_effect_redraws_with_the_art_measured`, `fx::tests::a_3d_effect_that_builds_nothing_draws_the_item_as_without_it`. Scores and estimates unchanged. | +| 2026-11-09 | minor | Canvas: a 3D effect (Extrude & Bevel, Inflate, Rotate, Revolve) changed on type or a group draws again where its art was and is, measured by that art; the canvas measures through its renderer and draws the part with the art it made to measure it. Exports and Object › Rasterize take the solid of 3D type. Fit to Artwork Bounds and per-artboard SVG export measure every artboard through one renderer, building each solid once. A 3D effect on a fill or stroke that builds nothing (Revolve after Roughen) no longer overflows the stack on the canvas, in Object › Rasterize and in raster exports: the fill or stroke draws as without it. Tests `tests::changed::a_3d_effect_changed_on_type_or_a_group_changes_where_its_solid_was`, `fx::tests::a_renderer_measures_the_art_on_each_artboard_building_each_solid_once`, `canvas::tests::an_edit_to_a_3d_effect_redraws_with_the_art_measured`, `fx::tests::a_3d_effect_that_builds_nothing_draws_the_item_as_without_it`. Scores and estimates unchanged. | | 2026-11-07 | minor | File formats and Type core (#6147): `.ai`/EPS type keeps its paragraphs' tab stops (positions and alignments; leaders aren't read; at most 1,024 a paragraph and 2^20 a story), and right-aligned area type sets the text after a line's last tab against the right edge, the text before it at its stops; centred and justified lines are aligned as a whole as before; evidence added. Scores and estimates unchanged. | | 2026-11-07 | minor | File formats and Type core (#6137): `.ai`/EPS type from the text document keeps auto leading per line, its hyphenation options, may show more of the last lines the file sets in an area frame of its own, when growing the frame by its lines' deepest descent plus 0.05 pt shows them, and a line a soft return ends is justified; evidence added. Limits: frames grow only for area type of one frame, horizontal, by its lines' deepest descent plus 0.05 pt; type in a font that isn't installed, and hyphenation in a language that isn't imported, still lay out differently. Scores and estimates unchanged. | | 2026-11-08 | minor | Style panels: a double-click on a user character style's row opens its Character Style Options (`ui.charStyleOptions`), and on a paragraph style's row its Paragraph Style Options (rename); the Character Style Options dialog keeps a fixed width and scrolls its sections in a shorter window, so OK and Cancel stay on screen. Tests `panels::text_styles::tests::double_clicking_a_character_style_row_opens_its_options` and `dialogs::char_style_options::tests::the_sections_scroll_in_a_window_shorter_than_the_general_list`. Scores and estimates unchanged. | @@ -1906,7 +1906,7 @@ Edit › Copy and Cut put the selected ruler guides on the clipboard, with the s | Date | Change | Summary | |---|---|---| -| 2026-11-09 | minor | Canvas: a 3D effect changed on type or a group redraws where its solid was, measured by the effect's art through the renderer that drew the frame; exports and Object › Rasterize take the solid of 3D type; Fit to Artwork Bounds and per-artboard SVG export measure all artboards through one renderer; a 3D effect on a fill or stroke that builds nothing no longer overflows the stack (evidence in Feature revisions). Scores and estimates unchanged. | +| 2026-11-09 | minor | Canvas: a 3D effect changed on type or a group redraws where its solid was, measured by the effect's art through the renderer that drew the frame; exports and Object › Rasterize take the solid of 3D type; Fit to Artwork Bounds and per-artboard SVG export measure all artboards through one renderer; a 3D effect on a fill or stroke that builds nothing no longer overflows the stack on the canvas, in Object › Rasterize and in raster exports (evidence in Feature revisions). Scores and estimates unchanged. | | 2026-11-09 | minor | Type advanced: Auto Spell Check (`edit.autoSpellCheck`), #4936; evidence added; the dialogs and the right-click Spelling menu remain; scores and hours unchanged. | | 2026-11-09 | minor | Bundled content: built-in UI Frames symbol library (Panel, Button, Bar with default 9-slice); symbol libraries evidence updated; ~30% → ~32%; more built-in symbol libraries remain. | | 2026-11-09 | minor | Symbols: on-canvas dynamic part appearance takes gradient/pattern fill and stroke and opacity/blend; evidence updated; area ~87% → ~88%; strokes remaining no longer lists Overlap/auto corners. |