LOGFONT是Windows内部字体的逻辑结构,主要用于设置字体格式,其定义如下:
typedef struct tagLOGFONTA
{
LONG lfHeight;
LONG lfWidth;
LONG lfEscapement;
LONG lfOrientation;
LONG lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
CHAR lfFaceName[LF_FACESIZE];
} LOGFONTA
其各个字段的含义如下:
lfHeight:指定逻辑单位的字符或者字符元高度。
lfWidth:指定逻辑单位的字体字符的平均宽度。
lfEscapement:指定每行文本输出时相对于设备x轴的角度,其单位为1/10度。
lfOrientation:指定字符基线相对于设备x轴的角度,其单位为1/10度。此值在Win9X中和lfEscapement具有相同的值,而在WinNT下有时候可能不同。
lfWeight:指定字体的重量,Windows中字体重量表示字体的粗细程度,其范围在0~1000之间,正常为400,粗体为700,若此值为空,则使用默认的字体重量。
lfItalic:此值为TRUE时,字体为斜体。
lfUnderline:此值为TRUE时,字体带下划线。
lfStrikeOut:此值为TRUE时,字体带删除线。
lfCharSet:指定所使用的字符集,如GB2312_CHARSET,CHINESEBIG5_CHARSET等。
lfOutPrecision:指定输出精度,它定义了输出与所要求的字体高度、宽度、字符方向及字体类型等相接近的程度。
lfClipPrecision:指定剪辑精度,它定义了当字符的一部分超过剪辑区域时对字符的剪辑方式。
lfQuality:指定输出质量,它定义了GDI在匹配逻辑字体属性到实际的物理字体时所使用的方式。
lfPitchAndFamily:指定字体的字符间距和族。
lfFaceName:指向NULL结尾的字符串的指针,此字符串即为所使用的字体名称,其长度不能超过32个字符,如果为空,则使用系统默认的字体。
Windows的字体
王佰营 徐丽红
字体是文字显示和打印的外观形式,它包括了文字的字样、风格和尺寸等方面的属性。字样是字符书写和显示时表现出的特定模式,例如,对于汉字通常有宋体、楷体、隶书、黑体以及魏碑林等多种字样;字体风格主要表现为字体的粗细和是否倾斜等特点;字体尺寸是用来指定字符所占区域的大小,通常用字符高度来描述。字体尺寸可以取毫米或英寸作为单位,但为了直观也常常采用一种称为点的单位,一点约折合为1/72英寸。对于汉字,还常用号数来表示字体尺寸,初号字最大,以下依次为小初、小一、二号、小二等,如此类推,字体尺寸越来越小。
根据字体的构造技术,可以把字体分为三种基本的技术类型:点阵字体、矢量字体和TrueType字体。点阵字体也称光栅字体或位图字体,其中每个字符的原型都是以固定的位图形式存储在字库中,如System,MS Serif,FixedSys,Terminal和Small Fonts等等;矢量字体也称为笔画字体或绘图仪字体,则是把字符分解为一系列直线而存储起来,如Modern,Roman和Script等等;TrueType字体有可称为写真字体,其字符原型是一系列直线和曲线指令的线索的集合,如Courier New, Times New Roman,Symbol和Arial等等。点阵字体依赖于特定的设备分辨率,是与设备相关的字体;矢量字体和TrueType字体都是与设备无关的,可以任意缩放。TrueType字体的生成速率较快,使用也最广泛。
为了编程的方便,又将字体分为逻辑字体与物理字体:逻辑字体与逻辑画笔和逻辑画刷相似,逻辑字体是应用程序对于理想字体的一种描述方式。而实际安装在操作系统中的和存在于设备中的字体都称为物理字体。应用程序在使用逻辑字体绘制文字时,系统会采用一种特定的算法把一种逻辑字体映射为最匹配的物理字体。windows的字体一般放在C:\WINDOWS\Fonts,如果对WINDOWS本身默认的字体不满意,可下载新字体安装在C:\WINDOWS\Fonts目录下即可。
在Windows中,逻辑字体的具体属性由LOGFONT结构描述。LOGFONT结构定义如下:
typedef struct tagLOGFONTA
{
LONG lfHeight; //字体高度
LONG lfWidth; //平均宽度
LONG lfEscapement; //字符排列角度
LONG lfOrientation; //字符本身旋转的角度
LONG lfWeight; //设置字体线条的宽度
BYTE lfItalic; //是否为斜体
BYTE lfUnderline; //是否加底线
BYTE lfStrikeOut; //是否字符*加横线
BYTE lfCharSet; //字符集
BYTE lfOutPrecision; //字体的精确度
BYTE lfClipPrecision; //裁剪字符的方法
BYTE lfQuality; //字体质量
BYTE lfPitchAndFamily; //选择字体的间距和字体家族
CHAR lfFaceName[LF_FACESIZE]; //字体的名称
} LOGFONTA, *PLOGFONTA, NEAR *NPLOGFONTA, FAR *LPLOGFONTA;
typedef struct tagLOGFONTW
{
LONG lfHeight; //字体高度
LONG lfWidth; //平均宽度
LONG lfEscapement; //字符排列角度
LONG lfOrientation; //字符本身旋转的角度
LONG lfWeight; //设置字体线条的宽度
BYTE lfItalic; //是否为斜体
BYTE lfUnderline; //是否加底线
BYTE lfStrikeOut; //是否字符*加横线
BYTE lfCharSet; //字符集
BYTE lfOutPrecision; //字体的精确度
BYTE lfClipPrecision; //裁剪字符的方法
BYTE lfQuality; //字体质量
BYTE lfPitchAndFamily; //选择字体的间距和字体家族
WCHAR lfFaceName[LF_FACESIZE]; //字体的名称
} LOGFONTW, *PLOGFONTW, NEAR *NPLOGFONTW, FAR *LPLOGFONTW;
#ifdef UNICODE
typedef LOGFONTW LOGFONT;
typedef PLOGFONTW PLOGFONT;
typedef NPLOGFONTW NPLOGFONT;
typedef LPLOGFONTW LPLOGFONT;
#else
typedef LOGFONTA LOGFONT;
typedef PLOGFONTA PLOGFONT;
typedef NPLOGFONTA NPLOGFONT;
typedef LPLOGFONTA LPLOGFONT;
#endif // UNICODE
其中:
(1)、LONG lfWeight; 设置字体线条的宽度选项:
符号 数值 意义
FW_DONTCARE 0 任意值
FW_THIN 100 非常细
FW_EXTRALIGHT 200 极细
FW_ULTRALIGHT 200 超细
FW_LIGHT 300 细
FW_NORMAL 400 正常
FW_REGULAR 400 标准
FW_MEDIUM 500 中等
FW_SEMIDBOLD 600 1/2粗
FW_DEMIBOLD 600 3/4粗
FW_BOLD 700 粗
FW_EXTRABOLD 800 特粗
FW_ULTRABOLD 800 极粗
FW_BLACK 900 黑体
FW_HEAVY 900 黑体
(2)、BYTE lfCharSet; //字符集选项:
#define ANSI_CHARSET 0
#define DEFAULT_CHARSET 1
#define SYMBOL_CHARSET 2
#define SHIFTJIS_CHARSET 128
#define HANGEUL_CHARSET 129
#define HANGUL_CHARSET 129
#define GB2312_CHARSET 134
#define CHINESEBIG5_CHARSET 136
#define OEM_CHARSET 255
#define JOHAB_CHARSET 130
#define HEBREW_CHARSET 177
#define ARABIC_CHARSET 178
#define GREEK_CHARSET 161
#define TURKISH_CHARSET 162
#define VIETNAMESE_CHARSET 163
#define THAI_CHARSET 222
#define EASTEUROPE_CHARSET 238
#define RUSSIAN_CHARSET 204
(3)、BYTE lfOutPrecision; //字体的精确度选项:
#define OUT_DEFAULT_PRECIS 0
#define OUT_STRING_PRECIS 1
#define OUT_CHARACTER_PRECIS 2
#define OUT_STROKE_PRECIS 3
#define OUT_TT_PRECIS 4
#define OUT_DEVICE_PRECIS 5
#define OUT_RASTER_PRECIS 6
#define OUT_TT_ONLY_PRECIS 7
#define OUT_OUTLINE_PRECIS 8
#define OUT_SCREEN_OUTLINE_PRECIS 9
(4)、BYTE lfClipPrecision; //裁剪字符的方法选项:
#define CLIP_DEFAULT_PRECIS 0
#define CLIP_CHARACTER_PRECIS 1
#define CLIP_STROKE_PRECIS 2
#define CLIP_MASK 0xf
#define CLIP_LH_ANGLES (1<<4)
#define CLIP_TT_ALWAYS (2<<4)
#define CLIP_EMBEDDED (8<<4)
(5)、BYTE lfQuality; //字体质量选项:
#define DEFAULT_QUALITY 0
#define DRAFT_QUALITY 1
#define PROOF_QUALITY 2
#define NONANTIALIASED_QUALITY 3
#define ANTIALIASED_QUALITY 4
(6)、BYTE lfPitchAndFamily; //选择字体的间距和字体家族
#define DEFAULT_PITCH 0 表示可缺省的间距
#define FIXED_PITCH 1 固定的间距
#define VARIABLE_PITCH 2 可变的间距
(7)、WCHAR lfFaceName[LF_FACESIZE]; //字样名称选择:
" Arial "
" Bell MT "
" Californian FB "
" Elephant "
" Forte "
" Garamond "
" Heallenschweiler "
" Impact "
" Jokerman "
" Kartika "
" Latha "
" Mangal "
" Niagara Solid "
" Onyx "
" Papyrus "
" Roman "
" Synbol "
" Tunqa "
" Verdana "
" Wide Latin "
"方正舒体"
"方正姚体"
"仿宋体"
"黑体"
"华文彩云"
"华文仿宋"
"华文琥珀"
"华文楷体"
"华文隶书"
"华文宋体"
"华文细黑"
"华文新魏"
"华文行楷"
"华文中宋"
"楷体"
"隶书"
"宋体 &新宋体"
"宋体-方正超大字符集"
"幼圆"
这仅仅是字样名称的一部分,更详细的字体名称请查自己电脑上文件夹:C:\WINDOWS\Fonts。
Windows环境下的显示是GDI对象通过设备描述表进行的,而字体对象就是GDI对象之一。实际上,Windows下的不同字体就是通过选择不同的逻辑字体而输出的。如同其他的GDI对象(如画笔、调色板)一样,字体对象不但具有固有的字体,我们可以建立所需要的逻辑字体,然后选进设备描述表就可以了。下面以VC 6.0环境为例加以说明。在VC 6.0中字体对象对应的类就是CFont类。CFont类有两个成员函数CreateFont和CreatePointFontIndirect,用这两个函数都可创建逻辑字体。函数定义如下:
BOOL CreateFont( int nHeight, //字体高度.>0:字体的高度值;=0:字体采//用缺省直.<0:此值的绝对值为高度.
int nWidth, //字体宽度.
int nEscapement, //文本行的倾斜度
int nOrientation, //字符基线的倾斜度
int nWeight, //字体的粗细
BYTE bItalic, //字体是否为斜体
BYTE bUnderline, //字体是否带下划线
BYTE cStrikeOut, //字体是否带删除线
BYTE nCharSet, //字体的字符集
BYTE nOutPrecision, //字符的输出精度
BYTE nClipPrecision, //字符裁剪的精度
BYTE nQuality, //字符的输出质量
BYTE nPitchAndFamily,// 字符间距和字体族
LPCTSTR lpszFacename //字体名称
);
该函数的各个参数和LOGFONT结构的对应的成员意义相同。
BOOL CreatePointFontIndirect(Const LOGFONT *lpLogFont);
用这个函数要定义一个LOGFONT结构体,用上一个函数就不用。以下为使用例程:
void CMainWindow::OnPaint ()
{
CRect rect;
GetClientRect(&rect);
CPaintDC dc (this)
dc.SetViewportOrg(rect.Width()/2,rect.Height()/2);
LONGFONT lf;
::ZeroMemory(&lf,sizeof(lf);
lf.lfHight = 160;
lf.lfWeight = WF_BOLD;
::lstrcpy(lf.lfFaceName,_T("Arial");
Cfont font;
Font. CreatePointFontIndirect(&lf);
CFont *pOldFont = dc.SelectObject(&font);
dc.Text(0,0,CString(_T("MFC HELL!")));
dc.SelectObject(pOldFont);
}
Windows C的使用例程如下:
HFONT hFont ;
LOGFONT lf ;
TCHAR szBuffer[] = _T("Windows C---SDK!");
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
lf.lfHeight = - (int) (fabs (pt.y) / 10.0 + 0.5) ;
lf.lfWidth = 0 ;
lf.lfEscapement = 0 ;
lf.lfOrientation = 0 ;
lf.lfWeight = 5;
lf.lfItalic = 0 ;
lf.lfUnderline = 0 ;
lf.lfStrikeOut = 0 ;
lf.lfCharSet = DEFAULT_CHARSET ;
lf.lfOutPrecision = 0 ;
lf.lfClipPrecision = 0 ;
lf.lfQuality = 0 ;
lf.lfPitchAndFamily = 0 ;
lstrcpy (lf.lfFaceName, _T("Arial") ;
hFont = CreateFontIndirect (&lf) ;
Se