Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Libraries/Components/View/ReactNativeStyleAttributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = {
*/
color: colorAttributes,
fontFamily: true,
fontVariationSettings: true,
fontSize: true,
fontStyle: true,
fontVariant: {process: processFontVariant},
Expand Down
1 change: 1 addition & 0 deletions Libraries/StyleSheet/StyleSheetTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ export interface TextStyleAndroid extends ViewStyle {
export interface TextStyle extends TextStyleIOS, TextStyleAndroid, ViewStyle {
color?: ColorValue | undefined;
fontFamily?: string | undefined;
fontVariationSettings?: string | undefined;
fontSize?: number | undefined;
fontStyle?: 'normal' | 'italic' | undefined;
/**
Expand Down
1 change: 1 addition & 0 deletions Libraries/StyleSheet/StyleSheetTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,7 @@ export type ____TextStyle_InternalCore = $ReadOnly<{
...$Exact<____ViewStyle_Internal>,
color?: ____ColorValue_Internal,
fontFamily?: string,
fontVariationSettings?: string,
fontSize?: number,
fontStyle?: 'normal' | 'italic',
fontWeight?: ____FontWeight_Internal,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public class ViewProps {
public static final String FONT_WEIGHT = "fontWeight";
public static final String FONT_STYLE = "fontStyle";
public static final String FONT_VARIANT = "fontVariant";
public static final String FONT_VARIATION_SETTINGS = "fontVariationSettings";
public static final String FONT_FAMILY = "fontFamily";
public static final String LINE_HEIGHT = "lineHeight";
public static final String LETTER_SPACING = "letterSpacing";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import android.content.res.AssetManager;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Build;
import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;
import androidx.annotation.Nullable;
Expand All @@ -33,30 +34,34 @@ public class CustomStyleSpan extends MetricAffectingSpan implements ReactSpan {

private final int mStyle;
private final int mWeight;

private final String mFontVariationSettings;
private final @Nullable String mFeatureSettings;
private final @Nullable String mFontFamily;

public CustomStyleSpan(
int fontStyle,
int fontWeight,
String fontVariationSettings,
@Nullable String fontFeatureSettings,
@Nullable String fontFamily,
AssetManager assetManager) {
mStyle = fontStyle;
mWeight = fontWeight;
mFeatureSettings = fontFeatureSettings;
mFontVariationSettings = fontVariationSettings;
mFontFamily = fontFamily;
mAssetManager = assetManager;
}

@Override
public void updateDrawState(TextPaint ds) {
apply(ds, mStyle, mWeight, mFeatureSettings, mFontFamily, mAssetManager);
apply(ds, mStyle, mWeight, mFontVariationSettings, mFeatureSettings, mFontFamily, mAssetManager);
}

@Override
public void updateMeasureState(TextPaint paint) {
apply(paint, mStyle, mWeight, mFeatureSettings, mFontFamily, mAssetManager);
apply(paint, mStyle, mWeight, mFontVariationSettings, mFeatureSettings, mFontFamily, mAssetManager);
}

public int getStyle() {
Expand All @@ -75,12 +80,16 @@ private static void apply(
Paint paint,
int style,
int weight,
String fontVariationSettings,
@Nullable String fontFeatureSettings,
@Nullable String family,
AssetManager assetManager) {
Typeface typeface =
ReactTypefaceUtils.applyStyles(paint.getTypeface(), style, weight, family, assetManager);
paint.setFontFeatureSettings(fontFeatureSettings);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
paint.setFontVariationSettings(fontVariationSettings);
}
paint.setTypeface(typeface);
paint.setSubpixelText(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import androidx.annotation.Nullable;
import com.facebook.common.logging.FLog;
Expand Down Expand Up @@ -200,6 +201,7 @@ private static void buildSpannedFromShadowNode(
}
if (textShadowNode.mFontStyle != UNSET
|| textShadowNode.mFontWeight != UNSET
|| textShadowNode.mFontVariationSettings != null
|| textShadowNode.mFontFamily != null) {
ops.add(
new SetSpanOperation(
Expand All @@ -208,6 +210,7 @@ private static void buildSpannedFromShadowNode(
new CustomStyleSpan(
textShadowNode.mFontStyle,
textShadowNode.mFontWeight,
textShadowNode.mFontVariationSettings,
textShadowNode.mFontFeatureSettings,
textShadowNode.mFontFamily,
textShadowNode.getThemedContext().getAssets())));
Expand Down Expand Up @@ -353,6 +356,11 @@ protected Spannable spannedFromShadowNode(
*/
protected int mFontStyle = UNSET;

/**
* mFontVariationSettings can be used for variable font features e.g: 'wght' 850
*/
protected String mFontVariationSettings;

protected int mFontWeight = UNSET;
/**
* NB: If a font family is used that does not have a style in a certain Android version (ie.
Expand Down Expand Up @@ -514,6 +522,7 @@ public void setFontFamily(@Nullable String fontFamily) {

@ReactProp(name = ViewProps.FONT_WEIGHT)
public void setFontWeight(@Nullable String fontWeightString) {
Log.d("ReactBaseTextShadowNode", "Font weight: " + fontWeightString);
int fontWeight = ReactTypefaceUtils.parseFontWeight(fontWeightString);
if (fontWeight != mFontWeight) {
mFontWeight = fontWeight;
Expand All @@ -531,6 +540,15 @@ public void setFontVariant(@Nullable ReadableArray fontVariantArray) {
}
}

@ReactProp(name = ViewProps.FONT_VARIATION_SETTINGS)
public void setFontVariationSettings(@Nullable String fontVariationSettings) {
Log.d("ReactBaseTextShadowNode", "fontVariationSettings: " + fontVariationSettings);
if(fontVariationSettings != mFontVariationSettings) {
mFontVariationSettings = fontVariationSettings;
markUpdated();
}
}

@ReactProp(name = ViewProps.FONT_STYLE)
public void setFontStyle(@Nullable String fontStyleString) {
int fontStyle = ReactTypefaceUtils.parseFontStyle(fontStyleString);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public class TextAttributeProps {
public static final short TA_KEY_IS_HIGHLIGHTED = 20;
public static final short TA_KEY_LAYOUT_DIRECTION = 21;
public static final short TA_KEY_ACCESSIBILITY_ROLE = 22;
public static final short TA_KEY_LINE_BREAK_STRATEGY = 23;
public static final short TA_KEY_FONT_VARIATION_SETTINGS = 24;

public static final int UNSET = -1;

Expand Down Expand Up @@ -129,6 +131,11 @@ public class TextAttributeProps {
* </pre>
*/
protected @Nullable String mFontFamily = null;

/**
* mFontVariationSettings can be used for variable font features e.g: 'wght' 850
*/
protected String mFontVariationSettings = null;

/** @see android.graphics.Paint#setFontFeatureSettings */
protected @Nullable String mFontFeatureSettings = null;
Expand Down Expand Up @@ -206,6 +213,12 @@ public static TextAttributeProps fromMapBuffer(MapBuffer props) {
case TA_KEY_ACCESSIBILITY_ROLE:
result.setAccessibilityRole(entry.getStringValue());
break;
case TA_KEY_LINE_BREAK_STRATEGY:
// TODO: add line break strategy
break;
case TA_KEY_FONT_VARIATION_SETTINGS:
result.setFontVariationSettings(entry.getStringValue());
break;
}
}

Expand Down Expand Up @@ -235,6 +248,7 @@ public static TextAttributeProps fromReadableMap(ReactStylesDiffMap props) {
? props.getInt(ViewProps.BACKGROUND_COLOR, 0)
: null);
result.setFontFamily(getStringProp(props, ViewProps.FONT_FAMILY));
result.setFontVariationSettings(getStringProp(props, ViewProps.FONT_VARIATION_SETTINGS));
result.setFontWeight(getStringProp(props, ViewProps.FONT_WEIGHT));
result.setFontStyle(getStringProp(props, ViewProps.FONT_STYLE));
result.setFontVariant(getArrayProp(props, ViewProps.FONT_VARIANT));
Expand Down Expand Up @@ -414,6 +428,10 @@ private void setFontFamily(@Nullable String fontFamily) {
mFontFamily = fontFamily;
}

private void setFontVariationSettings(String fontVariationSettings) {
mFontVariationSettings = fontVariationSettings;
}

private void setFontVariant(@Nullable ReadableArray fontVariant) {
mFontFeatureSettings = ReactTypefaceUtils.parseFontVariant(fontVariant);
}
Expand Down Expand Up @@ -647,4 +665,4 @@ public static int getHyphenationFrequency(@Nullable String hyphenationFrequency)
}
return androidHyphenationFrequency;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ private static void buildSpannableFromFragment(
new SetSpanOperation(start, end, new ReactAbsoluteSizeSpan(textAttributes.mFontSize)));
if (textAttributes.mFontStyle != UNSET
|| textAttributes.mFontWeight != UNSET
|| textAttributes.mFontVariationSettings != null
|| textAttributes.mFontFamily != null) {
ops.add(
new SetSpanOperation(
Expand All @@ -154,6 +155,7 @@ private static void buildSpannableFromFragment(
new CustomStyleSpan(
textAttributes.mFontStyle,
textAttributes.mFontWeight,
textAttributes.mFontVariationSettings,
textAttributes.mFontFeatureSettings,
textAttributes.mFontFamily,
context.getAssets())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ private static void buildSpannableFromFragment(
new SetSpanOperation(start, end, new ReactAbsoluteSizeSpan(textAttributes.mFontSize)));
if (textAttributes.mFontStyle != UNSET
|| textAttributes.mFontWeight != UNSET
|| textAttributes.mFontVariationSettings != null
|| textAttributes.mFontFamily != null) {
ops.add(
new SetSpanOperation(
Expand All @@ -170,6 +171,7 @@ private static void buildSpannableFromFragment(
new CustomStyleSpan(
textAttributes.mFontStyle,
textAttributes.mFontWeight,
textAttributes.mFontVariationSettings,
textAttributes.mFontFeatureSettings,
textAttributes.mFontFamily,
context.getAssets())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,7 @@ private void addSpansForMeasurement(Spannable spannable) {
new CustomStyleSpan(
mFontStyle,
mFontWeight,
"",
null, // TODO: do we need to support FontFeatureSettings / fontVariant?
mFontFamily,
getReactContext(ReactEditText.this).getAssets())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ void TextAttributes::apply(TextAttributes textAttributes) {
// Font
fontFamily = !textAttributes.fontFamily.empty() ? textAttributes.fontFamily
: fontFamily;

fontVariationSettings = !textAttributes.fontVariationSettings.empty() ? textAttributes.fontVariationSettings
: fontVariationSettings;

fontSize =
!std::isnan(textAttributes.fontSize) ? textAttributes.fontSize : fontSize;
fontSizeMultiplier = !std::isnan(textAttributes.fontSizeMultiplier)
Expand Down Expand Up @@ -110,6 +114,7 @@ bool TextAttributes::operator==(const TextAttributes &rhs) const {
foregroundColor,
backgroundColor,
fontFamily,
fontVariationSettings,
fontWeight,
fontStyle,
fontVariant,
Expand All @@ -131,6 +136,7 @@ bool TextAttributes::operator==(const TextAttributes &rhs) const {
rhs.foregroundColor,
rhs.backgroundColor,
rhs.fontFamily,
rhs.fontVariationSettings,
rhs.fontWeight,
rhs.fontStyle,
rhs.fontVariant,
Expand Down Expand Up @@ -168,6 +174,7 @@ TextAttributes TextAttributes::defaultTextAttributes() {
textAttributes.backgroundColor = clearColor();
textAttributes.fontSize = 14.0;
textAttributes.fontSizeMultiplier = 1.0;
textAttributes.fontVariationSettings = "";
return textAttributes;
}();
return textAttributes;
Expand All @@ -190,6 +197,7 @@ SharedDebugStringConvertibleList TextAttributes::getDebugProps() const {
debugStringConvertibleItem("fontWeight", fontWeight),
debugStringConvertibleItem("fontStyle", fontStyle),
debugStringConvertibleItem("fontVariant", fontVariant),
debugStringConvertibleItem("fontVariationSettings", fontVariationSettings),
debugStringConvertibleItem("allowFontScaling", allowFontScaling),
debugStringConvertibleItem("dynamicTypeRamp", dynamicTypeRamp),
debugStringConvertibleItem("letterSpacing", letterSpacing),
Expand Down
2 changes: 2 additions & 0 deletions ReactCommon/react/renderer/attributedstring/TextAttributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class TextAttributes : public DebugStringConvertible {

// Font
std::string fontFamily{""};
std::string fontVariationSettings{""};
Float fontSize{std::numeric_limits<Float>::quiet_NaN()};
Float fontSizeMultiplier{std::numeric_limits<Float>::quiet_NaN()};
std::optional<FontWeight> fontWeight{};
Expand Down Expand Up @@ -113,6 +114,7 @@ struct hash<facebook::react::TextAttributes> {
textAttributes.backgroundColor,
textAttributes.opacity,
textAttributes.fontFamily,
textAttributes.fontVariationSettings,
textAttributes.fontSize,
textAttributes.fontSizeMultiplier,
textAttributes.fontWeight,
Expand Down
7 changes: 7 additions & 0 deletions ReactCommon/react/renderer/attributedstring/conversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,9 @@ inline folly::dynamic toDynamic(const TextAttributes &textAttributes) {
if (!textAttributes.fontFamily.empty()) {
_textAttributes("fontFamily", textAttributes.fontFamily);
}
if (!textAttributes.fontVariationSettings.empty()) {
_textAttributes("fontVariationSettings", textAttributes.fontVariationSettings);
}
if (!std::isnan(textAttributes.fontSize)) {
_textAttributes("fontSize", textAttributes.fontSize);
}
Expand Down Expand Up @@ -1110,6 +1113,7 @@ constexpr static MapBuffer::Key TA_KEY_IS_HIGHLIGHTED = 20;
constexpr static MapBuffer::Key TA_KEY_LAYOUT_DIRECTION = 21;
constexpr static MapBuffer::Key TA_KEY_ACCESSIBILITY_ROLE = 22;
constexpr static MapBuffer::Key TA_KEY_LINE_BREAK_STRATEGY = 23;
constexpr static MapBuffer::Key TA_KEY_FONT_VARIATION_SETTINGS = 24;

// constants for ParagraphAttributes serialization
constexpr static MapBuffer::Key PA_KEY_MAX_NUMBER_OF_LINES = 0;
Expand Down Expand Up @@ -1177,6 +1181,9 @@ inline MapBuffer toMapBuffer(const TextAttributes &textAttributes) {
if (!textAttributes.fontFamily.empty()) {
builder.putString(TA_KEY_FONT_FAMILY, textAttributes.fontFamily);
}
if (!textAttributes.fontVariationSettings.empty()) {
builder.putString(TA_KEY_FONT_VARIATION_SETTINGS, textAttributes.fontVariationSettings);
}
if (!std::isnan(textAttributes.fontSize)) {
builder.putDouble(TA_KEY_FONT_SIZE, textAttributes.fontSize);
}
Expand Down
8 changes: 8 additions & 0 deletions ReactCommon/react/renderer/components/text/BaseTextProps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ static TextAttributes convertRawProp(
"fontFamily",
sourceTextAttributes.fontFamily,
defaultTextAttributes.fontFamily);
textAttributes.fontVariationSettings = convertRawProp(
context,
rawProps,
"fontVariationSettings",
sourceTextAttributes.fontVariationSettings,
defaultTextAttributes.fontVariationSettings);
textAttributes.fontSize = convertRawProp(
context,
rawProps,
Expand Down Expand Up @@ -297,6 +303,8 @@ void BaseTextProps::setProp(
defaults, value, textAttributes, opacity, "opacity");
REBUILD_FIELD_SWITCH_CASE(
defaults, value, textAttributes, backgroundColor, "backgroundColor");
REBUILD_FIELD_SWITCH_CASE(
defaults, value, textAttributes, fontVariationSettings, "fontVariationSettings");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ AndroidTextInputProps::AndroidTextInputProps(
convertRawProp(context, rawProps, "fontWeight", sourceProps.fontWeight, {})),
fontFamily(CoreFeatures::enablePropIteratorSetter? sourceProps.fontFamily :
convertRawProp(context, rawProps, "fontFamily", sourceProps.fontFamily, {})),
fontVariationSettings(CoreFeatures::enablePropIteratorSetter? sourceProps.fontVariationSettings :
convertRawProp(context, rawProps, "fontVariationSettings", sourceProps.fontVariationSettings, {})),
textAlignVertical(CoreFeatures::enablePropIteratorSetter? sourceProps.textAlignVertical : convertRawProp(context, rawProps,
"textAlignVertical",
sourceProps.textAlignVertical,
Expand Down Expand Up @@ -373,6 +375,7 @@ void AndroidTextInputProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(includeFontPadding);
RAW_SET_PROP_SWITCH_CASE_BASIC(fontWeight);
RAW_SET_PROP_SWITCH_CASE_BASIC(fontFamily);
RAW_SET_PROP_SWITCH_CASE_BASIC(fontVariationSettings);
RAW_SET_PROP_SWITCH_CASE_BASIC(textAlignVertical);
RAW_SET_PROP_SWITCH_CASE_BASIC(cursorColor);
RAW_SET_PROP_SWITCH_CASE_BASIC(mostRecentEventCount);
Expand Down Expand Up @@ -475,6 +478,7 @@ folly::dynamic AndroidTextInputProps::getDynamic() const {
props["includeFontPadding"] = includeFontPadding;
props["fontWeight"] = fontWeight;
props["fontFamily"] = fontFamily;
props["fontVariationSettings"] = fontVariationSettings;
props["textAlignVertical"] = textAlignVertical;
props["cursorColor"] = toAndroidRepr(cursorColor);
props["mostRecentEventCount"] = mostRecentEventCount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ class AndroidTextInputProps final : public ViewProps, public BaseTextProps {
bool includeFontPadding{false};
std::string fontWeight{};
std::string fontFamily{};
std::string fontVariationSettings{};
std::string textAlignVertical{};
SharedColor cursorColor{};
int mostRecentEventCount{0};
Expand Down
Loading