A set of .NET Framework managed libraries for developing graphical user interfaces.
Hi @mc ,
Thanks for reaching out.
The code snippets below are intended as reference samples, so you may need to adjust them a little to match your own project structure, rendering settings, and font handling.
Graphics.DrawString() does not have a built-in option to set character spacing in exact pixel units. It uses the font's own metrics, so if you draw the whole word in one call, you cannot tell it to always leave exactly 1, 2, or 3 visible pixels between letters.
If you just want to add spacing, the usual way is to draw one character at a time and move the x position forward yourself. Here is a simple sample:
private static Bitmap DrawTextWithSpacing(string text, Font font, int extraPixels)
{
using var measureBmp = new Bitmap(1, 1);
using var measureG = Graphics.FromImage(measureBmp);
using var format = (StringFormat)StringFormat.GenericTypographic.Clone();
format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
measureG.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
float width = 0;
float height = font.GetHeight(measureG);
foreach (char c in text)
{
SizeF size = measureG.MeasureString(c.ToString(), font, int.MaxValue, format);
width += size.Width + extraPixels;
}
if (text.Length > 0)
width -= extraPixels;
var bmp = new Bitmap((int)Math.Ceiling(width), (int)Math.Ceiling(height));
using Graphics g = Graphics.FromImage(bmp);
using var brush = new SolidBrush(Color.Black);
g.Clear(Color.White);
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
float x = 0;
foreach (char c in text)
{
string s = c.ToString();
g.DrawString(s, font, brush, x, 0, format);
SizeF size = g.MeasureString(s, font, int.MaxValue, format);
x += size.Width + extraPixels;
}
return bmp;
}
And this is how you could call it:
using Font font = new Font("Arial", 20, FontStyle.Regular, GraphicsUnit.Pixel);
Bitmap bmp = DrawTextWithSpacing("welcome", font, 3);
That said, this gives you extra drawing space, not an exact visible pixel gap. A font may already have empty pixels on the left or right side of a character, so the real gap you see in the bitmap can be larger or smaller than the value you add.
If your real goal is to know how many visible blank pixel columns you ended up with, then yes, you can get that, but you need to inspect the bitmap after rendering. A simple way is to render each character separately, find the first and last non-background pixel column for each glyph, and then calculate the gap from those bounds.
This helper shows the basic idea for finding the visible bounds:
private static Rectangle GetInkBounds(Bitmap bmp, Color background)
{
int left = bmp.Width;
int top = bmp.Height;
int right = -1;
int bottom = -1;
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < bmp.Width; x++)
{
if (bmp.GetPixel(x, y).ToArgb() != background.ToArgb())
{
if (x < left) left = x;
if (y < top) top = y;
if (x > right) right = x;
if (y > bottom) bottom = y;
}
}
}
if (right < left || bottom < top)
return Rectangle.Empty;
return Rectangle.FromLTRB(left, top, right + 1, bottom + 1);
}
Hope this helps! If my explanation and the information I provided were helpful, I would greatly appreciate it if you could follow the instructions here so others with the same problem can benefit as well.