@@ -29,12 +29,6 @@ static inline CGFloat CGFloatValueFrom(NSNumber * _Nullable num) {
2929#endif
3030}
3131
32- #if CGFLOAT_IS_DOUBLE
33- #define CGRound round
34- #else
35- #define CGRound roundf
36- #endif
37-
3832#define A_SIZE (x ) (sizeof (x)/sizeof (x)[0 ])
3933
4034/*
@@ -123,25 +117,31 @@ - (dispatch_queue_t)methodQueue {
123117 const CGFloat epsilon = 0.001 ;
124118 const CGFloat width = MIN (RCTCeilPixelValue (size.width + epsilon), maxSize.width );
125119 const CGFloat height = MIN (RCTCeilPixelValue (size.height + epsilon), maxSize.height );
126- const CGFloat lineCount = CGRound (size.height / (font.lineHeight + font.leading ));
120+ const NSInteger lineCount = [self getLineCount: layoutManager];
121+
122+ NSMutableDictionary *result = [[NSMutableDictionary alloc ]
123+ initWithObjectsAndKeys: @(width), @" width" ,
124+ @(height), @" height" ,
125+ @(lineCount), @" lineCount" ,
126+ nil ];
127127
128128 if ([options[@" usePreciseWidth" ] boolValue ]) {
129129 const CGFloat lastIndex = layoutManager.numberOfGlyphs - 1 ;
130130 const CGSize lastSize = [layoutManager lineFragmentUsedRectForGlyphAtIndex: lastIndex
131131 effectiveRange: nil ].size ;
132- resolve (@{
133- @" width" : @(width),
134- @" height" : @(height),
135- @" lastLineWidth" : @(lastSize.width ),
136- @" lineCount" : @(lineCount),
137- });
138- } else {
139- resolve (@{
140- @" width" : @(width),
141- @" height" : @(height),
142- @" lineCount" : @(lineCount),
143- });
132+ [result setValue: @(lastSize.width) forKey: @" lastLineWidth" ];
144133 }
134+
135+ const CGFloat optLine = CGFloatValueFrom (options[@" lineInfoForLine" ]);
136+ if (!isnan (optLine) && optLine >= 0 ) {
137+ const NSInteger line = MIN ((NSInteger ) optLine, lineCount);
138+ NSDictionary *lineInfo = [self getLineInfo: layoutManager str: text lineNo: line];
139+ if (lineInfo) {
140+ [result setValue: lineInfo forKey: @" lineInfo" ];
141+ }
142+ }
143+
144+ resolve (result);
145145}
146146
147147/* *
@@ -371,6 +371,66 @@ - (dispatch_queue_t)methodQueue {
371371// ============================================================================
372372//
373373
374+ /* *
375+ * Get extended info for a given line number.
376+ * @since v2.1.0
377+ */
378+ - (NSInteger )getLineCount : (NSLayoutManager *)layoutManager {
379+ NSRange lineRange;
380+ NSUInteger glyphCount = layoutManager.numberOfGlyphs ;
381+ NSInteger lineCount = 0 ;
382+
383+ for (NSUInteger index = 0 ; index < glyphCount; lineCount++) {
384+ [layoutManager
385+ lineFragmentUsedRectForGlyphAtIndex: index effectiveRange: &lineRange withoutAdditionalLayout: YES ];
386+ index = NSMaxRange (lineRange);
387+ }
388+
389+ return lineCount;
390+ }
391+
392+ /* *
393+ * Get extended info for a given line number.
394+ * @since v2.1.0
395+ */
396+ - (NSDictionary *)getLineInfo : (NSLayoutManager *)layoutManager str : (NSString *)str lineNo : (NSInteger )line {
397+ CGRect lineRect = CGRectZero;
398+ NSRange lineRange;
399+ NSUInteger glyphCount = layoutManager.numberOfGlyphs ;
400+ NSInteger lineCount = 0 ;
401+
402+ for (NSUInteger index = 0 ; index < glyphCount; lineCount++) {
403+ lineRect = [layoutManager
404+ lineFragmentUsedRectForGlyphAtIndex: index
405+ effectiveRange: &lineRange
406+ withoutAdditionalLayout: YES ];
407+ index = NSMaxRange (lineRange);
408+
409+ if (line == lineCount) {
410+ NSCharacterSet *ws = NSCharacterSet .whitespaceAndNewlineCharacterSet ;
411+ NSRange charRange = [layoutManager characterRangeForGlyphRange: lineRange actualGlyphRange: nil ];
412+ NSUInteger start = charRange.location ;
413+ index = NSMaxRange (charRange);
414+ /*
415+ Get the trimmed range of chars for the glyph range, to be consistent
416+ w/android, but the width here will include the trailing whitespace.
417+ */
418+ while (index > start && [ws characterIsMember: [str characterAtIndex: index - 1 ]]) {
419+ index--;
420+ }
421+ return @{
422+ @" line" : @(line),
423+ @" start" : @(start),
424+ @" end" : @(index),
425+ @" bottom" : @(lineRect.origin .y + lineRect.size .height ),
426+ @" width" : @(lineRect.size .width )
427+ };
428+ }
429+ }
430+
431+ return nil ;
432+ }
433+
374434/* *
375435 * Create a scaled font based on the given specs.
376436 *
0 commit comments