WEB开发网
开发学院软件开发VC 根据所选择的 TrueType 字体生成点阵数据 阅读

根据所选择的 TrueType 字体生成点阵数据

 2006-07-19 11:31:04 来源:WEB开发网   
核心提示: // Macro to pack a TrueType table name into a DWORD.#define MAKETABLENAME(ch1, ch2, ch3, ch4) (\(((DWORD)(ch4)) << 24) | \(((DWORD)(ch3)) &

// Macro to pack a TrueType table name into a DWORD.
#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;
  其中具体的一些操作也可以参照 msdn 中的文章。之后就是解析ttf文件了,这要参考MS发布的TrueType Font规格书了,当然即使看懂了规格书,要自己做解析程序也是短时间难以完成的,还是让我们来找找有没有其他的已经有了的经验,在这里就要提到一个开源的项目了 fontforge 这是个日本人和台湾人维护的一个项目,可以支持多种字体进行解析和编辑,可以是个 Linux 下的程序,不过我们可以使用 Cygwin 来使这个程序在 Windows下运行起来,具体请参考 freefonts.oaka.org,但是这个程序太复杂太庞大了,我们一时半会 还不能理出头绪来,幸好在 cle.linux.org 看到 fontfoge 中有一个小工具叫做 showttf.c 可以简单的对于ttf文件进行解析,下载过来,进行编译,很有效。之后将其改进成可以只针对于“cmap”数据进行解析,并得到字体中支持字符的分段。 /*
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;
}
3、通过选入字体的DC得到字体的点阵数据,这个处理依靠如下的函数, 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的各个参数,这里面的麻烦很多,后来总结如下如下:

Tags:根据 选择 TrueType

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接