GDI+ Fonts
FAQ Home
1. How do I set
the font for a control?
2. When I try to set a particular font style, say italics, I get an error
message "Property cannot be assigned to -- it is read only". How can I set
this read only property?
3. How can I draw font samples from the available fonts?
4. MeasureString seems to have problems with white space and punctuation. Is
there a better method to use?
5. How can I draw a single line of text with different fonts using DrawString?
6. How do I display adjacent text?
7. How can I fill a combobox with available fonts?
1 How do I set the font for a control?
Use the Font property for the control along with the Font class in the
System.Drawing class.
button1.Font = new Font
("Courier", 10, FontStyle.Bold);
2 When I try to set a particular font style, say italics, I get an error
message "Property cannot be assigned to -- it is read only". How can I set
this read only property?
Code such as
tabControl1.Font.Italic =
true;
will not work. Instead, you have to create a new Font object, and set the
property during its creation. This code will work.
tabControl1.Font = new
Font(tabControl1.Font, FontStyle.Italic);
3 How can I draw font samples from the available fonts?
James DeBroeck of Microsoft gave this response on the
microsoft.public.dotnet.framework.windowsforms.
Here is some C# OnPaint code that will show you how to use FontFamily to get
a list of fonts:
protected override void
OnPaint(System.Windows.Forms.PaintEventArgs e)
{
int i, nCount;
SolidBrush b = new SolidBrush( Color.Black );
int x = 0, y = 0;
nCount = FontFamily.Families.Length;
for(i=0;i
{
FontStyle fs = FontStyle.Regular;
Font f;
String StylesDesc = "";
if (FontFamily.Families[i].IsStyleAvailable(FontStyle.Regular))
StylesDesc += "Regular ";
else
fs = FontStyle.Italic;
if (FontFamily.Families[i].IsStyleAvailable(FontStyle.Italic))
StylesDesc += "Italic ";
else
fs = FontStyle.Bold;
if (FontFamily.Families[i].IsStyleAvailable(FontStyle.Bold))
StylesDesc += "Bold ";
if (FontFamily.Families[i].IsStyleAvailable(FontStyle.Underline))
StylesDesc += "Underline ";
if (FontFamily.Families[i].IsStyleAvailable(FontStyle.Strikeout))
StylesDesc += "Strikeout ";
if (StylesDesc.Length > 0)
StylesDesc = StylesDesc.Substring(0,StylesDesc.Length-1);
f = new Font( FontFamily.Families[i].Name, 12, fs);
String s = FontFamily.Families[i].Name + " " + StylesDesc;
e.Graphics.DrawString( s, f, b, x, y );
y += f.Height;
}
}
4 MeasureString seems to have problems with white space and punctuation.
Is there a better method to use?
Try calling one of the overloads of MeasureString that takes
an StringFormat parameter and pass it
StringFormat.GenericTypographic. Here is some code that shows the same
string and font giving different results depending upon the StringFormat
parameter.
StringFormat sf = new StringFormat(StringFormat.GenericTypographic);
SizeF size = e.Graphics.MeasureString("this has some words", Font, 500, sf);
SizeF size1 = e.Graphics.MeasureString("this has some words", Font);
string s = string.Format("GenericTypographic={0:f2} GenericDefault={1:f2}",
size.Width, size1.Width);
MessageBox.Show(s);
5 How can I draw a single line of text with different fonts using
DrawString?
The key is that you have to calculate the ascent height of the font. The
font ascent as reported by FontFamily.GetCellAscent is in what
is called 'Design Units'. The Cell Spacing design unit value of fonts is
proportional to the actual height of the font on the device. We use this
relationship to calculate cell ascent in device units.
The rendering code has to just ensure that the x, y position passed to
DrawString takes care of the ascent.
private void
HandlePaint(object sender, PaintEventArgs args)
{
// clear the background
Graphics g = args.Graphics;
g.Clear(Color.AliceBlue);
// create a pen
Pen pen = new Pen(Color.Red, 1f);
// the string to be drawn
string s = "Side by side";
// the first font
Font f1 = new Font("Arial", 10f);
float strWidth1 = g.MeasureString(s, f1).Width;
float fontHeight1 = f1.GetHeight(g);
float fontAscentHeight1 =
(fontHeight1/f1.FontFamily.GetLineSpacing(f1.Style))*f1.FontFamily.GetCellAscent(f1.Style);
// the second font
Font f2 = new Font("Times New Roman", 48);
float fontHeight2 = f2.GetHeight(g);
float fontAscentHeight2 =
(fontHeight2/f2.FontFamily.GetLineSpacing(f2.Style))*f2.FontFamily.GetCellAscent(f2.Style);
// draw the base line
Point ptStart = new Point(0, this.ClientSize.Height/2);
Point ptEnd = new Point(this.ClientSize.Width,
this.ClientSize.Height/2);
g.DrawLine(Pens.Black, ptStart, ptEnd);
// draw string with first font
g.DrawString(s, f1, Brushes.Red, new PointF(0, ptStart.Y -
fontAscentHeight1));
// draw string with second font
g.DrawString(s, f2, Brushes.Red, new PointF(strWidth1, ptStart.Y -
fontAscentHeight2));
}
6 How do I
display adjacent text?
Check out this article by David C. Browm of the Windows Forms team at
gotnetdot.com. It discusses several reasons why you GDI+ output may lok
differently that GDI output. One of the topics discussed is how to draw
adjacent text.
7 How can I fill a combobox with available fonts?
Try
comboBox1.Items.AddRange(FontFamily.Families);
|