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

StackOverflow https://stackoverflow.com/questions/604298

Вопрос

Я пытаюсь создать столбцы текста для приложения 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(), а также создать свою собственную функцию, которая добавляет отступы с использованием пробелов и табуляции.Оба отлично работают со шрифтами фиксированной ширины, но не работают со шрифтами переменной ширины.

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

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

Это было полезно?

Решение

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

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

Если у вас нет доступа к System.Windows.Fonts Графика.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 для столбцов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top