Reputation: 33
I am trying to find out the a character's width and height in windows environment using this code:
using(Graphics g = Graphics.FromImage(new Bitmap(800,550)))
{
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
SizeF size = g.MeasureString("0",new Font(FontFamily.GenericMonospace, 10) , new PointF(0, 0),
StringFormat.GenericTypographic);
Console.WriteLine(size.Height);
Console.WriteLine(size.Width);
}
The output is: Height: 15.104165 Width: 8.001301
I am trying to port this process to cross platform code using SkiaSharp using this code:
using (SKPaint p = new SKPaint
{
IsAntialias = true, Typeface = SKTypeface.FromFamilyName("monospace"),
TextSize = 10
})
{
string text = "0" ;
SKRect textBounds = SKRect.Empty;
p.Color = SKColors.Black;
p.Style = SKPaintStyle.Fill;
p.MeasureText(text, ref textBounds);
Console.WriteLine(textBounds.Height);
Console.WriteLine(textBounds.Width);
}
This is the height and width of same character in SkiaSharp: Height: 7 Width: 5
Can I get some help regarding this? What am I missing?
Upvotes: 1
Views: 1667
Reputation: 6539
This is how I measure text in millimeter given a font size in pt with System.Drawing
:
static double PtToMm(double pt) { return pt * 25.4 / 72.0; }
var familyName = "Arial";
var fontHeightPt = 10.0f;
using var font = new Font(familyName, fontHeightPt, FontStyle.Regular, GraphicsUnit.World);
using var graphicsImage = new Bitmap(1, 1);
graphicsImage.SetResolution(300.0f, 300.0f);
using var graphics = Graphics.FromImage(graphicsImage);
using var stringFormat = (StringFormat)StringFormat.GenericTypographic.Clone();
// System.Drawing doesn't measure trailing whitespace on default
// stringFormat.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
var nullPoint = new PointF(0, 0);
var textBounds = graphics.MeasureString(text, font, nullPoint, stringFormat);
var totalWidthMm = PtToMm(textBounds.Width);
var totalHeightMm = PtToMm(textBounds.Height);
With SkiaSharp, everything is a bit different. This is my current solution:
using var fontManager = SKFontManager.CreateDefault();
using var typeface = fontManager.MatchFamily(familyName, SKFontStyle.Normal);
using var fontPaint = new SKPaint
{
IsAntialias = true,
HintingLevel = SKPaintHinting.Normal,
TextAlign = SKTextAlign.Left,
TextSize = (float)PtToMm(fontHeightPt),
Typeface = typeface,
};
var textBounds = new SKRect();
var totalWidthMm = fontPaint.MeasureText(Text, ref textBounds);
var totalHeightMm = textBounds.Height;
// textBounds.Width => width of text without leading/trailing whitespace
// textBounds.Left => width of leading whitespace
If you want to measure the text with leading but without trailing whitespace:
var totalWidthMm = fontPaint.MeasureText(Text.AsSpan().TrimEnd(), ref textBounds);
Upvotes: 1