From 90b116a728c65694accd8eed6ff922a2dd9f80d6 Mon Sep 17 00:00:00 2001 From: Adrian Hartanto Date: Sat, 25 May 2024 20:06:56 +0700 Subject: [PATCH] Adjust line height calculation --- .../Libraries/Text/Text/RCTTextShadowView.mm | 76 +++++++++---------- .../TextInput/RCTBaseTextInputShadowView.mm | 76 +++++++++---------- 2 files changed, 68 insertions(+), 84 deletions(-) diff --git a/packages/react-native/Libraries/Text/Text/RCTTextShadowView.mm b/packages/react-native/Libraries/Text/Text/RCTTextShadowView.mm index 363170e617ed5c..cd511d6ede3dd2 100644 --- a/packages/react-native/Libraries/Text/Text/RCTTextShadowView.mm +++ b/packages/react-native/Libraries/Text/Text/RCTTextShadowView.mm @@ -123,48 +123,40 @@ - (void)uiManagerWillPerformMounting - (void)postprocessAttributedText:(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; - } - - if (maximumFontLineHeight <= font.lineHeight) { - maximumFontLineHeight = font.lineHeight; - } - }]; - - if (maximumLineHeight < maximumFontLineHeight) { - return; - } - - CGFloat baseLineOffset = maximumLineHeight / 2.0 - maximumFontLineHeight / 2.0; - - [attributedText addAttribute:NSBaselineOffsetAttributeName - value:@(baseLineOffset) - range:NSMakeRange(0, attributedText.length)]; + // Retrieve paragraph line height value + __block CGFloat paragraphLineHeight = 0; + [attributedText enumerateAttribute:NSParagraphStyleAttributeName + inRange:NSMakeRange(0, attributedText.length) + options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired + usingBlock:^(NSParagraphStyle *paragraphStyle, __unused NSRange range, __unused BOOL *stop) { + if (!paragraphStyle) { + return; + } + + paragraphLineHeight = paragraphStyle.maximumLineHeight; + }]; + + // Retrieve font size and font line height values + __block CGFloat fontSize = 0; + __block CGFloat fontLineHeight = 0; + [attributedText enumerateAttribute:NSFontAttributeName + inRange:NSMakeRange(0, attributedText.length) + options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired + usingBlock:^(UIFont *font, NSRange range, __unused BOOL *stop) { + if (!font) { + return; + } + + fontSize = font.pointSize; + fontLineHeight = font.lineHeight; + }]; + + // Calculate baseline offset based on font size and maximum available line height value + CGFloat maximumLineHeight = MAX(paragraphLineHeight, fontLineHeight); + CGFloat baselineOffset = (fontSize - maximumLineHeight) / 1.5; + [attributedText addAttribute:NSBaselineOffsetAttributeName + value:@(baselineOffset) + range:NSMakeRange(0, attributedText.length)]; } - (NSAttributedString *)attributedTextWithMeasuredAttachmentsThatFitSize:(CGSize)size diff --git a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.mm b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.mm index 8f151c25f914d2..91562b24a1a528 100644 --- a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.mm +++ b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.mm @@ -195,48 +195,40 @@ - (void)uiManagerWillPerformMounting - (void)postprocessAttributedText:(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; - } - - if (maximumFontLineHeight <= font.lineHeight) { - maximumFontLineHeight = font.lineHeight; - } - }]; - - if (maximumLineHeight < maximumFontLineHeight) { - return; - } - - CGFloat baseLineOffset = maximumLineHeight / 2.0 - maximumFontLineHeight / 2.0; - - [attributedText addAttribute:NSBaselineOffsetAttributeName - value:@(baseLineOffset) - range:NSMakeRange(0, attributedText.length)]; + // Retrieve paragraph line height value + __block CGFloat paragraphLineHeight = 0; + [attributedText enumerateAttribute:NSParagraphStyleAttributeName + inRange:NSMakeRange(0, attributedText.length) + options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired + usingBlock:^(NSParagraphStyle *paragraphStyle, __unused NSRange range, __unused BOOL *stop) { + if (!paragraphStyle) { + return; + } + + paragraphLineHeight = paragraphStyle.maximumLineHeight; + }]; + + // Retrieve font size and font line height values + __block CGFloat fontSize = 0; + __block CGFloat fontLineHeight = 0; + [attributedText enumerateAttribute:NSFontAttributeName + inRange:NSMakeRange(0, attributedText.length) + options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired + usingBlock:^(UIFont *font, NSRange range, __unused BOOL *stop) { + if (!font) { + return; + } + + fontSize = font.pointSize; + fontLineHeight = font.lineHeight; + }]; + + // Calculate baseline offset based on font size and maximum available line height value + CGFloat maximumLineHeight = MAX(paragraphLineHeight, fontLineHeight); + CGFloat baselineOffset = (fontSize - maximumLineHeight) / 1.5; + [attributedText addAttribute:NSBaselineOffsetAttributeName + value:@(baselineOffset) + range:NSMakeRange(0, attributedText.length)]; } #pragma mark -