Review: report module beside rasterfx, ids checked without a tree walk, docs trimmed (#1147)
The report module moves to cmd/rasterfx/report.rs (the crate's foo.rs + foo/ layout instead of #[path]). An object is the document's when its id is below the document's next id, so building the report no longer walks the whole document (and its symbols and patterns) on every PDF, SVG, print and clipboard export. The parity docs say what changed in the status line and one evidence bullet instead of a separate paragraph. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8d881cc0bc
commit
4603ebec7a
File diff suppressed because one or more lines are too long
|
|
@ -26,7 +26,6 @@ use vectorcraft_render::{AntiAlias, RenderOptions};
|
|||
|
||||
use super::*;
|
||||
|
||||
#[path = "rasterfx_report.rs"]
|
||||
mod report;
|
||||
use report::FlattenReport;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use std::collections::HashSet;
|
||||
//! The PDF export warnings for raster effects whose images the 64 million pixel cap rendered below
|
||||
//! the document's raster effects resolution, one per object of the document.
|
||||
|
||||
use vectorcraft_doc::{Document, Node, NodeId, NodeKind};
|
||||
|
||||
|
|
@ -8,7 +9,8 @@ pub(super) struct FlattenReport {
|
|||
pub which: Which,
|
||||
requested_ppi: f64,
|
||||
reductions: Vec<Reduction>,
|
||||
originals: HashSet<NodeId>,
|
||||
/// Ids from here on are the flattening's own (split appearance items, groups under shadows).
|
||||
first_new_id: u64,
|
||||
}
|
||||
|
||||
struct Reduction {
|
||||
|
|
@ -19,13 +21,10 @@ struct Reduction {
|
|||
|
||||
impl FlattenReport {
|
||||
pub fn new(which: Which, doc: &Document) -> Self {
|
||||
let mut originals = HashSet::new();
|
||||
for node in doc.layers.iter().chain(doc.symbols.iter().map(|s| &s.art)).chain(doc.patterns.iter().flat_map(|p| &p.art)) {
|
||||
collect_ids(node, &mut originals);
|
||||
}
|
||||
Self { which, requested_ppi: super::effects_scale(doc) * 72.0, reductions: vec![], originals }
|
||||
Self { which, requested_ppi: super::effects_scale(doc) * 72.0, reductions: vec![], first_new_id: doc.peek_next_id() }
|
||||
}
|
||||
|
||||
/// Note `image` (made for the raster effects of `original`) when the cap lowered its resolution.
|
||||
pub fn record(&mut self, original: &Node, image: &Node) {
|
||||
if let NodeKind::Image(image) = &image.kind {
|
||||
let [pixel_size, ..] = image.xf.as_coeffs();
|
||||
|
|
@ -40,12 +39,15 @@ impl FlattenReport {
|
|||
self.reductions.len()
|
||||
}
|
||||
|
||||
/// Give the reductions recorded since `checkpoint` on pieces the flattening made to `original`,
|
||||
/// a document object (the innermost one, as the walk returns from it).
|
||||
pub fn attribute_since(&mut self, checkpoint: usize, original: &Node) {
|
||||
if !self.originals.contains(&original.id) {
|
||||
let first_new_id = self.first_new_id;
|
||||
if original.id.0 >= first_new_id {
|
||||
return;
|
||||
}
|
||||
for reduction in self.reductions.iter_mut().skip(checkpoint) {
|
||||
if !self.originals.contains(&reduction.id) {
|
||||
if reduction.id.0 >= first_new_id {
|
||||
reduction.id = original.id;
|
||||
reduction.name.clone_from(&original.name);
|
||||
}
|
||||
|
|
@ -74,16 +76,6 @@ impl FlattenReport {
|
|||
}
|
||||
}
|
||||
|
||||
fn collect_ids(node: &Node, ids: &mut HashSet<NodeId>) {
|
||||
ids.insert(node.id);
|
||||
for child in node.children().into_iter().flatten() {
|
||||
collect_ids(child, ids);
|
||||
}
|
||||
if let Some(mask) = &node.mask {
|
||||
collect_ids(&mask.art, ids);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
@ -30,11 +30,9 @@ Part of [target-app-parity.md](target-app-parity.md); open work is in [gaps.md](
|
|||
| SVG Filters | Apply SVG Filter… and the filter list | 0/1 | the whole submenu (SVG filters on import round-trip already) |
|
||||
| Warp | Arc, Arc Lower, Arc Upper, Arch, Bulge, Shell Lower, Shell Upper, Flag, Wave, Fish, Rise, Fisheye, Inflate, Squeeze, Twist | 15/15 | warp point editing in envelopes |
|
||||
|
||||
Document Raster Effects Settings exists. PDF export reports when its unchanged 64 million pixel
|
||||
budget lowers raster-effect resolution: one warning per original object, with its id/name,
|
||||
requested ppi and lowest achieved ppi across generated images. Uncapped exports remain quiet.
|
||||
Evidence: `crates/engine/src/tests_pdfraster.rs` exercises actual 2400-ppi capped fill/stroke
|
||||
images and a small uncapped export; `cmd/rasterfx_report.rs` tests lowest-resolution aggregation.
|
||||
Document Raster Effects Settings exists. When the 64 million pixel cap on an effect image lowers
|
||||
its resolution, PDF export warns once per object with the requested and the lowest achieved ppi
|
||||
(`crates/engine/src/tests_pdfraster.rs`).
|
||||
|
||||
## Photoshop effects
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ Checked 2026-10-10 from the code, tests and open issues; no workflow fails, so V
|
|||
| M6 | Path operations (Pathfinder, Shape Builder, offset…) | ✅ mostly done (Boolean precision on almost-horizontal edges fixed and the property tests made deterministic; Shape Builder gap detection, large-offset bug open) | 3–6 |
|
||||
| M7 | Type (point/area/path, editing, styles, OpenType, threading, glyphs) | 🟡 Document-point character controls after object/group scaling (#1034; optional font-size preservation remains separate), Character/Paragraph Styles, per-paragraph paragraph attributes, Area Type Options (with Width/Height, Auto Size and Shrink Text to Fit; overflow reported to agents and vertical Align), type areas resized by their handles and reshaped with Direct Selection, threaded text, Fit Headline, Glyphs, OpenType panel, Find Font, installed system fonts in every font menu (fonts registered with Windows outside its font folders, the XDG and Flatpak host font folders on Linux, and fonts installed while the app runs, listed when it comes back to the front; searchable; the Character and Properties menus show each family's sample of the selected text, preview it live under the pointer or ↑/↓, filter by script and kind, list a family's styles, and star favourites; the Glyphs panel and Find Font's Replace With use the same menu without the live preview) and found by name on open/import, variable fonts' named instances as styles, CJK names in the UI, input methods (marked text in place, candidate window at the caret; Japanese IME), Text Wrap (offset, invert, both sides of an object; follows edits), Type on a Path effects and Options with draggable start/centre/end brackets (slide, flip), tab stops + Tabs panel (Above Text floats it over the selected text, its ruler at the canvas zoom so stops line up with the columns, #729), inline symbols in text (beyond parity), Hebrew/Arabic bidirectional text, Paragraph Direction, Every-line/Single-line Composer per object (ragged text too) done; tab leaders, spell check, vertical type pending | 45–60 |
|
||||
| M8 | Transform & distort (Puppet Warp, Liquify tools, Envelopes, Blends, Perspective Grid) | ✅ done (M8.1–M8.20 on 2026-10-06, fidelity pass): Liquify Tool Options with one shared brush, pen pressure, hold-to-apply, a safe scope and incremental strokes; tool options that last; Puppet Warp rotation, multi-select, Control bar and a rest-shape session that follows Undo; Width tool on compound paths; Envelope dialogs with preview, Reset with Warp/Mesh, full Envelope Options, type/images/symbols/appearance/gradients/patterns distorted on canvas and in every export, warps that keep their frame, Edit Contents, mesh handles and Control bar; Blend Options, anchor-targeted Blend tool, editable spine, keys picked on the canvas, faithful interpolation and knockout; Perspective Grid with Define Grid, presets, lock/snap/rulers, widgets, the 1–4 plane switch, movable planes, Perspective Selection scale/copy/perpendicular/Transform Again, and type and symbols truly projected with Edit Text. Left: Anti-Alias and Preserve Shape output, warp-envelope point editing, brush interpolation in blends, Free Transform/Scale/Reflect along a rotated box | 2–4 |
|
||||
| M9 | Live effects (+ 3D & Materials) | 🟡 2D effects done incl. Effect → Pathfinder, Color Adjustments and Document Raster Effects Settings; PDF reports resolution reduced by the unchanged raster-effect pixel cap per original object; initial Revolve only; SVG Filters, remaining raster effects and 3D pending | 81–130 |
|
||||
| M9 | Live effects (+ 3D & Materials) | 🟡 2D effects done incl. Effect → Pathfinder, Color Adjustments and Document Raster Effects Settings; PDF export warns when the pixel cap lowers raster-effect resolution; initial Revolve only; SVG Filters, remaining raster effects and 3D pending | 81–130 |
|
||||
| M10 | Brushes, symbols, patterns, Repeat | 🟡 pattern swatches (5 tile types, Pattern Options, editing mode, SVG `<pattern>`/PDF export) and live Repeat (radial/grid/mirror) done; brushes/symbols in progress | 23–37 |
|
||||
| M11 | Artboards & views (artboard panel/tool with Move Artwork for X/Y fields and Artboard Options, Trim View, middle-button pan, print tiling and the status bar's artboard navigator done; multiple windows, presentation polish) | 🟡 | 15–25 |
|
||||
| M12 | Advanced color & art (CMYK/ICC, separations, Gradient Mesh, Live Paint, Image Trace, Graphs) | 🟡 Gradient Mesh, Live Paint, Image Trace (13 presets, 18 ms/1k² image; the Flat Logo mode places edges to a fraction of a pixel, restores sharp corners, snaps lines and circles, and refuses gradients), Recolor Artwork, colour management (ICC, soft proofing, separations preview), Graphs (all 9 tools, Graph Data/Type, group-selected series colours persist through regenerate/save/open) done; graph Design/Column/Marker designs pending | 6–10 |
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
# Parity with Adobe Illustrator
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (Drawing tools: Live Corners round corners between curved sides, #1144; Type advanced: proportional vertical metrics (`vpal`) done, #966; Shape Builder: #893 fixed, merged regions of crossing lines no longer keep seams; scores unchanged while #937 is open; #1034: document-point character controls after object/group scaling; full readiness recomputed as the standard's additive weighted sum, ~62%; per-audience hours; essentials-user score ~75% added; ready-for-real-work re-examined: 50% → 55%, mainstream 65% added; earlier the same day: full re-measure against Illustrator 2026 30.x; merged the ROADMAP's parity estimate, honest assessment and "Shipped so far" into this file) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
|
||||
|
||||
Evidence update (2026-10-11, minor): PDF raster-effect resolution-cap warnings verified; scores and hours unchanged.
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (PDF export warns when the pixel cap lowers raster-effect resolution; Drawing tools: Live Corners round corners between curved sides, #1144; Type advanced: proportional vertical metrics (`vpal`) done, #966; Shape Builder: #893 fixed, merged regions of crossing lines no longer keep seams; scores unchanged while #937 is open; #1034: document-point character controls after object/group scaling; full readiness recomputed as the standard's additive weighted sum, ~62%; per-audience hours; essentials-user score ~75% added; ready-for-real-work re-examined: 50% → 55%, mainstream 65% added; earlier the same day: full re-measure against Illustrator 2026 30.x; merged the ROADMAP's parity estimate, honest assessment and "Shipped so far" into this file) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
|
||||
|
||||
The authoritative parity assessment. [`ROADMAP.md`](../ROADMAP.md) summarizes it; [`gaps.md`](gaps.md) is
|
||||
the work list made from it. Deep areas have their own checklists: [UI and interaction](ui-parity.md),
|
||||
|
|
@ -76,7 +74,7 @@ dominate; 3D, graphs and automation are specialist). They sum to 105. Feature de
|
|||
| Strokes, brushes, width profiles | 5 | 88% | Art brush Overlap, Pattern brush auto corners, brush libraries, pen pressure on macOS, tilt/bearing/rotation | 8–15 | estimated |
|
||||
| Appearance, transparency, graphic styles, masks | 5 | 97% | raster effect reach in preview bounds | 1–2 | estimated |
|
||||
| Live vector effects | 5 | 85% | Outline Object, Effect › Rasterize, Pathfinder Hard Mix/Soft Mix/Trap, SVG Filters, the Transform effect's missing options (#885) | 6–10 | measured count 44/50, depth estimated |
|
||||
| Raster effects (Effect Gallery) | 4 | 48% | 29 Photoshop-style filters (Artistic, Sketch), the Effect Gallery dialog, Load Texture | 24–40 | measured count 28/57; PDF resolution-cap reporting tested, score unchanged |
|
||||
| Raster effects (Effect Gallery) | 4 | 48% | 29 Photoshop-style filters (Artistic, Sketch), the Effect Gallery dialog, Load Texture | 24–40 | measured count 28/57 |
|
||||
| 3D and Materials (and Turntable) | 4 | ~8% | initial live Revolve done (flat shading, one light, no caps, approximate visibility for intersecting surfaces); Extrude & Bevel, Inflate, Rotate, materials, Turntable views, 3D export | 50–85 | estimated (Revolve landed after the first measure, #846) |
|
||||
| Type core | 9 | 80% | hyphenation and justification options, Optical Margin Alignment, Middle Eastern features beyond bidi layout, optional group font-size preservation; transformed character controls fixed (#1034), see [type-parity.md](type-parity.md) | 14–19 | estimated |
|
||||
| Type advanced (CJK, spelling, Touch Type, Retype) | 4 | 50% | CJK vertical composition (ruby, mojikumi), variable font axes, tab leaders, spell check, Touch Type, Retype | 20–28 | estimated |
|
||||
|
|
@ -457,11 +455,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
|||
- **Performance:** 20k shapes + 1k texts render in 27 ms per full-retina frame (7.8 ms zoomed), 7× faster than the first version. The UI thread never blocks. The web build is 7.1 MB gzipped.
|
||||
- **Graphics processor:** the canvas is rasterized on the CPU and the GPU only composites it, so any GPU that can show the window will do. Preferences › Performance › Graphics Processor (`gpuPreference`) is Automatic by default: the power-saving GPU on Windows and macOS (the integrated one on hybrid-graphics laptops, where presenting from the discrete GPU made the window flicker, #306), and the GPU the desktop runs on under Linux, where KWin on an NVIDIA GPU refused frames from a Ryzen's integrated GPU and 0.5.0 crashed at startup (#502). Power Saving and High Performance pick a kind of GPU; `WGPU_POWER_PREF`, `WGPU_ADAPTER_NAME` and `WGPU_BACKEND` override them. The app picks among the adapters that can present to the window (native backends before OpenGL, hardware before software, and on Windows a GPU's DX12 adapter before its Vulkan one: Intel's Vulkan driver made the whole window flicker black, #545), and if the window fails on one while starting up it starts again without it instead of crashing; Help › About, `ui.inspect` and the log name the adapter in use. When the browser drops the page's WebGPU device or WebGL context, the web build writes recovery copies, starts again on new graphics with the same app and uploads its textures again; if it can't, it removes the stale canvas and says to reload, which offers the copies back. The desktop app writes the copies and says to restart (#369). On Windows and Linux the tools' cursors are OS cursors (bitmaps rasterized once per display scale), which the system moves itself: painted into the window, they trailed the pointer by the frames waiting to be shown, and the window now queues one frame instead of two (#444). macOS and the web still paint them (macOS sizes cursor bitmaps in points, eframe has no bitmap cursors on the web). Pens and touch drive the tools as the mouse does, and a tap pressed and lifted within one frame clicks where it tapped (#491); pen pressure reaches the Liquify tools' Use Pressure Pen on Windows, while winit 0.30 reports none on macOS or Linux and egui none on the web. On Linux, see `docs/development.md` for pens under Wayland.
|
||||
- **Tests and robustness:** ~2,840 automated tests: model-based property tests, a junk-parameter sweep over every command, import fuzzing (SVG, PDF, libraries), golden renders, and MCP end-to-end tests over stdio. Shipped code never panics (workspace lints and a rollback safety net; see `docs/development.md`).
|
||||
|
||||
- **PDF raster-effect budget reporting (2026-10-11):** `crates/engine/src/tests_pdfraster.rs`
|
||||
exports actual capped 2400-ppi fill/stroke images and verifies one warning for the original
|
||||
object's id/name at the lowest achieved ppi; a small uncapped export and the existing PDF
|
||||
raster-fidelity suite stay warning-free. The renderer and 64 million pixel cap are unchanged.
|
||||
- **Raster-effect resolution in PDF:** when the 64 million pixel cap on an effect image renders an object's raster effects below the document's raster effects resolution, PDF export warns once per object with the requested and the lowest achieved ppi (`crates/engine/src/tests_pdfraster.rs`).
|
||||
|
||||
## Revision history
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue