mactype/fteng.h

698 lines
19 KiB
C
Raw Normal View History

#pragma once
#include <ft2build.h>
#include <freetype/freetype.h> /* FT_FREETYPE_H */
#include <freetype/ftcache.h> /* FT_CACHE_H */
#include <freetype/tttables.h>
#include <freetype/tttags.h> // FT_TRUETYPE_TAGS_H
#include <freetype/ftoutln.h>
#include <vector>
#include "ftref.h"
#include <math.h>
#include "undocAPI.h"
class FreeTypeFontEngine;
extern FreeTypeFontEngine* g_pFTEngine;
extern BOOL g_ccbCache;
extern BOOL g_ccbIndividual;
extern FTC_Manager cache_man;
typedef set<CBitmapCache*> CTLSDCArray;
extern CTLSDCArray TLSDCArray;
LOGFONTW* GetFontNameFromFile(LPCTSTR Filename);
bool GetFontLocalName(TCHAR* pszFontName, __out TCHAR* pszNameOut); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD>
struct CFontSetCache
{
const CFontSettings** fontsetlist;
int fontsetsize;
CFontSetCache()
:fontsetsize(0)
{
fontsetsize=64;
fontsetlist = (const CFontSettings**)malloc(fontsetsize * sizeof(void*));
}
~CFontSetCache()
{
free(fontsetlist);
}
void Set(FTC_FaceID faceid, const CFontSettings& fset)
{
while ((INT_PTR)faceid>=fontsetsize)
{
fontsetsize+=64;
fontsetlist = (const CFontSettings**)realloc(fontsetlist, fontsetsize);
}
fontsetlist[(INT_PTR)faceid]=&fset;
}
const CFontSettings*& Get(FTC_FaceID faceid) const
{
return fontsetlist[(INT_PTR)faceid];
}
};
struct myfont
{
wstring name;
int hash;
bool operator < (const myfont mf) const {
return name==mf.name? hash<mf.hash: name<mf.name;
}
public:
myfont(LPCWSTR lpFaceName, int nweight, int nitalic):
name(lpFaceName),hash((nitalic<<31) | nweight)
{}
};
enum FT_EngineConstants {
FT_MAX_CHARS = 65536,
};
/*
FreeType<EFBFBD>ɕ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>Α̂<EFBFBD><EFBFBD>L<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>V<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@<EFBFBD>\<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂ł<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1. <EFBFBD>܂<EFBFBD>DllMain(DLL_PROCESS_ATTACH)<EFBFBD><EFBFBD>FreeTypeFontEngine<EFBFBD>̃C<EFBFBD><EFBFBD><EFBFBD>X<EFBFBD>^<EFBFBD><EFBFBD><EFBFBD>X<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
(<EFBFBD><EFBFBD><EFBFBD>Ԃ<EFBFBD>CGdiPPSettings<EFBFBD><EFBFBD>FontLInit(FreeType)<EFBFBD><EFBFBD>FreeTypeFontEngine<EFBFBD><EFBFBD><EFBFBD>t<EFBFBD>b<EFBFBD>N)
ForceChangeFont<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŏ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
2. CreateFont<EFBFBD><EFBFBD>FreeTypeFontEngine::AddFont<EFBFBD><EFBFBD><EFBFBD>Ăяo<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>AFreeTypeFontInfo<EFBFBD><EFBFBD>
<EFBFBD>t<EFBFBD>H<EFBFBD><EFBFBD><EFBFBD>g<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>т‚<EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
<EFBFBD>‚<EFBFBD><EFBFBD>ł<EFBFBD>FreeTypeFontInfo<EFBFBD><EFBFBD>Individual<EFBFBD>̐ݒ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>R<EFBFBD>s<EFBFBD>[<EFBFBD><EFBFBD><EFBFBD>Ď<EFBFBD><EFBFBD>B
3. ExtTextOut<EFBFBD><EFBFBD>GetTextExtent<EFBFBD>Ȃǂ<EFBFBD><EFBFBD><EFBFBD>FreeTypePrepare<EFBFBD>֐<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ăяo<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɓ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>FreeTypeFontInfo::GetCache<EFBFBD><EFBFBD><EFBFBD>Ăяo<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>t<EFBFBD>H<EFBFBD><EFBFBD><EFBFBD>g<EFBFBD>T<EFBFBD>C<EFBFBD>Y<EFBFBD>Ȃǂ<EFBFBD><EFBFBD><EFBFBD>
FreeTypeFontCache<EFBFBD>𓾂<EFBFBD><EFBFBD>B<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΐ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
FreeTypeFontCache<EFBFBD>͓<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>FreeTypeCharData<EFBFBD>̃e<EFBFBD>[<EFBFBD>u<EFBFBD><EFBFBD>(UCS2<EFBFBD>Ȃ̂<EFBFBD>2^16<EFBFBD><EFBFBD>)<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><EFBFBD>āAFreeTypeCharData<EFBFBD>ɂ͕<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɃL<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>V<EFBFBD><EFBFBD><EFBFBD>f<EFBFBD>[<EFBFBD>^<EFBFBD><EFBFBD><EFBFBD>ۊǂ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
4. FreeTypeFontCache<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD>̓O<EFBFBD><EFBFBD><EFBFBD>t<EFBFBD>ԍ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>FreeTypeCharData<EFBFBD>𓾂<EFBFBD><EFBFBD>B
<EFBFBD>L<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>V<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ɏc<EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<EFBFBD>AMRU<EFBFBD>J<EFBFBD>E<EFBFBD><EFBFBD><EFBFBD>^<EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͈<EFBFBD><EFBFBD>U<EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>[<EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><EFBFBD><EFBFBD><EFBFBD>AddCharData<EFBFBD>ŃL<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>V<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>lj<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
5. <EFBFBD>lj<EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƃ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂ŁA<EFBFBD>lj<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(FREETYPE_REQCOUNTMAX)<EFBFBD>𒴂<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GC<EFBFBD><EFBFBD><EFBFBD>h<EFBFBD>L<EFBFBD>ōŋߎQ<EFBFBD>Ƃ<EFBFBD><EFBFBD><EFBFBD>L<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>V<EFBFBD><EFBFBD><EFBFBD>f<EFBFBD>[<EFBFBD>^<EFBFBD><EFBFBD>FREETYPE_GC_COUNTER<EFBFBD>‚<EFBFBD><EFBFBD><EFBFBD><EFBFBD>c<EFBFBD><EFBFBD><EFBFBD>A
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȊO<EFBFBD>̃f<EFBFBD>[<EFBFBD>^(FreeTypeCharData)<EFBFBD>͊J<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>‚̒<EFBFBD><EFBFBD>ini<EFBFBD>Őݒ<EFBFBD><EFBFBD>ύX<EFBFBD>ł<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȋC<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
6. <EFBFBD>Ō<EFBFBD><EFBFBD>ɁADllMain(DLL_PROCESS_DETACH)<EFBFBD><EFBFBD>FreeTypeFontEngine<EFBFBD>̃C<EFBFBD><EFBFBD><EFBFBD>X<EFBFBD>^<EFBFBD><EFBFBD><EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>j<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A
<EFBFBD>S<EFBFBD>ẴL<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>V<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>J<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
*/
class FreeTypeGCCounter
{
private:
int m_addcount; //<2F>lj<EFBFBD><C789>p
int m_mrucount; //MRU<52>p
public:
FreeTypeGCCounter()
: m_addcount(0), m_mrucount(0)
{
}
int AddIncrement() { return ++m_addcount; }
int DecIncrement() { return --m_addcount; }
int MruIncrement() { return ++m_mrucount; }
void ResetGCCounter()
{
m_mrucount = 0;
m_addcount = 0;
}
};
class FreeTypeMruCounter
{
private:
int m_mrucounter; //GC<47>p
public:
FreeTypeMruCounter(int n)
: m_mrucounter(n)
{
}
//GC<47>pMRU<52>J<EFBFBD>E<EFBFBD><45><EFBFBD>^
int GetMruCounter() const { return m_mrucounter; }
void ResetMruCounter() { m_mrucounter = 0; }
void SetMruCounter(FreeTypeGCCounter* p) { m_mrucounter = p->MruIncrement(); }
};
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A(glyph index)<29>AFT_BitmapGlyph(<28><><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>Α̂̂<CC82>)<29><><EFBFBD>L<EFBFBD><4C><EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
class FreeTypeCharData : public FreeTypeMruCounter
{
private:
typedef CValArray<FreeTypeCharData**> CharDataArray;
CharDataArray m_arrSelfChar; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>g<EFBFBD>̕ۑ<CC95><DB91><EFBFBD>(Char)
FreeTypeCharData** m_ppSelfGlyph; //(Glyph)
UINT m_glyphindex; //<2F>O<EFBFBD><4F><EFBFBD>t<EFBFBD>ԍ<EFBFBD>
int m_width; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int m_gdiWidth; //ʹ<><CAB9>GetCharWidth<74><68><EFBFBD>õ<EFBFBD>GDI<44><49><EFBFBD><EFBFBD>
FT_Referenced_BitmapGlyph m_glyph; //<2F>J<EFBFBD><4A><EFBFBD>[<5B>p
FT_Referenced_BitmapGlyph m_glyphMono; //<2F><><EFBFBD>m<EFBFBD>N<EFBFBD><4E><EFBFBD>p
int m_bmpSize; //<2F>r<EFBFBD>b<EFBFBD>g<EFBFBD>}<7D>b<EFBFBD>v<EFBFBD>T<EFBFBD>C<EFBFBD>Y
int m_bmpMonoSize; // <20>V
int m_AAMode;
// LONG m_refcounter; //<2F>Q<EFBFBD>ƃJ<C683>E<EFBFBD><45><EFBFBD>^
#ifdef _DEBUG
WCHAR m_wch; //UCS2<53><32><EFBFBD><EFBFBD>
#endif
NOCOPY(FreeTypeCharData);
//FT_Bitmap::buffer<65>̃T<CC83>C<EFBFBD>Y<EFBFBD><59><EFBFBD>Ԃ<EFBFBD>
static inline int FT_Bitmap_CalcSize(FT_BitmapGlyph gl)
{
return gl->bitmap.pitch * gl->bitmap.rows;
}
public:
FreeTypeCharData(FreeTypeCharData** ppCh, FreeTypeCharData** ppGl, WCHAR wch, UINT glyphindex, int width, int mru, int gdiWidth, int AAMode);
~FreeTypeCharData();
#ifdef _DEBUG
WCHAR GetChar() const { return m_wch; }
#else
WCHAR GetChar() const { return L'?'; }
#endif
UINT GetGlyphIndex() const { return m_glyphindex; }
int GetWidth() const { return m_width; }
void SetWidth(int width) { m_width = width; }
void SetGDIWidth(int width) { m_gdiWidth = width; }
int GetGDIWidth() const {return m_gdiWidth; }
int GetAAMode() const {return m_AAMode; }
void AddChar(FreeTypeCharData** ppCh)
{
if (ppCh)
m_arrSelfChar.Add(ppCh);
}
FT_Referenced_BitmapGlyph GetGlyph(FT_Render_Mode render_mode) const
{
return (render_mode == FT_RENDER_MODE_MONO) ? m_glyphMono : m_glyph;
}
void SetGlyph(FT_Render_Mode render_mode, FT_Referenced_BitmapGlyph glyph);
void Erase()
{
//delete this;
}
};
static INT_PTR NULL_INT = NULL;
class FreeTypeFontCache : public FreeTypeMruCounter, public FreeTypeGCCounter
{
typedef map<int, FreeTypeCharData*> GlyphCache;
private:
int m_px;
int m_weight;
bool m_italic;
bool m_active;
TEXTMETRIC m_tm;
//4<>~65536<33>~2<><32>512KB<4B><42><EFBFBD><EFBFBD><E782A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD><6D><EFBFBD>Ă<EFBFBD><C482>̂ŌŒ<C58C><C592>z<EFBFBD><7A><EFBFBD>Ŗ<EFBFBD><C596><EFBFBD><E896B3>
#ifdef _USE_ARRAY
FreeTypeCharData* m_chars[FT_MAX_CHARS];
FreeTypeCharData* m_glyphs[FT_MAX_CHARS];
#else
GlyphCache m_GlyphCache;
#endif
NOCOPY(FreeTypeFontCache);
void Compact();
FreeTypeCharData** _GetChar(WCHAR wch)
{
#ifdef _USE_ARRAY
return m_chars + wch;
#else
GlyphCache::iterator it=m_GlyphCache.find(wch);
return it==m_GlyphCache.end()? reinterpret_cast<FreeTypeCharData**>(&NULL_INT): &(it->second);
#endif
}
FreeTypeCharData** _GetGlyph(UINT glyph)
{
#ifdef _USE_ARRAY
return m_glyphs + glyph;
#else
GlyphCache::iterator it=m_GlyphCache.find(-(int)glyph);
return it == m_GlyphCache.end() ? reinterpret_cast<FreeTypeCharData**>(&NULL_INT) : &(it->second);
#endif
}
public:
FreeTypeFontCache(/*int px, int weight, bool italic, */int mru);
~FreeTypeFontCache();
const TEXTMETRIC& GetTextMetric(HDC hdc)
{
if (m_tm.tmHeight == 0) {
::GetTextMetrics(hdc, &m_tm);
}
return m_tm;
}
bool Equals(int px, int weight, bool italic) const
{
return (m_px == px && m_weight == weight && m_italic == italic);
}
FreeTypeCharData* FindChar(WCHAR wch)
{
/*if (!g_ccbCache) return NULL;*/
FreeTypeCharData* p = *_GetChar(wch);
if(p) {
p->SetMruCounter(this);
}
return p;
}
FreeTypeCharData* FindGlyphIndex(UINT glyph)
{
/*if (!g_ccbCache) return NULL;*/
FreeTypeCharData* p = (glyph & 0xffff0000) ? NULL : *_GetGlyph(glyph);
if(p) {
p->SetMruCounter(this);
}
return p;
}
bool Activate()
{
if (!m_active) {
m_active = true;
return true;
}
return false;
}
void Erase();
void Deactive() { m_active = false; };
void AddCharData(WCHAR wch, UINT glyphindex, int width, int gdiWidth, FT_Referenced_BitmapGlyph glyph, FT_Render_Mode render_mode, int AAMode);
void AddGlyphData(UINT glyphindex, int width, int gdiWidth, FT_Referenced_BitmapGlyph glyph, FT_Render_Mode render_mode, int AAMode);
};
// <20>t<EFBFBD>H<EFBFBD><48><EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD>FaceID(int<6E><74><EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD>Ƃɂ<C682><C982><EFBFBD>)
//extern CFontSetCache g_fsetcache;
extern CHashedStringList FontNameCache;
class FreeTypeFontInfo : public FreeTypeMruCounter, public FreeTypeGCCounter
{
private:
INT_PTR m_id;
int m_weight;
bool m_italic;
char m_hashinting;
int m_ftWeight;
int m_nMaxSizes;
int m_nFontFamily;
HFONT m_ggoFont;
TT_OS2* m_OS2Table;
char m_ebmps[256];
LONG volatile count;
CFontSettings m_set;
StringHashFont m_hash;
wstring m_fullname, m_familyname;
typedef map<UINT, FreeTypeFontCache*> CacheArray;
CacheArray m_cache;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
FTC_FaceID face_id_link[CFontLinkInfo::FONTMAX * 2 + 1];
HFONT ggo_link[CFontLinkInfo::FONTMAX * 2 + 1];
bool m_linkinited;
int m_linknum;
FTC_FaceID m_SimSunID;
NOCOPY(FreeTypeFontInfo);
void Compact();
void Createlink();
public:
void AddRef() {InterlockedIncrement(&count);};
void Release() {
if (InterlockedDecrement(&count)==0)
delete this;
}
TT_OS2* GetOS2Table()
{
if (!m_OS2Table)
{
TT_OS2 * os2_table = NULL;
FT_Face freetype_face;
CCriticalSectionLock __lock(CCriticalSectionLock::CS_MANAGER);
if (FTC_Manager_LookupFace(cache_man, (FTC_FaceID)m_id, &freetype_face))
return NULL;
os2_table = (TT_OS2*) FT_Get_Sfnt_Table(freetype_face, ft_sfnt_os2);
if (!os2_table) return NULL;
m_OS2Table = new TT_OS2;
memcpy(m_OS2Table, os2_table, sizeof(TT_OS2));
}
return m_OS2Table;
}
BOOL FontHasHinting()
{
if (m_hashinting==3)
{
FT_Face freetype_face;
CCriticalSectionLock __lock(CCriticalSectionLock::CS_MANAGER);
if (FTC_Manager_LookupFace(cache_man, (FTC_FaceID)m_id, &freetype_face)) //<2F><>ѯft face
{
m_hashinting = false;
return NULL;
}
FT_ULong length = 0;
FT_Error err = FT_Load_Sfnt_Table(freetype_face, TTAG_fpgm, 0, NULL, &length); //<2F><>ȡfpgm<67><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!err && length>50) //<2F>ɹ<EFBFBD><C9B9><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3>Ƚϳ<C8BD>
m_hashinting = true; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>hinting
else
m_hashinting = false;
}
return m_hashinting;
}
wstring GetFullName() {return m_fullname;};
bool m_isSimSun;
bool IsPixel;
UINT getCacheHash(int px, int weight, bool italic, int width) {return ((px<<20)|(width<<8)|(weight<<1)|(int)italic); }; //<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>hashֵ<68><D6B5><EFBFBD><EFBFBD>λcache
FreeTypeFontInfo(int n, LPCTSTR name, int weight, bool italic, int mru, wstring fullname, wstring familyname)
: m_id(n), m_weight(weight), m_italic(italic), m_OS2Table(NULL)
, FreeTypeMruCounter(mru), m_isSimSun(false), m_ggoFont(NULL), m_linkinited(false), m_linknum(0)
, m_SimSunID(0), count(1), m_fullname(fullname), m_familyname(familyname), m_hashinting(3), m_nFontFamily(0)
{
//m_set = set;
memset(m_ebmps, 0xff, sizeof(m_ebmps));
enum { FTC_MAX_SIZES_DEFAULT = 4 };
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
m_nMaxSizes = pSettings->CacheMaxSizes();
if (!m_nMaxSizes)
m_nMaxSizes = FTC_MAX_SIZES_DEFAULT;
//extern BOOL g_EngineCreateFont;
if (pSettings->FontSubstitutes() < SETTING_FONTSUBSTITUTE_ALL)
m_ggoFont = CreateFont(10,0,0,0,weight,italic,0,0,DEFAULT_CHARSET,0,FONT_MAGIC_NUMBER,0,0,name);
//use magic number to create unsubstitud font
else
m_ggoFont = CreateFont(10,0,0,0,weight,italic,0,0,DEFAULT_CHARSET,0,0,0,0,name);
HDC hdc = CreateCompatibleDC(NULL);
HFONT old = SelectFont(hdc, m_ggoFont);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>
int nSize=GetOutlineTextMetrics(hdc, 0, NULL);
if (nSize==0)
m_fullname = L"";
else
//if (m_fullname.size()==0) //<2F><><EFBFBD><EFBFBD><ECBAAF><EFBFBD>в<EFBFBD><D0B2><EFBFBD><E1B9A9><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD>ȡ
{
LPOUTLINETEXTMETRIC otm = (LPOUTLINETEXTMETRIC)malloc(nSize);
memset(otm, 0, nSize);
otm->otmSize = nSize;
GetOutlineTextMetrics(hdc, nSize, otm);
m_fullname = (wstring)(LPWSTR)((DWORD_PTR)otm+(DWORD_PTR)otm->otmpFullName)+(wstring)(LPWSTR)((DWORD_PTR)otm+(DWORD_PTR)otm->otmpStyleName);
TCHAR * localname = (LPWSTR)((DWORD_PTR)otm+(DWORD_PTR)otm->otmpFamilyName);
TCHAR buff[LF_FACESIZE+1];
GetFontLocalName(localname, buff);
m_nFontFamily = otm->otmTextMetrics.tmPitchAndFamily & 0xF0; //<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E5A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧʹ<D3A6><CAB9>ʲôĬ<C3B4><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_familyname = (wstring)buff;
m_set = pSettings->FindIndividual(m_familyname.c_str());
m_ftWeight = CalcBoldWeight(/*weight*/700);
m_hash = StringHashFont(name);
if (m_familyname.size()>0 && m_familyname.c_str()[0]==L'@') //<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>@
m_fullname = L'@'+m_fullname;
free(otm);
}
SelectFont(hdc, old);
DeleteDC(hdc);
//<2F><><EFBFBD><EFBFBD>
// g_EngineCreateFont = false;
face_id_link[0]=(FTC_FaceID)NULL;
ggo_link[0] = NULL;
//g_fsetcache.Set((FTC_FaceID)n, set);
}
~FreeTypeFontInfo()
{
Erase();
DeleteFont(m_ggoFont);
if (m_OS2Table)
delete m_OS2Table;
}
HFONT GetGGOFont(){return m_ggoFont;};
int CalcNormalWeight() const
{
return m_set.GetNormalWeight();
}
int CalcBoldWeight(int weight) const
{
// return weight - FW_NORMAL) / 8;
// return ((weight - FW_NORMAL) / 12) + (m_set.GetBoldWeight() << 2);
weight = weight < FW_BOLD ? 0: /*(weight > FW_BOLD ?*/ 612;
if (weight <= FW_NORMAL) {
return 0;
}
return ((weight - FW_NORMAL) / 8) + (m_set.GetBoldWeight() << 2);
}
int CalcBoldWeight(const LOGFONT& lf) const
{
return CalcBoldWeight(lf.lfWeight);
}
void CalcItalicSlant(FT_Matrix& matrix) const
{
matrix.xx = 1 << 16;
// matrix.xy = 0x5800;
matrix.xy = (5 + m_set.GetItalicSlant()) << 12;
matrix.yx = 0;
matrix.yy = 1 << 16;
}
bool Equals(const StringHashFont& hash, int weight, bool italic) const
{
weight = CalcBoldWeight(weight);
return (m_ftWeight == weight && m_italic == italic && m_hash == hash);
}
void UpdateFontSetting()
{
m_ftWeight = CalcBoldWeight(700/*m_weight*/);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
face_id_link[0]=NULL;
ggo_link[0]=NULL;
m_linknum = 0;
m_linkinited = false;
m_SimSunID = 0;
}
int GetFTLink(FTC_FaceID** llplink)
{
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTLINK);
if (!*face_id_link)
Createlink();
*llplink = face_id_link;
return m_linknum;
}
int GetGGOLink(HFONT** llplink)
{
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTLINK);
if (!*ggo_link)
Createlink();
*llplink = ggo_link;
return m_linknum;
}
FTC_FaceID GetSimSunID() {return m_SimSunID;}
INT_PTR GetId() const { return m_id; }
LPCTSTR GetName() const { return m_hash.c_str(); }
int GetFontWeight() const { return m_weight; }
int GetExactBoldWeight() const {return m_set.GetBoldWeight(); }
int GetFTWeight() const { return m_ftWeight; }
bool IsItalic() const { return m_italic; }
const StringHashFont& GetHash() const { return m_hash; }
const CFontSettings& GetFontSettings() const { return m_set; }
void SetFontSettings(const CFontSettings& set) { m_set = set;};
bool operator ==(const FreeTypeFontInfo& x) const { return (m_hash == x.m_hash); }
FreeTypeFontCache* GetCache(FTC_ScalerRec& scaler, const LOGFONT& lf);
bool EmbeddedBmpExist(int px);
void Erase()
{
CCriticalSectionLock __lock(CCriticalSectionLock::CS_FONTCACHE);
CacheArray::iterator it = m_cache.begin();
for (;it!=m_cache.end();++it)
{
delete it->second;
}
m_cache.clear();
}
};
class FreeTypeFontEngine : public FreeTypeGCCounter
{
private:
//typedef CArray<FreeTypeFontInfo*> FontListArray;
typedef map<myfont, FreeTypeFontInfo*> FontMap;
typedef map<wstring, FreeTypeFontInfo*> FullNameMap;
typedef vector<FreeTypeFontInfo*> FontList;
//FontListArray m_arrFontList;
int m_nMaxFaces;
int m_nMemUsed;
bool m_bAddOnFind;
FontMap m_mfontMap;
FullNameMap m_mfullMap;
FontList m_mfontList;
FT_Face* m_arrFace;
int m_nFaceCount;
void Compact();
int GrowFace()
{
FT_Face* a=(FT_Face*)malloc(m_nFaceCount*sizeof(FT_Face));
memcpy(a, m_arrFace, sizeof(FT_Face)*m_nFaceCount);
m_nFaceCount+=64;
m_arrFace = (FT_Face*)realloc(m_arrFace, sizeof(FT_Face) * m_nFaceCount);
memset(m_arrFace+m_nFaceCount-64, 0, sizeof(FT_Face)*64);
for (int i=0;i<m_nFaceCount-64;i++)
Assert(a[i]==m_arrFace[i]);
free(a);
return m_nFaceCount;
}
public:
FreeTypeFontEngine()
: m_nMemUsed(0), m_nMaxFaces(0), m_bAddOnFind(false), m_nFaceCount(64)
{
enum { FTC_MAX_FACES_DEFAULT = 2 };
const CGdippSettings* pSettings = CGdippSettings::GetInstanceNoInit();
m_nMaxFaces = pSettings->CacheMaxFaces();
if (m_nMaxFaces == 0)
m_nMaxFaces = FTC_MAX_FACES_DEFAULT;
//m_arrFace = (FT_Face*)malloc(m_nFaceCount*sizeof(FT_Face));
//memset(m_arrFace, 0, sizeof(FT_Face)*m_nFaceCount);
}
~FreeTypeFontEngine()
{
TRACE(_T("MaxFaces: %d\n"), m_mfontMap.size());
TRACE(_T("MemUsed : %d\n"), m_nMemUsed);
//FontListArray& arr = m_arrFontList;
FullNameMap::const_iterator iter=m_mfullMap.begin();
for (;iter!=m_mfullMap.end();++iter)
iter->second->Release();
//free(m_arrFace);
}
int CalcBoldWeight(int weight) const
{
return weight < FW_BOLD ? 0: FW_BOLD;
}
FreeTypeFontInfo* AddFont(LPCTSTR lpFaceName, int weight, bool italic, BOOL* bIsFontLoaded = NULL);
FreeTypeFontInfo* AddFont(void* lpparams);
int GetFontIdByName(LPCTSTR lpFaceName, int weight, bool italic);
// LPCTSTR GetFontById(int faceid, int& weight, bool& italic);
FreeTypeFontInfo* FindFont(LPCTSTR lpFaceName, int weight, bool italic, bool AddOnFind = true, BOOL* bIsFontLoaded=NULL);
FreeTypeFontInfo* FindFont(int faceid);
FreeTypeFontInfo* FindFont(void* lpparams);
bool FontExists(LPCTSTR lpFaceName, int weight, bool italic)
{
return !!FindFont(lpFaceName, weight, italic);
}
BOOL RemoveFont(LPCWSTR FontName);
BOOL RemoveFont(FreeTypeFontInfo* fontinfo);
BOOL RemoveThisFont(FreeTypeFontInfo* fontinfo, LOGFONT* lg);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>g<EFBFBD>p<EFBFBD>ʃJ<CA83>E<EFBFBD><45><EFBFBD>^
void AddMemUsed(int x)
{
m_nMemUsed += x;
}
void SubMemUsed(int x)
{
m_nMemUsed -= x;
if (m_nMemUsed < 0)
m_nMemUsed = 0;
}
template <class T>
void AddMemUsedObj(T* /*p*/)
{
AddMemUsed(sizeof(T));
}
template <class T>
void SubMemUsedObj(T* /*p*/)
{
SubMemUsed(sizeof(T));
}
void ReloadAll()
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E5A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E5BBBA>
COwnedCriticalSectionLock __olock(2);
CCriticalSectionLock __lock;
CGdippSettings* pSettings = CGdippSettings::GetInstance();
FullNameMap::const_iterator iter=m_mfullMap.begin();
for (;iter!=m_mfullMap.end();)
{
FreeTypeFontInfo* p =iter->second;
if (p)
{
/*
if (p->GetFullName()!=iter->first) //<2F><><EFBFBD><EFBFBD><E6BBBB><EFBFBD><EFBFBD>
{
p->Release(); //<2F>ͷŵ<CDB7><C5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_mfullMap.erase(iter++);
continue;
}*/
p->Erase();
p->SetFontSettings(pSettings->FindIndividual(p->GetName()));
p->UpdateFontSetting();
}
++iter;
}
//m_mfontMap.clear();
}
};
//GetFontData<74>̃<EFBFBD><CC83><EFBFBD><EFBFBD><EFBFBD><EFBFBD>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><>
class FreeTypeSysFontData
{
private:
HDC m_hdc;
HFONT m_hOldFont;
bool m_isTTC;
bool m_locked;
void* m_pMapping;
DWORD m_dwSize;
FT_Face m_ftFace;
wstring m_name;
FT_StreamRec m_ftStream;
FreeTypeSysFontData()
: m_hdc(NULL)
, m_hOldFont(NULL)
, m_isTTC(false)
, m_locked(false)
, m_pMapping(NULL)
, m_dwSize(0)
, m_ftFace(NULL)
{
ZeroMemory(&m_ftStream, sizeof(FT_StreamRec));
}
static unsigned long IoFunc(FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count);
static void CloseFunc(FT_Stream stream);
bool OpenFaceByIndex(int index);
bool Init(LPCTSTR name, int weight, bool italic);
public:
static FreeTypeSysFontData* CreateInstance(LPCTSTR name, int weight, bool italic);
~FreeTypeSysFontData()
{
if (m_pMapping) {
UnmapViewOfFile(m_pMapping);
}
if (m_hOldFont) {
DeleteFont(SelectFont(m_hdc, m_hOldFont));
}
if (m_hdc) {
DeleteDC(m_hdc);
}
}
FT_Face GetFace()
{
FT_Face face = m_ftFace;
m_ftFace = NULL;
return face;
}
};