I need to get the maximum width of 1,2,3,....8,9 on different font and font size.
In c#, the open source code is:
protected double MaxDigitWidth(string fontName, double dblSizePt)
{
double dblMaxDigitWidth = 0.0;
// Excel does not use the specified font size,
// instead, font size is rounded to an integral pixel size
// check if this works on non-Windows platforms, otherwise 96dpi could do fine here
// Graphics g = System.Drawing.Graphics.FromHwnd(new IntPtr());
float fSizePxl = (float)Math.Round(96 * dblSizePt / 72);
float fSizePt = (72 * fSizePxl / 96);
FontStyle fontStyle;
if (fontName == "Monotype Corsiva")
fontStyle = FontStyle.Italic;
else
fontStyle = FontStyle.Regular;
Font font = new Font(fontName, fSizePt, fontStyle, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
for (int i = 0; i < 10; i++)
{
// use a Label on a .NET 2.0 Form to measure the width of a digit
Form f = new Form();
Label l = new Label();
l.UseCompatibleTextRendering = false;
l.Font = font;
l.AutoSize = true;
f.Controls.Add(l);
l.Text = Convert.ToString(i) + Convert.ToString(i);
f.ResumeLayout(false);
f.PerformLayout();
int iWidth2 = l.Width;
l.Text = Convert.ToString(i);
f.PerformLayout();
// we measure twice so we can remove the padding
int iWidth1 = l.Width;
if (iWidth2 - iWidth1 > dblMaxDigitWidth)
{
dblMaxDigitWidth = iWidth2 - iWidth1;
}
}
return dblMaxDigitWidth;
}
I implemented it in Java. But the results are different.
protected double MaxDigitWidth(String fontName, double dblSizePt)
{
double dblMaxDigitWidth = 0.0;
Font f;
if (fontName == "Monotype Corsiva")
f = new Font(fontName, Font.ITALIC ,(int)dblSizePt);
else
f = new Font(fontName, Font.PLAIN ,(int)dblSizePt);
JComponent t = new JLabel();
FontMetrics fm = t.getFontMetrics(f);
for (int i = 0; i < 10; i++)
{
int iWidth2 = fm.stringWidth(String.valueOf(i)+String.valueOf(i));
int iWidth1 = fm.stringWidth(String.valueOf(i));
if (iWidth2 - iWidth1 > dblMaxDigitWidth)
{
dblMaxDigitWidth = iWidth2 - iWidth1;
}
}
return dblMaxDigitWidth;
}
But the result is different betweent c# and java.(I run them on the same machine.)
the result of c#
Font and Font size Maximum digit widht a = MaxDigitWidth("Arial", 11.0); 8 a = MaxDigitWidth("Arial", 12.0); 9 a = MaxDigitWidth("Arial", 13.0); 9 a = MaxDigitWidth("Arial", 14.0); 11 a = MaxDigitWidth("Arial", 15.0); 11 a = MaxDigitWidth("Arial", 16.0); 12 a = MaxDigitWidth("Arial", 17.0); 13 a = MaxDigitWidth("Arial", 18.0); 13 a = MaxDigitWidth("Arial", 19.0); 14 a = MaxDigitWidth("Arial", 20.0); 15
the result of java
Arial-11 6.0 Arial-12 7.0 Arial-13 7.0 Arial-14 开发者_运维知识库 8.0 Arial-15 8.0 Arial-16 9.0 Arial-17 9.0 Arial-18 10.0 Arial-19 11.0 Arial-20 11.0
The difference between .NET and Java is due to different assumptions about the screen resolution. .NET works with 96dpi, Java with 72dpi. That is if you ask Java for a 12pt font it will have a different size on the screen than if you ask .NET for the same font. On paper, they will be the same.
If you convert your results to mm (or inch), you'll find that they are the same except for the lost precision due to rounding.
I've also verified the numbers by printing some rows of digits from Microsoft Word and measuring them. Such a reality check often helps.
You're way of measuring the text length in .NET is pretty funny. Why not do it like this:
using System;
using System.Drawing;
namespace Codo
{
class Program
{
static void Main(string[] args)
{
Bitmap bitmap = new Bitmap(100, 100);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.PageUnit = GraphicsUnit.Pixel;
StringFormat strFormat = new StringFormat(StringFormat.GenericTypographic);
for (int fontSize = 11; fontSize <= 20; fontSize++)
{
Font font = new Font("Arial", fontSize, FontStyle.Regular);
float digitWidth = graphics.MeasureString("00000000", font, 1000, strFormat).Width / 8;
font.Dispose();
Console.WriteLine("Width of digit 0 for {0} {1}pt: {2} (96dpi)", font.FontFamily.Name, font.SizeInPoints, digitWidth);
digitWidth = digitWidth / 96 * 72;
Console.WriteLine("Width of digit 0 for {0} {1}pt: {2} (72dpi)", font.FontFamily.Name, font.SizeInPoints, digitWidth);
}
graphics.Dispose();
bitmap.Dispose();
}
}
}
Well, I'd say the problem is you're using different approaches. In Java you just use the FontMetrics
of a label that is not even displayed/layed out whereas in C# it seems you're using the size of the label that may have be resized and contain padding, borders etc.
Additionally, in your Java code you truncate dblSizePt
to an integer, losing any possibly fraction part. In C# you directly pass fSizePt
the the Font
construtctor.
Last but not least you're using two different UI frameworks that might have slight differences in text rendering.
精彩评论