export: add C ABI wrappers for paragraph measure/split + language-aware font parse#283
Merged
carlos7ags merged 1 commit intomainfrom May 1, 2026
Merged
Conversation
…uage-aware font parse
Surfaces four Go-side additions from v0.8.0 to the C ABI so non-Go
callers can use them without resorting to a CGO bridge of their own.
Paragraph (3 wrappers):
- folio_paragraph_measure_lines(p, max_width) — wraps Paragraph.MeasureLines
- folio_paragraph_measure_height(p, max_width) — wraps Paragraph.MeasureHeight
- folio_paragraph_split_after_line(p, n, max_width, *head, *tail) — wraps
Paragraph.SplitAfterLine. Returns two handles via out-pointers, either
of which may be 0 for the no-op halves (n <= 0 or n >= total). Caller
frees the non-zero handles.
Font (1 wrapper):
- folio_font_parse_for_language(data, length, lang) — wraps
font.ParseFontForLanguage. Pan-CJK TTC face selection by BCP-47 tag
("zh-CN", "ja", etc.). Empty lang falls back to face 0, matching
folio_font_parse_ttf semantics.
The font.Fallback / layout.NewParagraphFallback surface (#225) is
intentionally NOT wrapped here; per its PR description, C ABI exposure
is Phase 2 work tied to promoting *EmbeddedFont to an interface.
Tests: test_cabi.c grows from 397 to 411 assertions covering happy path,
bad handle, NULL out-pointers, n <= 0 / n >= total edge cases, and the
narrow-vs-wide width invariant for measure_lines.
Audit: scripts/audit-cabi.sh reports Go //export = header = built
symbols = 393.
2 tasks
carlos7ags
added a commit
that referenced
this pull request
May 2, 2026
Compiles the v0.7.1..main delta (114 commits, ~40 PRs) into release-ready CHANGELOG entries and updates MIGRATING with the v0.7.x → v0.8.0 upgrade guide. CHANGELOG additions to Unreleased: - Visual changes section: GPOS cursive horizontal placement (#220), CJK paragraphs across page breaks (#246), Unicode NFC normalization at layout entry point (#217) - Changed (breaking): layout.UnitValue no longer comparable with == (#236), in addition to the existing BasePath removal and @font-face resolution change (#85) - Added: font.Fallback (#225), Paragraph.MeasureLines/Height (#238), Paragraph.SplitAfterLine (#253), layout.Anchor + auto-named- destinations (#223), layout.UnitCalc + CalcUnit (#236), Info.Language (#214), PDF/A-3a + PDF/A-4 family (#214), C ABI additions (#214 + #283), CSS :empty / ::placeholder (#215), 8 Indic scripts (#216), GPOS Types 3/5/6 (#218 / #213), body-flow counter(page) (#221), GCPM bookmark properties (#224), the calc shorthand series across 13 properties (#236-#261) - Changed: HTML CSS parser refactored into declarative property registry (#271) - Fixed: GPOS cursive double-counted hmtx + Type 5 3+ component fallback (#220), inline elements + Arabic OriginalText preserved across page splits (#241), font: paren-aware slash detector + column-rule none/hidden zeros width (#270), transform() paren-aware arg extractor (#272), parseAngle/parseNumericVal/parseLineHeight understand calc/min/max/clamp (#274 / #275 / #284), margin auto-flag detector aligned (#263) - Deprecated reminder: the four core direct-field accesses from v0.7.0 carry forward to v0.8.0; removal target stays v1.0 - Tests: hyphenation contract guard (#250) - Documentation: docs/CSS_SUPPORT.md introduced (#271/#273) and extended with Selectors / At-rules / Functions sections (#162/#282) MIGRATING additions for v0.7.x → v0.8.0: - C ABI surface grew from 388 to 393 (+5): folio_document_set_language, FOLIO_PDFA_3A/4/4F/4E (#214), folio_paragraph_measure_lines / measure_height / split_after_line (#283), folio_font_parse_for_language (#283) - layout.UnitValue compile-error break for == comparisons - Visual-change checklist for regression-diffing PDFs - Asset-resolution side-effects from #229 (URLPolicy uniformity, absolute system font path with BaseFS=nil, FallbackFontPath programmatic-only carve-out)
carlos7ags
added a commit
that referenced
this pull request
May 2, 2026
CHANGELOG additions to Unreleased: - Visual changes: <th> behavioural shift from #288 — explicit text-align: left on <th> is now preserved instead of being silently re-centered by the table-cell default heuristic. - Added: text-align: start | end with direction-relative late binding (#288); text-decoration-line: overline (#289); CSS border styles groove/ridge/inset/outset rendered with per-side dark/light modulation (#290). MIGRATING additions to the v0.7.x → v0.8.0 Visual changes section: - <th> default-center heuristic shift (mirror of CHANGELOG entry, framed for upgraders auditing PDF diffs). - border 3D styles now render the bevel — documents that used ridge/groove/inset/outset will see colored modulation instead of a flat solid line. The text-align: start/end addition itself is in CHANGELOG Added but intentionally omitted from MIGRATING Visual changes — the new keywords were rejected pre-fix, so any document that relied on the keyword is opting INTO the new behaviour rather than seeing an existing render shift. text-decoration overline is similarly omitted from MIGRATING — the keyword was silently dropped pre-fix, so adding a visible overline is an opt-in. Three PRs (#283 C ABI, #284 calc fixes, #287 numeric font-weight) are already entered. v0.8.0 is now release-note ready once #285 itself merges.
carlos7ags
added a commit
that referenced
this pull request
May 3, 2026
Compiles the v0.7.1..main delta (114 commits, ~40 PRs) into release-ready CHANGELOG entries and updates MIGRATING with the v0.7.x → v0.8.0 upgrade guide. CHANGELOG additions to Unreleased: - Visual changes section: GPOS cursive horizontal placement (#220), CJK paragraphs across page breaks (#246), Unicode NFC normalization at layout entry point (#217) - Changed (breaking): layout.UnitValue no longer comparable with == (#236), in addition to the existing BasePath removal and @font-face resolution change (#85) - Added: font.Fallback (#225), Paragraph.MeasureLines/Height (#238), Paragraph.SplitAfterLine (#253), layout.Anchor + auto-named- destinations (#223), layout.UnitCalc + CalcUnit (#236), Info.Language (#214), PDF/A-3a + PDF/A-4 family (#214), C ABI additions (#214 + #283), CSS :empty / ::placeholder (#215), 8 Indic scripts (#216), GPOS Types 3/5/6 (#218 / #213), body-flow counter(page) (#221), GCPM bookmark properties (#224), the calc shorthand series across 13 properties (#236-#261) - Changed: HTML CSS parser refactored into declarative property registry (#271) - Fixed: GPOS cursive double-counted hmtx + Type 5 3+ component fallback (#220), inline elements + Arabic OriginalText preserved across page splits (#241), font: paren-aware slash detector + column-rule none/hidden zeros width (#270), transform() paren-aware arg extractor (#272), parseAngle/parseNumericVal/parseLineHeight understand calc/min/max/clamp (#274 / #275 / #284), margin auto-flag detector aligned (#263) - Deprecated reminder: the four core direct-field accesses from v0.7.0 carry forward to v0.8.0; removal target stays v1.0 - Tests: hyphenation contract guard (#250) - Documentation: docs/CSS_SUPPORT.md introduced (#271/#273) and extended with Selectors / At-rules / Functions sections (#162/#282) MIGRATING additions for v0.7.x → v0.8.0: - C ABI surface grew from 388 to 393 (+5): folio_document_set_language, FOLIO_PDFA_3A/4/4F/4E (#214), folio_paragraph_measure_lines / measure_height / split_after_line (#283), folio_font_parse_for_language (#283) - layout.UnitValue compile-error break for == comparisons - Visual-change checklist for regression-diffing PDFs - Asset-resolution side-effects from #229 (URLPolicy uniformity, absolute system font path with BaseFS=nil, FallbackFontPath programmatic-only carve-out)
carlos7ags
added a commit
that referenced
this pull request
May 3, 2026
CHANGELOG additions to Unreleased: - Visual changes: <th> behavioural shift from #288 — explicit text-align: left on <th> is now preserved instead of being silently re-centered by the table-cell default heuristic. - Added: text-align: start | end with direction-relative late binding (#288); text-decoration-line: overline (#289); CSS border styles groove/ridge/inset/outset rendered with per-side dark/light modulation (#290). MIGRATING additions to the v0.7.x → v0.8.0 Visual changes section: - <th> default-center heuristic shift (mirror of CHANGELOG entry, framed for upgraders auditing PDF diffs). - border 3D styles now render the bevel — documents that used ridge/groove/inset/outset will see colored modulation instead of a flat solid line. The text-align: start/end addition itself is in CHANGELOG Added but intentionally omitted from MIGRATING Visual changes — the new keywords were rejected pre-fix, so any document that relied on the keyword is opting INTO the new behaviour rather than seeing an existing render shift. text-decoration overline is similarly omitted from MIGRATING — the keyword was silently dropped pre-fix, so adding a visible overline is an opt-in. Three PRs (#283 C ABI, #284 calc fixes, #287 numeric font-weight) are already entered. v0.8.0 is now release-note ready once #285 itself merges.
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.
Summary
Surfaces four v0.8.0 Go-side additions to the C ABI so non-Go callers (Python, Node, Rust, etc.) get the same surface area without each having to write their own CGO bridge.
folio_paragraph_measure_lines(p, max_width)layout.Paragraph.MeasureLinesfolio_paragraph_measure_height(p, max_width)layout.Paragraph.MeasureHeightfolio_paragraph_split_after_line(p, n, max_width, *head, *tail)layout.Paragraph.SplitAfterLinefolio_font_parse_for_language(data, length, lang)font.ParseFontForLanguageOut of scope
font.Fallback/layout.NewParagraphFallback(#225) is intentionally NOT wrapped here. Per its PR description, C ABI exposure is Phase 2 work tied to promoting*EmbeddedFontto an interface soFallbackbecomes a drop-in replacement at every existing call site (heading, link, list, tab, table cell, page-level text, C ABI). Wiring the C ABI to the Phase-1*EmbeddedFont-only constructor and then refactoring it again in Phase 2 would create churn for downstream consumers.html.Options.Logger(*slog.Logger),Options.Client(*http.Client), andOptions.StrictAssetsare Go-specific by nature —slogand*http.Clientdon't have portable C equivalents. Adding a C-flavoured logging callback / HTTP transport surface is its own design pass, deferred.API design notes
split_after_line: returns two handles via out-pointers. Either may be 0 for the no-op halves:n <= 0returns(0, full clone);n >= total linesreturns(full clone, 0). The receiver is unchanged. Caller frees non-zero handles viafolio_paragraph_free.out_headandout_tailthemselves must be non-NULL — the wrapper returnserrInvalidHandleif either is missing rather than crashing.measure_linesreturnsint32_t:-1on bad handle. Callers should checkfolio_last_errorfor the message.measure_heightreturnsdouble:-1.0on bad handle (negative height is impossible for a real paragraph).font_parse_for_languageaccepts NULLlang: treated as empty string, whichfont.ParseFontForLanguagehandles by falling back to face 0 (matchingfolio_font_parse_ttfsemantics for non-TTC inputs).Tests
test_cabi.cgrows from 397 to 411 assertions (+14 new), covering:measure_lineshappy path (narrow vs wide width invariant), bad handlemeasure_heighthappy path, bad handlesplit_after_linen=2 success path with head/tail line-count assertionssplit_after_lineedge cases: n=0 (head=0, tail=full), n=large (head=full, tail=0)split_after_linebad handle, NULLout_head, NULLout_tailfont_parse_for_languageNULL data rejection (round-trip with real TTC is covered by Go-side tests infont/load_test.go)Audit
scripts/audit-cabi.sh --buildreports://exportdirectives: 393All three in sync.
Test plan
go vet ./export/...— cleanmake test-cabi— 411 passed, 0 failedscripts/audit-cabi.sh --build— clean