C++解析IconFont向量字型檔案ttf,以及無鋸齒顯示向量字型
阿新 • • 發佈:2019-02-01
一、下載向量字型檔案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編譯而成。(下載地址)