根据所选择的 TrueType 字体生成点阵数据
2006-07-19 11:31:04 来源:WEB开发网// Macro to pack a TrueType table name into a DWORD.
其中具体的一些操作也可以参照 msdn 中的文章。之后就是解析ttf文件了,这要参考MS发布的TrueType Font规格书了,当然即使看懂了规格书,要自己做解析程序也是短时间难以完成的,还是让我们来找找有没有其他的已经有了的经验,在这里就要提到一个开源的项目了 fontforge 这是个日本人和台湾人维护的一个项目,可以支持多种字体进行解析和编辑,可以是个 Linux 下的程序,不过我们可以使用 Cygwin 来使这个程序在 Windows下运行起来,具体请参考 freefonts.oaka.org,但是这个程序太复杂太庞大了,我们一时半会 还不能理出头绪来,幸好在 cle.linux.org 看到 fontfoge 中有一个小工具叫做 showttf.c 可以简单的对于ttf文件进行解析,下载过来,进行编译,很有效。之后将其改进成可以只针对于“cmap”数据进行解析,并得到字体中支持字符的分段。
#define MAKETABLENAME(ch1, ch2, ch3, ch4) (\
(((DWORD)(ch4)) << 24) | \
(((DWORD)(ch3)) << 16) | \
(((DWORD)(ch2)) << 8) | \
((DWORD)(ch1))
)
DWORD tag = MAKETABLENAME( ''c'',''m'',''a'',''p'' );
DWORD size = m_pFontDC->GetFontData(tag,0, NULL, 0);
unsigned char *pBuffer = new unsigned char[size];
m_pFontDC->GetFontData(tag,0,pBuffer,size);
//do something with pBuffer
delete[] pBuffer;/*
3、通过选入字体的DC得到字体的点阵数据,这个处理依靠如下的函数,
read a short(2 bytes) from a stream
**/
static int Getushort(unsigned char **ttf) {
unsigned char ch1 = **(ttf);
(*ttf)++;
unsigned char ch2 = **(ttf);
(*ttf)++;
return( (ch1<<8)|ch2 );
}
/*
read a long(4 bytes) from a stream
**/
static int Getlong(unsigned char **ttf) {
unsigned char ch1 = **(ttf);
(*ttf)++;
unsigned char ch2 = **(ttf);
(*ttf)++;
unsigned char ch3 = **(ttf);
(*ttf)++;
unsigned char ch4 = **(ttf);
(*ttf)++;
return( (ch1<<24)|(ch2<<16)|(ch3<<8)|ch4 );
}
/*
Parse the table of "cmap"
**/
BOOL ReadttfEncodings(unsigned char *start_addr)
{
BOOL bResult = TRUE;
unsigned char *ttf = start_addr;
//local variable
int i;
int nencs, version;
int enc = 0;
int platform, specific;
int offset, encoff;
int format, len;
int segCount;
unsigned short *endchars,*startchars;
version = Getushort(&ttf);
nencs = Getushort(&ttf);
if ( version!=0 && nencs==0 )
nencs = version;/* Sometimes they are backwards */
for ( i=0; i < nencs; ++i )
{
platform = Getushort(&ttf);
specific = Getushort(&ttf);
offset = Getlong(&ttf);
if ( platform==3 /*&& (specific==1 || specific==5)*/)
{
enc = 1;
encoff = offset;
} else if ( platform==1 && specific==0 && enc!=1 )
{
enc = 2;
encoff = offset;
} else if ( platform==1 && specific==1 )
{
enc = 1;
encoff = offset;
} else if ( platform==0 ) {
enc = 1;
encoff = offset;
}
if ( platform==3 )
{
//MS Symbol
}
else if ( platform==1 )
{
//Mac Roman;
}
else if ( platform==0 )
{
//Unicode Default
}
else{}
}
if ( enc!=0 )
{
//reset pointer address
ttf = start_addr + encoff;
format = Getushort(&ttf);
if ( format!=12 && format!=10 && format!=8 )
{
len = Getushort(&ttf);
/*Language*/ Getushort(&ttf);
}
else
{
/* padding */ Getushort(&ttf);
len = Getlong(&ttf);
/*Format*/ Getlong(&ttf);
}
if ( format==0 )
{
//can''t be supported
bResult = FALSE;
}
else if ( format==4 )
{
//Format 4 (Windows unicode),only supported Format 4
segCount = Getushort(&ttf)/2;
/* searchRange = */ Getushort(&ttf);
/* entrySelector = */ Getushort(&ttf);
/* rangeShift = */ Getushort(&ttf);
endchars = new unsigned short[segCount];
for ( i=0; i < segCount; ++i )
endchars[i] = Getushort(&ttf);
if ( Getushort(&ttf)!=0 )
{
//Expected 0 in true type font;
}
startchars = new unsigned short[segCount];
for ( i=0; i < segCount; ++i )
startchars[i] = Getushort(&ttf);
//do something with endchars & startchars
delete[] startchars;
delete[] endchars;
}
else if ( format==6 )
{
/* Apple''s unicode format */
/* Well, the docs say it''s for 2byte encodings, but Apple actually*/
/* uses it for 1 byte encodings which don''t fit into the require-*/
/* ments for a format 0 sub-table. See Zapfino.dfont */
//can''t be supported
bResult = FALSE;
}
else if ( format==2 )
{
//can''t be supported
bResult = FALSE;
}
else if ( format==12 )
{
//can''t be supported
bResult = FALSE;
}
else if ( format==8 )
{
// fprintf(stderr,"I don''t support mixed 16/32 bit
// characters (no unicode surogates), format=%d", format);
// can''t be supported
bResult = FALSE;
}
else if ( format==10 )
{
//fprintf(stderr,"I don''t support 32 bit characters format=%d", format);
//can''t be supported
bResult = FALSE;
}
else
{
//fprintf(stderr,"Eh? Unknown encoding format=%d", format);
//can''t be supported
bResult = FALSE;
}
}
return bResult;
}DWORD GetGlyphOutline( UINT nChar,
UINT nFormat,
LPGLYPHMETRICS lpgm,
DWORD cbBuffer,
LPVOID lpBuffer,
const MAT2 FAR* lpmat2 ) const;
Remarks
Retrieves the outline curve or bitmap for an outline character in the current font.
具体请参考 msdn 可以得到 anti-alias 等多种格式的数据。但是这个有一个问题就是如果对应一个字体的size的各个参数,这里面的麻烦很多,后来总结如下如下:
更多精彩
赞助商链接