Максимальная ширина цифры на разных шрифтах и ​​размер шрифта - PullRequest
2 голосов
/ 21 июля 2011

Мне нужно получить максимальную ширину 1,2,3, .... 8,9 для другого шрифта и размера шрифта.

В C # открытый исходный код:

    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;

    }

Я реализовал это на Java.Но результаты разные.

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;

}

Но результат отличается между C # и Java. (Я запускаю их на одной машине.)

  1. результат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   
    
  2. результат 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
    

Ответы [ 2 ]

3 голосов
/ 21 июля 2011

Разница между .NET и Java связана с различными предположениями о разрешении экрана..NET работает с 96dpi, Java с 72dpi.То есть, если вы спросите Java о шрифте 12pt, он будет иметь другой размер на экране, чем если бы вы спросили .NET для того же шрифта.На бумаге они будут одинаковыми.

Если вы преобразуете свои результаты в мм (или дюймы), вы обнаружите, что они одинаковы, за исключением потери точности из-за округления.

Я также проверил числа, напечатав несколько строк цифр из Microsoft Word и измерив их.Такая проверка реальности часто помогает.

Вы можете измерить длину текста в .NET довольно забавно.Почему бы не сделать это так:

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();
        }
    }
}
1 голос
/ 21 июля 2011

Ну, я бы сказал, проблема в том, что вы используете разные подходы. В Java вы просто используете FontMetrics метки, которая даже не отображается / не размещается, тогда как в C # кажется, что вы используете размер метки, размер которой может быть изменен и содержать отступы, границы и т. Д.

Кроме того, в вашем Java-коде вы усекаете dblSizePt до целого числа, теряя все возможные дробные части. В C # вы напрямую передаете fSizePt конструктор Font.

И последнее, но не менее важное: вы используете две разные структуры пользовательского интерфейса, которые могут иметь небольшие различия в визуализации текста.

...