• 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: Doing NSStringDrawingTruncatesLastVisibleLine with NSLayoutManger
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Doing NSStringDrawingTruncatesLastVisibleLine with NSLayoutManger


  • Subject: Re: Doing NSStringDrawingTruncatesLastVisibleLine with NSLayoutManger
  • From: Eric Gorr <email@hidden>
  • Date: Fri, 6 Mar 2009 11:49:21 -0500


On Mar 5, 2009, at 9:32 AM, Eric Gorr wrote:


On Mar 4, 2009, at 4:57 PM, Eric Gorr wrote:

I am drawing a string with a NSLayoutManager by doing:

[layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:NSMakePoint( [self bounds].origin.x,[self bounds].origin.y )];

What I would like is if the string I am drawing goes beyond the last visible line, is for the string to draw a truncated form of itself with an elipses at the last visible part of the string.

As near as I can tell, this is what the NSString drawing option NSStringDrawingTruncatesLastVisibleLine will do.

The paragraph style NSLineBreakByTruncatingTail comes close, but I have a single string that can be drawn over multiple lines and still be visible. The NSLineBreakByTruncatingTail style restrict my drawing to just a single line which isn't enough.

Anyone tried to emulate NSStringDrawingTruncatesLastVisibleLine with NSLayoutManager drawing?

Is there any sample code out there demonstrating the technique?


Here is the start of something that I think will work, but I have a strange problem...

NSRange glyphRange = [layoutManager glyphRangeForTextContainer:container];
NSUInteger index = 0;
NSUInteger x;
NSUInteger numberOfGlyphs = glyphRange.length;
NSMutableArray *visibleLines = [NSMutableArray array];
NSRect bounds = [self bounds];


if ( numberOfGlyphs > 0 ) {
//
// Find visible lines
//
for ( x = 0, index = 0; index < numberOfGlyphs; x++) {
NSRange lineRange;
NSRect lineRect = [layoutManager lineFragmentRectForGlyphAtIndex:index
effectiveRange:&lineRange];



if ( NSContainsRect( bounds, lineRect ) ) {
[visibleLines addObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithRange:lineRange], @"range",
[NSValue valueWithRect:lineRect], @"rect",
nil ]];
}


       index = NSMaxRange(lineRange);
   }

   //
   // draw visible lines
   //
   if ( [visibleLines count] > 0 ) {
       NSDictionary *visibleLine;

for ( visibleLine in visibleLines ) {
NSRange visibleRange = [[visibleLine objectForKey:@"range"] rangeValue];
NSRect visibleRect = [[visibleLine objectForKey:@"rect"] rectValue];


           NSLog( @"%@", NSStringFromRect( visibleRect ) );

[layoutManager drawGlyphsForGlyphRange:visibleRange atPoint:visibleRect.origin];
}
}
}




My text container is of unlimited height, so glyphRange will hold the range for all of the glyphs. I cycle through all of the lines of text remembering those lines which are visible. I then cycle through the visible lines to draw them.

My thought was that since I can obtain the range of characters for the glyphs on the last visible line (characterRangeForGlyphRange:actualGlyphRange:), I could set the NSLineBreakByTruncatingTail NSParagraphStyle for the the characters which appear on the last visible line to the end of the string. This should cause the ellipsis to appear for the last visible line of text.

However, the strange problem is that while I can see the visibleRect.origin's are all correct, the drawing appears to be double spaced which one can see at:

 http://ericgorr.net/cocoadev/outlinetable/doublespace.png

The visibleRect.origin's are:

2009-03-05 09:24:50.723 OutlineCollection-VB[29692:813] {{0, 0}, {70, 12}}
2009-03-05 09:24:50.731 OutlineCollection-VB[29692:813] {{0, 12}, {70, 12}}
2009-03-05 09:24:50.732 OutlineCollection-VB[29692:813] {{0, 24}, {70, 12}}
2009-03-05 09:24:50.733 OutlineCollection-VB[29692:813] {{0, 36}, {70, 12}}
2009-03-05 09:24:50.738 OutlineCollection-VB[29692:813] {{0, 48}, {70, 12}}


But, the characters which should be drawn at {{0, 12}, {70, 12}} are being drawn at {{0, 24}, {70, 12}} and I don't know why. I be interested in learning what I am doing wrong...anyone have any ideas?



My other thought is to use characterRangeForGlyphRange:actualGlyphRange: and glyphRangeForCharacterRange:actualCharacterRange: to figure out where I should clip the string and manually insert an ellipsis. If I do this, I can just use drawGlyphsForGlyphRange:atPoint: on the entire string.


This ended up being the solution...

I make a duplicate of the string I am about to draw, remove characters from it and insert an ellipsis at the end of the string until the string fits into a container which is the same size as the view I am drawing into.


I am still curious why drawing the string line by line wasn't working as expected. Is it is bug?


_______________________________________________

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: 
 >Doing NSStringDrawingTruncatesLastVisibleLine with NSLayoutManger (From: Eric Gorr <email@hidden>)
 >Re: Doing NSStringDrawingTruncatesLastVisibleLine with NSLayoutManger (From: Eric Gorr <email@hidden>)

  • Prev by Date: interpretKeyEvents not handling HOME and END keys?
  • Next by Date: Re: How to search for mop3 files, retrieve those file and play these file into apps
  • Previous by thread: Re: Doing NSStringDrawingTruncatesLastVisibleLine with NSLayoutManger
  • Next by thread: Re: Checking for NULL (was "Re: Can't get setDelegate to work...")
  • Index(es):
    • Date
    • Thread