wuhanht
路人甲
路人甲
  • 注册日期2007-05-24
  • 发帖数12
  • QQ
  • 铜币175枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:1434回复:0

[原创]TrueTypeFont文件中符号数据导出与绘制

楼主#
更多 发布于:2008-01-08 22:15
         TrueTypeFont文件作为流行的矢量形式字体文件,其中存储着大量的符号资源。为充分利用资源与达到数据共享目标,现以freetype2源代码为文件读取功能的支撑,导出TrueTypeFont文件中存储的符号并实现绘制。要注意的问题:
<P >1)  英文与汉字映射关系以Unicode编码为准。汉字为双字节,即宽字符。而符号以数字为索引依次读出。</P>
<P >2)  为避免重复和加速,可预先做链表,将新创建的符号填入,以方便再次查询时直接读出。</P>
<P >3)  使用De Casteljau 算法处理贝塞尔(Bezier)曲线。</P>
<P><P> </P>附参考代码:</P>
<P><P>      </P>程序入口:</P>
<P>      Process()</P>
<P>     {    const char* font_filename = "C:\\Windows\\Fonts\\WINGDNG3.TTF";<P></P></P>
<P>         fonts[0] = new FTGLOutlineFont( font_filename );   //矢量轮廓,以文件名称为参数<BR>         const unsigned char* c = (unsigned char*)string[j];<BR>         while( *c)                                                                               //依次处理字符<P></P></P>
<P  align=left>         {<BR>             fonts[0]->CheckGlyph(*c);<BR>              ++c;<BR>          }<BR>}<BR>调用的函数:</P>
<P  align=left>bool FTFont::CheckGlyph(const unsigned int characterCode)<P></P></P>
<P  align=left>{<BR>     if( NULL == glyphList->Glyph( characterCode))           //如果还没有添加进列表<P></P></P>
<P  align=left>     {<P></P></P>
<P  align=left>         unsigned int glyphIndex = glyphList->FontIndex( characterCode);  //取得索引<P></P></P>
<P  align=left>         FTGlyph* tempGlyph = MakeGlyph(glyphIndex);    //调用子类中的这个函数,制作Glyph<P></P></P>
<P  align=left>         if( NULL == tempGlyph)                                       //返回值为空的话<BR>          {<BR>               if( 0 == err)<BR>                {<BR>                  err = 0x13;<BR>                 }<BR>                 return false;<BR>            }<BR>            glyphList->Add( tempGlyph, characterCode);         //添加到容器中<BR>       }<BR>        return true;                                            //若已存在容器中直接返回true<P></P></P>
<P>}<P></P></P>
<P><P> </P></P>
<P>//构建Glyph<P></P></P>
<P  align=left>FTGlyph* FTGLOutlineFont::MakeGlyph( unsigned int g)<P></P></P>
<P  align=left>{<P></P></P>
<P  align=left>    FT_GlyphSlot ftGlyph = face.Glyph( g, FT_LOAD_NO_HINTING);                       //调用freetype函数  <BR>     if( ftGlyph)<BR>      {<P></P></P>
<P  align=left>         FTOutlineGlyph* tempGlyph = new FTOutlineGlyph( ftGlyph, useDisplayLists);          //以刚得到的ftGlyph为参数,新建FTOutlineGlyph,也为渲染函数建立需要的现实列表<P></P></P>
<P  align=left>        return tempGlyph;<P></P></P>
<P  align=left>    }<BR>    err = face.Error();<BR>    return NULL;<P></P></P>
<P>}<P></P></P>
<P><P> </P></P>
<P>//读取顶点信息<P></P></P>
<P  align=left>FTOutlineGlyph::FTOutlineGlyph( FT_GlyphSlot glyp)<P></P></P>
<P  align=left>:   FTGlyph( glyph)<P></P></P>
<P  align=left>{<BR> if( ft_glyph_format_outline != glyph->format)<BR>   {<BR>          err = 0x14; // Invalid_Outline<BR>          return;<BR>    }<BR>    FTVectoriser vectoriser( glyph);                                 //矢量化<BR>    size_t numContours = vectoriser.ContourCount();<BR>      if ( ( numContours < 1) || ( vectoriser.PointCount() < 3))<BR>      {<BR>           return;<BR>      }<BR>      for( unsigned int c = 0; c < numContours; ++c)<BR>      {<BR>         const FTContour* contour = vectoriser.Contour(c);<BR>         iPolylineNumbers = iPolylineNumbers + 1;<P></P></P>
<P  align=left>         geoAtomLine =(geoatom::CGeoAtomPolyline**)realloc(geoAtomLine,iPolylineNumbers*sizeof(geoatom::CGeoAtomPolyline*));<P></P></P>
<P  align=left>         geoAtomLine[iPolylineNumbers-1] = new geoatom::CGeoAtomPolyline();//原子分配内存,由于数组从开始记数,标记总是比个数少<P></P></P>
<P  align=left><P>       </P>  for( unsigned int pointIndex = 0; pointIndex < contour->PointCount(); ++pointIndex)<P></P></P>
<P  align=left>         {<BR>            FTPoint point = contour->Point(pointIndex);<BR>          geoAtomLine[iPolylineNumbers-1]->GetPtList()->add(fXaddition+iSize*point.X()/<ST1:CHMETCNV tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="64" unitname="F" w:st="on">64.0f</ST1:CHMETCNV>,fYaddition+iSize*point.Y()/<ST1:CHMETCNV tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="64" unitname="F" w:st="on">64.0f</ST1:CHMETCNV>);<P></P></P>
<P  align=left>         }<BR>        geoAtomLine[iPolylineNumbers-1]->SetClosed(true);       //将线段形成的区域封闭起来<BR>        geoSymPoint[iPointSymbolNum-1]->AddAtom(geoAtomLine[iPolylineNumbers-1]);  //将各条线要素添加到这个符号中,一个点符号中可能有多条线<BR>}<BR>}<BR>原始字体文件中符号;<BR></P>
<P><IMG src="http://www.cnblogs.com/images/cnblogs_com/wuhanhoutao/116501/r_original.JPG" border=0></P>
<P><FONT face=新宋体>导出TrueTypeFont文件中符号数据与绘制:</FONT></P>
<P><BR> </P><IMG src="http://www.cnblogs.com/images/cnblogs_com/wuhanhoutao/116501/r_symbolPlant.JPG" border=0>
喜欢0 评分0
游客

返回顶部