fix: crop SVG export to the visible canvas - #215
Closed
MiMoHo wants to merge 1 commit into
Closed
Conversation
The raster (PNG/JPG) export goes through MyCanvas.getBitmap(), which draws via onDraw() and therefore bakes in the current pan/zoom (canvas.translate(mPosX, mPosY) + canvas.scale(mScaleFactor, ..., mCenter)). The SVG export, however, wrote each path's raw recorded coordinates with no transform, so a saved SVG reflected the launch-time viewport instead of what was visible, appearing wrongly cropped after the canvas was moved or zoomed. Reproduce the same pan/zoom matrix that onDraw applies and bake it into every exported coordinate, and scale stroke-width by the current scale factor to match the raster output. The SVG structure stays flat so the existing loader round-trips unchanged, and with no pan and scaleFactor==1 the matrix is identity, keeping output byte-identical to before. Closes FossifyOrg#26
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Type of change(s)
What changed and why
The raster (PNG/JPG) export path goes through
MyCanvas.getBitmap(), which draws the canvas viaonDraw()and therefore bakes in the current pan/zoom (canvas.translate(mPosX, mPosY)+canvas.scale(mScaleFactor, mScaleFactor, mCenter)). The output is correctly cropped to what is visible at save time.The SVG export path (
Svg.saveToOutputStream->writeSvg) instead wrote each path's raw recorded coordinates with the viewport width/height and no transform. As a result a saved SVG reflected the launch-time coordinate space rather than the currently visible viewport, so it appeared wrongly cropped after the canvas had been moved or zoomed, exactly as the reporter describes.This change reproduces, in the SVG writer, the same pan/zoom matrix that
onDrawapplies (scale-about-center then translate) and bakes it into every exported coordinate viaMatrix.mapPoints. Stroke widths are multiplied by the current scale factor to match the raster output (wherecanvas.scalealso scales stroke widths). The<path>elements stay direct children of<svg>(flat structure), so the app's ownparseSvgloader is unchanged and re-opening a saved SVG round-trips exactly. The background<rect>is intentionally left untransformed since it fills the whole viewport in both raster and SVG. When there is no pan andscaleFactor == 1, the matrix is identity and the stroke-width multiplier is 1, so the output is byte-identical to before (backward compatible).Tests performed
detekt,lint, unit tests and the build all pass locally (CI-equivalent).Matrixtransform to each drawn action's coordinates that the raster (PNG/JPG) export already uses, so the exported SVG is cropped to the visible/moved canvas instead of the initial bounds.Closes the following issue(s)
Checklist
CHANGELOG.md(if applicable).Coded with Opus 4.8 ultracode.