Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed truncation error for ASTextNode2. #1295

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 36 additions & 25 deletions Source/Private/TextExperiment/Component/ASTextLayout.mm
Original file line number Diff line number Diff line change
Expand Up @@ -834,33 +834,44 @@ + (ASTextLayout *)layoutWithContainer:(ASTextContainer *)container text:(NSAttri
}
}
int i = 0;
if (type != kCTLineTruncationStart) { // Middle or End/Tail wants text preceding truncated content.
i = (int)removedLines.count - 1;
while (atLeastOneLine < truncatedWidth && i >= 0) {
if (lastLineText.length > 0 && [lastLineText.string characterAtIndex:lastLineText.string.length - 1] == '\n') { // Explicit newlines are always "long enough".
[lastLineText deleteCharactersInRange:NSMakeRange(lastLineText.string.length - 1, 1)];
break;
if (type == kCTLineTruncationStart) {
// If it is the start type, the last line is made up of the removed lines from the back to the front.
atLeastOneLine = 0;
lastLineText = [NSMutableAttributedString new];
while (atLeastOneLine < truncatedWidth && i < removedLines.count) {
NSMutableAttributedString *nextLineText = [text attributedSubstringFromRange:removedLines[i].range].mutableCopy;
if (nextLineText.length > 0 && [nextLineText.string characterAtIndex:nextLineText.string.length - 1] == '\n') { // Explicit newlines are always "long enough".
[nextLineText deleteCharactersInRange:NSMakeRange(nextLineText.string.length - 1, 1)];
break;
}
[lastLineText insertAttributedString:nextLineText atIndex:0];
atLeastOneLine += removedLines[i++].width;
}
[lastLineText appendAttributedString:[text attributedSubstringFromRange:removedLines[i].range]];
atLeastOneLine += removedLines[i--].width;
}
[lastLineText appendAttributedString:truncationToken];
}
if (type != kCTLineTruncationEnd && removedLines.count > 0) { // Middle or Start/Head wants text following truncated content.
i = 0;
atLeastOneLine = removedLines[i].width;
while (atLeastOneLine < truncatedWidth && i < removedLines.count) {
atLeastOneLine += removedLines[i++].width;
}
for (i--; i >= 0; i--) {
NSAttributedString *nextLine = [text attributedSubstringFromRange:removedLines[i].range];
if ([nextLine.string characterAtIndex:nextLine.string.length - 1] == '\n') { // Explicit newlines are always "long enough".
lastLineText = [NSMutableAttributedString new];
} else {
[lastLineText appendAttributedString:nextLine];
// If the last line width is not greater than truncatedWidth, we should insert truncationToken to head.
// Because the CTLineCreateTruncatedLine() method will do nothing.
if (atLeastOneLine <= truncatedWidth) {
[lastLineText insertAttributedString:truncationToken atIndex:0];
}
}
[lastLineText insertAttributedString:truncationToken atIndex:0];
} else if (type == kCTLineTruncationMiddle) {
// If it is the middle type, we do't known where is the middle position.
// So that the last line should add all removed lines and the CTLineCreateTruncatedLine() method make truncation correct.
i = (int)removedLines.count - 1;
while (i >= 0) {
NSAttributedString *nextLineText = [text attributedSubstringFromRange:removedLines[i].range];
[lastLineText appendAttributedString:nextLineText];
atLeastOneLine += removedLines[i--].width;
}
// If the last line width is not greater than truncatedWidth, we can't make truncation is middle type.
if (atLeastOneLine <= truncatedWidth) {
lastLineText = [text attributedSubstringFromRange:lastLine.range].mutableCopy;
// The result might be greater than truncatedWidth.
[lastLineText appendAttributedString:truncationToken];
// We should set type to end which is like UILabel's behavior.
type = kCTLineTruncationEnd;
}
} else {
// If it is the end type, we simply add it to the end.
[lastLineText appendAttributedString:truncationToken];
}

CTLineRef ctLastLineExtend = CTLineCreateWithAttributedString((CFAttributedStringRef) lastLineText);
Expand Down