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 new file mode 100644 index 000000000..d84d4d927 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomLineHeightSpan.java @@ -0,0 +1,30 @@ +// 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 f17ecec5d..aaa579ea9 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,6 +172,12 @@ 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()))); } } @@ -235,14 +241,6 @@ 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))) { @@ -253,8 +251,8 @@ public class ReactTextShadowNode extends LayoutShadowNode { textPaint, (int) Math.ceil(desiredWidth), Layout.Alignment.ALIGN_NORMAL, - lineSpacingMultiplier, - lineSpacingExtra, + 1.f, + 0.f, true); } else if (boring != null && (unconstrainedWidth || boring.width <= width)) { // Is used for single-line, boring text when the width is either unknown or bigger @@ -264,8 +262,8 @@ public class ReactTextShadowNode extends LayoutShadowNode { textPaint, boring.width, Layout.Alignment.ALIGN_NORMAL, - lineSpacingMultiplier, - lineSpacingExtra, + 1.f, + 0.f, boring, true); } else { @@ -275,8 +273,8 @@ public class ReactTextShadowNode extends LayoutShadowNode { textPaint, (int) width, Layout.Alignment.ALIGN_NORMAL, - lineSpacingMultiplier, - lineSpacingExtra, + 1.f, + 0.f, true); } @@ -588,7 +586,6 @@ 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 285ddb3cc..20cb5d51f 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,7 +10,6 @@ package com.facebook.react.views.text; import android.text.Spannable; -import android.view.Gravity; import com.facebook.csslayout.Spacing; @@ -28,7 +27,6 @@ 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( @@ -36,7 +34,6 @@ public class ReactTextUpdate { int jsEventCounter, boolean containsImages, Spacing padding, - float lineHeight, int textAlign) { mText = text; mJsEventCounter = jsEventCounter; @@ -45,7 +42,6 @@ public class ReactTextUpdate { mPaddingTop = padding.get(Spacing.TOP); mPaddingRight = padding.get(Spacing.END); mPaddingBottom = padding.get(Spacing.BOTTOM); - mLineHeight = lineHeight; mTextAlign = textAlign; } @@ -77,10 +73,6 @@ 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 819db6c69..0a5ad9463 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,7 +17,6 @@ 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 { @@ -54,16 +53,6 @@ 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 246ce8120..cac809562 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,7 +129,6 @@ public class ReactTextInputShadowNode extends ReactTextShadowNode implements mJsEventCount, mContainsImages, getPadding(), - getEffectiveLineHeight(), mTextAlign ); uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), reactTextUpdate);