diff --git a/ios/RCTMarkdownUtils.mm b/ios/RCTMarkdownUtils.mm index 879d5cac..f188429a 100644 --- a/ios/RCTMarkdownUtils.mm +++ b/ios/RCTMarkdownUtils.mm @@ -136,6 +136,8 @@ - (NSAttributedString *)parseMarkdown:(nullable NSAttributedString *)input withA } }]; + RCTApplyBaselineOffset(attributedString); + [attributedString endEditing]; _prevInputString = inputString; @@ -148,4 +150,47 @@ - (NSAttributedString *)parseMarkdown:(nullable NSAttributedString *)input withA } } +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)]; +} + @end