feat(🔤): expose SkFontStyleSet on SkFontMgr#3820
Open
IsaacInsoll wants to merge 1 commit intoShopify:mainfrom
Open
feat(🔤): expose SkFontStyleSet on SkFontMgr#3820IsaacInsoll wants to merge 1 commit intoShopify:mainfrom
IsaacInsoll wants to merge 1 commit intoShopify:mainfrom
Conversation
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.
feat(🔤): expose
SkFontStyleSetonSkFontMgrSummary
Adds JSI bindings for Skia's
SkFontStyleSet, letting JS enumerate the exactvariants a font family ships with. Two new methods on
SkFontMgr:matchFamily(name: string): SkFontStyleSet | nullcreateStyleSet(index: number): SkFontStyleSet | nullAnd a new host object,
SkFontStyleSet, exposing:count()getStyle(index)→FontStyleEntry({ weight, width, slant, name })createTypeface(index)matchStyle(style)dispose()Motivation
matchFamilyStyleis the only JS-side entry point for family lookup today, andit has two limitations:
exist — there is no way to distinguish "Helvetica Bold" from "some other
font's Bold that Skia picked for you".
(weight/width/slant) currently requires bundling the font metadata yourself.
SkFontStyleSetis the native Skia primitive that answers both questions. It'salready returned by
SkFontMgr::matchFamily/SkFontMgr::createStyleSetonboth platforms — this PR just lifts it into JS.
API
FontStyleEntryreuses the existingFontWeight/FontWidth/FontSlantenums via
Required<FontStyle>for type consistency with the rest of the fontAPI.
matchFamilyresolves family aliases ("System"on iOS, etc.) viaRNSkPlatformContext::resolveFontFamily— same behavior asmatchFamilyStyleafter #3603.
Implementation notes
cpp/api/JsiSkFontStyleSet.h. Follows theJsiSkTypefacepattern:EXPORT_JSI_API_TYPENAME,static toValue,getMemoryPressure,getObjectType,disposeinherited from the base.JsiSkFontMgr.hgainscreateStyleSet/matchFamilyas thin wrappers andre-uses
resolveFontFamilyfor alias resolution.index returns
jsi::Value::null()rather than throwing.JsiSkFontStyleSetthat throws "Not implemented on React NativeWeb", parallel to how
matchFamilyStyleis stubbed today. CanvasKit has noFontStyleSetequivalent, so web callers should guard withPlatform.OS.Testing
yarn lint— cleanyarn tsc— cleanyarn test— existing suite passes. No new unit tests yet — see the"Follow-ups" note below.
enumerating a known-multi-variant family (Helvetica on iOS, sans-serif on
Android) and confirming
count(),getStyle(i).name, andcreateTypeface(i)return sensible values.No
yarn e2erun yet either —e2erequires a rendering assertion, andSkFontStyleSetdoesn't draw. Open to suggestions on the right harness forthis; happy to add tests in whatever form you prefer before merge.
Docs
New page:
apps/docs/docs/text/font-style-set.md(included in this PR) withusage examples for
matchFamily,createStyleSet, and a "pick the closestvariant" worked example. Linked from the sidebar under Text.
Checklist
src/skia/types/Font/FontMgr.ts+ generated.d.ts)Notes for reviewers
packages/skia/src/skia/__tests__/seem to target pure JS; I'm not surewhat the preferred way is to cover a JSI host object that wraps native font
data. Pointers welcome.
SkFontStyleSetexpose a[Symbol.iterator]/ convenience helpers inJS (e.g.
getStyles(): FontStyleEntry[])? I kept the surface minimal andSkia-faithful; happy to add an idiomatic JS helper in a follow-up.
getMemoryPressurereturns2048to matchJsiSkFontMgr. A style set istiny; open to tuning this if you have a preferred heuristic.