How to determine the maximum number of characters specified by a fixed-width font and a maximum width in pixels

Given the number of pixels (say: 300) and the font (fixed type, fixed size, like Consolas), how do I determine the maximum number of characters that I could draw using GDI + ?

Text will not be written to a label or such, but drawn using GDI +:

public void DrawString( string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format ); 

But I want to perform certain text operations before drawing, so I would like to find out the maximum number of characters that I can safely output.

+4
source share
7 answers

The System.Drawing.Graphics MeasureString aligns the line width with a few extra pixels (I don’t know why), so measuring the width of one character of a fixed length and then dividing it by the maximum width gives an estimate of the number of characters that can fit into the maximum width.

To get the maximum number of characters, you need to do something iterative:

 using (Graphics g = this.CreateGraphics()) { string s = ""; SizeF size; int numberOfCharacters = 0; float maxWidth = 50; while (true) { s += "a"; size = g.MeasureString(s, this.Font); if (size.Width > maxWidth) { break; } numberOfCharacters++; } // numberOfCharacters will now contain your max string length } 

Update : You will learn something new every day. Graphics.MeasureString (and TextRenderer) fills the borders with a few extra pixels to place overhanging glyphs. It makes sense, but it can be annoying. Cm:

http://msdn.microsoft.com/en-us/library/6xe5hazb.aspx

Sounds like the best way to do this:

 using (Graphics g = this.CreateGraphics()) { g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; SizeF size = g.MeasureString("a", this.Font, new PointF(0, 0), StringFormat.GenericTypographic); float maxWidth = 50; // or whatever int numberOfCharacters = (int)(maxWidth / size.Width); } 
+6
source

There is also TextRenderer.MeasureText () that produces a different result (this is what is used when drawing Windows controls, so it’s usually more accurate).

There is a discussion about SO somewhere about this, but I cannot find it at the moment.

Edit: This MSDN article goes in more detail.

+3
source

I read several sites and came up with a solution like

 using (System.Drawing.Graphics graphics = CreateGraphics()) { System.Drawing.Size size = TextRenderer.MeasureText(graphics, id, e.Appearance.Font); if (size.Width > e.Column.Width) { int charFit = (int)(((double)e.Column.Width / (double)size.Width) * (double)id.Length); if (id.Length - charFit + 2 < id.Length) { e.DisplayText = string.Format("{0}{1}","...", id.Substring(id.Length - charFit + 2)); } } } 

I made changes to the CustomDrawCell event as a DevExpress grid. Please let me know if you see flaws in this solution.

+1
source

You can use Drawing.Graphics.MeasureString () to get the size of one of your glyphs.
Then just check how many of them fit into the drawing area.

0
source

If it's a fixed width, why not just use the floor (pixelcount / fontwidth)?

0
source

I think System.Drawing.Graphics.MeasureString () can help you. You can combine it with MeasureCharacterRanges or measure the size of one character, and then divide the number of pixels by this value. Something like this, you can play with the results to make it work. I'm sure this will be a working solution, so please ask, something is unclear =)

0
source

Although this is a late answer, I ran into the same problem.

I think the answer to your question is inside your question. The function of the DrawString function that you are talking about has the ability to automatically trim long lines. Take a look at the docs http://msdn.microsoft.com/en-us/library/19sb1bw6.aspx .

The function cuts the line so that it fits into the layout rectangle. You must set the trim property of the stringformat object that you pass as a parameter for something other than none.

0
source

All Articles