Calculate max font size that fits in a rect?
I'm attempting to find the maximum font size that will fit in a given rect for a given string. The goal of the algorithm is to fill as much of the rect as possible with as large of a font as possible. My approach -- which is modified from one I found online -- does a fair job, but it often doesn't fill the entire rect. I'd love to see some collaboration on how to improve this algorithm so that everyone might benefit from it:
-(float) maxFontSizeThatFitsForString:(NSString*)_string
inRect:(CGRect)rect
withFont:(NSString *)fontName
onDevice:(int)device
{
// this is the maximum size font that will fit on the device
float _fontSize = maxFontSize;
float widthTweak;
// how much to change the font each iteration. smaller
// numbers will come closer to an exact match at the
// expense of increasing the number of iterations.
float fontDelta = 2.0;
// sometimes sizeWithFont will break up a word
// if the tweak is not applied. also note that
// this should probably take into account the
// font being used -- some fonts work better
// than others using sizeWithFont.
if(device == IPAD)
widthTweak = 0.2;
else
widthTweak = 0.2;
CGSize tallerSize =
CGSizeMake(rect.size.width-(rect.size.width*widthTweak), 100000);
CGSize stringSize =
[_string sizeWithFont:[UIFont fontWithName:fontName size:_fontSize]
constrainedToSize:tallerSize];
while (stringSize.height >= rect.size.height)
{
_fontSize -= fontDelta;
stringSize = [_string sizeWithFont:[UIFont fontWithName:fontName
size:_fontSize]
constrainedToSize:tallerSize];
}
return _fontSize;
}
Use the following method to calculate the font which can fit, for a given rect and string.
You can change the font to the one which you require. Also, If required you can add a default font height;
Method is self explanatory.
-(UIFont*) getFontTofitInRect:(CGRect) rect forText:(NSString*) text {
CGFloat baseFont=0;
UIFont *myFont=[UIFont systemFontOfSize:baseFont];
CGSize fSize=[text sizeWithFont:myFont];
CGFloat step=0.1f;
BOOL stop=NO;
CGFloat previousH;
while (!stop) {
myFont=[UIFont systemFontOfSize:baseFont+step ];
fSize=[text sizeWithFont:myFont constrainedToSize:rect.size lineBreakMode:UILineBreakModeWordWrap];
if(fSize.height+myFont.lineHeight>rect.size.height){
myFont=[UIFont systemFontOfSize:previousH];
fSize=CGSizeMake(fSize.width, previousH);
stop=YES;
}else {
previousH=baseFont+step;
}
step++;
}
return myFont;
}
There is no need to waste time doing loops. First, measure the text width and height at the max and min font point settings. Depending on whichever is more restrictive, width or height, use the following math:
If width is more restrictive (ie, maxPointWidth / rectWidth > maxPointHeight / rectHeight
) use:
pointSize = minPointSize + rectWidth * [(maxPointSize - minPointSize) / (maxPointWidth - minPointWidth)]
Else, if height is more restrictive use:
pointSize = minPointSize + rectHeight * [(maxPointSize - minPointSize) / (maxPointHeight - minPointHeight)]
It may be impossible to fill a rectangle completely.
Say at a certain font size you have two lines of text, both filling the screen horizontally, but vertically you have almost but not quite three lines of space.
If you increase the font size just a tiny bit, then the lines don't fit anymore, so you need three lines, but three lines don't fit vertically.
So you have no choice but to live with the vertical gap.
链接地址: http://www.djcxy.com/p/48584.html上一篇: 如何在一个WPF应用程序中有多个窗口?
下一篇: 计算适合于矩形的最大字体大小?