BOOL FreeTypeFontEngine::RemoveFont(LPCWSTR FontName) { if (!FontName) return false; LOGFONTW* fontarray = GetFontNameFromFile(FontName); LOGFONTW* c_fontarray = fontarray; //记录原始指针 if (!fontarray) return false; FTC_FaceID fid = NULL; BOOL bIsFontLoaded, bIsFontFileLoaded = false; COwnedCriticalSectionLock __lock2(2, COwnedCriticalSectionLock::OCS_DC); //获取所有权,现在要处理DC,禁止所有绘图函数访问 CCriticalSectionLock __lock(CCriticalSectionLock::CS_MANAGER); while (*(char*)fontarray) { bIsFontLoaded = false; FreeTypeFontInfo* result = FindFont(fontarray->lfFaceName, fontarray->lfWeight, !!fontarray->lfItalic, false, &bIsFontLoaded); if (result) { fid = (FTC_FaceID)result->GetId(); if (bIsFontLoaded) //该字体已经被使用过 { RemoveFont(result); //枚举字体信息全部删除 bIsFontFileLoaded = true; //设置字体文件也被使用过 } else RemoveThisFont(result, fontarray); CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTENG); FTC_Manager_RemoveFaceID(cache_man, fid); m_mfontList[(int)fid-1]=NULL; } fontarray++; } free(c_fontarray); //利用原始指针释放 if (bIsFontFileLoaded) //若字体文件被使用过,则需要清楚所有DC { CTLSDCArray::iterator iter = TLSDCArray.begin(); while (iter!=TLSDCArray.end()) { ((CBitmapCache*)*iter)->~CBitmapCache(); //清除掉所有使用中的DC ++iter; } } return true; }
BOOL FASTCALL GetIniString(ALICE_INI_INFO *pIniInfo, PVOID, STL_STRINGA *pString) { BOOL Result; LONG Type; WCHAR szPath[MAX_PATH]; bool (FASTCALL *pfGetIniString)(PVOID pIniInfo, PVOID, STL_STRINGA *pString); enum { INI_TYPE_FACE, INI_TYPE_FONT }; static CHAR szFaceName[] = "FaceName"; static CHAR szFontName[] = "FontName"; *(PVOID *)&pfGetIniString = (PVOID)0x42CA40; LOOP_ALWAYS { Result = pfGetIniString(pIniInfo, 0, pString); if (!Result) return Result; if (pString->Length == sizeof(szFaceName) - 1 && !StrICompareA(pString->GetBuffer(), szFaceName)) { Type = INI_TYPE_FACE; } else if (pString->Length == sizeof(szFontName) - 1 && !StrICompareA(pString->GetBuffer(), szFontName)) { Type = INI_TYPE_FONT; } else { return TRUE; } LOOP_ONCE { if (!pfGetIniString(pIniInfo, 0, pString) || *pString->GetBuffer() != '=') break; if (!pfGetIniString(pIniInfo, 0, pString) || pString->Length == 0) break; switch (Type) { case INI_TYPE_FACE: MultiByteToWideChar( CP_ACP, 0, pString->GetBuffer(), -1, g_szFaceName, countof(g_szFaceName)); break; case INI_TYPE_FONT: MultiByteToWideChar( CP_ACP, 0, pString->GetBuffer(), -1, szPath, countof(szPath)); if (AddFontResourceExW(szPath, FR_PRIVATE, NULL) == 0) break; GetFontNameFromFile(szPath, g_szFaceName, countof(g_szFaceName)); break; } } } }