Possible Duplicate:
Change NSTextField font size to fit
I am trying to fit a string of variable length (the number of words in the string is unknown) inside a given rectangle. I want to optimally size the string so that it is as big as possible and fits inside the rectangle. Further more, the string should word wrap if there is more than one word and that a word should not be partially rendered on multiple lines. My problem is sometimes a word is partially laid out on multiple lines as seen below. Any suggestions on what I might be doing wrong?
Thank you.
I am using an NSLayoutManager, NSTextStorage and NSTextContainer.
I initialize everything as follows:
textStorage = [[NSTextStorage alloc] initWithString:@""];
layoutManager = [[NSLayoutManager alloc] init];
textContainer = [[NSTextContainer alloc] init];
[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];
paraStyle = [[NSMutableParagraphStyle alloc] init];
[paraStyle setLineBreakMode:NSLineBreakByWordWrapping];
[paraStyle setParagraphStyle:[NSParagraphStyle defaultParagraphStyle]];
[paraStyle setAlignment:NSCenterTextAlignment];
I then compute the font size as follows,
- (float)calculateFontSizeForString:(NSString *)aString andBoxSize:(NSSize)aBox
{
//Create the attributed string
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:aString];
[textStorage setAttributedString:attrString];
[textContainer setContainerSize:NSMakeSize(aBox.width, FLT_MAX)];
[attrString release]; //Clean up
//Initial values
float fontSize = 50.0;
float fontStepSize = 100.0;
NSRect stringRect;
BOOL didFindHeight = NO;
BOOL shouldIncreaseHeight = YES;
while (!didFindHeight)
{
NSMutableDictionary *stringAttributes = [NSMutableDictionary dictionaryWithObjectsAndKeys:
paraStyle, NSParagraphStyleAttributeName,
[NSFont systemFontOfSize:fontSize], NSFontAttributeName, nil];
[textStorage addAttributes:stringAttributes range:NSMakeRange(0, [textStorage length])];
(void)[layoutManager glyphRangeForTextContainer:textContainer];
stringRect = [layoutManager usedRectForTextContainer:textContainer];
if (shouldIncreaseHeight)
{
if (stringRect.size.height > aBox.height)
{
shouldIncreaseHeight = NO;
fontStepSize = fontStepSize/2;
}
fontSize += fontStepSize;
}
else
{
if (stringRect.size.height < aBox.height)
{
shouldIncreaseHeight = YES;
fontStepSize = fontStepSize/2;
if (fontStepSize <= 0.5)
{
didFindHeight = YES;
}
}
if ((fontSize - fontStepSize) <= 0)
{
fontStepSize = fontStepSize/2;
}
else
{
fontSize -= fontStepSize;
}
}
}
return fontSize;
}