Skip to content

Update HarfBuzzSharp binding#3490

Draft
mattleibow wants to merge 19 commits intomainfrom
dev/harfbuzz-binding-update
Draft

Update HarfBuzzSharp binding#3490
mattleibow wants to merge 19 commits intomainfrom
dev/harfbuzz-binding-update

Conversation

@mattleibow
Copy link
Contributor

This pull request adds several new features and APIs to the HarfBuzzSharp binding, primarily to improve support for OpenType font features, language matching, and variable font manipulation. It also introduces additional font property controls and minor documentation improvements for SkiaSharp resource and Skottie bindings.

Key enhancements and new APIs:

OpenType and Font Feature Support:

  • Added the OpenTypeLayoutTableTag enum and OpenTypeFeatureNameIds struct to represent OpenType layout tables and feature name metadata, respectively.
  • Face class: Added methods to retrieve OpenType name table entries, script tags, feature tags, and feature name IDs, including GetName, TryGetName, GetAllNameEntries, GetOpenTypeLayoutScriptTags, GetOpenTypeLayoutFeatureTags, and TryGetOpenTypeLayoutFeatureNameIds.

Font Variable and Synthetic Properties:

  • Font class: Added APIs to get/set pixels-per-em (GetPpem, SetPpem), point size (Ptem), synthetic slant (SyntheticSlant), synthetic bold (SetSyntheticBold, GetSyntheticBold), variation axes (SetVariation, SetVariations), and named instance selection (NamedInstance).

Buffer and Language Enhancements:

  • Buffer class: Added CreateSimilar method to create a new buffer with the same settings as an existing one.
  • Language class: Added a Matches method to check if one language matches another, considering language subtags.

Documentation and Generated Code Updates:

  • Updated comments in SkiaSharp Resources and Skottie generated bindings for better consistency with C pointer types (no functional changes). [1] [2] [3] [4] [5] [6] [7] [8] [9]

These changes significantly enhance the HarfBuzzSharp API's ability to work with advanced font features and variable fonts, making it easier to access and manipulate font metadata and shaping properties.

- Add comprehensive binding-generation.md documenting all config options
- Add harfbuzz-binding-migration-plan.md with detailed migration steps
- Add migration log and state files for progress tracking
- Documentation validated against actual generator code by 5 AI models
New APIs added:
- hb_set_invert (undeprecated in 2.9.0)

No configuration changes needed.
New APIs added (3.0.0 - 3.4.0):
- hb_buffer_create_similar
- hb_buffer_get_not_found_glyph / hb_buffer_set_not_found_glyph
- hb_font_get_synthetic_slant / hb_font_set_synthetic_slant
- hb_font_get_var_coords_design
- hb_ot_math_get_glyph_kernings
- hb_segment_properties_overlay
- hb_style_get_value

New types:
- StyleTag enum
- OpenTypeMathKernEntry struct

New enum members:
- BufferFlags.Verify
- GlyphFlags.UnsafeToConcat (GlyphFlags.Defined changed from 1 to 3)

Config changes:
- Added hb_style_tag_t member exclusion for _HB_STYLE_TAG_MAX_VALUE
New APIs added (4.0.0 - 4.4.1):
- Draw API: hb_draw_funcs_*, drawing callbacks for glyph outlines
- hb_font_changed, hb_font_get_serial
- hb_set_hash, hb_set_add_sorted_array, hb_set_next_many
- hb_map_copy, hb_map_hash, hb_map_is_equal
- hb_ot_layout_script_get_language_tags improvements
- New baseline and metrics APIs

New types:
- DrawState struct
- DrawFuncs handle type

New enum members:
- BufferFlags: Produce*, Defined
- SerializeFlag: Defined

Config changes:
- Added generateProxy: false for draw callback types:
  hb_draw_close_path_func_t, hb_draw_cubic_to_func_t,
  hb_draw_line_to_func_t, hb_draw_move_to_func_t,
  hb_draw_quadratic_to_func_t, hb_font_get_glyph_shape_func_t

Skipped APIs (require custom implementation):
- Draw callbacks require manual proxy implementation
New APIs added (5.0.0 - 5.3.1):
- hb_language_matches
- hb_ot_layout_lookup_get_optical_bound
- hb_face_builder_sort_tables

No configuration changes needed.
New APIs:
- Many glyph iteration and name APIs
- Buffer validation APIs
- Face/font name and family APIs
- Paint API (hb_font_paint_glyph_func_t, etc.)

Excluded (complex callbacks with struct-embedded function pointers):
- hb_paint_* namespace (Paint funcs with ColorLine callback struct)
- hb_color_line_* namespace (callback struct with function pointer fields)

These are excluded via namespace exclude feature for clean compilation.
New APIs (since 7.3.0):
- hb_ot_layout_get_baseline2
- hb_ot_layout_get_baseline_with_fallback2
- hb_ot_layout_get_font_extents
- hb_ot_layout_get_font_extents2
- hb_ot_layout_collect_features_map
- HB_CODEPOINT_INVALID constant

