一. TTF字体轮廓解析与绘制

1.1 数据提取

void CHYTTFCharacter::InitTTPOLY()
{if(0 == m_pTTPOLYData)           // GetGlyphOutline提取到的字体轮廓数据{return;}TTPOLYGONHEADER* pTTPOLYGONHEADER = 0;TTPOLYCURVE* pTTPOLYCURVE = 0;STTTPOLYGONHEADER* pSTTTPOLYGONHEADER = 0;STTTPOLYCURVE* pSTTTPOLYCURVE = 0;unsigned int nTTPOLYDataLen = 0;unsigned char* pTTPOLYData = m_pTTPOLYData;unsigned int nCURVELen = 0;unsigned char* pCURVE = 0;int nTemp = 0;while(nTTPOLYDataLen < m_nTTPOLYDataLen){pSTTTPOLYGONHEADER = new STTTPOLYGONHEADER;m_stTTPOLYGONHEADERVector.push_back(pSTTTPOLYGONHEADER);pTTPOLYGONHEADER = (TTPOLYGONHEADER*)pTTPOLYData;memcpy(&(pSTTTPOLYGONHEADER->m_TTPOLYGONHEADER), pTTPOLYGONHEADER, sizeof(TTPOLYGONHEADER));pCURVE = pTTPOLYData + sizeof(TTPOLYGONHEADER);nCURVELen = sizeof(TTPOLYGONHEADER);while(nCURVELen < pTTPOLYGONHEADER->cb){pTTPOLYCURVE = (TTPOLYCURVE*)pCURVE;pSTTTPOLYCURVE = new STTTPOLYCURVE;pSTTTPOLYCURVE->Init(pTTPOLYCURVE->wType, pTTPOLYCURVE->cpfx);pSTTTPOLYGONHEADER->m_stTTPOLYCURVEVector.push_back(pSTTTPOLYCURVE);memcpy(pSTTTPOLYCURVE->m_p_apfx, pCURVE + sizeof(TTPOLYCURVE) - sizeof(POINTFX), sizeof(POINTFX) * pTTPOLYCURVE->cpfx);nTemp = sizeof(TTPOLYCURVE) + sizeof(POINTFX) * (pTTPOLYCURVE->cpfx - 1);pCURVE += nTemp;nCURVELen += nTemp;}nTTPOLYDataLen += pTTPOLYGONHEADER->cb;pTTPOLYData += pTTPOLYGONHEADER->cb;}
}

1.2 绘制

