开发者

How would you calculate the point size of a font necessary to best fit a predefined area?

I have an interesting problem. I'm almost there but am curious how others would tackle it. I want to display some multi-line text in a predefined area. I don't know what the text will be or how big the area will be so the function would have to开发者_JAVA技巧 be written generically. You can assume a standard font is always used but the point size is what must change.

Assume you have a function that will draw text that is passed to it in a string parameter. The function has a form object to draw in, and is also passed a rectangle object defining the bounding area of the text on the form. The function needs to display the text on the form in the given rectangle in as large a font as will fit. The challenge for me was is in calculating the size of the font to use to have the text fit as best it can, in the rectangle with minimal white space.

These 2 equations might be useful:

float pixels = (points *dpi)/72f;
float points = (pixels*72f)/dpi);

Also:

float dpi = CreateGraphics().DpiY;


Well, it is tricky. Calculating a point size directly isn't going to work, the width of the text is dependent on the font metrics. Binary search is an obvious strategy but it cannot work in practice. True-type hinting and word wrapping conspire to destabilize it.

I'd recommend you start with binary search, setting hi and lo to reasonable defaults like 72 and 6. Then when the range narrows down to, say, 5 points, start testing each individual point size until you find the largest one that fits. When you write the algorithm, do make sure you count on a size N that fits but a size N-1 that doesn't fit.


There is a significant problem with any solution, which is you need to determine this based on the width as well, which is completely dependent upon the font. This means you need to calculate the width of each word independently based on a predefined point size font. As you change the point size, it is not guaranteed to be consistent.

The solution won't be fast if you want it to be accurate.

I would suggest selecting two point sizes (say 6 and 18) that represent the smallest and mid- to high-point and compute the pixel width of each word in each point size. You could then compute the area of both sizes of text.

You could then extrapolate the area of the rectangle you find appropriate and determine the target size (width and height) using an arbitrary width/height ratio based on the length of text - there is an optimum readable width, for instance.

You will then need to iteratively attempt to word-wrap inside the rectangle and work backwards in point size until the text fits within the rectangle.


binary search over point sizes: Start with the biggest available point size. If it doesn't fit, try half of that, ...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