From 4394419b60c7dfe5287e5e3f897e855eb7dc57c2 Mon Sep 17 00:00:00 2001 From: Steven Goff Date: Thu, 15 Dec 2016 17:41:12 -0800 Subject: [PATCH] Android Text component allowFontScaling Summary: The reason for this change is to implement `allowFontScaling` on the Android's React Native Text component. Prior to this PR `allowFontScaling` only works for iOS. The following link contains images of `allowFontScaling` working in Android on small, normal, large, and huge system fonts (from native Android display settings) http://imgur.com/a/94bF1 The following link is a video of the same thing working on an Android emulator https://youtu.be/1jTlZhPdj9Y Here is the sample code snippet driving the video/images ``` render() { const size = [12, 14, 16, 18]; return ( Default size no allowFontScaling prop (default true) Default size allowFontScaling: true Default size allowFontScaling: false { size.map( Closes https://github.com/facebook/react-native/pull/10898 Differential Revision: D4335190 Pulled By: lacker fbshipit-source-id: 0480809c44983644ff2abfcaf4887569b2bfede5 --- Libraries/Text/Text.js | 2 -- .../facebook/react/uimanager/ViewProps.java | 2 ++ .../react/views/text/ReactTextShadowNode.java | 29 +++++++++++++++++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Libraries/Text/Text.js b/Libraries/Text/Text.js index 1ecde22773c3af..8c990d0d5b4bd8 100644 --- a/Libraries/Text/Text.js +++ b/Libraries/Text/Text.js @@ -153,8 +153,6 @@ const Text = React.createClass({ /** * Specifies whether fonts should scale to respect Text Size accessibility setting on iOS. The * default is `true`. - * - * @platform ios */ allowFontScaling: React.PropTypes.bool, /** diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java index 14ce36632c4d72..f3faee5090f0a8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java @@ -83,6 +83,8 @@ public class ViewProps { public static final String TEXT_ALIGN_VERTICAL = "textAlignVertical"; public static final String TEXT_DECORATION_LINE = "textDecorationLine"; + public static final String ALLOW_FONT_SCALING = "allowFontScaling"; + public static final String BORDER_WIDTH = "borderWidth"; public static final String BORDER_LEFT_WIDTH = "borderLeftWidth"; public static final String BORDER_TOP_WIDTH = "borderTopWidth"; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java index 53e2bbca53ec20..1a38a51f3f024e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java @@ -195,7 +195,9 @@ protected static Spannable fromTextCSSNode(ReactTextShadowNode textCSSNode) { buildSpannedFromTextCSSNode(textCSSNode, sb, ops); if (textCSSNode.mFontSize == UNSET) { sb.setSpan( - new AbsoluteSizeSpan((int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP))), + new AbsoluteSizeSpan(textCSSNode.mAllowFontScaling + ? (int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP)) + : (int) Math.ceil(PixelUtil.toPixelFromDIP(ViewDefaults.FONT_SIZE_SP))), 0, sb.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); @@ -305,12 +307,15 @@ private static int parseNumericFontWeight(String fontWeightString) { private float mLineHeight = Float.NaN; private boolean mIsColorSet = false; + private boolean mAllowFontScaling = true; private int mColor; private boolean mIsBackgroundColorSet = false; private int mBackgroundColor; protected int mNumberOfLines = UNSET; protected int mFontSize = UNSET; + protected float mFontSizeInput = UNSET; + protected int mLineHeightInput = UNSET; protected int mTextAlign = Gravity.NO_GRAVITY; private float mTextShadowOffsetDx = 0; @@ -412,10 +417,26 @@ public void setNumberOfLines(int numberOfLines) { @ReactProp(name = ViewProps.LINE_HEIGHT, defaultInt = UNSET) public void setLineHeight(int lineHeight) { - mLineHeight = lineHeight == UNSET ? Float.NaN : PixelUtil.toPixelFromSP(lineHeight); + mLineHeightInput = lineHeight; + if (lineHeight == UNSET) { + mLineHeight = Float.NaN; + } else { + mLineHeight = mAllowFontScaling ? + PixelUtil.toPixelFromSP(lineHeight) : PixelUtil.toPixelFromDIP(lineHeight); + } markUpdated(); } + @ReactProp(name = ViewProps.ALLOW_FONT_SCALING, defaultBoolean = true) + public void setAllowFontScaling(boolean allowFontScaling) { + if (allowFontScaling != mAllowFontScaling) { + mAllowFontScaling = allowFontScaling; + setFontSize(mFontSizeInput); + setLineHeight(mLineHeightInput); + markUpdated(); + } + } + @ReactProp(name = ViewProps.TEXT_ALIGN) public void setTextAlign(@Nullable String textAlign) { if (textAlign == null || "auto".equals(textAlign)) { @@ -437,8 +458,10 @@ public void setTextAlign(@Nullable String textAlign) { @ReactProp(name = ViewProps.FONT_SIZE, defaultFloat = UNSET) public void setFontSize(float fontSize) { + mFontSizeInput = fontSize; if (fontSize != UNSET) { - fontSize = (float) Math.ceil(PixelUtil.toPixelFromSP(fontSize)); + fontSize = mAllowFontScaling ? (float) Math.ceil(PixelUtil.toPixelFromSP(fontSize)) + : (float) Math.ceil(PixelUtil.toPixelFromDIP(fontSize)); } mFontSize = (int) fontSize; markUpdated();