diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomStyleSpan.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomStyleSpan.java index 2b2ca224d84d03..3e922f34d51e9f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomStyleSpan.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomStyleSpan.java @@ -13,6 +13,7 @@ import android.text.TextPaint; import android.text.style.MetricAffectingSpan; import androidx.annotation.Nullable; +import com.facebook.common.logging.FLog; import com.facebook.infer.annotation.Nullsafe; @Nullsafe(Nullsafe.Mode.LOCAL) @@ -38,6 +39,7 @@ public class CustomStyleSpan extends MetricAffectingSpan implements ReactSpan { private final String mCurrentText; private String mTextAlignVertical; private int mHighestLineHeight; + private static float mFontSize; public CustomStyleSpan( int fontStyle, @@ -46,7 +48,8 @@ public CustomStyleSpan( @Nullable String fontFamily, AssetManager assetManager, @Nullable String textAlignVertical, - String currentText) { + String currentText, + @Nullable int fontSize) { mStyle = fontStyle; mWeight = fontWeight; mFeatureSettings = fontFeatureSettings; @@ -54,6 +57,7 @@ public CustomStyleSpan( mAssetManager = assetManager; mTextAlignVertical = textAlignVertical; mCurrentText = currentText; + mFontSize = fontSize; } @Override @@ -117,29 +121,47 @@ private static void apply( paint.getTextBounds(currentText, 0, currentText.length(), bounds); if (textAlignVertical == "top-child") { if (highestLineHeight != 0) { - // the span with the highest lineHeight over-rides sets the height for all rows + // the span with the highest lineHeight sets the height for all rows paint.baselineShift -= highestLineHeight / 2 - paint.getTextSize() / 2; } else { + String methodName = new Object() {}.getClass().getEnclosingMethod().getName(); + FLog.w( + "React::" + "CustomStyleSpan", + methodName + + " mCurrentText: " + + (currentText) + + " paint.getFontMetrics().top: " + + (paint.getFontMetrics().top) + + " paint.ascent(): " + + (paint.ascent()) + + " paint.baselineShift: " + + (paint.baselineShift) + + " paint.getFontMetrics().bottom: " + + (paint.getFontMetrics().bottom) + + " paint.descent(): " + + (paint.descent()) + + " paint.getTextSize(): " + + (paint.getTextSize()) + + " mFontSize: " + + (mFontSize)); // works only with single line // if lineHeight is not set, align the text using the font metrics // https://stackoverflow.com/a/27631737/7295772 - // top ------------- -26 - // ascent ------------- -30 - // baseline __my Text____ 0 - // descent _____________ 8 - // bottom _____________ 1 - paint.baselineShift -= bounds.top + bounds.bottom - paint.ascent(); + // top ------------- -41 ^ ^ + // ascent ------------- -36 | -51 | +36 ^ -15 + // baseline __my Text____ 0 | v ^ + // descent _____________ 9 | ^ + // bottom _____________ 10 | + // paint.baselineShift += + // (paint.getFontMetrics().top - paint.getFontMetrics().ascent) * mFontSize / 33; } } if (textAlignVertical == "bottom-child") { if (highestLineHeight != 0) { - // the span with the highest lineHeight over-rides sets the height for all rows paint.baselineShift += highestLineHeight / 2 - paint.getTextSize() / 2; } else { - // works only with single line - // if lineHeight is not set, align the text using the font metrics - // https://stackoverflow.com/a/27631737/7295772 - paint.baselineShift += paint.descent(); + // paint.baselineShift += (paint.getFontMetrics().bottom - paint.descent()) * mFontSize / + // 33; } } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactAbsoluteSizeSpan.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactAbsoluteSizeSpan.java index 073a57c21139a0..71ae03061438bb 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactAbsoluteSizeSpan.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactAbsoluteSizeSpan.java @@ -7,13 +7,29 @@ package com.facebook.react.views.text; +import android.text.TextPaint; import android.text.style.AbsoluteSizeSpan; /* * Wraps {@link AbsoluteSizeSpan} as a {@link ReactSpan}. */ public class ReactAbsoluteSizeSpan extends AbsoluteSizeSpan implements ReactSpan { - public ReactAbsoluteSizeSpan(int size) { + private String mTextAlignVertical; + + public ReactAbsoluteSizeSpan(int size, @Nullable String textAlignVertical) { super(size); + mTextAlignVertical = textVerticalAlign; + } + + @Override + public void updateDrawState(TextPaint ds) { + if (mTextAlignVertical == "top-child") { + ds.baselineShift += 50; + } + } + + @Override + public void updateMeasureState(TextPaint paint) { + // paint.baselineShift += 50; } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java index c9a4e7c5aca2dc..0c5d3204b68310 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java @@ -209,7 +209,7 @@ private static void buildSpannedFromShadowNode( textShadowNode.mFontWeight, textShadowNode.mFontFeatureSettings, textShadowNode.mFontFamily, - textShadowNode.getThemedContext().getAssets(), /* textAlignVertical not supported on Paper */ null, null))); + textShadowNode.getThemedContext().getAssets(), /* textAlignVertical not supported on Paper */ null, null, 0))); } if (textShadowNode.mIsUnderlineTextDecorationSet) { ops.add(new SetSpanOperation(start, end, new ReactUnderlineSpan())); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java index 008b8574c34919..5e274d341aa681 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java @@ -156,7 +156,7 @@ private static void buildSpannableFromFragment( textAttributes.mFontWeight, textAttributes.mFontFeatureSettings, textAttributes.mFontFamily, - context.getAssets(), /* textAlignVertical not supported on Paper */ null, null))); + context.getAssets(), /* textAlignVertical not supported on Paper */ null, null, 0))); } if (textAttributes.mIsUnderlineTextDecorationSet) { ops.add(new SetSpanOperation(start, end, new ReactUnderlineSpan())); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java index 38f1621cd37278..5832d13779bc53 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java @@ -159,7 +159,11 @@ private static void buildSpannableFromFragment( start, end, new CustomLetterSpacingSpan(textAttributes.getLetterSpacing()))); } ops.add( - new SetSpanOperation(start, end, new ReactAbsoluteSizeSpan(textAttributes.mFontSize))); + new SetSpanOperation( + start, + end, + new ReactAbsoluteSizeSpan( + textAttributes.mFontSize, textAttributes.mVerticalAlign))); if (textAttributes.mFontStyle != UNSET || textAttributes.mFontWeight != UNSET || textAttributes.mFontFamily != null @@ -176,7 +180,8 @@ private static void buildSpannableFromFragment( textAttributes.mFontFamily, context.getAssets(), textAttributes.mVerticalAlign, - currentText))); + currentText, + textAttributes.mFontSize))); } if (textAttributes.mIsUnderlineTextDecorationSet) { ops.add(new SetSpanOperation(start, end, new ReactUnderlineSpan())); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java index a29dffc7174d3f..74c548fa8f31ed 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java @@ -722,7 +722,7 @@ private void addSpansForMeasurement(Spannable spannable) { mFontWeight, null, // TODO: do we need to support FontFeatureSettings / fontVariant? mFontFamily, - getReactContext(ReactEditText.this).getAssets(), /* textAlignVertical not supported on TextInput */ null, null))); + getReactContext(ReactEditText.this).getAssets(), /* textAlignVertical not supported on TextInput */ null, null, 0))); } if (!Float.isNaN(mTextAttributes.getEffectiveLineHeight())) { ops.add(