This is a long shot, but does anyone know of an algorithm for estimating and categorising text width (for a variable width font) based on its contents?
For example, I\'d
For a nice* client-side solution, you could try a hybrid CSS-and-Javascript approach as suggested by RichieHindle's answer to my question.
Given that you don't know what font the user will see the page in (they can always override your selection, Ctrl-+ the page, etc), the "right" place to do this is on the browser... although browsers don't make it easy!
*
when I say "nice", I mean "probably nice but I haven't actually tried it yet".
I think you should choose one of these solutions:
Of course some mixed estimate is possible, but I think this is too much effort in the wrong direction.
You really have no way of knowing what browser, font settings, screen size etc the client is using. (OK, sometimes the request headers provide an indication, but really nothing consistent or reliable.)
So, I would:
I've generally found this "good enough", for example, for estimating the number of lines that some text will take up on a browser, in order to estimate how many adverts to show next to the text.
If it was really really crucial to you, then I can imagine a convoluted scheme whereby you initially send some Javascript to the client, which then takes a measurement and sends it back to your server, and you then use this information for future pages for that client. I can't imagine it's usually worth the effort, though.
This worked for me:
AffineTransform af = new AffineTransform();
FontRenderContext fr = new FontRenderContext(af,true,true);
Font f = new Font("Arial", 0, 10); // use exact font
double width= f.getStringBounds("my string", fr).getWidth();
Most GUI frameworks provide some way to calculate text metrics for fonts on given output devices.
Using java.awt.FontMetrics
, for example, I believe you can do this:
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
public int measureText(Graphics g, String text) {
g.setFont(new Font("TimesRoman", Font.PLAIN, 12));
FontMetrics metrics = g.getFontMetrics();
return metrics.stringWidth(text);
}
Not tested, but you get the idea.
Under .Net you can use the Graphics.MeasureString method. In C#:
private void MeasureStringMin(PaintEventArgs e)
{
// Set up string.
string measureString = "Measure String";
Font stringFont = new Font("Arial", 16);
// Measure string.
SizeF stringSize = new SizeF();
stringSize = e.Graphics.MeasureString(measureString, stringFont);
// Draw rectangle representing size of string.
e.Graphics.DrawRectangle(new Pen(Color.Red, 1), 0.0F, 0.0F, stringSize.Width, stringSize.Height);
// Draw string to screen.
e.Graphics.DrawString(measureString, stringFont, Brushes.Black, new PointF(0, 0));
}
For a web application, you cannot (really) get a proper estimation. Different fonts have different widths, so that this not only depends on the client (browser) and its zoom and DPI settings, but also on the fonts present on that machine (and operating system) or their substitutions.
If you need exact measuring, create a graphic (bitmap, SVG, or even some PDF or whatever) which will be layouted and rendered on the server and not on the client.