From f0893cf72ff0dfbd61b1fc28526420c6c20557d3 Mon Sep 17 00:00:00 2001 From: Finn Pauls Date: Wed, 5 Apr 2023 06:16:15 -0700 Subject: [PATCH] Support font-variant-ligatures values (#36740) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: The text style prop `fontVariant` in React Native is supposed to map to the CSS `font-variant` property. The CSS property is a short-hand for the following CSS properties: - [font-variant-alternates](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-alternates) - [font-variant-caps](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-caps) - [font-variant-east-asian](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-east-asian) - [font-variant-emoji](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-emoji) - [font-variant-ligatures](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-ligatures) 👈 - [font-variant-numeric](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-numeric) - [font-variant-position](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-position) Currently React Native only supports a subset of the values from `font-variant-numeric` and `font-variant-caps`. This change increases the `font-variant` support by adding all values from `font-variant-ligatures`. ## Changelog: [iOS] [Added] - Add all fontVariant values for font-variant-ligatures [Android] [Added] - Add all fontVariant values for font-variant-ligatures Pull Request resolved: https://github.com/facebook/react-native/pull/36740 Test Plan: See https://github.com/facebook/react-native/pull/36740#issuecomment-1492546631 ## Resources - [Apple True Type Reference](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html) - [Webkit Source Code](https://opensource.apple.com/source/WebCore/WebCore-7602.1.50.1.1/platform/graphics/cocoa/FontCacheCoreText.cpp) - [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-ligatures) - [Android TextView Documentation](https://developer.android.com/reference/android/widget/TextView#setFontFeatureSettings(java.lang.String)) Reviewed By: cipolleschi Differential Revision: D44705513 Pulled By: cortinico fbshipit-source-id: 1cde5fcc23ba99fd2f98fa73d934c8e51b0d292e --- .../Libraries/StyleSheet/StyleSheetTypes.d.ts | 10 +++++- .../Libraries/StyleSheet/StyleSheetTypes.js | 8 +++++ packages/react-native/React/Views/RCTFont.mm | 32 +++++++++++++++++++ .../react/views/text/ReactTypefaceUtils.java | 26 +++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts index 300877f65e8271..df6b5c4afdaf86 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts @@ -292,7 +292,15 @@ export type FontVariant = | 'oldstyle-nums' | 'lining-nums' | 'tabular-nums' - | 'proportional-nums'; + | 'proportional-nums' + | 'common-ligatures' + | 'no-common-ligatures' + | 'discretionary-ligatures' + | 'no-discretionary-ligatures' + | 'historical-ligatures' + | 'no-historical-ligatures' + | 'contextual' + | 'no-contextual'; export interface TextStyleIOS extends ViewStyle { fontVariant?: FontVariant[] | undefined; textDecorationColor?: ColorValue | undefined; diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js index 5d9b56c3f4ea6c..405f9e101659d2 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js @@ -788,6 +788,14 @@ export type ____FontVariantArray_Internal = $ReadOnlyArray< | 'oldstyle-nums' | 'lining-nums' | 'tabular-nums' + | 'common-ligatures' + | 'no-common-ligatures' + | 'discretionary-ligatures' + | 'no-discretionary-ligatures' + | 'historical-ligatures' + | 'no-historical-ligatures' + | 'contextual' + | 'no-contextual' | 'proportional-nums' | 'stylistic-one' | 'stylistic-two' diff --git a/packages/react-native/React/Views/RCTFont.mm b/packages/react-native/React/Views/RCTFont.mm index 9cbb2013ea474a..bfc273bdf43d79 100644 --- a/packages/react-native/React/Views/RCTFont.mm +++ b/packages/react-native/React/Views/RCTFont.mm @@ -248,6 +248,38 @@ + (RCTFontVariantDescriptor *)RCTFontVariantDescriptor:(id)json UIFontFeatureTypeIdentifierKey : @(kNumberSpacingType), UIFontFeatureSelectorIdentifierKey : @(kProportionalNumbersSelector), }, + @"common-ligatures" : @{ + UIFontFeatureTypeIdentifierKey : @(kLigaturesType), + UIFontFeatureSelectorIdentifierKey : @(kCommonLigaturesOnSelector), + }, + @"no-common-ligatures" : @{ + UIFontFeatureTypeIdentifierKey : @(kLigaturesType), + UIFontFeatureSelectorIdentifierKey : @(kCommonLigaturesOffSelector), + }, + @"discretionary-ligatures" : @{ + UIFontFeatureTypeIdentifierKey : @(kLigaturesType), + UIFontFeatureSelectorIdentifierKey : @(kRareLigaturesOnSelector), + }, + @"no-discretionary-ligatures" : @{ + UIFontFeatureTypeIdentifierKey : @(kLigaturesType), + UIFontFeatureSelectorIdentifierKey : @(kRareLigaturesOffSelector), + }, + @"historical-ligatures" : @{ + UIFontFeatureTypeIdentifierKey : @(kLigaturesType), + UIFontFeatureSelectorIdentifierKey : @(kHistoricalLigaturesOnSelector), + }, + @"no-historical-ligatures" : @{ + UIFontFeatureTypeIdentifierKey : @(kLigaturesType), + UIFontFeatureSelectorIdentifierKey : @(kHistoricalLigaturesOffSelector), + }, + @"contextual" : @{ + UIFontFeatureTypeIdentifierKey : @(kContextualAlternatesType), + UIFontFeatureSelectorIdentifierKey : @(kContextualAlternatesOnSelector), + }, + @"no-contextual" : @{ + UIFontFeatureTypeIdentifierKey : @(kContextualAlternatesType), + UIFontFeatureSelectorIdentifierKey : @(kContextualAlternatesOffSelector), + }, @"stylistic-one" : @{ UIFontFeatureTypeIdentifierKey : @(kStylisticAlternativesType), UIFontFeatureSelectorIdentifierKey : @(kStylisticAltOneOnSelector), diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.java index 6ca731ef4ff1aa..d71cbdea942626 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.java @@ -85,6 +85,32 @@ public static int parseFontStyle(@Nullable String fontStyleString) { case "proportional-nums": features.add("'pnum'"); break; + case "common-ligatures": + features.add("'liga'"); + features.add("'clig'"); + break; + case "no-common-ligatures": + features.add("'liga' off"); + features.add("'clig' off"); + break; + case "discretionary-ligatures": + features.add("'dlig'"); + break; + case "no-discretionary-ligatures": + features.add("'dlig' off"); + break; + case "historical-ligatures": + features.add("'hlig'"); + break; + case "no-historical-ligatures": + features.add("'hlig' off"); + break; + case "contextual": + features.add("'calt'"); + break; + case "no-contextual": + features.add("'calt' off"); + break; case "stylistic-one": features.add("'ss01'"); break;