Как точно измерить ширину символа? - PullRequest
5 голосов
/ 31 марта 2012

Может быть, я что-то не так понял, но ... я хочу смоделировать расстояние между персонажами.Я разбиваю слово (текст) на список отдельных символов, измеряю их ширину, а затем рисую их один за другим на растровом изображении.Я предполагал, что общая ширина отображаемого текста будет равна ширине всей неразделенной строки, но что-то не так.Рендеринг символов в цикле показывает более широкий результат.Есть ли способ получить общие (ожидаемые) результаты?

вот фрагмент кода:

private struct CharWidths
{
    public char Char;
    public float Width;
}

private List<CharWidths> CharacterWidths = new List<CharWidths>();

...

private void GetCharacterWidths(string Text, Bitmap BMP)
{
    int i;
    int l = Text.Length;
    CharacterWidths.Clear();
    Graphics g = Graphics.FromImage(BMP);

    CharWidths cw = new CharWidths();
    for (i = 0; i < l; i++)
    {
        Size textSize = TextRenderer.MeasureText(Text[i].ToString(), Font);
        cw.Char = Text[i];
        cw.Width = textSize.Width;
        CharacterWidths.Add(cw);
    }
}

...

public void RenderToBitmap(Bitmap BMP)
{
    //MessageBox.Show("color");

    Graphics g = Graphics.FromImage(BMP);
    GetCharacterWidths("Lyborko", BMP);

    int i;
    float X = 0;
    PointF P = new PointF(); 
    for (i = 0; i < CharacterWidths.Count; i++)
    {
        P.X = X;
        P.Y = 0;

        g.DrawString(CharacterWidths[i].Char.ToString(), Font, Brushes.White, P);

        X = X+CharacterWidths[i].Width;
    }

    P.X = 0;
    P.Y = 30;
    g.DrawString("Lyborko", Font, Brushes.White, P);
    // see the difference
}

Большое спасибо

1 Ответ

2 голосов
/ 31 марта 2012

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

  1. Учитывая, что вы, позвонив TextRenderer.MeasureText, делаетене передавать текущий device context (тот же, который вы используете для рисования строки после) и зная простой факт, что MeasureText просто в случае отсутствия этого параметра создает новый, совместимый с рабочим столом и вызывает DrawTextEx функцию WindowsSDK,Я бы сказал, сначала используйте перегрузку MeasureText , где вы указываете как первый аргумент device context, который вы используете для рендеринга текста после. Может изменить ситуацию.

  2. В случае неудачи попытается использовать Control.GetPreferredSize метод для догадываюсь наиболее точно предполагаемый размер визуализации элемента управления на экране, поэтому фактически размерность растрового изображения будущей строки.Для этого вы можете создать какой-то временный элемент управления, назначить строку, отобразить и после вызова этой функции.Для меня ясно, что это решение вряд ли вписывается в архитектуру вашего приложения, но может , возможно, даст лучшие результаты.

Надеюсь, это поможет.

...