From 70cc27c901aeb447910e30ac3ceac85990d3c16d Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Fri, 14 Oct 2022 10:32:50 -0700 Subject: [PATCH] Center text if line height isn't 0 Summary: changelog: Fix vertical text alignment in new architecture when line height is not 0. Reviewed By: javache Differential Revision: D40346225 fbshipit-source-id: f6282cb8df80e9a543e5602fddcca1a1a82377e3 --- .../platform/ios/RCTAttributedTextUtils.mm | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm b/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm index 0a5828ab7f5dbd..1e2343cde80193 100644 --- a/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm +++ b/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm @@ -305,6 +305,50 @@ inline static CGFloat RCTEffectiveFontSizeMultiplierFromTextAttributes(const Tex return [attributes copy]; } +static void RCTApplyBaselineOffset(NSMutableAttributedString *attributedText) +{ + __block CGFloat maximumLineHeight = 0; + + [attributedText enumerateAttribute:NSParagraphStyleAttributeName + inRange:NSMakeRange(0, attributedText.length) + options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired + usingBlock:^(NSParagraphStyle *paragraphStyle, __unused NSRange range, __unused BOOL *stop) { + if (!paragraphStyle) { + return; + } + + maximumLineHeight = MAX(paragraphStyle.maximumLineHeight, maximumLineHeight); + }]; + + if (maximumLineHeight == 0) { + // `lineHeight` was not specified, nothing to do. + return; + } + + __block CGFloat maximumFontLineHeight = 0; + + [attributedText enumerateAttribute:NSFontAttributeName + inRange:NSMakeRange(0, attributedText.length) + options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired + usingBlock:^(UIFont *font, NSRange range, __unused BOOL *stop) { + if (!font) { + return; + } + + maximumFontLineHeight = MAX(font.lineHeight, maximumFontLineHeight); + }]; + + if (maximumLineHeight < maximumFontLineHeight) { + return; + } + + CGFloat baseLineOffset = (maximumLineHeight - maximumFontLineHeight) / 2.0; + + [attributedText addAttribute:NSBaselineOffsetAttributeName + value:@(baseLineOffset) + range:NSMakeRange(0, attributedText.length)]; +} + NSAttributedString *RCTNSAttributedStringFromAttributedString(const AttributedString &attributedString) { static UIImage *placeholderImage; @@ -357,7 +401,7 @@ inline static CGFloat RCTEffectiveFontSizeMultiplierFromTextAttributes(const Tex [nsAttributedString appendAttributedString:nsAttributedStringFragment]; } - + RCTApplyBaselineOffset(nsAttributedString); [nsAttributedString endEditing]; return nsAttributedString;