7

I'm trying to estimate the widths in pixel if a text would be rendered in Chrome by using C# for a specific font (Arial 18px) in a tool that I'm creating.

Comparing my results with this tool (uses the browser to render the width): http://searchwilderness.com/tools/pixel-length/ the string:

"Lorem ipsum dolor sit amet, consectetur adipiscing elit."

Is calculated to be 439 pixels wide.

But with this code in C# I get 445px:

var font = new Font("Arial", 18, FontStyle.Regular, GraphicsUnit.Pixel);
var text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
var size = TextRenderer.MeasureText(text, font, new Size(int.MaxValue, int.MaxValue), TextFormatFlags.NoPadding);

Can I modify my code so it renders similar to the browser?

I've tried to output a label with the font and text and compared with browser rendering they do match (+/- 1px).

Niels Bosma
  • 11,758
  • 29
  • 89
  • 148
  • 5
    Perhaps you would have better luck comparing the two different vendors on a lower level. You're comparing a browser to a programming language when in reality that browser uses Webkit which may define its own custom drawing API whereas the API you're using in C# might be using GDI+, directx etc. – The Muffin Man Jan 21 '16 at 20:37
  • 1
    You could compare Graphics.MesaureString() with the StringFormat.GenericTypographic option. But really: 439 vs 445 is pretty close imo. – TaW Jan 24 '16 at 13:07
  • Which one is correct, in IE the searchwilderness is giving 438 on chrome 435? – Anil Jan 25 '16 at 09:41
  • Its a wild guess, but it looks like the "no padding" is being ignored. even if you put the flag `TextFormatFlags.LeftAndRightPadding` do you still get 445px? Is the size difference consistently around 6px? – Balah Jan 25 '16 at 10:34

2 Answers2

3

You can use GDI+ with StringFormat.GenericTypographic instead:

var font = new System.Drawing.Font("Arial", 18, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
var text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
var graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
var size = graphics.MeasureString(text, font, int.MaxValue, System.Drawing.StringFormat.GenericTypographic);

See also: https://stackoverflow.com/a/6404811

Community
  • 1
  • 1
M. Buga
  • 494
  • 2
  • 5
0

The most foolproof way is to build a database of client-rendered character widths. It's far from trivial, measuring all characters for each unique font, variation (bold/italic), size, scaling factors, browser, and platform.

To avoid this, it might be more sensible to do render logic at the client, where actual values can be found using an equivalent to getTextWidth().

John Valentine
  • 247
  • 1
  • 4