Создание столбцов текста с шрифтом переменной ширины

Я пытаюсь создать столбцы текста для приложения на C#, которое будет работать в MSN Messenger. У меня трупле, заставляющее все выстраиваться.

Вот пример вывода, который я хочу:

1)  Pizza Hut                                            123 Fake St.
2)  Domino's Pizza                                       123 Fake St.
3)  The Cheesecake Cafe                                  123 Fake St.
4)  Capital Pizza & Steakhouse                           123 Fake St.
5)  Funky Pickle Pizza                                   123 Fake St.
6)  Boston Pizza                                         123 Fake St.
7)  Rose Bowl Rouge Lounge                               123 Fake St.
8)  Royal Pizza                                          123 Fake St.
9)  A Columbus Pizza & Donair Inc                        123 Fake St.

Но поскольку это шрифт переменной ширины, он отображается так:

1)  Pizza Hut                                        123 Fake St.
2)  Domino's Pizza                                   123 Fake St.
3)  The Cheesecake Cafe                                  123 Fake St.
4)  Capital Pizza & Steakhouse                               123 Fake St.
5)  Funky Pickle Pizza                                   123 Fake St.
6)  Boston Pizza                                     123 Fake St.
7)  Rose Bowl Rouge Lounge                               123 Fake St.
8)  Royal Pizza                                          123 Fake St.
9)  A Columbus Pizza & Donair Inc                    123 Fake St.

Я попытался использовать функцию C# string.PadRight(), а также создать свою собственную функцию, которая добавляет заполнение, используя пробелы и табуляции. Оба прекрасно работают со шрифтами фиксированной ширины, но ломаются со шрифтами переменной ширины.

Есть ли способ определить ширину строки в данном шрифте?

Или у кого-нибудь есть другие предложения?

4 ответа

Решение

Просто используйте класс TextRenderer. Самый простой случай:

Size size = TextRenderer.MeasureText("Hello world", someFont);

Если у вас нет доступа к System.Windows.Fonts Graphics.MeasureString, у него есть некоторые ограничения, но он должен работать:

Bitmap bmp = new Bitmap(1,1);
Graphics graphics = Graphics.FromImage(bmp);
SizeF size = graphics.MeasureString("Hello world", someFont);

Но имейте в виду, что если шрифт вашего текста и пробелы ДОЛЖНЫ быть одинаковыми, будут случаи, когда вы не можете выровнять текст идеально. Я не знаю, что MSN Messenger может сделать в вашем случае, но за исключением того, что у вас есть доступ хотя бы к подмножеству HTML, у вас не будет идеального вывода.

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

Если также требуется поддержка нескольких операционных систем, у вас будут большие проблемы, так как шрифт Arial на Mac и ПК не выглядит (и измеряет) точно так же.

Вы можете попробовать использовать класс Graphics для измерения длины строки, заданной конкретным шрифтом, а затем использовать ее для определения количества используемых вкладок.

Похоже, вы пытаетесь отобразить все это в ASCII в одном текстовом поле. Да? Если это так, то это довольно сложно. Похоже, у вас есть фиксированное количество вкладок после каждой из них прямо сейчас, и это будет проблемой. Вместо этого вы могли бы делать пробелы - что я подозреваю, что вы делаете с padright (не очень знакомы с этой конкретной функцией).

Ключевым моментом, однако, является то, что с таким чистым ASCII, как этот, показанным шрифтом переменной ширины, вы никогда не добьетесь его идеального выравнивания во втором столбце. Вы можете подобрать это близко, если вы прилежны, но это все - если у вас есть одна строка с большим количеством заглавных букв W, а другая с большим количеством строчных i, у вас будут большие различия в ширине, независимо от того, что вы делаете. Если вы выполняете рендеринг в GDI, лучше всего сделать один вызов DrawText на столбец. Вы можете сделать одну большую строку из каждого столбца, если хотите, и вызвать MeasureString для первого столбца, чтобы определить, сколько места нужно переместить для второго столбца.

Или, если это интерфейс, где вы можете сделать HTML, таблицы или div будет работать отлично. Зависит от специфики вашей среды. Вы также можете сделать что-то, например, иметь две метки с автоматической настройкой высоты на панели FlowLayout, если это были WinForms и т. Д. Есть много вариантов сделать эту работу, но только не чистый ascii с шрифтом переменной ширины.

РЕДАКТИРОВАТЬ: Кроме того, я видел, как вы спросили о том, как получить экземпляр класса Graphics в веб-сервисе. Вы можете сделать что-то вроде этого:

    private static Bitmap bitmap = new Bitmap( 1, 1 );
    private static Graphics graphics = null;

    public static Graphics GetGeneralGraphics()
    {
        if ( graphics == null )
            graphics = Graphics.FromImage( bitmap );
        return graphics;
    }

Возможно, вы захотите сделать эти локальные переменные (которые вы правильно расположите, когда закончите) в контексте веб-сервисов.

Вы, вероятно, должны отформатировать все в HTML, тогда вы можете просто вывести элементы TABLE и TR/TD для столбцов

Другие вопросы по тегам