I have an array of classes that contains some text and a font. I want to draw all the text aligned on line independently on font size. I thought I can just subtract font height from Y-positiontion of the line and draw the text on the new position but this is a bit difficult because of top and bottom padding added to the text by GDI. The calculation works right, but the text floats somewhere in the middle of rectangle it should be in. I also found out that I can set TextFormatFlags
to NoPadding
but this helps just for left and right padding and the text still floats above the line. I was searching a long time for a way to get rid of all padding, but I didn't found anything that could do this.
This is my code:
public static void DrawTextOnLine(string text, Font font, Graphics graphics, Color color, int x, int dLineY)
{
float upperY = dLineY - GetFontAscent(font);
Point point = new Point(x, (int)upperY);
TextRenderer.DrawText(graphics, text, font, point, color, TextFormatFlags.NoPadding);
}
One thing I forgot to mention: I also tried to do it with TextFormatFlags
set to Bottom
. The problem with this is that descending letters are causing the text to be above the line.
Is there an easier way to do it or how can I remove all the padding?
The Link in donald's comment pointing to dar7yl's excellent answer get it just right.
All kudos to dar7yl! Below is an example and the result, nicely lined up on the same line:
private void Form1_Load(object sender, EventArgs e)
{
using (Graphics G = panel2.CreateGraphics() )
{
fonts.Add(new DrawFont(G, new FontFamily("Arial"), 7f));
fonts.Add(new DrawFont(G, new FontFamily("Arial"), 12f));
fonts.Add(new DrawFont(G, new FontFamily("Arial"), 17f));
fonts.Add(new DrawFont(G, new FontFamily("Consolas"), 8f));
fonts.Add(new DrawFont(G, new FontFamily("Consolas"), 10f));
fonts.Add(new DrawFont(G, new FontFamily("Consolas"), 14f));
fonts.Add(new DrawFont(G, new FontFamily("Times"), 9f));
fonts.Add(new DrawFont(G, new FontFamily("Times"), 12f));
fonts.Add(new DrawFont(G, new FontFamily("Times"), 20f));
fonts.Add(new DrawFont(G, new FontFamily("Segoe Print"), 6f));
fonts.Add(new DrawFont(G, new FontFamily("Segoe Print"), 12f));
fonts.Add(new DrawFont(G, new FontFamily("Segoe Print"), 24f));
}
}
List<DrawFont> fonts = new List<DrawFont>();
class DrawFont
{
public Font Font { get; set; }
public float baseLine { get; set; }
public DrawFont(Graphics G, FontFamily FF, float height, FontStyle style)
{
Font = new Font(FF, height, style);
float lineSpace = FF.GetLineSpacing(Font.Style);
float ascent = FF.GetCellAscent(Font.Style);
baseLine = Font.GetHeight(G) * ascent / lineSpace;
}
}
private void panel2_Paint(object sender, PaintEventArgs e)
{
float x = 5f;
foreach ( DrawFont font in fonts )
{
e.Graphics.DrawString("Fy", font.Font, Brushes.DarkSlateBlue, x, 80 - font.baseLine);
x += 50;
}
e.Graphics.DrawLine(Pens.LightSlateGray, 0, 80, 999, 80);
}
I use Graphics.DrawString
, but TextRenderer
should work just as well..