TrueTypeFont文件中符号数据导出与绘制

来源:互联网 发布:php字符串反转 编辑:程序博客网 时间:2024/04/28 23:51
 

TrueTypeFont文件作为流行的矢量形式字体文件,其中存储着大量的符号资源。为充分利用资源与达到数据共享目标,现以freetype2源代码为文件读取功能的支撑,导出TrueTypeFont文件中存储的符号并实现绘制。要注意的问题:
1)  英文与汉字映射关系以Unicode编码为准。汉字为双字节,即宽字符。而符号以数字为索引依次读出。
2)  为避免重复和加速,可预先做链表,将新创建的符号填入,以方便再次查询时直接读出。
3)  使用De Casteljau 算法处理贝塞尔(Bezier)曲线。

附参考代码:

程序入口:
      Process()
     {    const char* font_filename = "C:\\Windows\\Fonts\\WINGDNG3.TTF";

         fonts = new FTGLOutlineFont( font_filename );   //矢量轮廓,以文件名称为参数
         const unsigned char* c = (unsigned char*)string;
         while( *c)                                                                               //依次处理字符


         {
             fonts->CheckGlyph(*c);
              ++c;
          }
}
调用的函数:

bool FTFont::CheckGlyph(const unsigned int characterCode)

{
     if( NULL == glyphList->Glyph( characterCode))           //如果还没有添加进列表

     {

         unsigned int glyphIndex = glyphList->FontIndex( characterCode);  //取得索引

         FTGlyph* tempGlyph = MakeGlyph(glyphIndex);    //调用子类中的这个函数,制作Glyph

         if( NULL == tempGlyph)                                       //返回值为空的话
          {
               if( 0 == err)
                {
                  err = 0x13;
                 }
                 return false;
            }
            glyphList->Add( tempGlyph, characterCode);         //添加到容器中
       }
        return true;                                            //若已存在容器中直接返回true

}

 

//构建Glyph

FTGlyph* FTGLOutlineFont::MakeGlyph( unsigned int g)

{

    FT_GlyphSlot ftGlyph = face.Glyph( g, FT_LOAD_NO_HINTING);                       //调用freetype函数 
     if( ftGlyph)
      {

         FTOutlineGlyph* tempGlyph = new FTOutlineGlyph( ftGlyph, useDisplayLists);          //以刚得到的ftGlyph为参数,新建FTOutlineGlyph,也为渲染函数建立需要的现实列表

        return tempGlyph;

    }
    err = face.Error();
    return NULL;

}

 

//读取顶点信息

FTOutlineGlyph::FTOutlineGlyph( FT_GlyphSlot glyp)

:   FTGlyph( glyph)

{
if( ft_glyph_format_outline != glyph->format)
   {
          err = 0x14; // Invalid_Outline
          return;
    }
    FTVectoriser vectoriser( glyph);                                 //矢量化
    size_t numContours = vectoriser.ContourCount();
      if ( ( numContours < 1) || ( vectoriser.PointCount() < 3))
      {
           return;
      }
      for( unsigned int c = 0; c < numContours; ++c)
      {
         const FTContour* contour = vectoriser.Contour(c);
         iPolylineNumbers = iPolylineNumbers + 1;

         geoAtomLine =(geoatom::CGeoAtomPolyline**)realloc(geoAtomLine,iPolylineNumbers*sizeof(geoatom::CGeoAtomPolyline*));

         geoAtomLine = new geoatom::CGeoAtomPolyline();//原子分配内存,由于数组从开始记数,标记总是比个数少


  for( unsigned int pointIndex = 0; pointIndex < contour->PointCount(); ++pointIndex)

         {
            FTPoint point = contour->Point(pointIndex);
          geoAtomLine->GetPtList()->add(fXaddition+iSize*point.X()/64.0f,fYaddition+iSize*point.Y()/64.0f);


         }
        geoAtomLine->SetClosed(true);       //将线段形成的区域封闭起来
        geoSymPoint->AddAtom(geoAtomLine);  //将各条线要素添加到这个符号中,一个点符号中可能有多条线
}
}

原创粉丝点击