Repository navigation
Render: a generated widget is clipped to its box (#222) - #225
Merged
Merged
Conversation
The /BBox of an annotation's appearance stream is mapped onto its /Rect, and the border of a field lies on the edge of that box. With the box off the pixels, the exact clip and the border's edge, both antialiased, lightened the edge pixels twice: a field Editor.SetFields wrote was drawn with other edges than the same value shown from a FormState, which is not clipped. The clip of an annotation's appearance is now rounded outward to whole device pixels when it stays on the axes, as PDFium, MuPDF, Poppler and Ghostscript clip rectangles. The accuracy report against PDFium is unchanged. overlayFile puts its fields off the pixels, which the test held them to. Fixes #222.
The first fix of #222 rounded the clip of every annotation's appearance outward to whole pixels. That made the render of an appearance stream differ from the page it is flattened to, whose content clips exactly: the corpus API run reported 41 files of pdf.js whose flattened first page differed, by up to 4.9 % of its pixels. The other way round: the appearance cera generates for a widget is clipped to the widget's box exactly, as the stream Editor.SetFields writes for it and the form Editor.Flatten draws are. The render with a FormState, the saved file and the flattened page are drawn alike at any scale; the border of a field off the pixels is lighter on its outer edge in all three, as the appearance streams of documents are. The corpus API report and the accuracy report against PDFium are the same as on main.
This was referenced Oct 14, 2026
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.
Fixes #222.
Cause
An annotation's appearance stream is drawn with its
/BBoxmapped onto/Rectand clipped to it. The appearance cera generates for a widget (render withRenderOptions.Form) was not clipped, andflatLookgave the flattened form a box one point larger for the same reason. The border of a field lies on the edge of the box: with/Rectoff the pixels the clip and the border's edge are both antialiased, and the edge pixels of the streamSetFieldswrote came out lighter than those of the generated appearance (644 pixels, up to 88 levels in the issue's case).Change
The generated appearance of a widget is clipped to the widget's box exactly (
interp.annotation,ClipRectwith the widget matrix), andflatLookwrites the flattened form with/BBox [0 0 W H]. The render with a state, the saved file and the flattened page are now drawn alike at any scale; at a box off the pixels the outer edge of the border is lighter in all three, as for the appearance streams of documents.Discarded first attempt (first commit)
The first commit rounded the clip of every annotation appearance outward to whole device pixels (as PDFium, MuPDF, Poppler and Ghostscript clip rectangles). The corpus API run then reported 41 files of pdf.js whose flattened first page differs from the render, by up to 4.9 % of the pixels: content flattened into a page cannot be clipped to the pixels of a render. The second commit replaces it; the diff of the PR is only the second approach plus the test.
Tests
overlayFile(formoverlay_test.go) held its fields to pixels because of this bug; three of its four fields are now off the pixels.TestFormOverlayOrderfails without the fix (up to 1471 pixels, by 88) and passes with it.go test ./...green locally.main.main.