Re: Doing NSStringDrawingTruncatesLastVisibleLine with NSLayoutManger
Re: Doing NSStringDrawingTruncatesLastVisibleLine with NSLayoutManger
- Subject: Re: Doing NSStringDrawingTruncatesLastVisibleLine with NSLayoutManger
- From: Eric Gorr <email@hidden>
- Date: Thu, 5 Mar 2009 09:32:24 -0500
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.
p.s. through my searches, I found this useful bit of info...
unichar ellipsis = 0x2026;
_______________________________________________
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