Skip to content

LT-22324: add OpenType font feature options#870

Open
johnml1135 wants to merge 4 commits into
mainfrom
LT-22324
Open

LT-22324: add OpenType font feature options#870
johnml1135 wants to merge 4 commits into
mainfrom
LT-22324

Conversation

@johnml1135
Copy link
Copy Markdown
Contributor

@johnml1135 johnml1135 commented May 6, 2026

Summary

This PR contains only the direct OpenType font feature work from LT-22324 after splitting the broader branch into separate reviewable pieces.

Included

  • managed font feature settings model and dialog/UI integration
  • native Uniscribe/OpenType rendering updates
  • direct managed and unmanaged test coverage for font feature behavior
  • OpenSpec docs, research, tasks, manual testing, and evidence for the font-options change

Excluded


This change is Reviewable

Copilot AI review requested due to automatic review settings May 6, 2026 20:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds OpenType font-feature support to FieldWorks’ existing WinForms/Views stack (LT-22324), including a renderer-neutral feature string model, UI integration, native Uniscribe OpenType shaping, and layered test coverage plus OpenSpec/docs artifacts.

Changes:

  • Introduces renderer-neutral tag=value feature parsing/normalization and integrates it into WinForms font-feature UI.
  • Adds native Uniscribe OpenType shaping/placing path driven by run feature strings, plus deterministic native tests using a committed SIL font fixture.
  • Adds managed cache-identity tests and test-only HarfBuzzSharp/SkiaSharp comparison coverage; includes OpenSpec requirements/research/manual evidence docs.

Reviewed changes

Copilot reviewed 33 out of 38 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
openspec/changes/add-opentype-font-features/views-migration-matrix.md Adds a Views subsystem inventory/migration matrix to guide phased migration and feature parity work.
openspec/changes/add-opentype-font-features/tasks.md Documents implementation/task checklist for Phase 1 OpenType features and associated testing.
openspec/changes/add-opentype-font-features/specs/font-feature-settings/spec.md Defines requirements for feature independence from Graphite and renderer-neutral storage/application.
openspec/changes/add-opentype-font-features/specs/architecture/ui-framework/winforms-patterns/spec.md Specifies WinForms composition/localization requirements for feature controls.
openspec/changes/add-opentype-font-features/specs/architecture/ui-framework/views-rendering/spec.md Specifies Views rendering + cache identity requirements around feature strings.
openspec/changes/add-opentype-font-features/specs/architecture/testing/test-strategy/spec.md Defines layered test strategy including visual baselines and cross-renderer comparisons.
openspec/changes/add-opentype-font-features/research.md Captures research notes and external references (Uniscribe OT APIs, HarfBuzz, Skia/Avalonia).
openspec/changes/add-opentype-font-features/proposal.md Summarizes the change scope, goals, and impacted areas for LT-22324.
openspec/changes/add-opentype-font-features/manual-testing.md Records manual WinApp/WinForms MCP evidence steps and screenshots for the UI changes.
openspec/changes/add-opentype-font-features/design.md Documents design decisions (renderer-neutral model, Uniscribe OT, provider UI seam, test tooling).
openspec/changes/add-opentype-font-features/.openspec.yaml Adds OpenSpec metadata for the change set.
Src/views/lib/UniscribeSegment.cpp Adds OT feature parsing and optional ScriptShape/Place OpenType path during shaping/placing.
Src/views/Test/TestViews.vcxproj.filters Adds Charis SIL test font fixture files to VS filters.
Src/views/Test/TestViews.vcxproj Copies Charis SIL font fixture beside TestViews.exe for deterministic native tests.
Src/views/Test/TestUniscribeEngine.h Adds deterministic native tests for OT feature metrics/pixel deltas and state switching.
Src/views/Test/TestData/Fonts/CharisSIL-5.000/README.txt Adds redistributable font README to support deterministic fixture usage.
Src/views/Test/TestData/Fonts/CharisSIL-5.000/OFL.txt Adds SIL OFL license text for the committed test font fixture.
Src/views/Test/RenderEngineTestBase.h Extends TxtSrc to carry szFontVar feature strings into render props for tests.
Src/FwCoreDlgs/FwCoreDlgsTests/FwFontDialogTests.cs Adds test ensuring OpenType features round-trip and normalize through font dialog save.
Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControlsTests/TestFontFeaturesButton.cs Adds tests for renderer-neutral tag emission and normalization behavior in the control.
Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControlsTests/FwFontTabTests.cs Adds style/font-tab tests ensuring OpenType feature strings round-trip and normalize.
Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControlsTests/FwAttributesTests.cs Adds test verifying attributes control returns normalized feature strings and inheritance status.
Src/FwCoreDlgs/FwCoreDlgControls/FontFeaturesButton.cs Refactors button around provider seam; adds OpenType discovery via GDI table parsing; normalizes input.
Src/FwCoreDlgs/FwCoreDlgControls/DefaultFontsControl.resx Updates help text and group label to generic “Font Options” wording.
Src/FwCoreDlgs/FwCoreDlgControls/DefaultFontsControl.cs Decouples UI enablement from Graphite checkbox; wires provider preference and setup flow.
Src/Common/SimpleRootSite/SimpleRootSiteTests/RenderEngineFactoryTests.cs Adds tests for feature normalization propagation and cache identity behavior.
Src/Common/SimpleRootSite/RenderEngineFactory.cs Adds feature strings into renderer cache key and normalizes/copies features into graphics props.
Src/Common/RenderVerification/RenderComparisonTests/RenderComparisonTests.csproj Adds a test-only comparison project with HarfBuzzSharp/SkiaSharp dependencies.
Src/Common/RenderVerification/RenderComparisonTests/HarfBuzzSkiaComparisonTests.cs Adds HarfBuzz shaping-data toggle test and a basic Skia “non-blank render” comparison test.
Src/Common/FwUtils/FwUtilsTests/FontFeatureSettingsTests.cs Adds unit tests for parsing/normalizing renderer-neutral feature strings.
Src/Common/FwUtils/FontFeatureSettings.cs Introduces renderer-neutral parser/normalizer and validity checks for OpenType tags.
Docs/opentype-font-features.md Documents feature-string model, UI usage, renderer boundaries, and export notes.
Directory.Packages.props Adds centralized package versions for HarfBuzzSharp and SkiaSharp (test infrastructure).

