[Q] MeasureString results and mono-space fonts

  • Thread starter Thread starter Stuart Norris
  • Start date Start date
S

Stuart Norris

Dear Group,

I have a question about the result from ‘graphics.MeasureString' when
using a mono-spaced font. Firstly I assume that Courier New font is
mono-spaced, ie each character takes up the same space when drawn on
the screen.

I am working on a program that requires displaying data in fixed width
font. I assumed that with ‘graphics.MeasureString' I could calculate
the width of the string when drawn in a specified font.

However as can be seen from my simple example, that I have attached,
where I have overridden the ‘OnPaint' method for a label, with a
mono-spaced font, that the width of two characters is not the
summation of two single characters.

In my program I determined that width of "WW" is not the same as "W" +
"W". From lines 62 – 65 of my example

"W" or "1" - 18.07 pixels wide
"WW" - 29.82 pixels wide
"WWWWWWWW" - 100.29 pixels wide

Why are the widths not exactly the same for each character?

I was hoping to use the information to render my display by moving to
specific places on the screen to render the string.

What am I missing about MeasureString and fonts?


Thanks again for any comments.


Stuart

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace test
{
public class Form1 : System.Windows.Forms.Form
{
private myLabel label;
private System.ComponentModel.Container components = null;
public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code

private void InitializeComponent()
{
this.label = new myLabel();
this.label.Location = new System.Drawing.Point(48, 72);
this.label.Name = "Label";
this.label.Size = new System.Drawing.Size(168, 104);
this.label.TabIndex = 0;
this.label.Text = "Hi";
this.label.Font = new System.Drawing.Font("Courier New", 14.25F,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
((System.Byte)(0)));
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.label);
this.Name = "Form1";
this.Text = "Form1";
}
#endregion

[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
public class myLabel : Label
{
protected override void OnPaint(PaintEventArgs e)
{
Graphics graphics = e.Graphics;
Font font = base.Font;

SizeF one = graphics.MeasureString("1", font);
SizeF wone = graphics.MeasureString("W", font);
SizeF two = graphics.MeasureString("WW", font);
SizeF ten = graphics.MeasureString("WWWWWWWW", font);
}
}
}
 
You should try using MeasureCharacterRanges, as this provides more accurate
results.

--
John Wood
EMail: first name, dot, last name, at priorganize.com

Stuart Norris said:
Dear Group,

I have a question about the result from 'graphics.MeasureString' when
using a mono-spaced font. Firstly I assume that Courier New font is
mono-spaced, ie each character takes up the same space when drawn on
the screen.

I am working on a program that requires displaying data in fixed width
font. I assumed that with 'graphics.MeasureString' I could calculate
the width of the string when drawn in a specified font.

However as can be seen from my simple example, that I have attached,
where I have overridden the 'OnPaint' method for a label, with a
mono-spaced font, that the width of two characters is not the
summation of two single characters.

In my program I determined that width of "WW" is not the same as "W" +
"W". From lines 62 - 65 of my example

"W" or "1" - 18.07 pixels wide
"WW" - 29.82 pixels wide
"WWWWWWWW" - 100.29 pixels wide

Why are the widths not exactly the same for each character?

I was hoping to use the information to render my display by moving to
specific places on the screen to render the string.

What am I missing about MeasureString and fonts?


Thanks again for any comments.


Stuart

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace test
{
public class Form1 : System.Windows.Forms.Form
{
private myLabel label;
private System.ComponentModel.Container components = null;
public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code

private void InitializeComponent()
{
this.label = new myLabel();
this.label.Location = new System.Drawing.Point(48, 72);
this.label.Name = "Label";
this.label.Size = new System.Drawing.Size(168, 104);
this.label.TabIndex = 0;
this.label.Text = "Hi";
this.label.Font = new System.Drawing.Font("Courier New", 14.25F,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
((System.Byte)(0)));
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.label);
this.Name = "Form1";
this.Text = "Form1";
}
#endregion

[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
public class myLabel : Label
{
protected override void OnPaint(PaintEventArgs e)
{
Graphics graphics = e.Graphics;
Font font = base.Font;

SizeF one = graphics.MeasureString("1", font);
SizeF wone = graphics.MeasureString("W", font);
SizeF two = graphics.MeasureString("WW", font);
SizeF ten = graphics.MeasureString("WWWWWWWW", font);
}
}
}
 
Hi,

Stuart Norris said:
Dear Group,

I have a question about the result from 'graphics.MeasureString' when
using a mono-spaced font. Firstly I assume that Courier New font is
mono-spaced, ie each character takes up the same space when drawn on
the screen.

I am working on a program that requires displaying data in fixed width
font. I assumed that with 'graphics.MeasureString' I could calculate
the width of the string when drawn in a specified font.

However as can be seen from my simple example, that I have attached,
where I have overridden the 'OnPaint' method for a label, with a
mono-spaced font, that the width of two characters is not the
summation of two single characters.

In my program I determined that width of "WW" is not the same as "W" +
"W". From lines 62 - 65 of my example

"W" or "1" - 18.07 pixels wide
"WW" - 29.82 pixels wide
"WWWWWWWW" - 100.29 pixels wide

Try using a typographic StringFormat:

SizeF one = graphics.MeasureString("1", font, 0,
StringFormat.GenericTypographic);
SizeF wone = graphics.MeasureString("W", font,0,
StringFormat.GenericTypographic);
SizeF two = graphics.MeasureString("WW", font,0,
StringFormat.GenericTypographic);
SizeF ten = graphics.MeasureString("WWWWWWWWWW", font, 0,
StringFormat.GenericTypographic);


Don't know exactly why or how but according to msdn the 'default
StringFormat' includes some space before and after the string when using
measurestring.

HTH,
greetings

Why are the widths not exactly the same for each character?

I was hoping to use the information to render my display by moving to
specific places on the screen to render the string.

What am I missing about MeasureString and fonts?


Thanks again for any comments.


Stuart

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace test
{
public class Form1 : System.Windows.Forms.Form
{
private myLabel label;
private System.ComponentModel.Container components = null;
public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code

private void InitializeComponent()
{
this.label = new myLabel();
this.label.Location = new System.Drawing.Point(48, 72);
this.label.Name = "Label";
this.label.Size = new System.Drawing.Size(168, 104);
this.label.TabIndex = 0;
this.label.Text = "Hi";
this.label.Font = new System.Drawing.Font("Courier New", 14.25F,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
((System.Byte)(0)));
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.label);
this.Name = "Form1";
this.Text = "Form1";
}
#endregion

[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
public class myLabel : Label
{
protected override void OnPaint(PaintEventArgs e)
{
Graphics graphics = e.Graphics;
Font font = base.Font;

SizeF one = graphics.MeasureString("1", font);
SizeF wone = graphics.MeasureString("W", font);
SizeF two = graphics.MeasureString("WW", font);
SizeF ten = graphics.MeasureString("WWWWWWWW", font);
}
}
}
 
Back
Top