Skip to content

Commit 614e410

Browse files
sammy-SCkelset
authored andcommitted
Extract NSTextStorage measure into a helper method (facebook#36772)
Summary: Pull Request resolved: facebook#36772 changelog: [internal] Move NSTextStorage into a private method. Reviewed By: cipolleschi Differential Revision: D44620262 fbshipit-source-id: 4855879f3c3a09b2f352ab84c906c7bd106aebda
1 parent d3c94b4 commit 614e410

File tree

1 file changed

+82
-75
lines changed
  • packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager

1 file changed

+82
-75
lines changed

packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm

Lines changed: 82 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -56,43 +56,7 @@ - (TextMeasurement)measureNSAttributedString:(NSAttributedString *)attributedStr
5656
textStorage.layoutManagers.firstObject.textContainers.firstObject.size = maximumSize;
5757
}
5858

59-
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
60-
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
61-
[layoutManager ensureLayoutForTextContainer:textContainer];
62-
63-
CGSize size = [layoutManager usedRectForTextContainer:textContainer].size;
64-
65-
size = (CGSize){RCTCeilPixelValue(size.width), RCTCeilPixelValue(size.height)};
66-
67-
__block auto attachments = TextMeasurement::Attachments{};
68-
69-
[textStorage
70-
enumerateAttribute:NSAttachmentAttributeName
71-
inRange:NSMakeRange(0, textStorage.length)
72-
options:0
73-
usingBlock:^(NSTextAttachment *attachment, NSRange range, BOOL *stop) {
74-
if (!attachment) {
75-
return;
76-
}
77-
78-
CGSize attachmentSize = attachment.bounds.size;
79-
CGRect glyphRect = [layoutManager boundingRectForGlyphRange:range inTextContainer:textContainer];
80-
81-
UIFont *font = [textStorage attribute:NSFontAttributeName atIndex:range.location effectiveRange:nil];
82-
83-
CGRect frame = {
84-
{glyphRect.origin.x,
85-
glyphRect.origin.y + glyphRect.size.height - attachmentSize.height + font.descender},
86-
attachmentSize};
87-
88-
auto rect = facebook::react::Rect{
89-
facebook::react::Point{frame.origin.x, frame.origin.y},
90-
facebook::react::Size{frame.size.width, frame.size.height}};
91-
92-
attachments.push_back(TextMeasurement::Attachment{rect, false});
93-
}];
94-
95-
return TextMeasurement{{size.width, size.height}, attachments};
59+
return [self _measureTextStorage:textStorage];
9660
}
9761

9862
- (TextMeasurement)measureAttributedString:(AttributedString)attributedString
@@ -178,35 +142,6 @@ - (LinesMeasurements)getLinesForAttributedString:(AttributedString)attributedStr
178142
return paragraphLines;
179143
}
180144

181-
- (NSTextStorage *)_textStorageForNSAttributesString:(NSAttributedString *)attributedString
182-
paragraphAttributes:(ParagraphAttributes)paragraphAttributes
183-
size:(CGSize)size
184-
{
185-
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:size];
186-
187-
textContainer.lineFragmentPadding = 0.0; // Note, the default value is 5.
188-
textContainer.lineBreakMode = paragraphAttributes.maximumNumberOfLines > 0
189-
? RCTNSLineBreakModeFromEllipsizeMode(paragraphAttributes.ellipsizeMode)
190-
: NSLineBreakByClipping;
191-
textContainer.maximumNumberOfLines = paragraphAttributes.maximumNumberOfLines;
192-
193-
NSLayoutManager *layoutManager = [NSLayoutManager new];
194-
layoutManager.usesFontLeading = NO;
195-
[layoutManager addTextContainer:textContainer];
196-
197-
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString];
198-
199-
[textStorage addLayoutManager:layoutManager];
200-
201-
if (paragraphAttributes.adjustsFontSizeToFit) {
202-
CGFloat minimumFontSize = !isnan(paragraphAttributes.minimumFontSize) ? paragraphAttributes.minimumFontSize : 4.0;
203-
CGFloat maximumFontSize = !isnan(paragraphAttributes.maximumFontSize) ? paragraphAttributes.maximumFontSize : 96.0;
204-
[textStorage scaleFontSizeToFitSize:size minimumFontSize:minimumFontSize maximumFontSize:maximumFontSize];
205-
}
206-
207-
return textStorage;
208-
}
209-
210145
- (NSTextStorage *)textStorageForAttributesString:(AttributedString)attributedString
211146
paragraphAttributes:(ParagraphAttributes)paragraphAttributes
212147
size:(CGSize)size
@@ -246,15 +181,6 @@ - (SharedEventEmitter)getEventEmitterWithAttributeString:(AttributedString)attri
246181
return nil;
247182
}
248183

