Responding to myself, here:

> 1) When I dump rich text into the text view, this method is called *twice* 
> for each starting glyph index, and the proposed rect for the second call is 
> the proposed rect I modify during the first call. For plain text it's only 
> called once for each line. Any explanations for what's going on?

I still have no idea what the answer is.



> 2) Is simply modifying the proposed rect's origin the right approach?
>       a) Does the proposed rect ever include lineFragmentPadding
>       b) Is the proposed rect always a bazillion points wide?

Answers:
        2) Yes.
        2a) No.
        2b) It *think* so.



> 3) Is it always going to be safe to ask the layout manage 
> locationForGlyphAtIndex: for a glyph index < startingGlyphIndex or is there 
> any possibility of an infinite loop?

Answer: yes it's possible to get in an infinite loop. There seems to be no 
solution other than not using locationForGlyphAtIndex. So rather than using the 
location of the first non-whitespace character to determine indentation, the 
answer is to calculate the width of the indentation "manually". I took a look 
at how Xcode does it, and it actually does this as well. 


So here's what I've got:


- (void)getLineFragmentRect:(NSRectPointer)lineFragmentRect 
usedRect:(NSRectPointer)lineFragmentUsedRect 
remainingRect:(NSRectPointer)remainingRect 
forStartingGlyphAtIndex:(NSUInteger)startingGlyphIndex 
proposedRect:(NSRect)proposedRect lineSpacing:(CGFloat)lineSpacing 
paragraphSpacingBefore:(CGFloat)paragraphSpacingBefore 
paragraphSpacingAfter:(CGFloat)paragraphSpacingAfter
{
        AGSourceTextStorage * textStorage = (AGSourceTextStorage 
*)self.layoutManager.textStorage;
        
        if (![textStorage isKindOfClass:[AGSourceTextStorage class]]) {
                [NSException raise:@"" format:@"AGSourceTypesetter's text 
storage is not an AGSourceTextStorage"];
        }
        
        if (textStorage.indentWrappedLines) {
                NSString * string = textStorage.string;
                NSUInteger characterIndex = [self.layoutManager 
characterIndexForGlyphAtIndex:startingGlyphIndex];
                NSRange lineRange = [string 
lineRangeForRange:NSMakeRange(characterIndex, 0)];
                
                
                // Find the line range for the line of text this glyph is a 
part of
                characterIndex = [self.layoutManager 
characterIndexForGlyphAtIndex:startingGlyphIndex];
                lineRange = [string 
lineRangeForRange:NSMakeRange(characterIndex, 0)];
                
                
                // If the startingGlyphIndex's character is *after* the 
beginning of the line
                // of text it's on, then the lineFragmentRect being asked for 
must be part
                // of a wrapped line - which we want to indent.
                if (characterIndex > lineRange.location) {
                        NSUInteger lineNumber = [textStorage 
lineNumberAtCharacterLocation:characterIndex];
                        CGFloat indentation = [textStorage 
indentationForWrappedLineNumber:lineNumber];
                        
                        // TODO: Do we need to do anything special for 
lineFragmentPadding *here*?
                        // ...
                        
                        // Modify the proposed rect to create that indentation
                        CGFloat maxX = NSMaxX(proposedRect);
                        proposedRect.origin.x = indentation;
                        proposedRect.size.width = maxX - indentation;
                }
        }
        
        
        // After having possibly indented the proposed rect, let the standard 
class do its thing.
        [super getLineFragmentRect:lineFragmentRect 
usedRect:lineFragmentUsedRect remainingRect:remainingRect 
forStartingGlyphAtIndex:startingGlyphIndex proposedRect:proposedRect 
lineSpacing:lineSpacing paragraphSpacingBefore:paragraphSpacingBefore 
paragraphSpacingAfter:paragraphSpacingAfter];
}



indentationForWrappedLineNumber in the text storage class counts the number of 
spaces at the beginning of the line, and multiplies that by a standard width 
for a space which was precalculated. 

Seems to work, and it's reassuring to know that Xcode also apparently thinks 
this is a good solution and I think some smart folks work on that. ;-)



--
Seth Willits


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to