Skip to content

Draw a free text border's dash from /BS or /Border - #121

Merged
bobsingor merged 4 commits into
embedpdf/mainfrom
embedpdf/fix/free-text-border-dash
Nov 15, 2026
Merged

bobsingor merged 4 commits into
embedpdf/mainfrom
embedpdf/fix/free-text-border-dash

Conversation

@bobsingor

Copy link
Copy Markdown
Contributor

Stacked on #118. Until #118 merges, this PR also shows its commits. The change here is the last commit, 6bd0043.

The free text generator drew every border solid unless a plain box had a dashed /BS. A callout never dashed, and a plain box ignored a /Border dash array. EPDFAnnot_GetBorderStyle and the viewer's drawing dash both, so the live drawing and the generated appearance disagreed.

Change

  • New GetAnnotBorderStyleInfo (in cpdf_appearancegenerator_common.cpp) reads an annotation's border as ISO 32000-1 12.5.2 does: its /BS, or else its /Border width (default 1) and dash array, drawn as GetBorderWidth and GetDashPatternString take them. An empty dash array draws solid. The plain free text box draws its frame with it, which also replaces Read a free text box's border width from /Border when it has no /BS #118's inline width read.
  • A callout takes GetDashPatternString for its leader, the leader's ending and its box, as a line annotation dashes its line and endings. It then resets the dash ([] 0 d), so the text's underlines, which are stroked, draw solid.

The dash rule itself is unchanged: ISO's, as in #106 (a dashed /BS with no /D draws [3], an empty /D draws solid, a /Border draws its own array, /BS wins).

Tests

  • New unit test CPDFGenerateAPTest.FreeTextBorderDashFromBorderArray: /Border [0 0 2 [4 2]] draws the same stream as /BS << /W 2 /S /D /D [4 2] >>, and /Border [0 0 2 []] draws as a solid /BS << /W 2 >>.
  • New unit test CPDFGenerateAPTest.FreeTextCalloutBorderDash: a dashed /BS sets the dash before the leader and resets it after the box, before the text; the same dash in /Border draws the same stream; a solid callout draws no dash.
  • FreeTextBorderWidthFromBorderArray (Read a free text box's border width from /Border when it has no /BS #118) now shares the new test helpers.
  • macOS arm64: unit suite 1362 passed; embedder suite 1795 tests with the same 12 failures as an unchanged build of the base (Mac golden and progressive-render failures).
  • No pixel or embedder fixture has a dashed free text box, so no golden changes. Rendered by hand with pdfium_test: a /Border dash dashes the frame, an empty dash array draws solid, and a dashed callout dashes its leader, arrowhead and box.

KleiKodesh and others added 4 commits November 10, 2026 08:31
A free text box without /BS took the default 1 pt border even when its
/Border array says 0, so a box PDF.js wrote (/Border [0 0 0], no /AP,
no /RC) got a frame and a text plate inset by 2 pt on every side. Its
rect fits the text as PDF.js measured it, so the text then wrapped and
the second line was clipped away.

- Without /BS, the box's border width is the /Border array's, as the
  callout already reads it.
- A plain box (no /RC) whose border is 0 lays out as PDF.js draws it:
  lines break only at line breaks, text too wide or too tall for the
  box is drawn smaller to fit (CPDF_RichTextLayout::Options::
  shrink_to_fit), and each paragraph reads in its text's direction.
A borderless plain box lays out like every other box: its lines wrap
in the box. Choosing a layout from the border width would stop every
borderless plain box from wrapping, whoever wrote it.

The test now checks the width rule: /Border draws as the same width in
/BS does, frame and text plate alike; 1 pt with neither; /BS first.
The free text generator drew every border solid unless a plain box had
a dashed /BS: a callout never dashed, and a plain box ignored a /Border
dash array. The border reader and the viewer's drawing dash both.

GetAnnotBorderStyleInfo reads an annotation's border as ISO 32000-1
12.5.2 does: its /BS, or else its /Border width and dash array (an
empty one draws solid). The plain box draws its frame with it. A
callout takes GetDashPatternString for its leader, the leader's ending
and its box, as a line annotation dashes its line and endings, then
resets the dash so the text's underlines draw solid.
@bobsingor
bobsingor merged commit c9ee4f0 into embedpdf/main Nov 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants