@@ -395,6 +395,53 @@ + (ASTextLayout *)layoutWithContainer:(ASTextContainer *)container text:(NSAttri
395395 return [self layoutWithContainer: container text: text range: NSMakeRange (0 , text.length)];
396396}
397397
398+ + (BOOL )_isBeginningLineIndexOfParagraph: (NSAttributedString *)text index: (NSUInteger )index
399+ {
400+ NSString *string = [text string ];
401+ NSUInteger length = [string length ];
402+
403+ NSRange paragraphRange = [self _rangeOfParagraphsContainingRange: string range: NSMakeRange (0 , 0 ) parBegIndex: NULL parEndIndex: NULL ];
404+
405+ while (paragraphRange.length )
406+ {
407+ if (index == paragraphRange.location ) {
408+ return true ;
409+ }
410+ if (index < paragraphRange.location ) {
411+ return false ;
412+ }
413+ NSUInteger nextParagraphBegin = NSMaxRange (paragraphRange);
414+ if (nextParagraphBegin>=length)
415+ {
416+ break ;
417+ }
418+ // next paragraph
419+ paragraphRange = [self _rangeOfParagraphsContainingRange: string range: NSMakeRange (nextParagraphBegin, 0 ) parBegIndex: NULL parEndIndex: NULL ];
420+ }
421+ return false ;
422+ }
423+
424+ + (NSRange )_rangeOfParagraphsContainingRange: (NSString *)text range: (NSRange )range parBegIndex: (NSUInteger *)parBegIndex parEndIndex: (NSUInteger *)parEndIndex
425+ {
426+ // get beginning and end of paragraph containing the replaced range
427+ CFIndex beginIndex;
428+ CFIndex endIndex;
429+
430+ CFStringGetParagraphBounds ((__bridge CFStringRef)text, CFRangeMake (range.location , range.length ), &beginIndex, &endIndex, NULL );
431+
432+ if (parBegIndex)
433+ {
434+ *parBegIndex = beginIndex;
435+ }
436+
437+ if (parEndIndex)
438+ {
439+ *parEndIndex = endIndex;
440+ }
441+ // endIndex is the first character of the following paragraph, so we don't need to add 1
442+ return NSMakeRange (beginIndex, endIndex - beginIndex);
443+ }
444+
398445+ (ASTextLayout *)layoutWithContainer: (ASTextContainer *)container text: (NSAttributedString *)text range: (NSRange )range {
399446 ASTextLayout *layout = NULL ;
400447 CGPathRef cgPath = nil ;
@@ -864,10 +911,25 @@ + (ASTextLayout *)layoutWithContainer:(ASTextContainer *)container text:(NSAttri
864911 [lastLineText insertAttributedString: truncationToken atIndex: 0 ];
865912 }
866913 }
914+
915+ CGFloat headIndent = 0 ;
916+
917+ BOOL isAtBeginOfParagraph = [self _isBeginningLineIndexOfParagraph: text index: lastLine.range.location];
918+ // get the paragraph style at this index
919+ CTParagraphStyleRef paragraphStyle = (__bridge CTParagraphStyleRef)[text attribute: (id )kCTParagraphStyleAttributeName atIndex: lastRange.location effectiveRange: NULL ];
920+
921+ if (isAtBeginOfParagraph)
922+ {
923+ CTParagraphStyleGetValueForSpecifier (paragraphStyle, kCTParagraphStyleSpecifierFirstLineHeadIndent , sizeof (headIndent), &headIndent);
924+ }
925+ else
926+ {
927+ CTParagraphStyleGetValueForSpecifier (paragraphStyle, kCTParagraphStyleSpecifierHeadIndent , sizeof (headIndent), &headIndent);
928+ }
867929
868930 CTLineRef ctLastLineExtend = CTLineCreateWithAttributedString ((CFAttributedStringRef) lastLineText);
869931 if (ctLastLineExtend) {
870- CTLineRef ctTruncatedLine = CTLineCreateTruncatedLine (ctLastLineExtend, truncatedWidth, type, truncationTokenLine);
932+ CTLineRef ctTruncatedLine = CTLineCreateTruncatedLine (ctLastLineExtend, truncatedWidth - headIndent , type, truncationTokenLine);
871933 CFRelease (ctLastLineExtend);
872934 if (ctTruncatedLine) {
873935 truncatedLine = [ASTextLine lineWithCTLine: ctTruncatedLine position: lastLine.position vertical: isVerticalForm];
0 commit comments