Как нарисовать вертикальный текст в Windows GUI?

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

Как я произвожу текст от начала до конца кроме рисования каждого символа отдельно?

8
задан sharptooth 12 February 2010 в 08:25
поделиться

6 ответов

Обычный 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.

7
ответ дан 5 December 2019 в 09:25
поделиться

В 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

4
ответ дан 5 December 2019 в 09:25
поделиться

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

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

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

0
ответ дан 5 December 2019 в 09:25
поделиться

Является причиной использования typedef для получения назначение NSUInteger для работы без приведения?

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

NSInteger и NSUInteger были введены для облегчения миграции 64 битов приложений, обеспечивая независимый от архитектуры/платформы тип как для подписанных, так и для неподписанных целых чисел. Таким образом, независимо от количества битов ЦП, приложения не нуждаются в перезаписи.

Иногда typedef является одним из NSInteger/NSUInteger, почему бы не использовать NSInteger всегда? Есть ли реальная Преимущество использования NSUInteger?

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

  • NSInteger предлагает 2 ^ 31 положительные и отрицательные значения (на 32 битной архитектуре).
  • NSUInteger предлагает положительные значения 2 ^ 32 (на архитектуре 32 bits).
  • Если перечисление должно содержать только положительные значения, используйте NSUInteger.
  • Если перечисление должно содержать как положительные, так и отрицательные значения, используйте NSInteger.
  • NSUInteger обычно используется для перечисления флагов, поскольку он обеспечивает 32 различных значений (на архитектуре 32 битов), которые должны объединяться по желанию.

Я не знаю, есть ли для этого правило выбора в команде разработчиков Apple. Надеюсь, что да...

-121--2835557-

Это странно, в соответствии с руководством предел памяти может быть установлен в любом месте.

  • Установлен ли Сухосин? С помощью Сухосина можно установить глобальный предел памяти.

  • Есть ли у вас файл .htaccess , где-то говорящий php _ value memory_limit xyz ?

  • Активирована ли защита Shell Fork Bomb? Он может установить глобальный предел памяти. См. вопрос SO здесь . (Полагаю, это может быть частью Сухосина).

  • Что говорит ваш phpinfo () относительно «локальных» и «глобальных» значений memory_limit?

  • Как вы указываете предел, можете ли вы опубликовать фрагмент кода?

-121--3632124-

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

-1
ответ дан 5 December 2019 в 09:25
поделиться

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

Есть три способа сделать это:

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

Вот статья, в которой обсуждаются некоторые из этих подходов.

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

5
ответ дан 5 December 2019 в 09:25
поделиться

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

0
ответ дан 5 December 2019 в 09:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: