如何在Windows GUI中绘制垂直文本?

时间:2010-02-12 08:25:20

标签: user-interface winapi visual-c++ fonts

我需要在我的原生C ++ Win32 GUI应用程序中绘制一列垂直文本(日语 - 从上到下而不是从左到右)。我查看了MSDN并且只找到了如何绘制从右到左的文本。

除了分别绘制每个字符外,如何输出从上到下的文字?

8 个答案:

答案 0 :(得分:7)

直接的Win32 API无法以这种方式绘制(未旋转的)垂直文本(使用任意字体),除了1个字符。

您可以使用GDI+执行更复杂的文本输出 但这可能不是你想要的,因为文本是垂直的,但字符也将被旋转。

类似地,您可以使用具有900或2700的lfEscapement值的CreateFont来获取旋转文本,但这将旋转所有内容。所以这也无济于事。

要执行日语从上到下的绘制,您希望字符不旋转,但每个字符的位置要在Y中前进而不在X中前进.Windows没有为所有字体执行此操作的API。 (你可以从右到左,从左到右,但不是从上到下)。

理论上,创建一个方向为900且擒纵系数为2700的字体可以达到你想要的效果,但是如果你设置了擒纵机构,那么大多数字体都会忽略方向。对于日语字体,这可能会有所不同。值得花一些时间玩。 (有关详细信息,请参阅附录)

我认为你最好的选择可能是用ExtTextOut一次绘制一个角色的循环,这样你就可以完全控制每个角色的位置。

如果您使用ETO_OPAQUE绘制列中的第一个字符,而不是所有其他字符,那么您将被允许在需要时垂直填充字符。

附录

Roygbiv指出一篇有趣的文章说,当你使用CreateFont一个lfEscapement值为2700的字体时,名字以@开头的字体与其他字体不同,这些特殊字体会产生直立字符,同时仍会向下移动页面。因此,虽然没有办法对任意字体进行任何操作,但您可以使用某些字体使其工作。

Options for Displaying Text

出于好奇,我写了一个小的控制台应用程序来枚举字体并列出名称。我的Windows Server 2003计算机没有名称以@开头的字体。但我的Windows 7机器有一些。所有似乎都是中文字体,我在默认的Windows 7 Ultimate安装中看不到日文字体。

答案 1 :(得分:5)

正确答案是:

有三种方法可以做到这一点:

  • 使用修改或RichEdit控件渲染文字
  • 使用Uniscribe API
  • 使用TextOut函数,其字体名称以at符号(@)开头。

Here是一篇讨论其中一些方法的文章。

  
    

幸运的是,使用Win32,您不需要编写代码来旋转字符。要在Windows 2000和Windows XP上垂直显示文本,请照常枚举可用字体,并选择字体名称以at符号(@)开头的字体。然后创建一个LOGFONT结构,将擒纵机构和方向设置为270度。对TextOut的调用与水平文本相同。

  

答案 2 :(得分:4)

在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功能

的在线帮助

答案 3 :(得分:2)

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" );

答案 4 :(得分:1)

使用lfEscapement(以及必要的lfOrientation)在很多方面都优于使矩形最小化(例如:荷兰语'wij'将具有'i'和'j'彼此相邻,因为它们的组合宽度小于'w',或者在每个字符后插入换行符。

答案 5 :(得分:0)

此库使用的方法听起来很慢,但如果确实需要它,则会显示源代码:

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

您可能还会发现此讨论很有用 - http://www.eggheadcafe.com/forumarchives/win32programmergdi/Aug2005/post23542233.asp - 显然您需要一个垂直字体(一个以@开头),API将负责其余部分。

答案 6 :(得分:0)

作为一种快速破解类型的答案,如果您使用标准控件(例如CEdit)并在每个字符输入后插入换行符会发生什么?

答案 7 :(得分:-1)

只是一个想法: 您是否尝试使用符合最宽字符的非常窄的矩形来使用DrawTextDrawTextEx