How can I calculate (without searching) the font size corresponding to the size of the rectangle?

I want my text to fit a specific rectangle, so I need something to determine the font size. Questions has pretty much done it already, but they do a search that seems terribly inefficient, especially if you want to be able to calculate while changing the drag and drop in real time. The following example can be improved for binary search and height limits, but it does still is a search. Instead of searching, how can I calculate the font size to fit the rectangle?

#define kMaxFontSize 10000 - (CGFloat)fontSizeForAreaSize:(NSSize)areaSize withString:(NSString *)stringToSize usingFont:(NSString *)fontName; { NSFont * displayFont = nil; NSSize stringSize = NSZeroSize; NSMutableDictionary * fontAttributes = [[NSMutableDictionary alloc] init]; if (areaSize.width == 0.0 && areaSize.height == 0.0) return 0.0; NSUInteger fontLoop = 0; for (fontLoop = 1; fontLoop <= kMaxFontSize; fontLoop++) { displayFont = [[NSFontManager sharedFontManager] convertWeight:YES ofFont:[NSFont fontWithName:fontName size:fontLoop]]; [fontAttributes setObject:displayFont forKey:NSFontAttributeName]; stringSize = [stringToSize sizeWithAttributes:fontAttributes]; if (stringSize.width > areaSize.width) break; if (stringSize.height > areaSize.height) break; } [fontAttributes release], fontAttributes = nil; return (CGFloat)fontLoop - 1.0; } 
+4
source share
1 answer

Choose any font size and measure text of that size. Divide all its sizes (width and height) by the same size of your target rectangle, then divide the font size by a larger factor.

Please note that the text will be measured in one line, since there is no maximum width for it. For a long line / line, this can lead to a small font size. For a text field, you just need to enter the minimum size (for example, the small font size of the system) and set the behavior of the field truncation. If you intend to wrap the text, you will need to measure it using what takes a bounding box or size.

Survey code based on this idea:

 -(float)scaleToAspectFit:(CGSize)source into:(CGSize)into padding:(float)padding { return MIN((into.width-padding) / source.width, (into.height-padding) / source.height); } -(NSFont*)fontSizedForAreaSize:(NSSize)size withString:(NSString*)string usingFont:(NSFont*)font; { NSFont* sampleFont = [NSFont fontWithDescriptor:font.fontDescriptor size:12.];//use standard size to prevent error accrual CGSize sampleSize = [string sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:sampleFont, NSFontAttributeName, nil]]; float scale = [self scaleToAspectFit:sampleSize into:size padding:10]; return [NSFont fontWithDescriptor:font.fontDescriptor size:scale * sampleFont.pointSize]; } -(void)windowDidResize:(NSNotification*)notification { text.font = [self fontSizedForAreaSize:text.frame.size withString:text.stringValue usingFont:text.font]; } 
+12
source

All Articles