249-
- (NSAttributedString *)_nsAttributedStringFromAttributedString:(AttributedString)attributedString
250-
{
251-
auto sharedNSAttributedString = _cache.get(attributedString, [](AttributedString attributedString) {
252-
return wrapManagedObject(RCTNSAttributedStringFromAttributedString(attributedString));
253-
});
254-
255-
return unwrapManagedObject(sharedNSAttributedString);
256-
}
257-
258184
- (void)getRectWithAttributedString:(AttributedString)attributedString
259185
paragraphAttributes:(ParagraphAttributes)paragraphAttributes
260186
enumerateAttribute:(NSString *)enumerateAttribute
@@ -294,4 +220,85 @@ - (void)getRectWithAttributedString:(AttributedString)attributedString
294220
}];
295221
}
296222

223+
#pragma mark - Private
224+
225+
- (NSTextStorage *)_textStorageForNSAttributesString:(NSAttributedString *)attributedString
226+
paragraphAttributes:(ParagraphAttributes)paragraphAttributes
227+
size:(CGSize)size
228+
{
229+
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:size];
230+
231+
textContainer.lineFragmentPadding = 0.0; // Note, the default value is 5.
232+
textContainer.lineBreakMode = paragraphAttributes.maximumNumberOfLines > 0
233+
? RCTNSLineBreakModeFromEllipsizeMode(paragraphAttributes.ellipsizeMode)
234+
: NSLineBreakByClipping;
235+
textContainer.maximumNumberOfLines = paragraphAttributes.maximumNumberOfLines;
236+
237+
NSLayoutManager *layoutManager = [NSLayoutManager new];
238+
layoutManager.usesFontLeading = NO;
239+
[layoutManager addTextContainer:textContainer];
240+
241+
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString];
242+
243+
[textStorage addLayoutManager:layoutManager];
244+
245+
if (paragraphAttributes.adjustsFontSizeToFit) {
246+
CGFloat minimumFontSize = !isnan(paragraphAttributes.minimumFontSize) ? paragraphAttributes.minimumFontSize : 4.0;
247+
CGFloat maximumFontSize = !isnan(paragraphAttributes.maximumFontSize) ? paragraphAttributes.maximumFontSize : 96.0;
248+
[textStorage scaleFontSizeToFitSize:size minimumFontSize:minimumFontSize maximumFontSize:maximumFontSize];
249+
}
250+
251+
return textStorage;
252+
}
253+
254+
- (NSAttributedString *)_nsAttributedStringFromAttributedString:(AttributedString)attributedString
255+
{
256+
auto sharedNSAttributedString = _cache.get(attributedString, [](AttributedString attributedString) {
257+
return wrapManagedObject(RCTNSAttributedStringFromAttributedString(attributedString));
258+
});
259+
260+
return unwrapManagedObject(sharedNSAttributedString);
261+
}
262+
263+
- (TextMeasurement)_measureTextStorage:(NSTextStorage *)textStorage
264+
{
265+
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
266+
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
267+
[layoutManager ensureLayoutForTextContainer:textContainer];
268+
269+
CGSize size = [layoutManager usedRectForTextContainer:textContainer].size;
270+
271+
size = (CGSize){RCTCeilPixelValue(size.width), RCTCeilPixelValue(size.height)};
272+
273+
__block auto attachments = TextMeasurement::Attachments{};
274+
275+
[textStorage
276+
enumerateAttribute:NSAttachmentAttributeName
277+
inRange:NSMakeRange(0, textStorage.length)
278+
options:0
279+
usingBlock:^(NSTextAttachment *attachment, NSRange range, BOOL *stop) {
280+
if (!attachment) {
281+
return;
282+
}
283+
284+
CGSize attachmentSize = attachment.bounds.size;
285+
CGRect glyphRect = [layoutManager boundingRectForGlyphRange:range inTextContainer:textContainer];
286+
287+
UIFont *font = [textStorage attribute:NSFontAttributeName atIndex:range.location effectiveRange:nil];
288+
289+
CGRect frame = {
290+
{glyphRect.origin.x,
291+
glyphRect.origin.y + glyphRect.size.height - attachmentSize.height + font.descender},
292+
attachmentSize};
293+
294+
auto rect = facebook::react::Rect{
295+
facebook::react::Point{frame.origin.x, frame.origin.y},
296+
facebook::react::Size{frame.size.width, frame.size.height}};
297+
298+
attachments.push_back(TextMeasurement::Attachment{rect, false});
299+
}];
300+
301+
return TextMeasurement{{size.width, size.height}, attachments};
302+
}
303+
297304
@end

0 commit comments

Comments
 (0)