From 2eaf0b0848d660eb19fde2921570f9e8bd2bd1de Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Thu, 20 Jun 2024 11:09:15 -0700 Subject: [PATCH] Add an overload for `createLayout` to reduce code duplication (#45083) Summary: Adds an overload for `createLayout` method that also handles extracting paragraph attributes and scaling font size if necessary. ## Changelog: [ANDROID] [CHANGED] - Extracted common parts related to calculating text layout to a helper Pull Request resolved: https://github.com/facebook/react-native/pull/45083 Test Plan: Tried out on RNTester Reviewed By: robhogan Differential Revision: D58818560 Pulled By: cortinico fbshipit-source-id: a42b5de04c4a70edb88cdd734387d7e4cee94032 --- .../ReactAndroid/api/ReactAndroid.api | 1 + .../react/views/text/TextLayoutManager.java | 178 ++++++++---------- 2 files changed, 75 insertions(+), 104 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 5140979d64d..1b209ef24d3 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -7628,6 +7628,7 @@ public class com/facebook/react/views/text/TextLayoutManager { public static final field PA_KEY_TEXT_BREAK_STRATEGY S public fun ()V public static fun adjustSpannableFontToFit (Landroid/text/Spannable;FLcom/facebook/yoga/YogaMeasureMode;FLcom/facebook/yoga/YogaMeasureMode;DIZIILandroid/text/Layout$Alignment;)V + public static fun createLayout (Landroid/content/Context;Lcom/facebook/react/common/mapbuffer/MapBuffer;Lcom/facebook/react/common/mapbuffer/MapBuffer;FFLcom/facebook/react/views/text/ReactTextViewManagerCallback;)Landroid/text/Layout; public static fun deleteCachedSpannableForTag (I)V public static fun getOrCreateSpannableForText (Landroid/content/Context;Lcom/facebook/react/common/mapbuffer/MapBuffer;Lcom/facebook/react/views/text/ReactTextViewManagerCallback;)Landroid/text/Spannable; public static fun getTextAlignment (Lcom/facebook/react/common/mapbuffer/MapBuffer;Landroid/text/Spannable;)Landroid/text/Layout$Alignment; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java index 2921f84140d..4857780a3a2 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java @@ -422,6 +422,69 @@ public class TextLayoutManager { return layout; } + public static Layout createLayout( + @NonNull Context context, + MapBuffer attributedString, + MapBuffer paragraphAttributes, + float width, + float height, + ReactTextViewManagerCallback reactTextViewManagerCallback) { + Spannable text = + getOrCreateSpannableForText(context, attributedString, reactTextViewManagerCallback); + BoringLayout.Metrics boring = BoringLayout.isBoring(text, sTextPaintInstance); + + int textBreakStrategy = + TextAttributeProps.getTextBreakStrategy( + paragraphAttributes.getString(PA_KEY_TEXT_BREAK_STRATEGY)); + boolean includeFontPadding = + paragraphAttributes.contains(PA_KEY_INCLUDE_FONT_PADDING) + ? paragraphAttributes.getBoolean(PA_KEY_INCLUDE_FONT_PADDING) + : DEFAULT_INCLUDE_FONT_PADDING; + int hyphenationFrequency = + TextAttributeProps.getTextBreakStrategy( + paragraphAttributes.getString(PA_KEY_HYPHENATION_FREQUENCY)); + boolean adjustFontSizeToFit = + paragraphAttributes.contains(PA_KEY_ADJUST_FONT_SIZE_TO_FIT) + ? paragraphAttributes.getBoolean(PA_KEY_ADJUST_FONT_SIZE_TO_FIT) + : DEFAULT_ADJUST_FONT_SIZE_TO_FIT; + int maximumNumberOfLines = + paragraphAttributes.contains(PA_KEY_MAX_NUMBER_OF_LINES) + ? paragraphAttributes.getInt(PA_KEY_MAX_NUMBER_OF_LINES) + : ReactConstants.UNSET; + + Layout.Alignment alignment = getTextAlignment(attributedString, text); + + if (adjustFontSizeToFit) { + double minimumFontSize = + paragraphAttributes.contains(PA_KEY_MINIMUM_FONT_SIZE) + ? paragraphAttributes.getDouble(PA_KEY_MINIMUM_FONT_SIZE) + : Double.NaN; + + adjustSpannableFontToFit( + text, + width, + YogaMeasureMode.EXACTLY, + height, + YogaMeasureMode.UNDEFINED, + minimumFontSize, + maximumNumberOfLines, + includeFontPadding, + textBreakStrategy, + hyphenationFrequency, + alignment); + } + + return createLayout( + text, + boring, + width, + YogaMeasureMode.EXACTLY, + includeFontPadding, + textBreakStrategy, + hyphenationFrequency, + alignment); + } + public static void adjustSpannableFontToFit( Spannable text, float width, @@ -505,66 +568,25 @@ public class TextLayoutManager { @Nullable float[] attachmentsPositions) { // TODO(5578671): Handle text direction (see View#getTextDirectionHeuristic) - Spannable text = - getOrCreateSpannableForText(context, attributedString, reactTextViewManagerCallback); + Layout layout = + createLayout( + context, + attributedString, + paragraphAttributes, + width, + height, + reactTextViewManagerCallback); + Spannable text = (Spannable) layout.getText(); if (text == null) { return 0; } - int textBreakStrategy = - TextAttributeProps.getTextBreakStrategy( - paragraphAttributes.getString(PA_KEY_TEXT_BREAK_STRATEGY)); - boolean includeFontPadding = - paragraphAttributes.contains(PA_KEY_INCLUDE_FONT_PADDING) - ? paragraphAttributes.getBoolean(PA_KEY_INCLUDE_FONT_PADDING) - : DEFAULT_INCLUDE_FONT_PADDING; - int hyphenationFrequency = - TextAttributeProps.getHyphenationFrequency( - paragraphAttributes.getString(PA_KEY_HYPHENATION_FREQUENCY)); - boolean adjustFontSizeToFit = - paragraphAttributes.contains(PA_KEY_ADJUST_FONT_SIZE_TO_FIT) - ? paragraphAttributes.getBoolean(PA_KEY_ADJUST_FONT_SIZE_TO_FIT) - : DEFAULT_ADJUST_FONT_SIZE_TO_FIT; int maximumNumberOfLines = paragraphAttributes.contains(PA_KEY_MAX_NUMBER_OF_LINES) ? paragraphAttributes.getInt(PA_KEY_MAX_NUMBER_OF_LINES) : ReactConstants.UNSET; - Layout.Alignment alignment = getTextAlignment(attributedString, text); - - if (adjustFontSizeToFit) { - double minimumFontSize = - paragraphAttributes.contains(PA_KEY_MINIMUM_FONT_SIZE) - ? paragraphAttributes.getDouble(PA_KEY_MINIMUM_FONT_SIZE) - : Double.NaN; - - adjustSpannableFontToFit( - text, - width, - widthYogaMeasureMode, - height, - heightYogaMeasureMode, - minimumFontSize, - maximumNumberOfLines, - includeFontPadding, - textBreakStrategy, - hyphenationFrequency, - alignment); - } - - BoringLayout.Metrics boring = BoringLayout.isBoring(text, sTextPaintInstance); - Layout layout = - createLayout( - text, - boring, - width, - widthYogaMeasureMode, - includeFontPadding, - textBreakStrategy, - hyphenationFrequency, - alignment); - int calculatedLineCount = maximumNumberOfLines == ReactConstants.UNSET || maximumNumberOfLines == 0 ? layout.getLineCount() @@ -718,60 +740,8 @@ public class TextLayoutManager { float width, float height) { - Spannable text = getOrCreateSpannableForText(context, attributedString, null); - BoringLayout.Metrics boring = BoringLayout.isBoring(text, sTextPaintInstance); - - int textBreakStrategy = - TextAttributeProps.getTextBreakStrategy( - paragraphAttributes.getString(PA_KEY_TEXT_BREAK_STRATEGY)); - boolean includeFontPadding = - paragraphAttributes.contains(PA_KEY_INCLUDE_FONT_PADDING) - ? paragraphAttributes.getBoolean(PA_KEY_INCLUDE_FONT_PADDING) - : DEFAULT_INCLUDE_FONT_PADDING; - int hyphenationFrequency = - TextAttributeProps.getTextBreakStrategy( - paragraphAttributes.getString(PA_KEY_HYPHENATION_FREQUENCY)); - boolean adjustFontSizeToFit = - paragraphAttributes.contains(PA_KEY_ADJUST_FONT_SIZE_TO_FIT) - ? paragraphAttributes.getBoolean(PA_KEY_ADJUST_FONT_SIZE_TO_FIT) - : DEFAULT_ADJUST_FONT_SIZE_TO_FIT; - int maximumNumberOfLines = - paragraphAttributes.contains(PA_KEY_MAX_NUMBER_OF_LINES) - ? paragraphAttributes.getInt(PA_KEY_MAX_NUMBER_OF_LINES) - : ReactConstants.UNSET; - - Layout.Alignment alignment = getTextAlignment(attributedString, text); - - if (adjustFontSizeToFit) { - double minimumFontSize = - paragraphAttributes.contains(PA_KEY_MINIMUM_FONT_SIZE) - ? paragraphAttributes.getDouble(PA_KEY_MINIMUM_FONT_SIZE) - : Double.NaN; - - adjustSpannableFontToFit( - text, - width, - YogaMeasureMode.EXACTLY, - height, - YogaMeasureMode.UNDEFINED, - minimumFontSize, - maximumNumberOfLines, - includeFontPadding, - textBreakStrategy, - hyphenationFrequency, - alignment); - } - Layout layout = - createLayout( - text, - boring, - width, - YogaMeasureMode.EXACTLY, - includeFontPadding, - textBreakStrategy, - hyphenationFrequency, - alignment); - return FontMetricsUtil.getFontMetrics(text, layout, sTextPaintInstance, context); + createLayout(context, attributedString, paragraphAttributes, width, height, null); + return FontMetricsUtil.getFontMetrics(layout.getText(), layout, sTextPaintInstance, context); } }