From 51b3529f6c2ca354800c0cf6ecb8eb3115eaa36e Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Thu, 15 Feb 2018 17:40:12 -0800 Subject: [PATCH] `base-line` metric exposure for Summary: Now exposes base-line metric to Yoga. Before: https://cl.ly/1F0B0D430U3e After: https://cl.ly/0G1Q29450O0y Reviewed By: yungsters Differential Revision: D6957055 fbshipit-source-id: 04c1df693915e294b54e3c33e0aea21611dcc232 --- Libraries/Text/Text/RCTTextShadowView.m | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Libraries/Text/Text/RCTTextShadowView.m b/Libraries/Text/Text/RCTTextShadowView.m index 2a00e97ba2eb7c..790916354067b0 100644 --- a/Libraries/Text/Text/RCTTextShadowView.m +++ b/Libraries/Text/Text/RCTTextShadowView.m @@ -31,6 +31,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge _cachedTextStorages = [NSMapTable strongToStrongObjectsMapTable]; _needsUpdateView = YES; YGNodeSetMeasureFunc(self.yogaNode, RCTTextShadowViewMeasure); + YGNodeSetBaselineFunc(self.yogaNode, RCTTextShadowViewBaseline); } return self; @@ -307,6 +308,27 @@ - (void)layoutSubviewsWithContext:(RCTLayoutContext)layoutContext ]; } +- (CGFloat)lastBaselineForSize:(CGSize)size +{ + NSAttributedString *attributedText = + [self textStorageAndLayoutManagerThatFitsSize:size exclusiveOwnership:NO]; + + __block CGFloat maximumDescender = 0.0; + + [attributedText enumerateAttribute:NSFontAttributeName + inRange:NSMakeRange(0, attributedText.length) + options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired + usingBlock: + ^(UIFont *font, NSRange range, __unused BOOL *stop) { + if (maximumDescender > font.descender) { + maximumDescender = font.descender; + } + } + ]; + + return size.height + maximumDescender; +} + static YGSize RCTTextShadowViewMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode) { CGSize maximumSize = (CGSize){ @@ -341,4 +363,18 @@ static YGSize RCTTextShadowViewMeasure(YGNodeRef node, float width, YGMeasureMod }; } +static float RCTTextShadowViewBaseline(YGNodeRef node, const float width, const float height) +{ + RCTTextShadowView *shadowTextView = (__bridge RCTTextShadowView *)YGNodeGetContext(node); + + CGSize size = (CGSize){ + RCTCoreGraphicsFloatFromYogaFloat(width), + RCTCoreGraphicsFloatFromYogaFloat(height) + }; + + CGFloat lastBaseline = [shadowTextView lastBaselineForSize:size]; + + return RCTYogaFloatFromCoreGraphicsFloat(lastBaseline); +} + @end