Synthesize /Square annotation appearances - #6
Closed
sebgoubier wants to merge 1 commit into
Closed
sebgoubier wants to merge 1 commit into
sebgoubier wants to merge 1 commit into
Conversation
A visible /Square without /AP failed the whole page, even when the correct appearance for it is the empty one. The annotation found in a real drawing declares /Border [0 0 0] with no /C, /IC or /CA: a zero-width border and no interior colour, which paints nothing at all. The synthesizer already had both the mechanism and the precedent. A zero-width /Link border returns null, documented there as explicitly non-painting rather than an unsupported visible annotation. /Square now follows the same rule, so the registry policy stated on resolveAnnotationAppearance is untouched: hidden annotations return null, visible unsupported ones still fail. The synthesis follows ISO 32000-1 12.5.6.8. The path is /Rect inset by half the border width, since the border straddles it. /C strokes it and falls back to black exactly as /Link does; /IC fills it and has no default, so an absent /IC simply leaves the square unfilled. The operator is B, f or S depending on which colour paints. /CA 0 returns null and a translucent square raises the same typed error a translucent Link border does. One deliberate reading: an empty /C is transparent, as the existing /Link tests already assert, but the declared border width still places the path. Colour decides what is painted, width decides where the path runs, so a transparent border over an interior colour fills the inset rectangle rather than the whole /Rect. The test states this. Three helpers became subtype-neutral rather than duplicated: readAnnotationColor, readAnnotationBorderStyle and readAnnotationGeometry. /Link keeps its exact diagnostics through the label argument. Refs soadzoor#2 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Owner
|
I cherrypicked your changes, but extended them with support for |
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.
What this fixes
The
/Squareitem of #2:Visible /Square annotation 0 has no usable normal appearance; native synthesis is not implemented.The annotation that triggers it, probed from a real drawing, is:
A zero-width border with no interior colour. It paints nothing — and it takes the whole page down with it. That is what makes this worth fixing rather than tolerating: the correct appearance for this annotation is the empty one.
nativeAppearanceSynthesis.tsalready had the mechanism and the precedent./Linkreturnsnullfor a zero-width border, documented there as "explicitly non-painting… not an unsupported visible annotation"./Squarenow follows the same rule, so the registry's policy — hidden annotations return null, visible unsupported ones fail — is untouched.What the synthesis does
ISO 32000-1 12.5.6.8, matching what existing processors draw:
/Rectinset by half the border width (the border straddles the path)/Cstrokes it, falling back to black when absent, exactly as/Linkalready does/ICfills it; unlike/Cit has no default, so an absent/ICsimply leaves the square unfilledB,forSdepending on which of the two colours paints/CA0 returnsnull; a translucent square raises the same typed "not yet synthesizable" error that a translucent Link border doesnullOne deliberate call worth flagging: an empty
/Cis transparent (as the existing/Linktests already assert), but the declared border width still positions the path. Colour decides what is painted, width decides where the path runs — so a transparent border with an interior colour fills the inset rectangle, not the full/Rect. The test states this explicitly.Three helpers became subtype-neutral so
/Squarecould reuse them rather than duplicate their validation:readAnnotationColor(key, missing, label),readAnnotationBorderStyle(annotation, label, signal)andreadAnnotationGeometry(annotation, label)./Linkkeeps its exact diagnostics through the label argument.Tests
testSquareAppearanceSynthesiscovers six squares in one fixture page: the non-painting one from the real file, a/C-less black border, an interior colour with a zero-width border, border plus interior, a transparent/Cwith an interior, and/CA 0. Each asserts the emitted content stream, so the inset arithmetic and the choice ofB/f/Sare pinned, not just the absence of a throw.All six fail on
mainwith the production error.Checks
npm run test:file -- scripts/test-native-appearance-synthesis.mjs— passes,/Linkand/Widgetcases includednpm test—tsc --noEmitclean, 36 / 37 fast files passnpm run test:integration— 41 / 41npm run test:unit— 66 / 68node PDFtoHEP.jsThe two failing files (
test-text-lod-core.mjs,test-room-segment-extractor.mjs) also fail onmainwithout this change; they are Windows-only path failures (/C:/dev/...resolving toC:\C:\dev\...), unrelated here.Scope
/Squareonly./Circleis its twin in 12.5.6.8 and would reuse all of this plus theellipsePathhelper already in the file — happy to add it here or in a follow-up, whichever you prefer. Independent of #4 and #5.Refs #2