Comment thread Src/Common/SimpleRootSite/RenderEngineFactory.cs Outdated
Comment thread Src/views/lib/UniscribeSegment.cpp Outdated
Comment thread Src/FwCoreDlgs/FwCoreDlgControls/FontFeaturesButton.cs
Comment thread Src/FwCoreDlgs/FwCoreDlgControls/FontFeaturesButton.cs
Comment thread Src/FwCoreDlgs/FwCoreDlgControls/FontFeaturesButton.cs
Comment thread Src/views/Test/TestUniscribeEngine.h Outdated
Comment thread Src/FwCoreDlgs/FwCoreDlgControls/DefaultFontsControl.cs Outdated
@johnml1135 johnml1135 changed the base branch from main to 001-render-speedup May 7, 2026 19:29
Base automatically changed from 001-render-speedup to main May 8, 2026 20:01
@johnml1135
Copy link
Copy Markdown
Contributor Author

Validated the Word export changes on this branch.

How it was validated:

  • Added an automated regression in LcmWordGeneratorTests that verifies the Normal Word style picks up the writing-system default font (Charis SIL) and emits the expected OpenType stylistic sets (ss11 and ss12).
  • Added two gated manual artifact tests in LcmWordGeneratorTests:
    • baseline export with no font options
    • export with ss11=1,ss12=1
  • Ran the manual tests locally with FW_RUN_MANUAL_DOCX_EXPORT_TESTS=1, which regenerated:
    • Output/Debug/ManualDocxArtifacts/charis-baseline-no-font-options.docx
    • Output/Debug/ManualDocxArtifacts/charis-ss11-ss12.docx
  • Verified the generated DOCX packages directly by inspecting word/styles.xml:
    • the baseline export has no w14:styleSet entries
    • the feature export contains w14:styleSet ids 11 and 12
  • Also updated the styles part so the saved package carries the required mc / w14 namespace declarations and Ignorable="w14", ensuring the Word typography markup survives serialization.

I do not have Microsoft Word installed on this machine, so the validation here is at the DOCX/package level rather than a final visual check in Word itself. But the exported document now contains the expected WordprocessingML that Word uses for these OpenType stylistic sets.

