From d12385cae65a49fd8a276848d112c6aca63af412 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Wed, 4 Dec 2019 18:34:29 -0800 Subject: [PATCH] Fabric: Support for AttributedStringBox::Mode::OpaquePointer in RCTTextLayoutManager Summary: Now RCTTextLayoutManager (and TextLayoutManager) not only accept `AttributedStringBox` but also is capable to measure such kind of string when it contains a pointer to NSAttributedString. The same can be implemented for Android when/if needed. Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D18670791 fbshipit-source-id: f19089de64d00e1290767310a500ade4cede4685 --- .../platform/ios/RCTTextLayoutManager.h | 14 ++++----- .../platform/ios/RCTTextLayoutManager.mm | 24 ++++++++++----- .../platform/ios/TextLayoutManager.mm | 30 +++++++++++++++---- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/ReactCommon/fabric/textlayoutmanager/platform/ios/RCTTextLayoutManager.h b/ReactCommon/fabric/textlayoutmanager/platform/ios/RCTTextLayoutManager.h index 4dd28f8f8dd..0091b23b6a7 100644 --- a/ReactCommon/fabric/textlayoutmanager/platform/ios/RCTTextLayoutManager.h +++ b/ReactCommon/fabric/textlayoutmanager/platform/ios/RCTTextLayoutManager.h @@ -19,13 +19,13 @@ NS_ASSUME_NONNULL_BEGIN */ @interface RCTTextLayoutManager : NSObject -- (facebook::react::Size) - measureWithAttributedString: - (facebook::react::AttributedString)attributedString - paragraphAttributes: - (facebook::react::ParagraphAttributes)paragraphAttributes - layoutConstraints: - (facebook::react::LayoutConstraints)layoutConstraints; +- (facebook::react::Size)measureAttributedString:(facebook::react::AttributedString)attributedString + paragraphAttributes:(facebook::react::ParagraphAttributes)paragraphAttributes + layoutConstraints:(facebook::react::LayoutConstraints)layoutConstraints; + +- (facebook::react::Size)measureNSAttributedString:(NSAttributedString *)attributedString + paragraphAttributes:(facebook::react::ParagraphAttributes)paragraphAttributes + layoutConstraints:(facebook::react::LayoutConstraints)layoutConstraints; - (void)drawAttributedString:(facebook::react::AttributedString)attributedString paragraphAttributes: diff --git a/ReactCommon/fabric/textlayoutmanager/platform/ios/RCTTextLayoutManager.mm b/ReactCommon/fabric/textlayoutmanager/platform/ios/RCTTextLayoutManager.mm index 850613bd7a7..b36571fe618 100644 --- a/ReactCommon/fabric/textlayoutmanager/platform/ios/RCTTextLayoutManager.mm +++ b/ReactCommon/fabric/textlayoutmanager/platform/ios/RCTTextLayoutManager.mm @@ -32,16 +32,15 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi } } -- (facebook::react::Size) - measureWithAttributedString:(AttributedString)attributedString - paragraphAttributes:(ParagraphAttributes)paragraphAttributes - layoutConstraints:(LayoutConstraints)layoutConstraints { +- (facebook::react::Size)measureNSAttributedString:(NSAttributedString *)attributedString + paragraphAttributes:(ParagraphAttributes)paragraphAttributes + layoutConstraints:(LayoutConstraints)layoutConstraints +{ CGSize maximumSize = CGSize{layoutConstraints.maximumSize.width, layoutConstraints.maximumSize.height}; - NSTextStorage *textStorage = [self - _textStorageAndLayoutManagerWithAttributesString:[self _nsAttributedStringFromAttributedString:attributedString] - paragraphAttributes:paragraphAttributes - size:maximumSize]; + NSTextStorage *textStorage = [self _textStorageAndLayoutManagerWithAttributesString:attributedString + paragraphAttributes:paragraphAttributes + size:maximumSize]; NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject; NSTextContainer *textContainer = layoutManager.textContainers.firstObject; @@ -55,6 +54,15 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi return facebook::react::Size{size.width, size.height}; } +- (facebook::react::Size)measureAttributedString:(AttributedString)attributedString + paragraphAttributes:(ParagraphAttributes)paragraphAttributes + layoutConstraints:(LayoutConstraints)layoutConstraints +{ + return [self measureNSAttributedString:[self _nsAttributedStringFromAttributedString:attributedString] + paragraphAttributes:paragraphAttributes + layoutConstraints:layoutConstraints]; +} + - (void)drawAttributedString:(AttributedString)attributedString paragraphAttributes:(ParagraphAttributes)paragraphAttributes frame:(CGRect)frame { diff --git a/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.mm b/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.mm index 614c26e0f7b..ed27d1356d3 100644 --- a/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.mm +++ b/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.mm @@ -7,6 +7,8 @@ #include "TextLayoutManager.h" +#include + #import "RCTTextLayoutManager.h" namespace facebook { @@ -34,15 +36,31 @@ Size TextLayoutManager::measure( ParagraphAttributes paragraphAttributes, LayoutConstraints layoutConstraints) const { - auto &attributedString = attributedStringBox.getValue(); + RCTTextLayoutManager *textLayoutManager = (__bridge RCTTextLayoutManager *)self_; - return measureCache_.get( - MeasureCacheKey{attributedString, paragraphAttributes, layoutConstraints}, [&](MeasureCacheKey const &key) { - RCTTextLayoutManager *textLayoutManager = (__bridge RCTTextLayoutManager *)self_; - return [textLayoutManager measureWithAttributedString:attributedString + switch (attributedStringBox.getMode()) { + case AttributedStringBox::Mode::Value: { + auto &attributedString = attributedStringBox.getValue(); + + return measureCache_.get( + MeasureCacheKey{attributedString, paragraphAttributes, layoutConstraints}, [&](MeasureCacheKey const &key) { + return [textLayoutManager measureAttributedString:attributedString paragraphAttributes:paragraphAttributes layoutConstraints:layoutConstraints]; - }); + }); + break; + } + + case AttributedStringBox::Mode::OpaquePointer: { + NSAttributedString *nsAttributedString = + (NSAttributedString *)unwrapManagedObject(attributedStringBox.getOpaquePointer()); + + return [textLayoutManager measureNSAttributedString:nsAttributedString + paragraphAttributes:paragraphAttributes + layoutConstraints:layoutConstraints]; + break; + } + } } } // namespace react