NSLayoutManager broken on Jaguar?
NSLayoutManager broken on Jaguar?
- Subject: NSLayoutManager broken on Jaguar?
- From: Steve Gehrman <email@hidden>
- Date: Fri, 2 Aug 2002 05:15:06 -0700
Under Jaguar my text drawing code stopped working. The problem is that
the text does not wrap around my container. It just draws a long
horizontal line and doesn't wrap at the end of the container.
This code works great on < 10.2
the code is pretty basic, I'm just setting the container size, and
calling lineFragmentUsedRectForGlyphAtIndex to get each line and then
drawing the paginated lines.
- (NSLayoutManager*)newLayoutManager;
{
NSLayoutManager* layoutManager;
NSTextContainer *textContainer;
layoutManager = [[[NSLayoutManager alloc] init] autorelease];
textContainer = [[[NSTextContainer allocWithZone:NULL]
initWithContainerSize:NSMakeSize(1.0e6, 1.0e6)] autorelease];
[textContainer setWidthTracksTextView:NO];
[textContainer setHeightTracksTextView:NO];
[textContainer
setLineFragmentPadding:kBrowserTextLineFragmentPadding];
[layoutManager addTextContainer:textContainer];
return layoutManager;
}
- (NSRect)doDrawTextStorage:(NSTextStorage*)textStorage
inRect:(NSRect)rect drawLines:(int)drawLines
backColor:(NSColor*)backColor verticallyCenter:(BOOL)verticallyCenter
drawText:(BOOL)drawText shadowText:(BOOL)shadowText;
{
NSRect minRect = NSZeroRect;
if ([textStorage length] > 0)
{
id obj=nil;
NSTextContainer *textContainer;
NSRange glyphRange;
NSSize containerSize = rect.size;
NSLayoutManager *layoutManager;
BOOL usingSharedLayoutMgr = NO;
// we add a layout manager if non exists
if ([[textStorage layoutManagers] count] == 0)
{
usingSharedLayoutMgr = YES;
layoutManager = _sharedLayoutManager;
[textStorage addLayoutManager:_sharedLayoutManager];
}
else
layoutManager = [[textStorage layoutManagers]
objectAtIndex:0];
textContainer = [[layoutManager textContainers] objectAtIndex:0];
if (shadowText)
obj = [DrawShadowTextHack turnOnShadowedDrawing];
// some font's or text (like japanese characters or Arial Black)
need more space
// just set the height+20 and detect when the line is past the
bottom of the rect
containerSize.height += 20;
if (!NSEqualSizes([textContainer containerSize], containerSize))
[textContainer setContainerSize:containerSize];
// Force layout of the text and find out how much of it fits in
the container.
glyphRange = [layoutManager
glyphRangeForTextContainer:textContainer];
if (glyphRange.length > 0)
{
NSRect lineRect, offsetLineRect, textRect = rect;
unsigned glyphIndex=0;
NSRange range;
int i, numLines = 0;
// first calc height
while (YES)
{
lineRect = [layoutManager
lineFragmentUsedRectForGlyphAtIndex:glyphIndex effectiveRange:&range];
offsetLineRect = lineRect;
offsetLineRect.origin.x += rect.origin.x;
offsetLineRect.origin.y += rect.origin.y;
// check to see if the line's bottom is >= than the
drawRects bottom
if ((numLines > 0) && NSMaxY(offsetLineRect) >
NSMaxY(rect))
break;
minRect = NSUnionRect(minRect, lineRect);
numLines++;
if (NSMaxRange(range) >= NSMaxRange(glyphRange))
break;
// limit how many lines are drawn with the drawLines
parameter
if (drawLines != 0)
{
if (numLines >= drawLines)
break;
}
glyphIndex = NSMaxRange(range);
}
// center the text vertically if necessary
if (verticallyCenter)
{
if (minRect.size.height < rect.size.height)
textRect.origin.y += ((rect.size.height -
minRect.size.height) / 2);
else if (minRect.size.height > rect.size.height)
textRect.origin.y -= ((minRect.size.height -
rect.size.height) / 2);
}
minRect.origin.x += textRect.origin.x;
minRect.origin.y += textRect.origin.y;
if (drawText)
{
glyphIndex=0;
// now draw, the second time should be fast, I'm
assuming it's paginated
for (i=0;i<numLines;i++)
{
lineRect = [layoutManager
lineFragmentUsedRectForGlyphAtIndex:glyphIndex effectiveRange:&range];
// draw back color
if (backColor)
{
lineRect.origin.x += textRect.origin.x;
lineRect.origin.y += textRect.origin.y;
if (shadowText)
[DrawShadowTextHack
turnOffShadowedDrawing:obj];
[backColor set];
NSRectFill(lineRect);
if (shadowText)
obj = [DrawShadowTextHack
turnOnShadowedDrawing];
}
[layoutManager drawGlyphsForGlyphRange:range
atPoint:textRect.origin];
// draw shadowed text twice to make the shadow
darker SNG hack
if (shadowText)
[layoutManager drawGlyphsForGlyphRange:range
atPoint:textRect.origin];
glyphIndex = NSMaxRange(range);
}
}
}
if (usingSharedLayoutMgr)
[textStorage removeLayoutManager:_sharedLayoutManager];
if (shadowText)
[DrawShadowTextHack turnOffShadowedDrawing:obj];
}
return minRect;
}
--
Steve Gehrman
email@hidden
http://www.cocoatech.com
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.