Как нарисовать вертикальный текст в Windows GUI? - PullRequest
8 голосов
/ 12 февраля 2010

Мне нужно нарисовать столбец вертикального текста (на японском языке - он рисуется сверху вниз, а не слева направо) в моем родном приложении C ++ Win32 GUI.Я просмотрел MSDN и нашел только способ рисования текста справа налево.

Как вывести текст сверху вниз, кроме отрисовки каждого символа отдельно?

Ответы [ 8 ]

7 голосов
/ 12 февраля 2010

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

Вы можете сделать более сложный вывод текста с помощью GDI + Но это, вероятно, не то, что вы хотите, так как текст будет вертикальным, но символы также будут поворачиваться.

Аналогично, вы можете использовать CreateFont со значением lfEscapement 900 или 2700, чтобы получить повернутый текст, но это будет вращать все. Так что это тоже не поможет.

Чтобы выполнить рисование сверху вниз на японском языке, необходимо, чтобы символы не были повернуты, а расположение каждого символа перемещалось по Y, а не по X. В Windows нет API, который бы делал это для всех шрифтов. (вы можете делать справа налево и слева направо, но не сверху вниз).

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

Я думаю, что ваша лучшая ставка - это, вероятно, цикл, рисующий по одному символу за раз с ExtTextOut , который дает вам полный контроль над размещением каждого персонажа.

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

Добавление

Ройгбив указывает на интересную статью, в которой говорится, что шрифты, имена которых начинаются с @, ведут себя иначе, чем другие шрифты, когда вы используете CreateFont шрифт со значением lfEscapement 2700. Эти специальные шрифты производят вертикальные символы, все еще продвигаясь по странице. Поэтому, хотя для произвольных шрифтов не существует способа сделать то, что вы хотите, вы можете заставить его работать, используя определенные шрифты.

Параметры отображения текста

Из любопытства я написал небольшое консольное приложение для перечисления шрифтов и перечисления имен. На моем компьютере с Windows Server 2003 нет шрифтов с именами, начинающимися с @. Но у моей машины с Windows 7 их немного. Все, кажется, китайские шрифты, хотя я не вижу японских шрифтов в стандартной установке Windows 7 Ultimate.

5 голосов
/ 12 февраля 2010

Правильный ответ:

Для этого есть три способа:

  • Использование элементов управления Edit или RichEdit для визуализации текста
  • Использование Uniscribe API
  • Использование функции TextOut с именем шрифта, которое начинается со знака (@).

Здесь - статья, в которой рассматриваются некоторые из этих подходов.

К счастью, с Win32 вам не нужно писать код для поворота символов. Для вертикального отображения текста в Windows 2000 и Windows XP перечислите доступные шрифты как обычно и выберите шрифт, имя шрифта которого начинается со знака (@). Затем создайте структуру LOGFONT, установив спуск и ориентацию на 270 градусов. Вызовы TextOut такие же, как и для горизонтального текста.

4 голосов
/ 12 февраля 2010

В Win32 используйте lfEscapement член структуры LOGFONT для определения поворота шрифта:

LOGFONT LogFont

LogFont.lfEscapement = 900;  // 90 degreees rotated text
... // Many more initializations
HFONT newFont = CreateFontIndirect(LogFont);
SelectObject(hdc, newFont);

char tx[255];
strcpy(tx, "vertical text");
TextOut(hdc, x, y, tx, strlen(tx)); // draw a vertical font

Для получения дополнительной информации см. Интерактивную справку LOGFONT структуры и CreateFontIndirect Функция

2 голосов
/ 18 августа 2016
HFONT gui_font  =   CreateFont( -MulDiv( 9, GetDeviceCaps( GetDC( hWnd ), LOGPIXELSY ), 72 ),
                        0, 
                        900,  // here
                        0,
                        FW_THIN, 0, 0, 0,
                        DEFAULT_CHARSET,
                        OUT_DEFAULT_PRECIS,
                        CLIP_DEFAULT_PRECIS,
                        DEFAULT_QUALITY, FF_MODERN | FIXED_PITCH,
                        L"Segoe UI" );
1 голос
/ 04 января 2011

Использование lfEscapement (и при необходимости lfOrientation) во многих отношениях превосходит минимальную ширину прямоугольника (например: голландское слово 'wij' будет иметь 'i' и 'j' рядом друг с другом потому что их объединенная ширина меньше, чем 'w'), или вставка новой строки после каждого символа.

0 голосов
/ 23 февраля 2010

Как быстрый ответ типа хак, что произойдет, если вы используете стандартный элемент управления (например, CEdit) и вставляете новую строку после каждого набранного символа?

0 голосов
/ 12 февраля 2010

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

http://www.ucancode.net/faq/CDC-DrawText-Drawing-Vertical-Text.htm

Вы также можете найти это обсуждение полезным - http://www.eggheadcafe.com/forumarchives/win32programmergdi/Aug2005/post23542233.asp - очевидно, вам нужен вертикальный шрифт (один начинается с @), а API позаботится обо всем остальном.

0 голосов
/ 12 февраля 2010

Просто идея: Вы пытались использовать DrawText или DrawTextEx, используя очень узкий прямоугольник, который просто подходит для самого широкого символа?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...