Add word generation font options

Finish up the docx font updates

Partial fixes

LT-22324: preserve OpenType font features

xWorks: preserve OpenType features in Word export
@johnml1135
Copy link
Copy Markdown
Contributor Author

Follow-up review pass is pushed in db8a0f108.

Addressed in this pass:

  • RenderEngineFactory: default writing-system features now only flow in when the run is actually using <default font>, and numeric legacy Graphite feature strings are preserved instead of being normalized away.
  • FontFeaturesButton: the OpenType menu path no longer routes renderer-neutral tags through GraphiteFontFeatures.ConvertFontFeatureCodesToIds(...); it now converts valid OpenType tags directly in a renderer-neutral helper.
  • DefaultFontsControl: feature discovery refreshes through a single RefreshFeatureContext(...) path instead of double-running SetupFontFeatures().
  • TestUniscribeEngine: fixed the test helper GDI leak by releasing the desktop DC and restoring the original bitmap selection before cleanup.
  • Native UniscribeSegment: also fixed two additional local issues from review/debugging that were not in the Copilot threads: the OpenType path now copies SCRIPT_VISATTR data back into uri.prgsva, and the feature parser now guards against numeric overflow.
  • Export/test follow-ups: CSS now reuses FontFeatureSettings.Parse(...) so it only emits valid OpenType tags, DOCX numbering parts now carry the same mc/w14 compatibility declarations as styles, and RenderComparisonTests is now included in FieldWorks.sln so solution restore/build stays aligned with the traversal build.

Left open intentionally for a later pass:

  • deriving Uniscribe script/langsys tags instead of the current latn / DFLT fallback
  • localizing the OpenType provider Off / On labels
  • caching OpenType feature discovery results across repeated font selections

Validation run on this branch after the new commit:

  • ./test.ps1 -SkipManaged -TestProject TestViews -StartedBy agent
  • ./test.ps1 -SkipNative -TestProject FwCoreDlgControlsTests -StartedBy agent
  • ./test.ps1 -SkipNative -TestProject xWorksTests -StartedBy agent
  • CI: Full local check

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 11, 2026

NUnit Tests

    1 files  ± 0      1 suites  ±0   8m 43s ⏱️ - 2m 48s
4 219 tests +32  4 144 ✅ +28  74 💤 +3  1 ❌ +1 
4 228 runs  +32  4 153 ✅ +28  74 💤 +3  1 ❌ +1 

For more details on these failures, see this check.

Results for commit 79163e3. ± Comparison against base commit 502b832.

♻️ This comment has been updated with latest results.

@johnml1135
Copy link
Copy Markdown
Contributor Author

Final OpenType review cleanup is pushed in 314e7f6bd.

Addressed in this pass:

  • Native OpenType shaping now derives script tags through Uniscribe OpenType itemization/font script APIs and derives language-system tags from the writing-system ICU/SLDR locale via Windows LOCALE_SOPENTYPELANGUAGETAG, with font-language validation/fallbacks.
  • OpenType feature runs now bypass the shared analysis/shape cache paths that are not keyed by locale/tag state, keeping ordinary runs on the existing cache path.
  • OpenType provider labels are resource-backed, including Off/On and the common OpenType feature names.
  • OpenType feature discovery now has a small bounded cache keyed from the selected GDI LOGFONT values.
  • Added native coverage for Serbian Cyrillic locl language-system behavior and managed coverage for the feature discovery cache.

Validation:

  • ./build.ps1 passed.
  • Output/Debug/TestViews.exe -v UniscribeEngine passed 6/6.
  • ./test.ps1 -SkipNative -TestProject FwCoreDlgControlsTests -NoBuild passed 45/45.
  • ./test.ps1 -SkipNative -TestProject RootSiteTests -TestFilter "Name=RenderHarness_CapturesSimpleView_ReturnsValidBitmap" -NoBuild passed 1/1.
  • Full ./test.ps1 ran to completion with 4204 passed, 61 skipped, and 1 failed test: ToneParsInvokerTest.
  • I verified ToneParsInvokerTest also fails in a clean baseline worktree at db8a0f108, so it is not introduced by this pass.
  • CI: Full local check passed: commit-message lint and whitespace check reported no problems.

The three remaining Copilot review threads were replied to and resolved after this push.

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