|
阅读:888回复:0
TrueTypeFont文件中符号数据导出与绘制
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 w:st="on" unitname="F" sourcevalue="64" hasspace="False" negative="False" numbertype="1" tcsc="0">64.0f</st1:chmetcnv>,fYaddition+iSize*point.Y()/<st1:chmetcnv w:st="on" unitname="F" sourcevalue="64" hasspace="False" negative="False" numbertype="1" tcsc="0">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> <img src="http://www.cnblogs.com/images/cnblogs_com/wuhanhoutao/116501/r_original.JPG" alt="" border="0"><br> <br> 导出TrueTypeFont文件中符号数据与绘制<br> <img src="http://www.cnblogs.com/images/cnblogs_com/wuhanhoutao/116501/r_symbolPlant.JPG" alt="" border="0"></p> |
|
|