• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Typesetter - Fragment Generation
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Typesetter - Fragment Generation


  • Subject: Re: Typesetter - Fragment Generation
  • From: Seth Willits <email@hidden>
  • Date: Thu, 14 Mar 2013 22:16:01 -0700

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 (email@hidden)

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:

This email sent to email@hidden

References: 
 >Typesetter - Fragment Generation (From: Seth Willits <email@hidden>)

  • Prev by Date: Re: Setting the position of new windows
  • Next by Date: Re: Objective-C Question
  • Previous by thread: Typesetter - Fragment Generation
  • Next by thread: Re: [OT] Sync vs ASync Server Comms
  • Index(es):
    • Date
    • Thread