Add color font palette support to C API#197
Merged
Merged
Conversation
Expose SkTypeface variable font functionality through the C API: - sk_typeface_get_variation_design_position: query current axis coordinates - sk_typeface_get_variation_design_parameters: query axis metadata (tag, min, default, max, hidden) - sk_typeface_clone_with_arguments: create typeface clone with specific variation coordinates Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace reinterpret_cast between C and C++ structs with field-by-field copy. The structs have identical layout so the cast worked in practice, but accessing memory through an unrelated type is undefined behavior per the C++ standard. Compilers optimize the copy loop to the same code. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add sk_fourbytetag_t typedef (uint32_t) matching SkFourByteTag - Use sk_fourbytetag_t in variation axis/coordinate C structs - Add AsVariationPositionCoordinate/ToVariationPositionCoordinate for layout-compatible Coordinate struct (verified by static_assert) - Add ToVariationAxis for Axis conversion (handles isHidden() getter) - Add AsSkFontArguments helper for clone_with_arguments - Simplify sk_typeface.cpp: remove manual copy loops, use reinterpret_cast for coordinates, use helpers for parameters and font arguments Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace manual reinterpret_cast functions with DEF_MAP macro for VariationPosition::Coordinate (generates As*/To* automatically) - Move static_assert to sk_structs.cpp following existing pattern - Use AsVariationPositionCoordinate() in sk_typeface.cpp instead of inline reinterpret_cast Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add sk_fontarguments_palette_override_t struct - Extend sk_typeface_clone_with_arguments with palette parameters - Add DEF_MAP for Palette::Override (layout-compatible) - Add static_assert for Palette::Override size check - Update AsSkFontArguments to pass palette through Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace manual reinterpret_cast functions with DEF_MAP macro for VariationPosition::Coordinate (generates As*/To* automatically) - Move static_assert to sk_structs.cpp following existing pattern - Use AsVariationPositionCoordinate() in sk_typeface.cpp instead of inline reinterpret_cast Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The generator reads harfbuzz headers to produce HarfBuzzApi.generated.cs. It needs the 2.8.2 headers (63e15eac) not the build-time version. The build-time harfbuzz version is controlled separately by the native build. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This reverts commit 4ae600d.
…-enhancements # Conflicts: # include/c/sk_typeface.h # src/c/sk_structs.cpp # src/c/sk_typeface.cpp # src/c/sk_types_priv.h
There was a problem hiding this comment.
Pull request overview
This PR extends the Skia C typeface/variable-font API to support OpenType color palettes by introducing a palette override struct and plumbing palette selection/overrides through the typeface cloning API.
Changes:
- Added
sk_fontarguments_palette_override_tto represent CPAL entry overrides (index + color). - Extended
sk_typeface_clone_with_argumentsto accept palette index and override list/count. - Added C↔C++ struct mapping and ABI size static-asserts for the new palette override type.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/c/sk_types_priv.h |
Adds DEF_MAP for SkFontArguments::Palette::Override and extends AsSkFontArguments to set palette arguments. |
src/c/sk_typeface.cpp |
Updates sk_typeface_clone_with_arguments implementation to pass palette args into SkTypeface::makeClone. |
src/c/sk_structs.cpp |
Adds static_assert to ensure C/C++ palette override struct sizes match. |
include/c/sk_typeface.h |
Introduces sk_fontarguments_palette_override_t and extends the public C API function signature for cloning with arguments. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
mattleibow
marked this pull request as ready for review
April 26, 2026 16:21
mattleibow
added a commit
to mono/SkiaSharp
that referenced
this pull request
Apr 26, 2026
…3742) Add color font palette support and improve variable font robustness (#3742) Requires: mono/skia#197 Extends the variable font support merged in #3703 with color font palette APIs, Span method robustness fixes, and a pre-existing bug fix. ~~ Color font palette support ~~ SkiaSharp: * SKTypeface.Clone(int paletteIndex) — clone with a built-in palette * SKTypeface.Clone(SKFontArguments) — clone with palette index, per-color overrides, variation position, and collection index * SKFontArguments ref struct gains PaletteIndex and PaletteOverrides * SKFontPaletteOverride struct for individual color entry overrides HarfBuzzSharp: * Face.HasPalettes, PaletteCount — query color font support * Face.GetPaletteColors (array + Span) — retrieve palette entries * Face.GetPaletteFlags, GetPaletteNameId, GetPaletteColorNameId * Face.HasColorLayers, HasColorPng, HasColorSvg C API (mono/skia#197): * sk_fontarguments_palette_override_t struct * sk_typeface_clone_with_arguments extended with palette parameters * DEF_MAP + static_assert for Palette::Override ~~ Span method robustness ~~ Skia's getVariationDesignParameters/Position use all-or-nothing semantics: if the buffer is undersized, they return the total count but write nothing. The C# Span methods now detect this and retry with a pooled buffer (ArrayPool), copying what fits. Empty spans return 0 immediately without native calls or allocations. Font.GetVariationCoordsNormalized(Span) fixed to return the written count instead of the total length when the buffer is undersized. ~~ Bug fix ~~ SKTypeface.ContainsGlyphs(ReadOnlySpan<byte>, SKTextEncoding) had a pre-existing infinite recursion (called itself instead of GetFont().ContainsGlyphs) causing StackOverflowException. ~~ Test coverage ~~ Every Span API tested across empty, undersized, exact, and oversized buffers with exact assertions. Palette APIs tested for colors, flags, name IDs, different palettes, and negative index validation. Added InterVariable.ttf (multi-axis) and test_glyphs-COLRv1.ttf (3 palettes) as test fonts. Gallery sample demonstrates Nabla (COLRv1, 7 palettes, variable axes) with palette picker and weight/optical size sliders. Co-authored-by: Ramez Gerges <ramezragaa@proton.me> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.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.
Summary
Extends the variable font C API (merged in #185) with color palette support, enabling SkiaSharp to clone typefaces with specific palette selections and per-color overrides for COLRv1/COLR fonts.
Companion PR: mono/SkiaSharp#3742
Changes
New struct
sk_fontarguments_palette_override_t— maps toSkFontArguments::Palette::Overridewithindex(uint16_t) andcolor(sk_color_t) fieldsExtended function
sk_typeface_clone_with_arguments— extended from 4 to 7 parameters:paletteIndex— select a built-in palette by indexpaletteOverrides— pointer to array of color overridespaletteOverrideCount— number of overridesType mapping (sk_types_priv.h)
DEF_MAP(SkFontArguments::Palette::Override, sk_fontarguments_palette_override_t, PaletteOverride)— layout-compatible, usesreinterpret_castAsSkFontArgumentshelper updated to callsetPalette()with the new parametersABI verification (sk_structs.cpp)
static_assertforsk_fontarguments_palette_override_tsize matchingSkFontArguments::Palette::OverrideFiles changed
include/c/sk_typeface.hsrc/c/sk_typeface.cppsrc/c/sk_types_priv.hsrc/c/sk_structs.cpp