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 9dd823dfdf6fb2..4edaa69ec8ed66 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 @@ -109,10 +109,10 @@ private static void apply( // other use cases will be added in separate PRs // the span with the highest lineHeight sets the height for all rows if (textAlignVertical == "top-child" && highestLineHeight != 0) { - tp.baselineShift -= highestLineHeight / 2 - tp.getTextSize() / 2; + // tp.baselineShift -= highestLineHeight / 2 - tp.getTextSize() / 2; } if (textAlignVertical == "bottom-child" && highestLineHeight != 0) { - tp.baselineShift += highestLineHeight / 2 - tp.getTextSize() / 2; + // tp.baselineShift += highestLineHeight / 2 - tp.getTextSize() / 2; } } 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..210ec9e9d79046 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,51 @@ package com.facebook.react.views.text; +import android.graphics.Rect; +import android.text.TextPaint; import android.text.style.AbsoluteSizeSpan; +import androidx.annotation.Nullable; /* * Wraps {@link AbsoluteSizeSpan} as a {@link ReactSpan}. */ public class ReactAbsoluteSizeSpan extends AbsoluteSizeSpan implements ReactSpan { - public ReactAbsoluteSizeSpan(int size) { + private static final String TAG = "ReactAbsoluteSizeSpan"; + private final String mText; + private String mTextAlignVertical = "center-child"; + + public ReactAbsoluteSizeSpan( + int size, @Nullable String textAlignVertical, @Nullable String text) { super(size); + mTextAlignVertical = textAlignVertical; + mText = text; + } + + @Override + public void updateMeasureState(TextPaint tp) { + updateDrawState(tp); + } + + @Override + public void updateDrawState(TextPaint ds) { + super.updateDrawState(ds); + // if lineHeight is not set, align the text using the font metrics + // works only with single line + // https://stackoverflow.com/a/27631737/7295772 + // top ------------- -26 + // ascent ------------- -30 + // baseline __my Text____ 0 + // descent _____________ 8 + // bottom _____________ 1 + if (mText != null) { + Rect bounds = new Rect(); + ds.getTextBounds(mText, 0, mText.length(), bounds); + if (mTextAlignVertical == "top-child") { + ds.baselineShift += ds.getFontMetrics().top - ds.ascent() - ds.descent(); + } + if (mTextAlignVertical == "bottom-child") { + ds.baselineShift += ds.getFontMetrics().bottom - ds.descent(); + } + } } } 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 b07b5979b348d9..aa056613304cc3 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 @@ -195,7 +195,7 @@ private static void buildSpannedFromShadowNode( // `Float.NaN`. parentTextAttributes == null || parentTextAttributes.getEffectiveFontSize() != effectiveFontSize) { - ops.add(new SetSpanOperation(start, end, new ReactAbsoluteSizeSpan(effectiveFontSize))); + ops.add(new SetSpanOperation(start, end, new ReactAbsoluteSizeSpan(effectiveFontSize, null, null))); } if (textShadowNode.mFontStyle != UNSET || textShadowNode.mFontWeight != UNSET 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 4e67070aca4bd0..f44c676d770834 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 @@ -95,7 +95,7 @@ public long measure( for (ReactAbsoluteSizeSpan span : sizeSpans) { text.setSpan( new ReactAbsoluteSizeSpan( - (int) Math.max((span.getSize() * ratio), minimumFontSize)), + (int) Math.max((span.getSize() * ratio), minimumFontSize), null, null), text.getSpanStart(span), text.getSpanEnd(span), text.getSpanFlags(span)); 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 c5193fccbbc7a7..e06e84b38d6225 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 @@ -143,7 +143,7 @@ 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, null, null))); if (textAttributes.mFontStyle != UNSET || textAttributes.mFontWeight != UNSET || textAttributes.mFontFamily != null) { 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 57159e785f8914..2808018540354a 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 @@ -158,8 +158,13 @@ private static void buildSpannableFromFragment( new SetSpanOperation( start, end, new CustomLetterSpacingSpan(textAttributes.getLetterSpacing()))); } + String currentText = String.valueOf(sb.subSequence(start, end)); ops.add( - new SetSpanOperation(start, end, new ReactAbsoluteSizeSpan(textAttributes.mFontSize))); + new SetSpanOperation( + start, + end, + new ReactAbsoluteSizeSpan( + textAttributes.mFontSize, textAttributes.mTextAlignVertical, currentText))); if (textAttributes.mFontStyle != UNSET || textAttributes.mFontWeight != UNSET || textAttributes.mFontFamily != null 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 33cebf1e2cec1e..659df9c032837b 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 @@ -711,7 +711,7 @@ private void addSpansForMeasurement(Spannable spannable) { } ops.add( new TextLayoutManager.SetSpanOperation( - start, end, new ReactAbsoluteSizeSpan((int) mTextAttributes.getEffectiveFontSize()))); + start, end, new ReactAbsoluteSizeSpan((int) mTextAttributes.getEffectiveFontSize(), null, null))); if (mFontStyle != UNSET || mFontWeight != UNSET || mFontFamily != null) { ops.add( new TextLayoutManager.SetSpanOperation(