diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomLineHeightSpan.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomLineHeightSpan.java deleted file mode 100644 index d84d4d927..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomLineHeightSpan.java +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -package com.facebook.react.views.text; - -import android.graphics.Paint; -import android.text.style.LineHeightSpan; - -/** - * We use a custom {@link LineHeightSpan}, because `lineSpacingExtra` is broken. Details here: - * https://github.com/facebook/react-native/issues/7546 - */ -public class CustomLineHeightSpan implements LineHeightSpan { - private final float mHeight; - - CustomLineHeightSpan(float height) { - this.mHeight = height; - } - - @Override - public void chooseHeight( - CharSequence text, - int start, - int end, - int spanstartv, - int v, - Paint.FontMetricsInt fm) { - fm.ascent = fm.top = 0; - fm.descent = fm.bottom = (int) Math.ceil(mHeight); - } -} 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 aaa579ea9..f17ecec5d 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 @@ -172,12 +172,6 @@ public class ReactTextShadowNode extends LayoutShadowNode { textCSSNode.mTextShadowRadius, textCSSNode.mTextShadowColor))); } - if (!Float.isNaN(textCSSNode.getEffectiveLineHeight())) { - ops.add(new SetSpanOperation( - start, - end, - new CustomLineHeightSpan(textCSSNode.getEffectiveLineHeight()))); - } ops.add(new SetSpanOperation(start, end, new ReactTagSpan(textCSSNode.getReactTag()))); } } @@ -241,6 +235,14 @@ public class ReactTextShadowNode extends LayoutShadowNode { // technically, width should never be negative, but there is currently a bug in boolean unconstrainedWidth = widthMode == CSSMeasureMode.UNDEFINED || width < 0; + float effectiveLineHeight = reactCSSNode.getEffectiveLineHeight(); + float lineSpacingExtra = 0; + float lineSpacingMultiplier = 1; + if (!Float.isNaN(effectiveLineHeight)) { + lineSpacingExtra = effectiveLineHeight; + lineSpacingMultiplier = 0; + } + if (boring == null && (unconstrainedWidth || (!CSSConstants.isUndefined(desiredWidth) && desiredWidth <= width))) { @@ -251,8 +253,8 @@ public class ReactTextShadowNode extends LayoutShadowNode { textPaint, (int) Math.ceil(desiredWidth), Layout.Alignment.ALIGN_NORMAL, - 1.f, - 0.f, + lineSpacingMultiplier, + lineSpacingExtra, true); } else if (boring != null && (unconstrainedWidth || boring.width <= width)) { // Is used for single-line, boring text when the width is either unknown or bigger @@ -262,8 +264,8 @@ public class ReactTextShadowNode extends LayoutShadowNode { textPaint, boring.width, Layout.Alignment.ALIGN_NORMAL, - 1.f, - 0.f, + lineSpacingMultiplier, + lineSpacingExtra, boring, true); } else { @@ -273,8 +275,8 @@ public class ReactTextShadowNode extends LayoutShadowNode { textPaint, (int) width, Layout.Alignment.ALIGN_NORMAL, - 1.f, - 0.f, + lineSpacingMultiplier, + lineSpacingExtra, true); } @@ -586,6 +588,7 @@ public class ReactTextShadowNode extends LayoutShadowNode { UNSET, mContainsImages, getPadding(), + getEffectiveLineHeight(), getTextAlign() ); uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), reactTextUpdate); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextUpdate.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextUpdate.java index 20cb5d51f..285ddb3cc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextUpdate.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextUpdate.java @@ -10,6 +10,7 @@ package com.facebook.react.views.text; import android.text.Spannable; +import android.view.Gravity; import com.facebook.csslayout.Spacing; @@ -27,6 +28,7 @@ public class ReactTextUpdate { private final float mPaddingTop; private final float mPaddingRight; private final float mPaddingBottom; + private final float mLineHeight; private final int mTextAlign; public ReactTextUpdate( @@ -34,6 +36,7 @@ public class ReactTextUpdate { int jsEventCounter, boolean containsImages, Spacing padding, + float lineHeight, int textAlign) { mText = text; mJsEventCounter = jsEventCounter; @@ -42,6 +45,7 @@ public class ReactTextUpdate { mPaddingTop = padding.get(Spacing.TOP); mPaddingRight = padding.get(Spacing.END); mPaddingBottom = padding.get(Spacing.BOTTOM); + mLineHeight = lineHeight; mTextAlign = textAlign; } @@ -73,6 +77,10 @@ public class ReactTextUpdate { return mPaddingBottom; } + public float getLineHeight() { + return mLineHeight; + } + public int getTextAlign() { return mTextAlign; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java index 0a5ad9463..819db6c69 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java @@ -17,6 +17,7 @@ import android.view.Gravity; import android.view.ViewGroup; import android.widget.TextView; +import com.facebook.csslayout.FloatUtil; import com.facebook.react.uimanager.ReactCompoundView; public class ReactTextView extends TextView implements ReactCompoundView { @@ -53,6 +54,16 @@ public class ReactTextView extends TextView implements ReactCompoundView { (int) Math.ceil(update.getPaddingRight()), (int) Math.ceil(update.getPaddingBottom())); + float nextLineHeight = update.getLineHeight(); + if (!FloatUtil.floatsEqual(mLineHeight, nextLineHeight)) { + mLineHeight = nextLineHeight; + if (Float.isNaN(mLineHeight)) { // NaN will be used if property gets reset + setLineSpacing(0, 1); + } else { + setLineSpacing(mLineHeight, 0); + } + } + int nextTextAlign = update.getTextAlign(); if (mTextAlign != nextTextAlign) { mTextAlign = nextTextAlign; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java index cac809562..246ce8120 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java @@ -129,6 +129,7 @@ public class ReactTextInputShadowNode extends ReactTextShadowNode implements mJsEventCount, mContainsImages, getPadding(), + getEffectiveLineHeight(), mTextAlign ); uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), reactTextUpdate);