龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > VB开发 >

旋转字体

时间:2009-12-30 15:42来源:未知 作者:admin 点击:
分享到:
如何使自己设计的程序具有漂亮和友好的界面,是程序员间永恒的话题。这里,笔者向您介绍一种非常简单的技巧,使文字旋转起来。 这里的“旋转字体”指的是让一行字体的水平基线
如何使自己设计的程序具有漂亮和友好的界面,是程序员间永恒的话题。这里,笔者向您介绍一种非常简单的技巧,使文字旋转起来。
  这里的“旋转字体”指的是让一行字体的水平基线(baseline)转过一定的角度。正如您所看到的,旋转字体会产生轻松、活泼的视觉效果,可以给观者以特殊的联想,是一种行之有效的显示特技。
  有一种很容易想到的办法可以实现旋转字体,即首先生成文字的点阵(位图),然后利用坐标旋转变换生成新的位图再输出到屏幕或打印机上。这种办法思路清晰,不但可以用于字体的旋转,也可以用于其他种种字体变形,如同WinWord中的WordArt或中文之星的“艺术汉字”。但这种办法实现起来比较麻烦,需要一些计算机绘图学方面的知识,而且位图变换过程中需要占用较多的内存。而我们所要介绍的方法,可以有效地解决这些问题,而且不需要什么专门的知识,而是充分地利用WindowsAPI已有的功能实现旋转字体的效果。
  我们知道,逻辑字体是一类非常重要的WindowsGDI对象。我们正是通过选择不同的逻辑字体来输出各种秀美的字体的。而所谓“旋转字体”不过是一类特殊的逻辑字体。如同其他的GDI对象(如画笔、画刷、调色板)一样,字体对象不但具有固有的字体,我们也可以建立自己的逻辑字体。建立字体可以使用WindowsAPI的CreateFontIndirect()函数。在调用该函数之前,我们将字体的特征放入LOGFONT
  结构变量中。LOGFONT结构是这样定义的:
  TypeLOGFONT
  lfHeightAsInteger'字体的高度
  lfWidthAsInteger'字体的宽度
  lfEscapementAsInteger'字体旋转的角度
  lfOrientationAsInteger
  lfWeightAsInteger'字体的轻重
  lfItalicAsString*1'是否为斜体
  lfUnderlineAsString*1'是否有下划线
  lfStrikeOutAsString*1'是否有强调线
  lfCharSetAsString*1'字符集
  lfOutPrecisionAsString*1'输出精度
  lfClipPrecisionAsString*1'剪裁精度
  lfQualityAsString*1'输出质量
  lfPitchAndFamilyAsString*1'间距和字体族
  lfFaceNameAsString*LF_FACESIZE'字体名,如“宋体”
  EndType
  
  利用这个数据结构,你可以方便地设置各种字体参数,比如高度、宽度等。该结构中同我们所要讨论的问题关系最大的是lfEscapement,它表示字符的基线同坐标的X轴之间的旋转角度,从X轴正方向开始沿逆时针方向旋转,以十分之一度为单位(图2)。蔡明志先生著的《Windows程序设计?绘图篇--使用BorlandC forWindows》一书(科学出版社1993年9月出版)的482页上指出旋转角度以十度为单位,为此笔者查阅了SDK手册,其英文原文为:“measuredintenthsofadegree”,似应为以十分之一度为单位。
  lfFaceName指明字体的名称,如“宋体”、“行楷”。需要指出的是,个别字体不支持字体旋转,主要是字体宽度不可变的种类,如FixedSys就不支持字体旋转,好在这样的字体只有一两种。
  具体的实现参见文后所附的程序(用VisualBasic3.0编写),其中RotPrint过程用来输出旋转字体。其步骤如下:首先,利用GetObject()函数获得当前字体的LOGFONT结构,修改lfEscapement,设置旋转角度,然后调用CreateFontIndirect()函数建立逻辑字体并选用之。接下来,调用TextOut()函数输出字符串。使用TextOut()函数可以使那些不支持Print方法的控制(如标签),同样可以输出旋转字体。最后,用DeleteObject()函数删除建立的逻辑字体并恢复原字体。
  您可以通过示例程序的“选择”菜单中的“字体”项来尝试不同的字体效果,从中选出令人满意的组合。
  
  附录:源程序
  ROTFONT.BAS文件:
  DefIntA-Z
  '逻辑字体
  GlobalConstLF_FACESIZE=32'最长的字体名称
  GlobalConstSYSTEM_FONT=13
  TypeLOGFONT
  lfHeightAsInteger
  lfWidthAsInteger
  lfEscapementAsInteger
  lfOrientationAsInteger
  lfWeightAsInteger
  lfItalicAsString*1
  lfUnderlineAsString*1
  lfStrikeOutAsString*1
  lfCharSetAsString*1
  lfOutPrecisionAsString*1
  lfClipPrecisionAsString*1
  lfQualityAsString*1
  lfPitchAndFamilyAsString*1
  lfFaceNameAsString*LF_FACESIZE
  EndType
  '字体的族
  GlobalConstFF_DONTCARE=0'无所谓
  GlobalConstFF_ROMAN=16'字体宽度可变,TimesRoman,Century
  'Schoolbook等
  GlobalConstFF_SWISS=32'宽度可变,带衬线,如Helvetica,Swiss等
  GlobalConstFF_MODERN=48'具有规定的宽度,衬线可有可无,
  '如Pica,Elite,Courier等等.
  GlobalConstFF_SCRIPT=64'手写体,如Cursive
  GlobalConstFF_DECORATIVE=80'特殊字体,如OldEnglish
  'GDI字体函数
  DeclareFunctionCreateFontIndirectLib"GDI"(lpLogFontAsLOGFONT)As
  Integer
  DeclareFunctionSelectObjectLib"GDI"(ByValhDC,ByValObject)As
  Integer
  DeclareSubDeleteObjectLib"GDI"(ByValObject)
  DeclareFunctionGetStockObjectLib"GDI"(ByValnIndexAsInteger)As
  Integer
  DeclareSubGDIGetObjectLib"GDI"Alias"GetObject"(ByValhObjectAs
  Integer,ByValnCountAsInteger,lpObjectAsAny)
  DeclareSubTextOutLib"GDI"(ByValhDCAsInteger,ByValXAsInteger,
  ByValYAsInteger,ByVallpStringAsString,ByValnCountAsInteger)
  
  ROTFONT.FRM文件:
  VERSION2.00
  BeginFormfrmRotDemo
  Caption="旋转字体演示"
  ClientHeight=4980
  ClientLeft=1095
  ClientTop=1785
  ClientWidth=4380
  FontBold=-1'True
  FontItalic=0'False
  FontName="CourierNew"
  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
  BeginCommonDialogCMDialog1
  Flags=257
  Left=0
  Top=0
  End
  BeginMenumnuOption
  Caption="选择(&O)"
  BeginMenumnuFont
  Caption="字体(&F)..."
  Shortcut=^F
  End
  BeginMenumnuS1
  Caption="-"
  End
  BeginMenumnuExit
  Caption="退出(&X)"
  Shortcut=^X
  End
  End
  End
  OptionExplicit
  
  SubForm_Paint()
  DimnAngle
  Cls
  FornAngle=20To80Step10
  ForeColor=QBColor(nAngle/10-2)
  RotPrinthDC,"热情技术技巧旋转字体",10,290,nAngle
  Next
  EndSub
  
  SubmnuExit_Click()
  End
  EndSub
  
  SubmnuFont_Click()
  '初始化对话框控制
  CMDialog1.FontName=FontName
  CMDialog1.FontSize=FontSize
  CMDialog1.FontItalic=FontItalic
  CMDialog1.FontBold=FontBold
  CMDialog1.FontUnderLine=FontUnderLine
  CMDialog1.FontStrikeThru=FontStrikeThru
  OnErrorGoToErrHandle
  CMDialog1.Action=4
  '设置窗体的字体属性
  FontName=CMDialog1.FontName
  FontSize=CMDialog1.FontSize
  FontItalic=CMDialog1.FontItalic
  FontBold=CMDialog1.FontBold
  FontUnderLine=CMDialog1.FontUnderLine
  FontStrikeThru=CMDialog1.FontStrikeThru
  Refresh
  ErrHandle:
  EndSub
  
  SubRotPrint(ByValhDestDCAsInteger,Text$,xAsInteger,yAs
  Integer,LineAngleAsInteger)
  DimhFontAsInteger,hOldFontAsInteger,r
  DimFontAsLOGFONT
  hOldFont=SelectObject(hDestDC,GetStockObject(SYSTEM_FONT))
  GDIGetObjecthOldFont,Len(Font),Font
  '填充LOGFONT结构
  Font.lfEscapement=LineAngle*10'输出字体行与水平页底间的角度(以1/10
  度为单位)
  '必须是可变点字体
  Font.lfPitchAndFamily=Chr$(VARIABLE_PITCHOrFF_DONTCARE)
  '创建字体
  hFont=CreateFontIndirect(Font)
  '选择旋转字体
  r=SelectObject(hDestDC,hFont)
  '显示字体
  TextOuthDestDC,x,y,Text$,Len(Text$)
  '恢复原字体
  hFont=SelectObject(hDestDC,hOldFont)
  '删除创建的字体
  DeleteObjecthFont
  EndSub->

精彩图集

赞助商链接