views:

35

answers:

3

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 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;
A: 

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

sebastian
How would you determine a "fit"?
AlanKley
+2  A: 

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.

Hans Passant
Would not allowing word wrap make it easier?
AlanKley
Yes, much less likely for binary search to fail. But not zero due to hinting. Stop searching when the range is less than 1 point btw.
Hans Passant
+2  A: 
Tom Slick
What if we don't take into account word wrap. We'll assume newlines break up the lines and no one line will extend beyond the rectangle
AlanKley
The important thing is to calculate the width first and don't change it once calculated, you can then use the width to limit the length of lines and end up with a rectangle that will (probably) be one or two extra lines tall. It doesn't always look good, but newspaper columns use a carefully calculated column width to allow maximum readability. Go with US Letter or A4 ratio rectangles (around 1.3:1). Also, the array of word widths would be helpful in quickly iterating solutions.
Tom Slick