分享
 
 
 

用"旋转字体"美化界面

王朝厨房·作者佚名  2007-01-04
窄屏简体版  字體: |||超大  

如何使自己设计的程序具有漂亮和友好的界面,是程序员间永恒的话题。这里,笔者向您介绍一种非常简单的技巧,使文字旋转起来。

这里的“旋转字体”指的是让一行字体的水平基线(baseline)转过一定的角度。正如您所看到的,旋转字体会产生轻松、活泼的视觉效果,可以给观者以特殊的联想,是一种行之有效的显示特技。

有一种很容易想到的办法可以实现旋转字体,即首先生成文字的点阵(位图),然后利用坐标旋转变换生成新的位图再输出到屏幕或打印机上。这种办法思路清晰,不但可以用于字体的旋转,也可以用于其他种种字体变形,如同WinWord中的WordArt或中文之星的“艺术汉字”。但这种办法实现起来比较麻烦,需要一些计算机绘图学方面的知识,而且位图变换过程中需要占用较多的内存。而我们所要介绍的方法,可以有效地解决这些问题,而且不需要什么专门的知识,而是充分地利用Windows API已有的功能实现旋转字体的效果。

我们知道,逻辑字体是一类非常重要的Windows GDI对象。我们正是通过选择不同的逻辑字体来输出各种秀美的字体的。而所谓“旋转字体”不过是一类特殊的逻辑字体。如同其他的GDI对象(如画笔、画刷、调色板)一样,字体对象不但具有固有的字体,我们也可以建立自己的逻辑字体。建立字体可以使用Windows API的CreateFontIndirect()函数。在调用该函数之前,我们将字体的特征放入LOGFONT结构变量中。LOGFONT结构是这样定义的:

Type LOGFONT

lfHeight As Integer ’ 字体的高度

lfWidth As Integer ’ 字体的宽度

lfEscapement As Integer ’ 字体旋转的角度

lfOrientation As Integer

lfWeight As Integer ’ 字体的轻重

lfItalic As String * 1 ’ 是否为斜体

lfUnderline As String * 1 ’ 是否有下划线

lfStrikeOut As String * 1 ’ 是否有强调线

lfCharSet As String * 1 ’ 字符集

lfOutPrecision As String * 1 ’ 输出精度

lfClipPrecision As String * 1 ’ 剪裁精度

lfQuality As String * 1 ’ 输出质量

lfPitchAndFamily As String * 1 ’ 间距和字体族

lfFaceName As String * LF_FACESIZE ’ 字体名,如“宋体”

End Type

利用这个数据结构,你可以方便地设置各种字体参数,比如高度、宽度等。该结构中同我们所要讨论的问题关系最大的是lfEscapement,它表示字符的基线同坐标的X轴之间的旋转角度,从X轴正方向开始沿逆时针方向旋转,以十分之一度为单位(图2)。蔡明志先生著的《Windows程序设计?绘图篇--使用Borland C++ for Windows》一书(科学出版社1993年9月出版)的482页上指出旋转角度以十度为单位,为此笔者查阅了SDK手册,其英文原文为:“measured in tenths of a degree”,似应为以十分之一度为单位。

lfFaceName指明字体的名称,如“宋体”、“行楷”。需要指出的是,个别字体不支持字体旋转,主要是字体宽度不可变的种类,如FixedSys就不支持字体旋转,好在这样的字体只有一两种。

具体的实现参见文后所附的程序(用Visual Basic 3.0编写),其中RotPrint过程用来输出旋转字体。其步骤如下:首先,利用GetObject()函数获得当前字体的LOGFONT结构,修改lfEscapement,设置旋转角度,然后调用CreateFontIndirect()函数建立逻辑字体并选用之。接下来,调用TextOut()函数输出字符串。使用TextOut()函数可以使那些不支持Print方法的控制(如标签),同样可以输出旋转字体。最后,用DeleteObject()函数删除建立的逻辑字体并恢复原字体。

您可以通过示例程序的“选择”菜单中的“字体”项来尝试不同的字体效果,从中选出令人满意的组合。

附录:源程序

ROTFONT.BAS文件:

DefInt A-Z

’ 逻辑字体

Global Const LF_FACESIZE = 32 ’ 最长的字体名称

Global Const SYSTEM_FONT = 13

Type LOGFONT

lfHeight As Integer

lfWidth As Integer

lfEscapement As Integer

lfOrientation As Integer

lfWeight As Integer

lfItalic As String * 1

lfUnderline As String * 1

lfStrikeOut As String * 1

lfCharSet As String * 1

lfOutPrecision As String * 1

lfClipPrecision As String * 1

lfQuality As String * 1

