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

[原创]TrueTypeFont文件中汉字的矢量化与绘制

楼主#
更多 发布于:2008-01-12 12:16
<P><FONT face=宋体>    在</FONT> C:"WINDOWS"Fonts 文件夹下面有几个矢量字体文件,如SIMFANG.TTF,SIMHEI.TTF,SIMKAI,SIMSUN分别对应着仿宋体,黑体,楷体和宋体。希望首先提取文件当中的存储的汉字位置信息,接着完成矢量化处理后,然后采用DC或OpenGL进行绘制。从表面上看,这个工作也就是想实现Windows API中间的TextOut和wglUseFontOuline等函数所实现的功能。但自己编程实现汉字的矢量化,能在后续工作中获得更多的灵活性,比如将用户输入的汉字换行处理,根据用户的输入对汉字进行任意角度的倾斜,总之,主动性掌握在自己手里。完成矢量化工作后,对这些汉字的处理如同处理普通的矢量图形一样,相当方便,而再不仅仅受制于系统 API所能提供的功能。</P>
<P>     具体的步骤为:</P>
<P >1)     根据Unicode编码标准,存储汉字的编码表 。</P>
<P  align=left>wchar_t Mystring[1001];                       //存储准备显示的宽字符的编码</P>
<P  align=left>    count = 0;</P>
<P  align=left>    for (i=0;i<1000;i++)</P>
<P  align=left>    {</P>
<P  align=left>        Mystring[count] = 19968 + i;         //十进制的对应着十六进制的e00 </P>
<P  align=left>        count++;</P>
<P  align=left>    }</P>
<P>    Mystring[1000] = '"0';</P>
<P>上面的例子中只准备提取1000个汉字,其实可以让循环从4e00进行到9521(十六进制),代表十进制的19968和38176,分别对应着汉字:一,锠。</P>
<P>2)采用FreeType2代码读取*.ttf文件,得到每个汉字的轮廓信息。</P>
<P  align=left>while( *c)                                                                     //依次处理字符</P>
<P  align=left>        {</P>
<P  align=left>                         fonts[0]->CheckGlyph(*c);</P>
<P  align=left>                         ++c;</P>
<P  align=left>}</P>
<P>    </P>
<P>3)在上叙第2步当中,完成矢量化工作的过程中,可采用De Casteljau算法处理贝塞尔(bezier)曲线。</P>
<P>矢量化工作的入口:</P>
<P  align=left>for( short contourIndex = 0; contourIndex < ftContourCount; ++contourIndex)</P>
<P  align=left>    {</P>
<P  align=left>        FT_Vector* pointList = ;outline.points[startIndex];</P>
<P  align=left>        char* tagList = ;outline.tags[startIndex];</P>
<P  align=left>        </P>
<P  align=left>        endIndex = outline.contours[contourIndex];</P>
<P  align=left>        contourLength = ( endIndex - startIndex) + 1;</P>
<P  align=left>        FTContour* contour = new FTContour( pointList, tagList, contourLength);</P>
<P  align=left>        </P>
<P  align=left>        contourList[contourIndex] = contour;</P>
<P  align=left>        </P>
<P  align=left>        startIndex = endIndex + 1;</P>
<P >}</P>
<P >4)根据提取的位置信息,采用DC或OpenGL进行绘制。</P>
<P >//采用DC绘制</P>
<P  align=left>for( unsigned int c = 0; c < numContours; ++c)</P>
<P  align=left>    {</P>
<P  align=left>        const FTContour* contour = vectoriser.Contour(c);</P>
<P  align=left>        iPolylineNumbers = iPolylineNumbers + 1;</P>
<P  align=left>        geoAtomLine =(geoatom::CGeoAtomPolyline**)realloc(geoAtomLine,iPolylineNumbers*sizeof(geoatom::CGeoAtomPolyline*));</P>
<P  align=left>        geoAtomLine[iPolylineNumbers-1] = new geoatom::CGeoAtomPolyline();    //原子分配内存,由于数组从开始记数,标记总是比个数少</P>
<P  align=left>        for( unsigned int pointIndex = 0; pointIndex < contour->PointCount(); ++pointIndex)</P>
<P  align=left>        {</P>
<P  align=left>            FTPoint point = contour->Point(pointIndex);</P>
<P  align=left>            geoAtomLine[iPolylineNumbers-1]->GetPtList()->add(fXaddition+iSize*point.X()/64.0f,fYaddition+iSize*point.Y()/64.0f);</P>
<P  align=left>        }</P>
<P  align=left>        geoAtomLine[iPolylineNumbers-1]->SetClosed(true);                          //将线段形成的区域封闭起来</P>
<P  align=left>        geoSymPoint[iPointSymbolNum-1]->AddAtom(geoAtomLine[iPolylineNumbers-1]); //将线要素添加到这个符号中</P>
<P  align=left>    }</P>
<P  align=left>    </P>
<P >}</P>
<P >//采用OpenGL进行绘制。</P>
<P  align=left>for( unsigned int c = 0; c < numContours; ++c)</P>
<P  align=left>    {</P>
<P  align=left>        const FTContour* contour = vectoriser.Contour(c);</P>
<P  align=left>        </P>
<P  align=left>        glBegin( GL_LINE_LOOP);                           //首尾相连接的多边形</P>
<P  align=left>           for( unsigned int pointIndex = 0; pointIndex < contour->PointCount(); ++pointIndex)</P>
<P  align=left>            {</P>
<P  align=left>                FTPoint point = contour->Point(pointIndex);</P>
<P  align=left>        //        glVertex2f( point.X() / 64.0f, point.Y() / 64.0f);           //提取顶点信息,绘制的落脚点</P>
<P  align=left>                </P>
<P  align=left>            }</P>
<P  align=left>      // glEnd();</P>
<P >    }<BR><BR>输出的图形:<BR></P><IMG src="http://www.cnblogs.com/images/cnblogs_com/wuhanhoutao/116501/r_textout.jpg" border=0>
喜欢0 评分0
游客

返回顶部