Skip to content

Commit

Permalink
Reland: [iOS] Fixes ellipsis carries background from trimmed text
Browse files Browse the repository at this point in the history
  • Loading branch information
zhongwuzw committed Jul 12, 2024
1 parent c16761d commit cf94a8b
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
46 changes: 46 additions & 0 deletions packages/react-native/Libraries/Text/Text/RCTTextShadowView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,59 @@ - (NSTextStorage *)textStorageAndLayoutManagerThatFitsSize:(CGSize)size exclusiv
maximumFontSize:self.textAttributes.effectiveFont.pointSize];
}

[self processTruncatedAttributedText:textStorage textContainer:textContainer layoutManager:layoutManager];

if (!exclusiveOwnership) {
[_cachedTextStorages setObject:textStorage forKey:key];
}

return textStorage;
}

- (void)processTruncatedAttributedText:(NSTextStorage *)textStorage
textContainer:(NSTextContainer *)textContainer
layoutManager:(NSLayoutManager *)layoutManager
{
if (_maximumNumberOfLines > 0) {
[layoutManager ensureLayoutForTextContainer:textContainer];
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
__block int line = 0;
[layoutManager
enumerateLineFragmentsForGlyphRange:glyphRange
usingBlock:^(
CGRect rect,
CGRect usedRect,
NSTextContainer *_Nonnull _,
NSRange lineGlyphRange,
BOOL *_Nonnull stop) {
if (line == textContainer.maximumNumberOfLines - 1) {
NSRange truncatedRange = [layoutManager
truncatedGlyphRangeInLineFragmentForGlyphAtIndex:lineGlyphRange.location];

if (truncatedRange.location != NSNotFound) {
NSRange characterRange =
[layoutManager characterRangeForGlyphRange:truncatedRange
actualGlyphRange:nil];
if (characterRange.location > 0 && characterRange.length > 0) {
// Remove color attributes for truncated range
for (NSAttributedStringKey key in
@[ NSForegroundColorAttributeName, NSBackgroundColorAttributeName ]) {
[textStorage removeAttribute:key range:characterRange];
id attribute = [textStorage attribute:key
atIndex:characterRange.location - 1
effectiveRange:nil];
if (attribute) {
[textStorage addAttribute:key value:attribute range:characterRange];
}
}
}
}
}
line++;
}];
}
}

- (void)layoutWithMetrics:(RCTLayoutMetrics)layoutMetrics layoutContext:(RCTLayoutContext)layoutContext
{
// If the view got new `contentFrame`, we have to redraw it because
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ - (void)drawAttributedString:(AttributedString)attributedString
#endif

NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];

[self processTruncatedAttributedText:textStorage textContainer:textContainer layoutManager:layoutManager];

[layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:frame.origin];
[layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:frame.origin];

Expand Down Expand Up @@ -123,6 +126,49 @@ - (void)drawAttributedString:(AttributedString)attributedString
}
}

- (void)processTruncatedAttributedText:(NSTextStorage *)textStorage
textContainer:(NSTextContainer *)textContainer
layoutManager:(NSLayoutManager *)layoutManager
{
if (textContainer.maximumNumberOfLines > 0) {
[layoutManager ensureLayoutForTextContainer:textContainer];
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
__block int line = 0;
[layoutManager
enumerateLineFragmentsForGlyphRange:glyphRange
usingBlock:^(
CGRect rect,
CGRect usedRect,
NSTextContainer *_Nonnull _,
NSRange lineGlyphRange,
BOOL *_Nonnull stop) {
if (line == textContainer.maximumNumberOfLines - 1) {
NSRange truncatedRange = [layoutManager
truncatedGlyphRangeInLineFragmentForGlyphAtIndex:lineGlyphRange.location];
if (truncatedRange.location != NSNotFound) {
NSRange characterRange =
[layoutManager characterRangeForGlyphRange:truncatedRange
actualGlyphRange:nil];
if (characterRange.location > 0 && characterRange.length > 0) {
// Remove color attributes for truncated range
for (NSAttributedStringKey key in
@[ NSForegroundColorAttributeName, NSBackgroundColorAttributeName ]) {
[textStorage removeAttribute:key range:characterRange];
id attribute = [textStorage attribute:key
atIndex:characterRange.location - 1
effectiveRange:nil];
if (attribute) {
[textStorage addAttribute:key value:attribute range:characterRange];
}
}
}
}
}
line++;
}];
}
}

- (LinesMeasurements)getLinesForAttributedString:(facebook::react::AttributedString)attributedString
paragraphAttributes:(facebook::react::ParagraphAttributes)paragraphAttributes
size:(CGSize)size
Expand Down

0 comments on commit cf94a8b

Please sign in to comment.