lfPitchAndFamily As String * 1

lfFaceName As String * LF_FACESIZE

End Type

’字体的族

Global Const FF_DONTCARE = 0 ’ 无所谓

Global Const FF_ROMAN = 16 ’ 字体宽度可变,Times Roman, Century ’ Schoolbook等

Global Const FF_SWISS = 32 ’ 宽度可变,带衬线,如Helvetica, Swiss等

Global Const FF_MODERN = 48 ’ 具有规定的宽度,衬线可有可无,

’ 如Pica, Elite, Courier等等.

Global Const FF_SCRIPT = 64 ’ 手写体,如Cursive

Global Const FF_DECORATIVE = 80 ’ 特殊字体,如Old English

’ GDI字体函数

Declare Function CreateFontIndirect Lib "GDI" (lpLogFont As LOGFONT) As Integer

Declare Function SelectObject Lib "GDI" (ByVal hDC%, ByVal Object%) As Integer

Declare Sub DeleteObject Lib "GDI" (ByVal Object%)

Declare Function GetStockObject Lib "GDI" (ByVal nIndex As Integer) As Integer

Declare Sub GDIGetObject Lib "GDI" Alias "GetObject" (ByVal hObject As Integer, ByVal nCount As Integer, lpObject As Any)

Declare Sub TextOut Lib "GDI" (ByVal hDC As Integer, ByVal X As Integer, ByVal Y As Integer, ByVal lpString As String, ByVal nCount As Integer)

ROTFONT.FRM文件:

VERSION 2.00

Begin Form frmRotDemo

Caption = "旋转字体演示"

ClientHeight = 4980

ClientLeft = 1095

ClientTop = 1785

ClientWidth = 4380

FontBold = -1 ’True

FontItalic = 0 ’False

FontName = "Courier New"

FontSize = 18

FontStrikethru = 0 ’False

FontUnderline = 0 ’False

Height = 5670

Left = 1035

LinkTopic = "Form1"

ScaleHeight = 332

ScaleMode = 3 ’Pixel

ScaleWidth = 292

Top = 1155

Width = 4500

Begin CommonDialog CMDialog1

Flags = 257

Left = 0

Top = 0

End

Begin Menu mnuOption

Caption = "选择(&O)"

Begin Menu mnuFont

Caption = "字体(&F)..."

Shortcut = ^F

End

Begin Menu mnuS1

Caption = "-"

End

Begin Menu mnuExit

Caption = "退出(&X)"

Shortcut = ^X

End

End

End

Option Explicit

Sub Form_Paint ()

Dim nAngle%

Cls

For nAngle% = 20 To 80 Step 10

ForeColor = QBColor(nAngle% / 10 - 2)

RotPrint hDC, "热情技术技巧 旋转字体", 10, 290, nAngle%

Next

End Sub

Sub mnuExit_Click ()

End

End Sub

Sub mnuFont_Click ()

’ 初始化对话框控制

CMDialog1.FontName = FontName

CMDialog1.FontSize = FontSize

CMDialog1.FontItalic = FontItalic

CMDialog1.FontBold = FontBold

CMDialog1.FontUnderLine = FontUnderLine

CMDialog1.FontStrikeThru = FontStrikeThru

On Error GoTo ErrHandle

CMDialog1.Action = 4

’ 设置窗体的字体属性

FontName = CMDialog1.FontName

FontSize = CMDialog1.FontSize

FontItalic = CMDialog1.FontItalic

FontBold = CMDialog1.FontBold

FontUnderLine = CMDialog1.FontUnderLine

FontStrikeThru = CMDialog1.FontStrikeThru

Refresh

ErrHandle:

End Sub

Sub RotPrint (ByVal hDestDC As Integer, Text$, x As Integer, y As Integer, LineAngle As Integer)

Dim hFont As Integer, hOldFont As Integer, r%

Dim Font As LOGFONT

hOldFont = SelectObject(hDestDC, GetStockObject(SYSTEM_FONT))

GDIGetObject hOldFont, Len(Font), Font

’ 填充LOGFONT结构

Font.lfEscapement = LineAngle * 10 ’ 输出字体行与水平页底间的角度(以1/10度为单位)

’ 必须是可变点字体

Font.lfPitchAndFamily = Chr$(VARIABLE_PITCH Or FF_DONTCARE)

’ 创建字体

hFont = CreateFontIndirect(Font)

’ 选择旋转字体

r% = SelectObject(hDestDC, hFont)

’ 显示字体

TextOut hDestDC, x, y, Text$, Len(Text$)

’ 恢复原字体

hFont = SelectObject(hDestDC, hOldFont)

’ 删除创建的字体

DeleteObject hFont

End Sub

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有