mirror of
https://github.com/snowie2000/mactype.git
synced 2025-01-08 11:47:43 +08:00
1065 lines
28 KiB
C++
1065 lines
28 KiB
C++
|
#include "override.h"
|
|||
|
#include "ft.h"
|
|||
|
#include <windows.h>
|
|||
|
#include <tchar.h>
|
|||
|
#include "fteng.h"
|
|||
|
|
|||
|
#ifdef _DLL
|
|||
|
#pragma comment(linker, "/nod:msvcprt.lib /nod:msvcprtd.lib")
|
|||
|
#endif
|
|||
|
|
|||
|
#if 0
|
|||
|
#define FREETYPE_REQCOUNTMAX 10
|
|||
|
#define GC_TRACE TRACE
|
|||
|
#define FREETYPE_GC_COUNTER 128
|
|||
|
#else
|
|||
|
#define FREETYPE_REQCOUNTMAX 2048//Ĭ<><C4AC>4096,ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>ˢ<EFBFBD>»<EFBFBD><C2BB>潵<EFBFBD><E6BDB5><EFBFBD>ڴ<EFBFBD>ռ<EFBFBD><D5BC>
|
|||
|
#define GC_TRACE NOP_FUNCTION
|
|||
|
#define FREETYPE_GC_COUNTER 1024//ˢ<>»<EFBFBD><C2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
#endif
|
|||
|
|
|||
|
FreeTypeFontEngine* g_pFTEngine;
|
|||
|
FT_Library freetype_library;
|
|||
|
FTC_Manager cache_man;
|
|||
|
FTC_CMapCache cmap_cache;
|
|||
|
FTC_ImageCache image_cache;
|
|||
|
CTLSDCArray TLSDCArray;
|
|||
|
|
|||
|
int CALLBACK EnumFontCallBack(const LOGFONT *lplf, const TEXTMETRIC *lptm, DWORD /*FontType*/, LPARAM lParam)
|
|||
|
{
|
|||
|
LOGFONT * lf=(LOGFONT *)lParam;
|
|||
|
StringCchCopy(lf->lfFaceName, LF_FACESIZE, lplf->lfFaceName);
|
|||
|
lf->lfQuality=0x2d; //magic number
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
bool GetFontLocalName(TCHAR* pszFontName, __out TCHAR* pszNameOut) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>ֵΪ<D6B5><CEAA><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
LOGFONT lf = {0};
|
|||
|
TCHAR* ret;
|
|||
|
lf.lfQuality = 0x2d;
|
|||
|
if (!(ret = FontNameCache.Find((TCHAR*)pszFontName)))
|
|||
|
{
|
|||
|
StringCchCopy(lf.lfFaceName, LF_FACESIZE, pszFontName);
|
|||
|
lf.lfCharSet=DEFAULT_CHARSET;
|
|||
|
HDC dc=GetDC(NULL);
|
|||
|
lf.lfQuality=0;
|
|||
|
EnumFontFamiliesEx(dc, &lf, &EnumFontCallBack, (LPARAM)&lf, 0);
|
|||
|
ReleaseDC(NULL, dc);
|
|||
|
if (lf.lfQuality==0x2d)
|
|||
|
FontNameCache.Add((TCHAR*)pszFontName, lf.lfFaceName);
|
|||
|
ret=lf.lfFaceName;
|
|||
|
}
|
|||
|
StringCchCopy(pszNameOut, LF_FACESIZE, ret);
|
|||
|
return lf.lfQuality == 0x2d;
|
|||
|
}
|
|||
|
|
|||
|
LOGFONTW* GetFontNameFromFile(LPCWSTR Filename) //<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>ڰ<EFBFBD><DAB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>s
|
|||
|
{
|
|||
|
LOGFONTW* logfonts = NULL;
|
|||
|
DWORD bufsize=0;
|
|||
|
if (GetFontResourceInfo(Filename, &bufsize, NULL, 2))
|
|||
|
{
|
|||
|
logfonts = (LOGFONTW*)malloc(bufsize+1);
|
|||
|
if (GetFontResourceInfo(Filename, &bufsize, logfonts, 2))
|
|||
|
{
|
|||
|
((char*)logfonts)[bufsize]=0;
|
|||
|
return logfonts;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
free(logfonts);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
AddFontResourceW(Filename);
|
|||
|
if (GetFontResourceInfo(Filename, &bufsize, NULL, 2))
|
|||
|
{
|
|||
|
logfonts = (LOGFONTW*)malloc(bufsize+1);
|
|||
|
if (GetFontResourceInfo(Filename, &bufsize, logfonts, 2))
|
|||
|
{
|
|||
|
((char*)logfonts)[bufsize]=0;
|
|||
|
ORIG_RemoveFontResourceExW(Filename,0,NULL);
|
|||
|
return logfonts;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
free(logfonts);
|
|||
|
ORIG_RemoveFontResourceExW(Filename,0,NULL);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
ORIG_RemoveFontResourceExW(Filename,0,NULL);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <class T>
|
|||
|
struct GCCounterSortFunc : public std::binary_function<const T*, const T*, bool>
|
|||
|
{
|
|||
|
bool operator()(const T* arg1, const T* arg2) const
|
|||
|
{
|
|||
|
const int cnt1 = arg1 ? arg1->GetMruCounter() : -1;
|
|||
|
const int cnt2 = arg2 ? arg2->GetMruCounter() : -1;
|
|||
|
return cnt1 > cnt2;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
struct DeleteCharFunc : public std::unary_function<FreeTypeCharData*&, void>
|
|||
|
{
|
|||
|
void operator()(FreeTypeCharData*& arg) const
|
|||
|
{
|
|||
|
if (!arg)
|
|||
|
return;
|
|||
|
delete arg;
|
|||
|
arg = NULL;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
template <class T>
|
|||
|
void CompactMap(T& pp, int count, int reduce)
|
|||
|
{
|
|||
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTCACHE);
|
|||
|
int reducecount = pp.size() - reduce;
|
|||
|
T::iterator it= pp.begin();
|
|||
|
for (int i=0;i<reducecount;i++) //ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>FREETYPE_GC_COUNTER֮<52><D6AE><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD>
|
|||
|
{
|
|||
|
//it->second->Erase();
|
|||
|
delete it->second;
|
|||
|
pp.erase(it++);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
template <class T>
|
|||
|
void Compact(T** pp, int count, int reduce)
|
|||
|
{
|
|||
|
Assert(count >= 0);
|
|||
|
Assert(reduce > 0);
|
|||
|
if (!pp || !count || count < reduce) {
|
|||
|
return;
|
|||
|
}
|
|||
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTCACHE);
|
|||
|
TRACE(_T("Compact(0x%p, %d, %d)\n"), pp, count, reduce);
|
|||
|
//GC<47><43><EFBFBD>h<EFBFBD>L
|
|||
|
//T::m_mrucounter<65>̍~<7E><><EFBFBD>ɕ<EFBFBD><C995>Ԃ̂<D482>
|
|||
|
//reduce<63><EFBFBD><F092B482>镔<EFBFBD><E99594><EFBFBD><EFBFBD><EFBFBD>폜<EFBFBD><ED8F9C><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
T** ppTemp = (T**)malloc(sizeof(T*) * count);
|
|||
|
if (!ppTemp) {
|
|||
|
return;
|
|||
|
}
|
|||
|
memcpy(ppTemp, pp, sizeof(T*) * count);
|
|||
|
|
|||
|
std::sort(ppTemp, ppTemp + count, GCCounterSortFunc<T>());
|
|||
|
int i;
|
|||
|
for (i=0; i<reduce; i++) {
|
|||
|
if (!ppTemp[i])
|
|||
|
break;
|
|||
|
ppTemp[i]->ResetMruCounter();
|
|||
|
}
|
|||
|
|
|||
|
//GC_TRACE(_T("GC:"));
|
|||
|
for (i=reduce; i<count; i++) {
|
|||
|
if (!ppTemp[i])
|
|||
|
break;
|
|||
|
//GC_TRACE(_T(" %wc"), ppTemp[i]->GetChar());
|
|||
|
ppTemp[i]->Erase();
|
|||
|
}
|
|||
|
//GC_TRACE(_T("\n"));
|
|||
|
free(ppTemp);
|
|||
|
}
|
|||
|
|
|||
|
//FreeTypeCharData
|
|||
|
FreeTypeCharData::FreeTypeCharData(FreeTypeCharData** ppCh, FreeTypeCharData** ppGl, WCHAR wch, UINT glyphindex, int width, int mru, int gdiWidth, int AAMode)
|
|||
|
: m_ppSelfGlyph(ppGl), m_glyphindex(glyphindex), m_width(width)
|
|||
|
, m_glyph(NULL), m_glyphMono(NULL), m_bmpSize(0), m_bmpMonoSize(0)
|
|||
|
, FreeTypeMruCounter(mru), m_gdiWidth(gdiWidth), m_AAMode(AAMode)
|
|||
|
{
|
|||
|
g_pFTEngine->AddMemUsedObj(this);
|
|||
|
AddChar(ppCh);
|
|||
|
#ifdef _DEBUG
|
|||
|
m_wch = wch;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
FreeTypeCharData::~FreeTypeCharData()
|
|||
|
{
|
|||
|
CharDataArray& arr = m_arrSelfChar;
|
|||
|
int n = arr.GetSize();
|
|||
|
while (n--) {
|
|||
|
FreeTypeCharData** pp = arr[n];
|
|||
|
Assert(*pp == this);
|
|||
|
*pp = NULL;
|
|||
|
}
|
|||
|
if(m_ppSelfGlyph) {
|
|||
|
Assert(*m_ppSelfGlyph == this);
|
|||
|
*m_ppSelfGlyph = NULL;
|
|||
|
}
|
|||
|
if(m_glyph){
|
|||
|
FT_Done_Ref_Glyph((FT_Referenced_Glyph*)&m_glyph);
|
|||
|
}
|
|||
|
if(m_glyphMono){
|
|||
|
FT_Done_Ref_Glyph((FT_Referenced_Glyph*)&m_glyphMono);
|
|||
|
}
|
|||
|
|
|||
|
g_pFTEngine->SubMemUsed(m_bmpSize);
|
|||
|
g_pFTEngine->SubMemUsed(m_bmpMonoSize);
|
|||
|
g_pFTEngine->SubMemUsedObj(this);
|
|||
|
}
|
|||
|
|
|||
|
void FreeTypeCharData::SetGlyph(FT_Render_Mode render_mode, FT_Referenced_BitmapGlyph glyph)
|
|||
|
{
|
|||
|
const bool bMono = (render_mode == FT_RENDER_MODE_MONO);
|
|||
|
FT_Referenced_BitmapGlyph& gl = bMono ? m_glyphMono : m_glyph;
|
|||
|
if (gl)
|
|||
|
FT_Done_Ref_Glyph((FT_Referenced_Glyph*)&gl);
|
|||
|
{
|
|||
|
FT_Glyph_Ref_Copy((FT_Referenced_Glyph)glyph, (FT_Referenced_Glyph*)&gl);
|
|||
|
if (gl) {
|
|||
|
int& size = bMono ? m_bmpMonoSize : m_bmpSize;
|
|||
|
size = FT_Bitmap_CalcSize(gl->ft_glyph);
|
|||
|
size += sizeof(FT_BitmapGlyphRec);
|
|||
|
g_pFTEngine->AddMemUsed(size);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//FreeTypeFontCache
|
|||
|
FreeTypeFontCache::FreeTypeFontCache(/*int px, int weight, bool italic, */int mru)
|
|||
|
: /*m_px(px), m_weight(weight), m_italic(italic), */m_active(false)
|
|||
|
, FreeTypeMruCounter(mru)
|
|||
|
{
|
|||
|
#ifdef _USE_ARRAY
|
|||
|
ZeroMemory(&m_tm, sizeof(TEXTMETRIC));
|
|||
|
ZeroMemory(m_chars, sizeof(m_chars));
|
|||
|
ZeroMemory(m_glyphs, sizeof(m_glyphs));
|
|||
|
#else
|
|||
|
m_GlyphCache.clear();
|
|||
|
#endif
|
|||
|
g_pFTEngine->AddMemUsedObj(this);
|
|||
|
}
|
|||
|
|
|||
|
FreeTypeFontCache::~FreeTypeFontCache()
|
|||
|
{
|
|||
|
Erase();
|
|||
|
g_pFTEngine->SubMemUsedObj(this);
|
|||
|
}
|
|||
|
|
|||
|
void FreeTypeFontCache::Compact()
|
|||
|
{
|
|||
|
//TRACE(_T("FreeTypeFontCache::Compact: %d > %d\n"), countof(m_chars), FREETYPE_GC_COUNTER);
|
|||
|
ResetGCCounter();
|
|||
|
#ifdef _USE_ARRAY
|
|||
|
::Compact(m_glyphs, countof(m_glyphs), FREETYPE_GC_COUNTER);
|
|||
|
#else
|
|||
|
::CompactMap(m_GlyphCache, m_GlyphCache.size(), FREETYPE_GC_COUNTER);
|
|||
|
#endif
|
|||
|
//GlyphCache::const_iterator it=m_GlyphCache.begin();
|
|||
|
}
|
|||
|
|
|||
|
void FreeTypeFontCache::Erase()
|
|||
|
{
|
|||
|
m_active = false;
|
|||
|
#ifdef _USE_ARRAY
|
|||
|
std::for_each(m_chars, m_chars + FT_MAX_CHARS, DeleteCharFunc());
|
|||
|
std::for_each(m_glyphs, m_glyphs + FT_MAX_CHARS, DeleteCharFunc());
|
|||
|
#else
|
|||
|
GlyphCache::iterator it=m_GlyphCache.begin();
|
|||
|
for (;it!=m_GlyphCache.end();++it)
|
|||
|
delete it->second;
|
|||
|
m_GlyphCache.clear();
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
void FreeTypeFontCache::AddCharData(WCHAR wch, UINT glyphindex, int width, int gdiWidth, FT_Referenced_BitmapGlyph glyph, FT_Render_Mode render_mode, int AAMode)
|
|||
|
{
|
|||
|
if (glyphindex & 0xffff0000 /*|| !g_ccbCache*/) {
|
|||
|
return;
|
|||
|
}
|
|||
|
if (AddIncrement() >= FREETYPE_REQCOUNTMAX) { //<2F><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Compact();
|
|||
|
}
|
|||
|
|
|||
|
#ifdef _USE_ARRAY
|
|||
|
FreeTypeCharData** ppChar = _GetChar(wch);
|
|||
|
if (*ppChar) {
|
|||
|
(*ppChar)->SetGlyph(render_mode, glyph);
|
|||
|
(*ppChar)->SetMruCounter(this);
|
|||
|
return;
|
|||
|
}
|
|||
|
#else
|
|||
|
GlyphCache::iterator it=m_GlyphCache.find(wch);
|
|||
|
if (it!=m_GlyphCache.end()) //<2F>ҵ<EFBFBD><D2B5>˾<EFBFBD><CBBE><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
FreeTypeCharData* ppChar = it->second;
|
|||
|
if (ppChar) {
|
|||
|
ppChar->SetGlyph(render_mode, glyph);
|
|||
|
ppChar->SetMruCounter(this);
|
|||
|
ppChar->SetWidth(width);
|
|||
|
ppChar->SetGDIWidth(gdiWidth);
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
FreeTypeCharData* p = new FreeTypeCharData(/*ppChar*/NULL, NULL, wch, glyphindex, width, MruIncrement(), gdiWidth, AAMode);
|
|||
|
if (p == NULL) {
|
|||
|
return;
|
|||
|
}
|
|||
|
p->SetGlyph(render_mode, glyph);
|
|||
|
|
|||
|
#ifdef _USE_ARRAY
|
|||
|
*ppChar = p;
|
|||
|
#else
|
|||
|
m_GlyphCache[wch]=p;
|
|||
|
#endif
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void FreeTypeFontCache::AddGlyphData(UINT glyphindex, int width, int gdiWidth, FT_Referenced_BitmapGlyph glyph, FT_Render_Mode render_mode, int AAMode)
|
|||
|
{
|
|||
|
if (glyphindex & 0xffff0000 /*|| !g_ccbCache*/) {
|
|||
|
return;
|
|||
|
}
|
|||
|
//GC
|
|||
|
if (AddIncrement() >= FREETYPE_REQCOUNTMAX) {
|
|||
|
//TRACE(_T("Compact(0x%p)\n"), this);
|
|||
|
Compact();
|
|||
|
}
|
|||
|
|
|||
|
#ifdef _USE_ARRAY
|
|||
|
FreeTypeCharData** ppGlyph = _GetGlyph(glyphindex);
|
|||
|
if (*ppGlyph) {
|
|||
|
(*ppGlyph)->SetGlyph(render_mode, glyph);
|
|||
|
(*ppGlyph)->SetMruCounter(this);
|
|||
|
return;
|
|||
|
}
|
|||
|
#else
|
|||
|
GlyphCache::iterator it=m_GlyphCache.find(-(int)glyphindex);
|
|||
|
if (it!=m_GlyphCache.end()) //<2F>ҵ<EFBFBD><D2B5>˾<EFBFBD><CBBE><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
FreeTypeCharData* ppChar = it->second;
|
|||
|
if (ppChar) {
|
|||
|
(ppChar)->SetGlyph(render_mode, glyph);
|
|||
|
(ppChar)->SetMruCounter(this);
|
|||
|
ppChar->SetWidth(width);
|
|||
|
ppChar->SetGDIWidth(gdiWidth);
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
//<2F>lj<EFBFBD>(glyph<70>̂<EFBFBD>)
|
|||
|
FreeTypeCharData* p = new FreeTypeCharData(NULL, /*ppGlyph*/NULL, 0, glyphindex, width, MruIncrement(), gdiWidth, AAMode);
|
|||
|
if (p == NULL) {
|
|||
|
return;
|
|||
|
}
|
|||
|
p->SetGlyph(render_mode, glyph);
|
|||
|
|
|||
|
#ifdef _USE_ARRAY
|
|||
|
*ppGlyph = p;
|
|||
|
#else
|
|||
|
m_GlyphCache[-(int)glyphindex]=p;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//FreeTypeFontInfo
|
|||
|
void FreeTypeFontInfo::Compact()
|
|||
|
{
|
|||
|
//TRACE(_T("FreeTypeFontInfo::Compact: %d > %d\n"), m_cache.GetSize(), m_nMaxSizes);
|
|||
|
ResetGCCounter();
|
|||
|
::CompactMap(m_cache, m_cache.size(), m_nMaxSizes);
|
|||
|
CacheArray::const_iterator it=m_cache.begin();
|
|||
|
for (;it!=m_cache.end();++it)
|
|||
|
it->second->Deactive();
|
|||
|
}
|
|||
|
|
|||
|
void FreeTypeFontInfo::Createlink()
|
|||
|
{
|
|||
|
CFontFaceNamesEnumerator fn(m_hash.c_str(), m_nFontFamily);
|
|||
|
std::set<int> linkset; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>弯<EFBFBD>ϣ<EFBFBD><CFA3><EFBFBD>ֹ<EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>
|
|||
|
linkset.insert(m_id);
|
|||
|
face_id_link[m_linknum] = (FTC_FaceID)m_id;
|
|||
|
ggo_link[m_linknum++] = m_ggoFont; //<2F><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ȡ
|
|||
|
LOGFONT lf;
|
|||
|
BOOL IsSimSun = false;
|
|||
|
memset(&lf, 0, sizeof(LOGFONT));
|
|||
|
lf.lfCharSet=DEFAULT_CHARSET;
|
|||
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|||
|
for (fn.next() ; !fn.atend(); fn.next()) { //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//FreeTypeFontInfo* pfitemp = g_pFTEngine->FindFont(fn, m_weight, m_italic);
|
|||
|
//if (pfitemp && pfitemp->m_isSimSun)
|
|||
|
// IsSimSun = true;
|
|||
|
if (!m_SimSunID)
|
|||
|
IsSimSun = (_wcsicmp(fn,L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>")==0 || _wcsicmp(fn,L"SimSun")==0);
|
|||
|
StringCchCopy(lf.lfFaceName, LF_FACESIZE, fn);
|
|||
|
pSettings->CopyForceFont(lf,lf);
|
|||
|
FreeTypeFontInfo* pfitemp = g_pFTEngine->FindFont(lf.lfFaceName, /*m_weight*/0, /*m_italic*/false);
|
|||
|
if (pfitemp && linkset.find(pfitemp->GetId())==linkset.end()) {
|
|||
|
linkset.insert(pfitemp->GetId());
|
|||
|
face_id_link[m_linknum] = (FTC_FaceID)pfitemp->GetId();
|
|||
|
ggo_link[m_linknum++] = pfitemp->GetGGOFont();
|
|||
|
if (!m_SimSunID && IsSimSun)
|
|||
|
m_SimSunID = (FTC_FaceID)pfitemp->GetId();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
bool FreeTypeFontInfo::EmbeddedBmpExist(int px)
|
|||
|
{
|
|||
|
if (px>=256 || px<0)
|
|||
|
return false;
|
|||
|
if (m_ebmps[px]!=-1)
|
|||
|
return !!m_ebmps[px];
|
|||
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_MANAGER);
|
|||
|
FTC_ImageTypeRec imgtype={(FTC_FaceID)m_id, px, px, FT_LOAD_DEFAULT}; //<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>С<EFBFBD><D0A1>imagetype
|
|||
|
FT_Glyph temp_glyph=NULL;
|
|||
|
FT_UInt gindex = FTC_CMapCache_Lookup(cmap_cache, (FTC_FaceID)m_id, -1, FT_UInt32(L'0')); //<2F><><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
|||
|
FTC_ImageCache_Lookup(image_cache, &imgtype, gindex, &temp_glyph, NULL);
|
|||
|
if (temp_glyph && temp_glyph->format==FT_GLYPH_FORMAT_BITMAP) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>0<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD>
|
|||
|
m_ebmps[px]=1; //<2F><><EFBFBD><EFBFBD><EFBFBD>ֺŴ<D6BA><C5B4>ڵ<EFBFBD><DAB5><EFBFBD>
|
|||
|
else
|
|||
|
{
|
|||
|
gindex = FTC_CMapCache_Lookup(cmap_cache, (FTC_FaceID)m_id, -1, FT_UInt32(L'<EFBFBD><EFBFBD>')); //<2F><><EFBFBD><EFBFBD>"<22><>"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
|||
|
if (gindex)
|
|||
|
FTC_ImageCache_Lookup(image_cache, &imgtype, gindex, &temp_glyph, NULL); //<2F><>ȡ<EFBFBD><C8A1><EFBFBD>ġ<EFBFBD><C4A1>ĵ<EFBFBD><C4B5><EFBFBD>
|
|||
|
if (temp_glyph && temp_glyph->format==FT_GLYPH_FORMAT_BITMAP) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>0<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD>
|
|||
|
m_ebmps[px]=1; //<2F><><EFBFBD><EFBFBD><EFBFBD>ֺŴ<D6BA><C5B4>ڵ<EFBFBD><DAB5><EFBFBD>
|
|||
|
else
|
|||
|
m_ebmps[px]=0;
|
|||
|
}
|
|||
|
return !!m_ebmps[px];
|
|||
|
}
|
|||
|
|
|||
|
FreeTypeFontCache* FreeTypeFontInfo::GetCache(FTC_ScalerRec& scaler, const LOGFONT& lf)
|
|||
|
{
|
|||
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTCACHE);
|
|||
|
|
|||
|
if (AddIncrement() > m_nMaxSizes) { //<2F><>ѹ<EFBFBD><D1B9>
|
|||
|
Compact();
|
|||
|
}
|
|||
|
int weight = lf.lfWeight;
|
|||
|
weight = weight < FW_BOLD ? 0: 1/*FW_BOLD*/;
|
|||
|
const bool italic = !!lf.lfItalic;
|
|||
|
if (scaler.height>0xfff || scaler.width>0xfff || scaler.height<0 || scaler.width<0) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>岻<EFBFBD><E5B2BB>Ⱦ
|
|||
|
return NULL;
|
|||
|
FreeTypeFontCache* p = NULL;
|
|||
|
UINT hash=getCacheHash(scaler.height, weight, italic, lf.lfWidth ? scaler.width : 0); //<2F><><EFBFBD><EFBFBD>hash
|
|||
|
CacheArray::iterator it=m_cache.find(hash); //Ѱ<><D1B0>cache
|
|||
|
if (it!=m_cache.end())//cache<68><65><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
p = it->second;
|
|||
|
goto OK; //<2F><><EFBFBD><EFBFBD>cache
|
|||
|
}
|
|||
|
|
|||
|
p = new FreeTypeFontCache(/*scaler.height, weight, italic,*/ MruIncrement());
|
|||
|
if (!p) {
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
if (m_cache[hash]=p) {
|
|||
|
goto OK;
|
|||
|
}
|
|||
|
delete p;
|
|||
|
return NULL;
|
|||
|
|
|||
|
OK:
|
|||
|
Assert(p != NULL);
|
|||
|
if (p && p->Activate()) {
|
|||
|
DecIncrement(); //<2F>ظ<EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
|||
|
}
|
|||
|
return p;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//FreeTypeFontEngine
|
|||
|
void FreeTypeFontEngine::Compact()
|
|||
|
{
|
|||
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTENG);
|
|||
|
|
|||
|
TRACE(_T("FreeTypeFontEngine::Compact: %d > %d\n"), m_mfontMap.size(), m_nMaxFaces);
|
|||
|
ResetGCCounter();
|
|||
|
//memset(m_arrFace, 0, sizeof(FT_Face)*m_nFaceCount); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>face<63><65><EFBFBD>ˣ<EFBFBD><CBA3>ϵ<EFBFBD>face<63>ᱻft<66>ͷŵ<CDB7><C5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫȫ<D2AA><C8AB><EFBFBD><EFBFBD><EFBFBD>»<EFBFBD>ȡ
|
|||
|
//FontListArray& arr = m_arrFontList;
|
|||
|
//::Compact(arr.GetData(), arr.GetSize(), m_nMaxFaces);
|
|||
|
}
|
|||
|
|
|||
|
BOOL FreeTypeFontEngine::RemoveFont(FreeTypeFontInfo* fontinfo)
|
|||
|
{
|
|||
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTMAP);
|
|||
|
{
|
|||
|
FontMap::const_iterator iter=m_mfontMap.begin(); //<2F><><EFBFBD><EFBFBD>fontmap
|
|||
|
while (iter!=m_mfontMap.end())
|
|||
|
{
|
|||
|
FreeTypeFontInfo* p = iter->second;
|
|||
|
if (p==fontinfo)
|
|||
|
m_mfontMap.erase(iter++); //ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
else
|
|||
|
++iter;
|
|||
|
}
|
|||
|
}
|
|||
|
{
|
|||
|
FullNameMap::const_iterator iter=m_mfullMap.begin(); //<2F><><EFBFBD><EFBFBD>fullmap
|
|||
|
while (iter!=m_mfullMap.end())
|
|||
|
{
|
|||
|
FreeTypeFontInfo* p = iter->second;
|
|||
|
if (p==fontinfo)
|
|||
|
m_mfullMap.erase(iter++); //ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
else
|
|||
|
{
|
|||
|
iter->second->UpdateFontSetting();
|
|||
|
++iter;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
delete fontinfo;
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
BOOL FreeTypeFontEngine::RemoveThisFont(FreeTypeFontInfo* fontinfo, LOGFONT* lg)
|
|||
|
{
|
|||
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTMAP);
|
|||
|
{
|
|||
|
FontMap::const_iterator iter=m_mfontMap.find(myfont(lg->lfFaceName, CalcBoldWeight(lg->lfWeight), lg->lfItalic)); //<2F><><EFBFBD><EFBFBD>fontmap
|
|||
|
if (iter!=m_mfontMap.end())
|
|||
|
m_mfontMap.erase(iter); //ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
{
|
|||
|
FullNameMap::const_iterator iter=m_mfullMap.find(fontinfo->GetFullName()); //<2F><><EFBFBD><EFBFBD>fullmap
|
|||
|
if (iter!=m_mfullMap.end())
|
|||
|
m_mfullMap.erase(iter); //ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
delete fontinfo;
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
BOOL FreeTypeFontEngine::RemoveFont(LPCWSTR FontName)
|
|||
|
{
|
|||
|
if (!FontName) return false;
|
|||
|
LOGFONTW* fontarray = GetFontNameFromFile(FontName);
|
|||
|
LOGFONTW* c_fontarray = fontarray; //<2F><>¼ԭʼָ<CABC><D6B8>
|
|||
|
if (!fontarray) return false;
|
|||
|
FTC_FaceID fid = NULL;
|
|||
|
BOOL bIsFontLoaded, bIsFontFileLoaded = false;
|
|||
|
COwnedCriticalSectionLock __lock2(2, COwnedCriticalSectionLock::OCS_DC); //<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>DC<44><43><EFBFBD><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD>л<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
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) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD>ʹ<EFBFBD>ù<EFBFBD>
|
|||
|
{
|
|||
|
RemoveFont(result); //ö<><C3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣȫ<CFA2><C8AB>ɾ<EFBFBD><C9BE>
|
|||
|
bIsFontFileLoaded = true; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>Ҳ<EFBFBD><D2B2>ʹ<EFBFBD>ù<EFBFBD>
|
|||
|
}
|
|||
|
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); //<2F><><EFBFBD><EFBFBD>ԭʼָ<CABC><D6B8><EFBFBD>ͷ<EFBFBD>
|
|||
|
if (bIsFontFileLoaded) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ʹ<EFBFBD>ù<EFBFBD><C3B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DC
|
|||
|
{
|
|||
|
CTLSDCArray::iterator iter = TLSDCArray.begin();
|
|||
|
while (iter!=TLSDCArray.end())
|
|||
|
{
|
|||
|
((CBitmapCache*)*iter)->~CBitmapCache(); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD>е<EFBFBD>DC
|
|||
|
++iter;
|
|||
|
}
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
static int FaceIDHolder = 0;
|
|||
|
int GetFaceID(void)
|
|||
|
{
|
|||
|
return (int)InterlockedIncrement((LONG volatile*)&FaceIDHolder);
|
|||
|
}
|
|||
|
|
|||
|
void ReleaseFaceID(void)
|
|||
|
{
|
|||
|
InterlockedDecrement((LONG volatile*)&FaceIDHolder);
|
|||
|
}
|
|||
|
|
|||
|
FreeTypeFontInfo* FreeTypeFontEngine::AddFont(void* lpparams)
|
|||
|
{
|
|||
|
FREETYPE_PARAMS* params = (FREETYPE_PARAMS*)lpparams;
|
|||
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTENG);
|
|||
|
const LOGFONT& lplf = *params->lplf;
|
|||
|
if(lplf.lfFaceName == NULL || _tcslen(lplf.lfFaceName) == 0)
|
|||
|
return NULL;
|
|||
|
|
|||
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|||
|
//const CFontSettings& fs = pSettings->FindIndividual(params->strFamilyName.c_str());
|
|||
|
FreeTypeFontInfo* pfi = new FreeTypeFontInfo(/*m_mfullMap.size() + 1*/GetFaceID(), lplf.lfFaceName, lplf.lfWeight, !!lplf.lfItalic, MruIncrement(), params->strFullName, params->strFamilyName);
|
|||
|
if (!pfi)
|
|||
|
return NULL;
|
|||
|
|
|||
|
if (pfi->GetFullName().size()==0) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
delete pfi;
|
|||
|
ReleaseFaceID();
|
|||
|
return false;
|
|||
|
}
|
|||
|
/*
|
|||
|
TCHAR buff[255]={0};
|
|||
|
if (params->strFamilyName.length()==8)
|
|||
|
{
|
|||
|
wsprintf(buff, L"Adding familiyname \"%s\" fullname \"%s\" weight %d\n\result: \"%s\"\n", params->strFamilyName.c_str(), params->strFullName.c_str(),
|
|||
|
params->lplf->lfWeight, pfi->GetFullName().c_str());
|
|||
|
Log(buff);
|
|||
|
}*/
|
|||
|
|
|||
|
FullNameMap::const_iterator it = m_mfullMap.find(pfi->GetFullName());
|
|||
|
if (it!=m_mfullMap.end()) //<2F><><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,ԭ<><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>滻ʹ<E6BBBB><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
delete pfi; //ɾ<><C9BE><EFBFBD>ղŴ<D5B2><C5B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
ReleaseFaceID();
|
|||
|
pfi = it->second;//ָ<><D6B8>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_mfullMap[pfi->GetFullName()]=pfi; //<2F><><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD>ӵ<EFBFBD>map<61><70>
|
|||
|
m_mfontList.push_back(pfi);
|
|||
|
}
|
|||
|
|
|||
|
if (pfi->GetFullName()!=params->strFullName) //<2F><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD>ƺ<EFBFBD><C6BA><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>Ʋ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>滻
|
|||
|
{
|
|||
|
pfi->AddRef(); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ü<EFBFBD><C3BC><EFBFBD>
|
|||
|
m_mfullMap[params->strFullName] = pfi; //˫<><CBAB><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>ָ<EFBFBD><D6B8>ͬһ<CDAC><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
|
|||
|
//bool ret = !!arr.Add(pfi);
|
|||
|
//weight = weight < FW_BOLD ? 0: FW_BOLD;
|
|||
|
myfont font(lplf.lfFaceName, lplf.lfWeight, !!params->otm->otmTextMetrics.tmItalic);
|
|||
|
/*
|
|||
|
FontMap::const_iterator it = m_mfontMap.find(font);
|
|||
|
if (it!=m_mfontMap.end())
|
|||
|
{
|
|||
|
it->second->Release();
|
|||
|
}*/
|
|||
|
|
|||
|
m_mfontMap[font]=pfi;
|
|||
|
/*
|
|||
|
if (!ret) {
|
|||
|
delete pfi;
|
|||
|
return NULL;
|
|||
|
}*/
|
|||
|
|
|||
|
|
|||
|
#ifdef _DEBUG
|
|||
|
{
|
|||
|
const CFontSettings& fs = pfi->GetFontSettings();
|
|||
|
TRACE(_T("AddFont: %s, %d, %d, %d, %d, %d, %d\n"), pfi->GetName(),
|
|||
|
fs.GetParam(0), fs.GetParam(1), fs.GetParam(2), fs.GetParam(3), fs.GetParam(4), fs.GetParam(5));
|
|||
|
}
|
|||
|
#endif
|
|||
|
return pfi;
|
|||
|
}
|
|||
|
|
|||
|
FreeTypeFontInfo* FreeTypeFontEngine::AddFont(LPCTSTR lpFaceName, int weight, bool italic, BOOL* bIsFontLoaded)
|
|||
|
{
|
|||
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTENG);
|
|||
|
if(lpFaceName == NULL || _tcslen(lpFaceName) == 0/* || FontExists(lpFaceName, weight, italic)*/)
|
|||
|
return NULL;
|
|||
|
|
|||
|
//FontListArray& arr = m_arrFontList;
|
|||
|
|
|||
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|||
|
//const CFontSettings& fs = pSettings->FindIndividual(lpFaceName);
|
|||
|
wstring dumy;
|
|||
|
//dumy.clear();
|
|||
|
FreeTypeFontInfo* pfi = new FreeTypeFontInfo(/*m_mfullMap.size() + 1*/GetFaceID(), lpFaceName, weight, italic, MruIncrement(), dumy, dumy);
|
|||
|
if (!pfi)
|
|||
|
return NULL;
|
|||
|
if (pfi->GetFullName().size()==0) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
delete pfi;
|
|||
|
ReleaseFaceID();
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
FullNameMap::const_iterator it = m_mfullMap.find(pfi->GetFullName()); //<2F>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>map<61><70><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (it!=m_mfullMap.end()) //<2F>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
delete pfi; //ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
ReleaseFaceID();
|
|||
|
pfi = it->second; //ָ<><D6B8><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (bIsFontLoaded)
|
|||
|
*bIsFontLoaded = true;
|
|||
|
//pfi->AddRef();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_mfullMap[pfi->GetFullName()]=pfi; //<2F><><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD>ӵ<EFBFBD>map<61><70>
|
|||
|
m_mfontList.push_back(pfi);
|
|||
|
if (bIsFontLoaded)
|
|||
|
*bIsFontLoaded = false;
|
|||
|
}
|
|||
|
|
|||
|
//bool ret = !!arr.Add(pfi);
|
|||
|
//weight = weight < FW_BOLD ? 0: FW_BOLD;
|
|||
|
myfont font(lpFaceName, weight, italic);
|
|||
|
m_mfontMap[font]=pfi; //<2F><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>Ҫmap<61><70>
|
|||
|
/*
|
|||
|
if (!ret) {
|
|||
|
delete pfi;
|
|||
|
return NULL;
|
|||
|
}*/
|
|||
|
|
|||
|
|
|||
|
#ifdef _DEBUG
|
|||
|
{
|
|||
|
const CFontSettings& fs = pfi->GetFontSettings();
|
|||
|
TRACE(_T("AddFont: %s, %d, %d, %d, %d, %d, %d\n"), pfi->GetName(),
|
|||
|
fs.GetParam(0), fs.GetParam(1), fs.GetParam(2), fs.GetParam(3), fs.GetParam(4), fs.GetParam(5));
|
|||
|
}
|
|||
|
#endif
|
|||
|
return pfi;
|
|||
|
}
|
|||
|
|
|||
|
int FreeTypeFontEngine::GetFontIdByName(LPCTSTR lpFaceName, int weight, bool italic)
|
|||
|
{
|
|||
|
const FreeTypeFontInfo* pfi = FindFont(lpFaceName, weight, italic);
|
|||
|
return pfi ? pfi->GetId() : 0;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
LPCTSTR FreeTypeFontEngine::GetFontById(int faceid, int& weight, bool& italic)
|
|||
|
{
|
|||
|
CCriticalSectionLock __lock;
|
|||
|
|
|||
|
FreeTypeFontInfo** pp = m_arrFontList.Begin();
|
|||
|
FreeTypeFontInfo** end = m_arrFontList.End();
|
|||
|
for(; pp != end; ++pp) {
|
|||
|
FreeTypeFontInfo* p = *pp;
|
|||
|
if (p->GetId() == faceid) {
|
|||
|
p->SetMruCounter(this);
|
|||
|
weight = p->GetWeight();
|
|||
|
italic = p->IsItalic();
|
|||
|
return p->GetName();
|
|||
|
}
|
|||
|
}
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
*/
|
|||
|
FreeTypeFontInfo* FreeTypeFontEngine::FindFont(void* lpparams)
|
|||
|
{
|
|||
|
FREETYPE_PARAMS* params = (FREETYPE_PARAMS*)lpparams;
|
|||
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTMAP);
|
|||
|
FullNameMap::const_iterator iter=m_mfullMap.find(params->strFullName);
|
|||
|
if (iter!=m_mfullMap.end())
|
|||
|
{
|
|||
|
FreeTypeFontInfo* p = iter->second;
|
|||
|
if (p->GetFullName()!=params->strFullName) //<2F><><EFBFBD><EFBFBD><EFBFBD>滻<EFBFBD><E6BBBB><EFBFBD><EFBFBD>
|
|||
|
return FindFont(params->lplf->lfFaceName, params->lplf->lfWeight, !!params->lplf->lfItalic);
|
|||
|
p->SetMruCounter(this);
|
|||
|
return p;
|
|||
|
}
|
|||
|
//m_bAddOnFind = true;
|
|||
|
return AddFont(params);
|
|||
|
}
|
|||
|
|
|||
|
FreeTypeFontInfo* FreeTypeFontEngine::FindFont(LPCTSTR lpFaceName, int weight, bool italic, bool AddOnFind, BOOL* bIsFontLoaded)
|
|||
|
{
|
|||
|
/*
|
|||
|
if (m_bAddOnFind)
|
|||
|
{
|
|||
|
m_bAddOnFind = false;
|
|||
|
return NULL;
|
|||
|
}*/
|
|||
|
|
|||
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTMAP);
|
|||
|
weight = CalcBoldWeight(weight);
|
|||
|
myfont font(lpFaceName, weight, italic);
|
|||
|
FontMap::const_iterator iter=m_mfontMap.find(font);
|
|||
|
if (iter!=m_mfontMap.end())
|
|||
|
{
|
|||
|
FreeTypeFontInfo* p = iter->second;
|
|||
|
p->SetMruCounter(this);
|
|||
|
/*
|
|||
|
TCHAR buff[255]={0};
|
|||
|
if (wcslen(lpFaceName)==8)
|
|||
|
{
|
|||
|
wsprintf(buff, L"Finding familiyname \"%s\" weight %d\n\tFound: \"%s\"\n", lpFaceName,
|
|||
|
weight, p->GetFullName().c_str());
|
|||
|
Log(buff);
|
|||
|
}*/
|
|||
|
if (bIsFontLoaded)
|
|||
|
*bIsFontLoaded = true;
|
|||
|
return p;
|
|||
|
}
|
|||
|
//m_bAddOnFind = true;
|
|||
|
return AddFont(lpFaceName, weight, italic, bIsFontLoaded);
|
|||
|
}
|
|||
|
|
|||
|
FreeTypeFontInfo* FreeTypeFontEngine::FindFont(int faceid)
|
|||
|
{
|
|||
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTMAP);
|
|||
|
if (faceid>m_mfontList.size())
|
|||
|
return NULL;
|
|||
|
else
|
|||
|
return m_mfontList[faceid-1]; //<2F><><EFBFBD><EFBFBD>bug<75><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
/*
|
|||
|
FullNameMap::const_iterator iter=m_mfullMap.begin();
|
|||
|
for(; iter != m_mfullMap.end(); ++iter) {
|
|||
|
FreeTypeFontInfo* p = iter->second;
|
|||
|
if (p->GetId() == faceid) {
|
|||
|
p->SetMruCounter(this);
|
|||
|
return p;
|
|||
|
}
|
|||
|
}
|
|||
|
return NULL;*/
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//FreeTypeSysFontData
|
|||
|
// http://kikyou.info/diary/?200510#i10 <20><><EFBFBD>Q<EFBFBD>l<EFBFBD>ɂ<EFBFBD><C982><EFBFBD>
|
|||
|
#include <freetype/tttables.h> // FT_TRUETYPE_TABLES_H
|
|||
|
#include <mmsystem.h> //mmioFOURCC
|
|||
|
#define TVP_TT_TABLE_ttcf mmioFOURCC('t', 't', 'c', 'f')
|
|||
|
#define TVP_TT_TABLE_name mmioFOURCC('n', 'a', 'm', 'e')
|
|||
|
|
|||
|
// Windows<77>ɓo<C993>^<5E><><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>t<EFBFBD>H<EFBFBD><48><EFBFBD>g<EFBFBD>̃o<CC83>C<EFBFBD>i<EFBFBD><69><EFBFBD>f<EFBFBD>[<5B>^<5E>𖼏̂<F096BC8F><CC82><EFBFBD><EFBFBD>擾
|
|||
|
FreeTypeSysFontData* FreeTypeSysFontData::CreateInstance(LPCTSTR name, int weight, bool italic)
|
|||
|
{
|
|||
|
FreeTypeSysFontData* pData = new FreeTypeSysFontData;
|
|||
|
if (!pData) {
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
if (!pData->Init(name, weight, italic)) {
|
|||
|
delete pData;
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
return pData;
|
|||
|
}
|
|||
|
|
|||
|
bool FreeTypeSysFontData::Init(LPCTSTR name, int weight, bool italic)
|
|||
|
{
|
|||
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|||
|
void* pNameFromGDI = NULL; // Windows <20><><EFBFBD><EFBFBD><EFBFBD>擾<EFBFBD><E693BE><EFBFBD><EFBFBD> name <20>^<5E>O<EFBFBD>̓<EFBFBD><CC93>e
|
|||
|
void* pNameFromFreeType = NULL; // FreeType <20><><EFBFBD><EFBFBD><EFBFBD>擾<EFBFBD><E693BE><EFBFBD><EFBFBD> name <20>^<5E>O<EFBFBD>̓<EFBFBD><CC93>e
|
|||
|
HFONT hf = NULL;
|
|||
|
DWORD cbNameTable;
|
|||
|
DWORD cbFontData;
|
|||
|
int index;
|
|||
|
DWORD buf;
|
|||
|
FT_StreamRec& fsr = m_ftStream;
|
|||
|
m_name.assign(name);
|
|||
|
m_hdc = CreateCompatibleDC(NULL);
|
|||
|
if(m_hdc == NULL) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
// <20><><EFBFBD>O<EFBFBD>ȊO<C88A>K<EFBFBD><4B>
|
|||
|
if (pSettings->FontSubstitutes() < SETTING_FONTSUBSTITUTE_ALL)
|
|||
|
{
|
|||
|
hf = CreateFont(
|
|||
|
12, 0, 0, 0, weight,
|
|||
|
italic, FALSE, FALSE,
|
|||
|
DEFAULT_CHARSET,
|
|||
|
OUT_DEFAULT_PRECIS,
|
|||
|
FONT_MAGIC_NUMBER,
|
|||
|
DEFAULT_QUALITY,
|
|||
|
DEFAULT_PITCH | FF_DONTCARE,
|
|||
|
name);
|
|||
|
}
|
|||
|
else
|
|||
|
hf = CreateFont(
|
|||
|
12, 0, 0, 0, weight,
|
|||
|
italic, FALSE, FALSE,
|
|||
|
DEFAULT_CHARSET,
|
|||
|
OUT_DEFAULT_PRECIS,
|
|||
|
CLIP_DEFAULT_PRECIS,
|
|||
|
DEFAULT_QUALITY,
|
|||
|
DEFAULT_PITCH | FF_DONTCARE,
|
|||
|
name);
|
|||
|
|
|||
|
if(hf == NULL){
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
m_hOldFont = SelectFont(m_hdc, hf);
|
|||
|
// <20>t<EFBFBD>H<EFBFBD><48><EFBFBD>g<EFBFBD>f<EFBFBD>[<5B>^<5E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ꂻ<EFBFBD><EA82BB><EFBFBD><EFBFBD><EFBFBD>`<60>F<EFBFBD>b<EFBFBD>N
|
|||
|
cbNameTable = ::GetFontData(m_hdc, TVP_TT_TABLE_name, 0, NULL, 0);
|
|||
|
if(cbNameTable == GDI_ERROR){
|
|||
|
goto ERROR_Init;
|
|||
|
}
|
|||
|
|
|||
|
pNameFromGDI = malloc(cbNameTable);
|
|||
|
if (!pNameFromGDI) {
|
|||
|
goto ERROR_Init;
|
|||
|
}
|
|||
|
pNameFromFreeType = malloc(cbNameTable);
|
|||
|
if (!pNameFromFreeType) {
|
|||
|
goto ERROR_Init;
|
|||
|
}
|
|||
|
|
|||
|
//- name <20>^<5E>O<EFBFBD>̓<EFBFBD><CC93>e<EFBFBD><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɓǂݍ<C782><DD8D><EFBFBD>
|
|||
|
if(GetFontData(m_hdc, TVP_TT_TABLE_name, 0, pNameFromGDI, cbNameTable) == GDI_ERROR){
|
|||
|
goto ERROR_Init;
|
|||
|
}
|
|||
|
|
|||
|
// <20>t<EFBFBD>H<EFBFBD><48><EFBFBD>g<EFBFBD>T<EFBFBD>C<EFBFBD>Y<EFBFBD>擾<EFBFBD><E693BE><EFBFBD><EFBFBD>
|
|||
|
cbFontData = ::GetFontData(m_hdc, TVP_TT_TABLE_ttcf, 0, &buf, 1);
|
|||
|
if(cbFontData == 1){
|
|||
|
// TTC <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD>Ǝv<C68E><76><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
cbFontData = ::GetFontData(m_hdc, TVP_TT_TABLE_ttcf, 0, NULL, 0);
|
|||
|
m_isTTC = true;
|
|||
|
}
|
|||
|
else{
|
|||
|
cbFontData = ::GetFontData(m_hdc, 0, 0, NULL, 0);
|
|||
|
}
|
|||
|
if(cbFontData == GDI_ERROR){
|
|||
|
// <20>G<EFBFBD><47><EFBFBD>[; GetFontData <20>ł͈<C582><CD88><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
goto ERROR_Init;
|
|||
|
}
|
|||
|
|
|||
|
if (pSettings->UseMapping()) {
|
|||
|
HANDLE hmap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT | SEC_NOCACHE, 0, cbFontData, NULL);
|
|||
|
if (!hmap) {
|
|||
|
goto ERROR_Init;
|
|||
|
}
|
|||
|
m_pMapping = MapViewOfFile(hmap, FILE_MAP_ALL_ACCESS, 0, 0, cbFontData);
|
|||
|
m_dwSize = cbFontData;
|
|||
|
CloseHandle(hmap);
|
|||
|
|
|||
|
if (m_pMapping) {
|
|||
|
::GetFontData(m_hdc, m_isTTC ? TVP_TT_TABLE_ttcf : 0, 0, m_pMapping, cbFontData);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// FT_StreamRec <20>̊e<CC8A>t<EFBFBD>B<EFBFBD>[<5B><><EFBFBD>h<EFBFBD>߂<F0968482>
|
|||
|
fsr.base = 0;
|
|||
|
fsr.size = cbFontData;
|
|||
|
fsr.pos = 0;
|
|||
|
fsr.descriptor.pointer = this;
|
|||
|
fsr.pathname.pointer = NULL;
|
|||
|
fsr.read = IoFunc;
|
|||
|
fsr.close = CloseFunc;
|
|||
|
|
|||
|
index = 0;
|
|||
|
m_locked = true;
|
|||
|
if(!OpenFaceByIndex(index)){
|
|||
|
goto ERROR_Init;
|
|||
|
}
|
|||
|
|
|||
|
for(;;) {
|
|||
|
// FreeType <20><><EFBFBD><EFBFBD><EFBFBD>Aname <20>^<5E>O<EFBFBD>̃T<CC83>C<EFBFBD>Y<EFBFBD><59><EFBFBD>擾<EFBFBD><E693BE><EFBFBD><EFBFBD>
|
|||
|
FT_ULong length = 0;
|
|||
|
FT_Error err = FT_Load_Sfnt_Table(m_ftFace, TTAG_name, 0, NULL, &length);
|
|||
|
if(err){
|
|||
|
goto ERROR_Init;
|
|||
|
}
|
|||
|
|
|||
|
// FreeType <20><><EFBFBD>瓾<EFBFBD><E793BE> name <20>^<5E>O<EFBFBD>̒<EFBFBD><CC92><EFBFBD><EFBFBD><EFBFBD> Windows <20><><EFBFBD>瓾<EFBFBD><E793BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ɣ<EFBFBD><C694>r
|
|||
|
if(length == cbNameTable){
|
|||
|
// FreeType <20><><EFBFBD><EFBFBD> name <20>^<5E>O<EFBFBD><4F><EFBFBD>擾
|
|||
|
err = FT_Load_Sfnt_Table(m_ftFace, TTAG_name, 0, (unsigned char*)pNameFromFreeType, &length);
|
|||
|
if(err){
|
|||
|
goto ERROR_Init;
|
|||
|
}
|
|||
|
// FreeType <20><><EFBFBD><EFBFBD><EFBFBD>ǂݍ<C782><DD8D><EFBFBD><EFBFBD><EFBFBD> name <20>^<5E>O<EFBFBD>̓<EFBFBD><CC93>e<EFBFBD>ƁAWindows <20><><EFBFBD><EFBFBD><EFBFBD>ǂݍ<C782><DD8D><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
// name <20>^<5E>O<EFBFBD>̓<EFBFBD><CC93>e<EFBFBD><65><EFBFBD><EFBFBD><EFBFBD>r<EFBFBD><72><EFBFBD><EFBFBD><EFBFBD>B
|
|||
|
// <20><><EFBFBD>v<EFBFBD><76><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD><EFBFBD><CE82><EFBFBD> index <20>̃t<CC83>H<EFBFBD><48><EFBFBD>g<EFBFBD><67><EFBFBD>g<EFBFBD><67><EFBFBD>B
|
|||
|
if(!memcmp(pNameFromGDI, pNameFromFreeType, cbNameTable)){
|
|||
|
// <20><><EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD>
|
|||
|
// face <20>͊J<CD8A><4A><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD>
|
|||
|
break; // <20><><EFBFBD>[<5B>v<EFBFBD><EFBFBD><F094B282><EFBFBD>
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD>v<EFBFBD><76><EFBFBD>Ȃ<EFBFBD><C882><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
// <20>C<EFBFBD><43><EFBFBD>f<EFBFBD>b<EFBFBD>N<EFBFBD>X<EFBFBD><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD><C291>₵<EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD> face <20><><EFBFBD>J<EFBFBD><4A>
|
|||
|
index ++;
|
|||
|
|
|||
|
if(!OpenFaceByIndex(index)){
|
|||
|
// <20><><EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD> face <20><><EFBFBD>Ȃ<EFBFBD><C882>܂<EFBFBD> <20>C<EFBFBD><43><EFBFBD>f<EFBFBD>b<EFBFBD>N<EFBFBD>X<EFBFBD><58><EFBFBD>͈͂<CD82><F092B482><EFBFBD><EFBFBD>ƌ<EFBFBD><C68C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
// index <20><> 0 <20>ɐݒ肵<DD92>Ă<EFBFBD><C482><EFBFBD> index <20><><EFBFBD>J<EFBFBD><4A><EFBFBD>A<EFBFBD><41><EFBFBD>[<5B>v<EFBFBD><EFBFBD><F094B282><EFBFBD>
|
|||
|
index = 0;
|
|||
|
if(!OpenFaceByIndex(index)){
|
|||
|
goto ERROR_Init;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
free(pNameFromGDI);
|
|||
|
free(pNameFromFreeType);
|
|||
|
m_locked = false;
|
|||
|
return true;
|
|||
|
|
|||
|
ERROR_Init:
|
|||
|
m_locked = false;
|
|||
|
if (hf) {
|
|||
|
SelectFont(m_hdc, m_hOldFont);
|
|||
|
DeleteFont(hf);
|
|||
|
m_hOldFont = NULL;
|
|||
|
}
|
|||
|
free(pNameFromGDI);
|
|||
|
free(pNameFromFreeType);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
unsigned long FreeTypeSysFontData::IoFunc(
|
|||
|
FT_Stream stream,
|
|||
|
unsigned long offset,
|
|||
|
unsigned char* buffer,
|
|||
|
unsigned long count )
|
|||
|
{
|
|||
|
if(count == 0){
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
FreeTypeSysFontData * pThis = reinterpret_cast<FreeTypeSysFontData*>(stream->descriptor.pointer);
|
|||
|
Assert(pThis != NULL);
|
|||
|
|
|||
|
DWORD result = 0;
|
|||
|
if (pThis->m_pMapping) {
|
|||
|
result = Min(pThis->m_dwSize - offset, count);
|
|||
|
memcpy(buffer, (const BYTE*)pThis->m_pMapping + offset, result);
|
|||
|
} else {
|
|||
|
result = ::GetFontData(pThis->m_hdc, pThis->m_isTTC ? TVP_TT_TABLE_ttcf : 0, offset, buffer, count);
|
|||
|
if(result == GDI_ERROR) {
|
|||
|
// <20>G<EFBFBD><47><EFBFBD>[
|
|||
|
return 0;
|
|||
|
}
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
void FreeTypeSysFontData::CloseFunc(FT_Stream stream)
|
|||
|
{
|
|||
|
FreeTypeSysFontData * pThis = reinterpret_cast<FreeTypeSysFontData*>(stream->descriptor.pointer);
|
|||
|
Assert(pThis != NULL);
|
|||
|
|
|||
|
if(!pThis->m_locked)
|
|||
|
delete pThis;
|
|||
|
}
|
|||
|
|
|||
|
bool FreeTypeSysFontData::OpenFaceByIndex(int index)
|
|||
|
{
|
|||
|
if(m_ftFace) {
|
|||
|
FT_Done_Face(m_ftFace);
|
|||
|
m_ftFace = NULL;
|
|||
|
}
|
|||
|
|
|||
|
FT_Open_Args args = { 0 };
|
|||
|
args.flags = FT_OPEN_STREAM;
|
|||
|
args.stream = &m_ftStream;
|
|||
|
|
|||
|
// FreeType <20>ň<EFBFBD><C588><EFBFBD><EFBFBD>邩<EFBFBD>H
|
|||
|
return (FT_Open_Face(freetype_library, &args, index, &m_ftFace) == 0);
|
|||
|
}
|