Fix #186 — honour the §11.4.2 font directives - #202
Merged
Merged
Conversation
Every font directive was reported as unsupported and dropped, so all text was Libertinus Serif at sizes the renderer fixed. Parser - TextFontRole (titlefont … setfont-4) and FontSpec(name?, size?) in the model, carried as CeolKitDirective.font. File header → file-global; tune header and body → tune-global. - `<font name> [<size>]`, a quoted name for families with spaces, and `*` to keep the face in force (abcm2ps). Anything else is reported as .invalidFontDirective and dropped. Renderer - Each tune's text styles are resolved from CeolKit's defaults, then SVGRenderConfig.textFonts (new: a host house style), then file directives, then tune directives, each half of a spec overriding only what it states. Faces resolve through the #190 FontProvider. - With no directive a role has no face and is drawn by the existing code, so documents without font directives are byte-identical (the snapshots confirm it). - Staff text (gchord, annotation, vocal, an inline tempo) scales with %%ceolkit:scale; page text (title, subtitle, composer, info, header tempo, words) is in absolute points. - Layout follows the text: title rows grow past their default size; chord/annotation and lyric bands take their line height and ascent/descent from the style; words lines scale; chord symbols, annotations and syllables are measured in their own face for spacing. - Libertinus Serif Bold and Bold Italic (v7.040, the same release as the bundled Regular/Italic, OFL) are bundled, so bold requests render bold without system fonts. fontFace mode embeds them only when used. - Substitutions are reported once per directive, at the directive: info while system lookup is off, warning when it was searched and nothing answered. The §14.4 Canzonetta sets 32 pt titles and 14 pt lyrics and relies on abcm2ps's %%scale 0.7, which CeolKit doesn't implement, so it now runs to two pages. Its structural checks are now per page, and its snapshot was re-recorded after a visual check. Not done: $1–$4 in-string switches (setfont-n is parsed only); partsfont and textfont have no printed text to style yet. CONFORMANCE.md documents all of this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Fix #186
Decisions (from the discussion on this issue)
%%ceolkit:scale. Page text (title, subtitle, composer, info, header tempo,W:words) is in absolute points.SVGRenderConfig.textFonts: [TextFontRole: FontSpec]sits under the document's directives. For example, "everything default, but composers in Zapf Chancery"; a%%composerfontin the ABC still wins.What changed
Model / parser
TextFontRole(one case per §11.4.2 directive) andFontSpec(name?, size?), carried asCeolKitDirective.font(role, spec).<font name> [<size>], a quoted name, and*to keep the current face (abcm2ps). A size of zero or below, a non-numeric size, extra words after the size, or an unterminated quote produces.invalidFontDirectiveand the directive is dropped.Renderer
TextStyles, layered: defaults, then config, then file directives, then tune directives. A spec overrides only the half (face or size) it states. Faces resolve through Font provider: use host-registered and system fonts instead of bundling more faces #190'sFontProvider.W:lines scale;fontFacemode,<text>gets that face's family plusfont-weight/font-style. The bold@font-facerules are embedded only in documents that use them.FontResolutiondiagnostics are reported once per directive, at the directive's source line.Libertinus-7.040.zip, sha2562cce0850…). Its Regular and Italic are byte-identical to the faces already bundled, so all four come from one build. The existing OFL licence file covers the family. Adds about 0.6 MB.Behaviour change worth knowing
The §14.4 Canzonetta fixture sets
%%titlefont Times-Bold 32,%%vocalfont Times-Roman 14and similar, which are now honoured. It also depends on abcm2ps's%%scale 0.7, which shrinks the whole page and which CeolKit does not implement. The larger lyrics widen the columns, so the tune now breaks into four systems on two pages instead of three on one.Not done (documented in CONFORMANCE.md)
$1–$4font switches inside strings.setfont-nis parsed and scoped only.partsfontandtextfont:P:labels and%%textaren't printed yet.%%fontdeclarations and abcm2ps'sbox/class=arguments.%%scale.Upgrading (for the release notes)
CeolKitFonts.Facehas two new cases,.libertinusSerifBoldand.libertinusSerifBoldItalic. An exhaustiveswitchover it needs updating.register()andinstall(into:)now include them.DiagnosticCode.invalidFontDirective.Tests
FontDirectiveTests(parser):*, fractional sizes;FontSpeclayering.FontDirectiveRenderingTests(11):*keeping the italic default;Times-Bolddrawn in the bundled bold face (libertinusSerifBold-g…);With directive handling disabled, 10 of the 11 fail (the defaults test should, and does, still pass).
Visual: Monsieur de la Miranda (
%%wordsfont Courier-Bold 16) prints its words in Libertinus Serif Bold 16, andckprobereports[info] line 2: Courier-Bold not found; using LibertinusSerif-Bold.swift test: all tests pass on macOS. The Linuxswift:6.3container passes 1,437 tests.🤖 Generated with Claude Code