void CHYTTFCharacter::Draw(HDC hDC, int nOffsetX, int nOffsetY)
{int nXTemp, nYTemp, nXBegin, nYBegin;STTTPOLYGONHEADER* pSTTTPOLYGONHEADER = 0;STTTPOLYCURVE* pSTTTPOLYCURVE = 0;int nCountH = m_stTTPOLYGONHEADERVector.size();int nCountC = 0;int i = 0, j = 0, k = 0;for(i = 0; i < nCountH; ++i){pSTTTPOLYGONHEADER = m_stTTPOLYGONHEADERVector[i];nXBegin = nOffsetX + FIXEDToInt(pSTTTPOLYGONHEADER->m_TTPOLYGONHEADER.pfxStart.x);nYBegin = nOffsetY - FIXEDToInt(pSTTTPOLYGONHEADER->m_TTPOLYGONHEADER.pfxStart.y);::MoveToEx(hDC, nXBegin, nYBegin, NULL);nCountC = pSTTTPOLYGONHEADER->m_stTTPOLYCURVEVector.size();for(j = 0; j < nCountC; ++j){pSTTTPOLYCURVE = pSTTTPOLYGONHEADER->m_stTTPOLYCURVEVector[j];// 这里可以根具线条的类型做样条曲线的绘制, 这样字体会绘制的比较圆滑.***********注意注意*****************// 我这里直接使用直线连接, 有些地方可能绘制的比较粗糙.************************注意注意******************for(k = 0; k < pSTTTPOLYCURVE->m_cpfx; ++k){::LineTo(hDC, nOffsetX + FIXEDToInt(pSTTTPOLYCURVE->m_p_apfx[k].x), nOffsetY - FIXEDToInt(pSTTTPOLYCURVE->m_p_apfx[k].y));}}::LineTo(hDC, nXBegin, nYBegin);}
}

1.3 调用

void CTestTypeDlg::PaintType()
{CClientDC dc(this);HDC hDC = dc.GetSafeHdc();//创建字体CFont font;VERIFY(font.CreateFont(70, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, ANSI_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "宋体"));CFont *pOldFont = dc.SelectObject(&font);// 定义并初始化变换矩阵MAT2 mat2;                                     memset(&mat2, 0, sizeof(mat2));mat2.eM11.value = 1;mat2.eM22.value = 1;GLYPHMETRICS metrics;      // 保存字符相关信息DWORD dwDataSize = 0;       // 初始化字符数据缓冲区大小//……// 通过函数GetGlyphOutline()确定存储字符结构的空间//char nChar = 'A';wchar_t nChar = L'A';::TextOut(dc.m_hDC, 0, 0, "A", 1);//dwDataSize = pDC->GetGlyphOutline((UINT)nChar, GGO_NATIVE, &metrics, 0, NULL, &mat2);dwDataSize = ::GetGlyphOutlineW(dc.m_hDC, (UINT)nChar, GGO_NATIVE, &metrics, 0, NULL, &mat2);if ((dwDataSize != 0) && (dwDataSize != GDI_ERROR)){CHYTTFCharacter hyTTFCharacter;hyTTFCharacter.InitTTPOLY(dwDataSize);dwDataSize = ::GetGlyphOutlineW(dc.m_hDC, (UINT)nChar,GGO_NATIVE,&metrics, dwDataSize, hyTTFCharacter.m_pTTPOLYData, &mat2);hyTTFCharacter.InitTTPOLY();int nXOffset = 200;int nYOffset = 200;hyTTFCharacter.Draw(dc.m_hDC, nXOffset, nYOffset);}
}

1.4 网上的一些参考

http://blog.csdn.net/kingstar158/article/details/7257347

HDC hDC = pDC->GetSafeHdc();
//创建字体
CFont font;
VERIFY(font.CreateFont(m_iFontHeight, 0, 0, 0,FW_NORMAL, FALSE, FALSE, 0, ANSI_CHARSET,OUT_DEFAULT_PRECIS,               CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS,m_sFontFaceName));
CFont *pOldFont = pDC->SelectObject(&font);
//定义并初始化变换矩阵
MAT2 mat2;
memset(&mat2, 0, sizeof(mat2));
mat2.eM11 = 1;
mat2.eM22 = 1;GLYPHMETRICS metrics;    //保存字符相关信息
DWORD dwDataSize = 0;  //初始化字符数据缓冲区大小//……//通过函数GetGlyphOutline()确定存储字符结构的空间
dwDataSize = pDC->GetGlyphOutline(nChar, GGO_NATIVE, &metrics, 0, NULL, &mat2);
if ((dwDataSize != 0) && (dwDataSize != GDI_ERROR))
{//创建保存字符数据缓冲区大小LPBYTE pPixels = new BYTE[dwDataSize];                 ASSERT( pPixels != NULL );TTPOLYGONHEADER *pHeader = (TTPOLYGONHEADER*)pPixels;dwDataSize = pDC->GetGlyphOutline(nChar,GGO_NATIVE,&metrics, dwDataSize, pPixels, &mat2);while(dwDataSize > 0){//计算字符轮廓的起点,转换坐标int xOld = MapFXY(pHeader->pfxStart.x);int yOld = MapFXY(pHeader->pfxStart.y);//根据TTF字体结构获取字符轮廓::MoveToEx(hDC,iXpos + xOld,iYpos - yOld,NULL);TTPOLYCURVE *pCurrentCurve = (TTPOLYCURVE*)(pHeader + 1);  int remainByte = pHeader->cb - sizeof(TTPOLYGONHEADER);while (remainByte > 0){CPoint lpPoint[1000];CPoint bezi[2];int index;for (index = 0; index < pCurrentCurve->cpfx; ++index){lpPoint[index].x = iXpos + MapFXY(pCurrentCurve->apfx[index].x);lpPoint[index].y = iYpos - MapFXY(pCurrentCurve->apfx[index].y);}      switch (pCurrentCurve->wType){case TT_PRIM_LINE:case TT_PRIM_QSPLINE:for (index =0; index < pCurrentCurve->cpfx; index++){::LineTo(hDC,lpPoint[index].x,lpPoint[index].y);}break;default:MessageBox(_T("字体不支持"));break;}int count = sizeof(TTPOLYCURVE) + (pCurrentCurve->cpfx -1)*sizeof(POINTFX);pCurrentCurve = (TTPOLYCURVE*)((char*)pCurrentCurve  + count);remainByte -= count;}::LineTo(hDC,iXpos + xOld, iYpos - yOld);dwDataSize -= pHeader->cb;pHeader = (TTPOLYGONHEADER*)((char*)pHeader + pHeader->cb);}delete [] pPixels;}}

二. 应用

TTF字体是一种矢量字体. 好处就是可以随便放大, 缩小, 旋转等. 例如做"仿射变换". 而对于位图字体, 如果位图字体很大时, 做这些变换都是对位图上的每一个点来操作的, 效率会很低. 而如果对矢量数据操作的话, 要操作的点是有限的(比位图操作的点要少很多). 所以当你提取到了TTF字体的轮廓数据后, 你想干嘛都可以了(做一些文字的二维处理, 三维处理等都可以)..

[TTF字体]提取TTF字体的轮廓(二)相关推荐

  1. linux提取ttf字体轮廓,[TTF字体]提取TTF字体的轮廓(二)

    一. TTF字体轮廓解析与绘制 1.1 数据提取 void CHYTTFCharacter::InitTTPOLY() { if(0 == m_pTTPOLYData)// GetGlyphOutli ...

  2. pythonttf字体提取_[TTF字体]提取TTF字体的轮廓(二) | 学步园

    一. TTF字体轮廓解析与绘制 1.1 数据提取 void CHYTTFCharacter::InitTTPOLY() { if(0 == m_pTTPOLYData)// GetGlyphOutli ...

  3. [TTF字体]提取TTF字体的轮廓(一)

    一. 相关结构 TrueType Font ,由Apple和微软公司合作推出的文字文件格式. 一个TTF字符由许多轮廓组成,每一个轮廓由一个名叫TTPOLYGONHEADER的数据结构开始,跟在TTP ...

  4. 怎么把需要的字从TTF里面提取出来\字体压缩

    一.使用font-spider 1.1.下载 官网:http://font-spider.org 项目地址:https://github.com/aui/font-spider 用法打开官网就有,和f ...

  5. 苹果ttc转ttf_字体 – 将TTC字体转换或提取为TTF – 如何?

    假设Windows并不知道如何处理TTC文件(我真的很奇怪),如果使用 fontforge,您可以通过简单的方式"分割"组合的字体. 步骤是: >下载文件. 解压缩(例如解压 ...

  6. ttf字体包瘦身,ttf字体包提取指定字体,缩小ttf文件体积。

    ttf字体包瘦身 注:此方法只试用于只需要少数字体的情况. 需求 做APP时出现了一个需求,应用登录页面和主页面的系统名称需要根据用户所属行政区划进行动态调节. 为了突出系统名和样式的美观,系统名在显 ...

  7. 【Flutter】Flutter 自定义字体 ( 下载 TTF 字体 | pubspec.yaml 配置字体资源 | 同步资源 | 全局应用字体 | 局部应用字体 )

    文章目录 一.Flutter 自定义字体 1.ttf 字体文件 2.ttf 字体资源配置 3.获取字体 4.全局使用字体 5.局部使用字体 二.完整代码示例 三.相关资源 一.Flutter 自定义字 ...

  8. C++解析IconFont矢量字体文件ttf,以及无锯齿显示矢量字体

    一.下载矢量字体文件TTF 1.可以使用集成好的矢量字体,如FontAwesome.openwebicons.IcoMoon-Free.typicons-- 只要去搜索关键字,找到对应的官网即可下载到 ...

  9. 自定义字体 Typeface ttf

    一.简介 有时候界面在设计app时会使用一些比较美观的字体,在安卓中使用起来也并不困难,随着安卓SDK的更新,它的实现方式也有所不同,该文章来看看怎么实现自定义字体. 二.普通方法 设置字体TextV ...

  10. android 字体设置ttf

    Android系统默认字体支持四种字体,分别为: noraml (普通字体,系统默认使用的字体) sans(非衬线字体) serif (衬线字体) monospace(等宽字体) 除此之外还可以使用其 ...

最新文章

  1. 张杰和机器人_张杰 - 精密运动与先进机器人技术团队 - robotics.nimte.ac.cn
  2. iOS经典面试题之深入分析block相关高频面试题
  3. ### 学习《C++ Primer》- 8
  4. 像素/厘米与像素/英寸区别_像素/体素艺术入门指南
  5. .NET Core 中有等价的 HttpContext.Response.Cache 吗?
  6. 【C++编程题1】数组指针之字符串排序
  7. leetcode226 反转二叉树
  8. 数字图像处理实验6图像编码
  9. linux命令sort的用法,linux之sort命令的用法
  10. 小程序登录及用户信息和手机号的获取
  11. TUXEDO配置常见问题及解决方法
  12. 在linux系统下安装与配置SVN服务器
  13. 一级b类计算机考试题目和类型,第五章计算机一级B类高职考试习题资料.doc
  14. oracle sys_lob$$清理,清理 oracle lobsegment
  15. PHP字符串运算结果,php字符运算
  16. 冯东阳:解读纯文本链接到底算不算外链
  17. Div与Span标签详解
  18. CentOS安装JDK1.8
  19. 产品范围与项目范围的联系与区别
  20. 我的智能充电桩开发笔记(二):系统硬件电路设计概述

热门文章

  1. 疯狂膜拜!万字长文轻松彻底入门spring
  2. VSCode Python运行环境配置
  3. 如何让vnc控制由默认的twm界面改为gnome?(转)
  4. OpenGL EGL简介
  5. 职业探索1——霍兰德职业兴趣测试
  6. java DNS域名解析
  7. Springboot中Feign的使用方法
  8. P1138 第k小整数
  9. R平方值python实现
  10. 51单片机系列——定时/计数器