Note: Using 8.3.0 instead of 8.3.1 due to libclang parsing issue
with inttypes.h header change in 8.3.1. The API is identical.

Removed (deprecated in earlier versions):
- hb_font_funcs_set_glyph_shape_func (use hb_font_funcs_set_draw_glyph_func)
- hb_font_get_glyph_shape (use hb_font_draw_glyph)
New C# API wrappers:
- Language.Matches(Language specific) - checks if language matches (prefix match)
- Buffer.CreateSimilar(Buffer source) - creates buffer with same settings
- Font.SyntheticSlant - get/set synthetic slant for oblique fonts

New test file:
- HBNewApiTest.cs with tests for new APIs

Documentation:
- Updated harfbuzz-migration-log.md with progress
- Created harfbuzz-skipped-apis.md documenting excluded APIs
All phases complete:
- Phase 1: Documentation Creation ✅
- Phase 2: Documentation Review ✅
- Phase 3: Baseline Verification ✅
- Phase 4: Version Bumps (2.8.2 → 8.3.0) ✅
- Phase 5: Skipped API Documentation ✅
New Font APIs:
- SetVariations(Variation[]) - set multiple axes at once
- SetVariations(ReadOnlySpan<Variation>) - span overload
- SetVariation(uint tag, float value) - set single axis by tag
- SetVariation(string tag, float value) - set single axis by name
- SetSyntheticBold/GetSyntheticBold - synthetic emboldening
- NamedInstance property - get/set named instance index

This addresses issue #2397 which has 39 upvotes requesting
variable font support (hb_font_set_variations).

New tests added:
- Font synthetic bold (2 tests)
- Font variations (6 tests)
- Font named instance (2 tests)
- Variation struct (2 tests)
- Tag struct (3 tests)

Total HarfBuzz tests: 130 (was 115)

Also added nuget.org to nuget.config for future package updates.
- Moved Language tests to HBCommonTest.cs
- Moved Tag tests to HBCommonTest.cs
- Moved Variation tests to HBCommonTest.cs
- Moved Buffer.CreateSimilar tests to HBBufferTest.cs
- Moved Font tests (SyntheticSlant, SyntheticBold, Variations, NamedInstance) to HBFontTest.cs
- Deleted HBNewApiTest.cs

All 130 HarfBuzz tests pass.
Added methods to retrieve font name strings from the OpenType 'name' table:
- Face.GetName(OpenTypeNameId) - returns empty string if not found
- Face.GetName(OpenTypeNameId, Language) - with language parameter
- Face.TryGetName(OpenTypeNameId, out string) - returns false if not found
- Face.TryGetName(OpenTypeNameId, Language, out string) - with language parameter

Added 9 new tests for Face name retrieval.
All 130 HarfBuzz tests pass.
Added to summary:
- Face.GetName/TryGetName APIs
- Font.SetVariations/SetVariation APIs
- Font.SetSyntheticBold/GetSyntheticBold APIs
- Font.NamedInstance property
- Test count updated to 130
Font APIs:
- GetPpem(out int, out int) / SetPpem(int, int) - pixels per em
- Ptem property - point size for optical sizing

Face APIs:
- GetAllNameEntries() - enumerate all name table entries
- GetOpenTypeLayoutScriptTags(tableTag) - scripts in GSUB/GPOS
- GetOpenTypeLayoutFeatureTags(tableTag) - features in GSUB/GPOS
- TryGetOpenTypeLayoutFeatureNameIds() - feature names for UI

New types:
- OpenTypeLayoutTableTag enum (Gsub, Gpos)
- OpenTypeFeatureNameIds struct

Added 25 new tests, fixed Buffer.CreateSimilar test expectations.
All 155 HarfBuzz tests pass.
- Upgrade CppAst NuGet package from 0.13.0 to 0.24.0
- Add cross-platform system include path detection:
  - macOS: SDK include path for inttypes.h resolution
  - Linux: /usr/include and /usr/local/include
  - Windows: Windows Kits ucrt path
- Fix type normalization for CppAst 0.24+ output:
  - Handle trailing 'const' in type names
  - Normalize pointer spacing ('hb_blob_t *' → 'hb_blob_t*')
- Update type mappings for proper resolution:
  - 'unsigned char' → Byte (was void)
  - 'signed char' → SByte (was void)
  - Add 'unsigned long long' → UInt64
  - Add 'signed long long' → Int64
- Add libSkiaSharp.json mapping for sk_stream_move 'long' parameter
  to maintain Int32 for cross-platform ABI compatibility

This enables parsing HarfBuzz 8.3.1+ which uses inttypes.h instead of stdint.h.
- Update harfbuzz-skipped-apis.md to reflect resolved parsing issue
- Add CppAst 0.24.0 documentation to binding-generation.md:
  - Cross-platform system include path configuration
  - Type resolution changes and mappings
  - Pointer spacing normalization
  - Const qualifier handling
@mattleibow mattleibow added the copilot Created by GitHub Copilot label Feb 2, 2026
mattleibow added a commit that referenced this pull request Feb 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

copilot Created by GitHub Copilot

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant