Repository navigation
fix(render): bound the pixels an SVG layout export embeds - #912
Conversation
Each picture in an SVG export was limited on its own, but the document kept all of them, so a page with many large or stacked map frames could grow without bound. When the pictures together would take more than twice the page's pixel budget, all of them are now drawn at the resolution that fits, as an oversized PNG page is.
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Calculate and apply picture DPI crates/render/src/layout.rs, crates/render/src/svg.rs |
MAX_PIXELS is now crate-visible. layout_svg calculates and passes a shared picture DPI based on visible non-vector area. Tests cover retained DPI for small layouts, reduced DPI for multiple full-page frames, and off-page frames. |
Priority:
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Bug fix
Possibly related issues
- opengeos/RustGIS#682 — The issue describes page-sized map layouts, and this change adjusts picture resolution for SVG exports of those layouts.
Possibly related PRs
- opengeos/RustGIS#839 — This PR introduced the
layout_svgandrender_elementpath that this change updates.
Suggested reviewers: giswqs
Merge Risk: 
Minimal · up to 63a93
-
No new merge-blocking issue was established for this change. The previously published minimum-DPI limitation remains for the owner to consider.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passed -
Finishing Touches
-
🧪 Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
A rabbit checks the page at dawn
Picture pixels gather, then scale down
Small maps keep their chosen light
Large frames fit within the bound
Off-page scenes leave DPI alone
The SVG hops onward, crisp and sound
One shared measure guides the way
Comment @coderabbitai help to get the list of available commands.
| .sum(); | ||
| let k = page_geometry(layout, dpi).2; | ||
| let fit = (2.0 * MAX_PIXELS / (area * k * k)).sqrt(); | ||
| if fit < 1.0 { k * fit / PT_PER_MM * 96.0 } else { dpi } |
There was a problem hiding this comment.
Low-confidence: page_geometry clamps ppp to [0.25, 8.0] (about 24 dpi), so the budget isn't a hard bound. With enough stacked frames, fit asks for a lower dpi than that and the clamp wins. The embedded pixels then exceed 2 * MAX_PIXELS again, and the SVG still grows with the frame count. A cap on the picture count, or a doc note that the bound holds only down to 24 dpi, would make "without bound" accurate. The tests only go to 8 frames, so a test with a very large n would show it.
Code reviewThe change is small and correct. Bugs
Security
Performance
Quality
AGENTS.md
Change sizeCompared: the whole PR against main (merge base c7bf8e1 to PR head 315377f).
|
📖 Docs preview
GitHub Pages takes a minute or two to publish a new commit. |
Code reviewI found no bugs, security issues or guideline violations in this PR. I checked What I checked
Quality (minor, low confidence)
Change sizeCompared: the whole PR against main (merge base c7bf8e1 to PR head 63a93f8)
|
Code reviewI found no bugs, security issues or performance problems in this PR. I read the full diff and checked it against Bugs
Security
Performance
Quality
AGENTS.md
Change sizeCompared: the whole PR against main (merge base c7bf8e1 to PR head 63a93f8).
|
Summary
A follow-up to #839, from the review note on bounding the SVG output. Each picture in an SVG layout export is limited to the page's pixel budget on its own, but the document keeps all of them, so a page with many large or stacked map frames could grow without bound.
layout_svgnow adds up the on-page area of the elements it draws as pictures. When they would take more than twice the page's pixel budget (MAX_PIXELS), all of them are drawn at the resolution that fits, the way an oversized PNG page is drawn at a lower resolution rather than refused. Twice, because legends, scale bars and insets usually sit on a map frame: an ordinary layout keeps the resolution it has now, even on an A0 page already at the limit.Testing
surrounds_on_a_frame_keep_the_picture_resolution: a legend on a frame at 600 dpi, and two frames filling an A0 page at its pixel limit, keep 600 dpistacked_frames_share_the_picture_budget: eight full-page frames on A0 get a lower resolution that uses (and stays within) twice the page's budget; frames moved off the page take nothing from itcargo fmt --all --check,cargo clippy --workspace --all-targets -D warnings(withcollapsible_matchallowed: my clippy 1.95 flags it incrates/ui-egui/src/opendataui.rson main),cargo test -p rustgis-render(188 passed),cargo xtask layerscargo test --workspaceon Windows: 2192 passed, 74 failed, all in fourrustgis-ui-eguiUI test targets (define_projection,measurement_units,menu_checkboxes,smoke); the same 74 fail on main on this machine, and the Linux CI run here is greenRelated issue
Follow-up to #839 (review comment on
crates/render/src/svg.rs, "Bound the total SVG output size")Summary by CodeRabbit