一、下载矢量字体文件TTF
1、可以使用集成好的矢量字体,如FontAwesome、openwebicons、IcoMoon-Free、typicons……
只要去搜索关键字,找到对应的官网即可下载到,其中FontAwesome使用最为广泛。
2、国内最大的IconFont下载基地:阿里巴巴矢量图标库。
将喜欢的矢量字体图标加入到购物车,然后点击下载代码即可,目前是免费的。
二、使用C++解析TTF文件
首先加载Gdiplus必备三行代码
#include "gdiplus.h" #pragma comment(lib,"gdiplus.lib") using namespace Gdiplus;
1、获取字体名称(gdiplus初始化的代码最好放在程序的初始化中,且全局只能初始化一次)
BOOL GetFontName(LPCTSTR pFilePath, LPTSTR pFontName) { // 初始化gdiplus ULONG_PTR m_gdiplusToken; Gdiplus::GdiplusStartupInput gdiplusStartupInput; Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL); // 添加字体 Gdiplus::PrivateFontCollection pCollection; if (Gdiplus::Status::Ok != pCollection.AddFontFile(pFilePath)) return FALSE; int count = pCollection.GetFamilyCount(); if (count == 0) return FALSE; int found = 0; Gdiplus::FontFamily* pFontFamily = (Gdiplus::FontFamily*)malloc(count * sizeof(Gdiplus::FontFamily)); pCollection.GetFamilies(count, pFontFamily, &found); if (found == 0) { free(pFontFamily); return FALSE; } // 获取字体名称 pFontFamily->GetFamilyName(pFontName); free(pFontFamily); // 卸载gdiplus Gdiplus::GdiplusShutdown(m_gdiplusToken); return TRUE; }
2、获取字体所包含的所有图标的unicode代码
std::vector<wchar_t> GetIconNames(LPCTSTR pFilePath,LPCTSTR pFontName) { // 加载字体文件 ::AddFontResourceEx(pFilePath, FR_PRIVATE, 0); std::vector<wchar_t> vcNames; // 临时获取一个HDC HDC hDc = ::GetDC(NULL); // 创建所加载的文件的字体 HFONT hfont = ::CreateFont(20, 0, 0, 0, FW_HEAVY, 0, 0, 0, DEFAULT_CHARSET,\ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, pFontName); // 载入到当前的HDC中 HFONT oldFont = (HFONT)::SelectObject(hDc, (HGDIOBJ)hfont); // 获取该ttf字体文件所有的全部unicode字符 DWORD size = ::GetFontUnicodeRanges(hDc, NULL); GLYPHSET * pGlyphSet = (GLYPHSET*) new BYTE[size]; pGlyphSet->cbThis = size; size = GetFontUnicodeRanges(hDc, pGlyphSet); for (int i = 0; i < pGlyphSet->cRanges; i++) for (int j = 0; j < pGlyphSet->ranges[i].cGlyphs; j++) vcNames.emplace_back(j + pGlyphSet->ranges[i].wcLow); ::SelectObject(hDc, (HGDIOBJ)oldFont); ::ReleaseDC(NULL, hDc); ::RemoveFontResourceEx(pFilePath, FR_PRIVATE, 0); delete pGlyphSet; return vcNames; }使用如下:
void Cmfc2Dlg::OnBnClickedOk() { TCHAR * pFontPath = _T("F:\\MyCode\\CPP\\DuiLib\\Fonts\\fontawesome-webfont.ttf"); TCHAR fontName[MAX_PATH] = {0}; if (!GetFontName(pFontPath, fontName)) return; auto iconNames = GetIconNames(pFontPath, fontName); for (auto iconName : iconNames) { TRACE(_T("%x\n"), iconName); } }
三、使用GdiPlus绘制无锯齿的矢量图标
使用Gdiplus绘制,需要将gdiplus初始化的代码放在应用初始化中,且只初始化一次,不然会报错。
1、gdiplus属性
ULONG_PTR m_gdiplusToken; Gdiplus::GdiplusStartupInput gdiplusStartupInput;2、初始化
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);3、程序退出时
Gdiplus::GdiplusShutdown(m_gdiplusToken);
4、绘制代码如下:
void Cmfc2Dlg::OnBnClickedOk() { TCHAR * pFontPath = _T("F:\\MyCode\\CPP\\DuiLib\\Fonts\\fontawesome-webfont.ttf"); TCHAR fontName[MAX_PATH] = {0}; if (!GetFontName(pFontPath, fontName)) return; auto iconNames = GetIconNames(pFontPath, fontName); HDC hDC = ::GetDC(m_hWnd); // 添加字体 Gdiplus::PrivateFontCollection pCollection; if (Gdiplus::Status::Ok != pCollection.AddFontFile(pFontPath)) return; Gdiplus::Font font(fontName, 16, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel, &pCollection); int i = 0 , j = 0; for (auto iconName : iconNames) { wchar_t iconFont[2] = {0}; iconFont[0] = iconName; Gdiplus::Graphics graphics(hDC); graphics.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); Gdiplus::SolidBrush solidBrush(Gdiplus::Color(255,0,0,0)); graphics.DrawString(iconFont, 1, &font,Gdiplus::PointF(i,j), &solidBrush); i += 50; if (i % 500 == 0) { i = 0; j += 50; } } }
5、绘制的效果图
四、矢量字体查看工具,使用Duilib编译而成。(下载地址)