317 lines
10 KiB
C++
317 lines
10 KiB
C++
// MLFLink.h : Declaration of the CMLFLink
|
|
|
|
#ifndef __MLFLINK_H_
|
|
#define __MLFLINK_H_
|
|
|
|
#include "mlatl.h"
|
|
#include "font.h"
|
|
|
|
#define NUMFONTMAPENTRIES 15
|
|
|
|
// Error Code
|
|
#define FACILITY_MLSTR 0x0A15
|
|
#define MLSTR_E_FACEMAPPINGFAILURE MAKE_HRESULT(1, FACILITY_MLSTR, 1001)
|
|
|
|
|
|
extern FONTINFO *g_pfont_table;
|
|
|
|
|
|
class CMultiLanguage;
|
|
class CMultiLanguage2;
|
|
|
|
// Code Page Table Cache
|
|
struct CCodePagesHeader
|
|
{
|
|
DWORD m_dwID;
|
|
DWORD m_dwVersion;
|
|
DWORD m_dwFileSize;
|
|
DWORD m_dwBlockSize;
|
|
DWORD m_dwTableOffset;
|
|
DWORD m_dwReserved;
|
|
BYTE m_abCmdCode[8];
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMLFLink
|
|
class ATL_NO_VTABLE CMLFLink :
|
|
public CComTearOffObjectBase<CMultiLanguage>,
|
|
public IMLangFontLink
|
|
{
|
|
friend void CMLangFontLink_FreeGlobalObjects(void);
|
|
friend HRESULT GetCharCodePagesEx(WCHAR chSrc, DWORD* pdwCodePages, DWORD dwFlags);
|
|
friend HRESULT GetStrCodePagesEx(const WCHAR* pszSrc, long cchSrc, DWORD dwPriorityCodePages, DWORD* pdwCodePages, long* pcchCodePages, DWORD dwFlags);
|
|
friend HRESULT CodePageToCodePagesEx(UINT uCodePage, DWORD* pdwCodePages, DWORD* pdwCodePagesExt);
|
|
friend HRESULT CodePagesToCodePageEx(DWORD dwCodePages, UINT uDefaultCodePage, UINT* puCodePage, BOOL bCodePagesExt);
|
|
|
|
public:
|
|
CMLFLink(void);
|
|
~CMLFLink(void)
|
|
{
|
|
if (m_pFlinkTable)
|
|
FreeFlinkTable();
|
|
DllRelease();
|
|
}
|
|
|
|
DECLARE_NO_REGISTRY()
|
|
|
|
BEGIN_COM_MAP(CMLFLink)
|
|
COM_INTERFACE_ENTRY(IMLangCodePages)
|
|
COM_INTERFACE_ENTRY(IMLangFontLink)
|
|
END_COM_MAP()
|
|
|
|
public:
|
|
// IMLangCodePages
|
|
STDMETHOD(GetCharCodePages)(/*[in]*/ WCHAR chSrc, /*[out]*/ DWORD* pdwCodePages);
|
|
STDMETHOD(GetStrCodePages)(/*[in, size_is(cchSrc)]*/ const WCHAR* pszSrc, /*[in]*/ long cchSrc, /*[in]*/ DWORD dwPriorityCodePages, /*[out]*/ DWORD* pdwCodePages, /*[out]*/ long* pcchCodePages);
|
|
STDMETHOD(CodePageToCodePages)(/*[in]*/ UINT uCodePage, /*[out]*/ DWORD* pdwCodePages);
|
|
STDMETHOD(CodePagesToCodePage)(/*[in]*/ DWORD dwCodePages, /*[in]*/ UINT uDefaultCodePage, /*[out]*/ UINT* puCodePage);
|
|
// IMLangFontLink
|
|
STDMETHOD(GetFontCodePages)(/*[in]*/ HDC hDC, /*[in]*/ HFONT hFont, /*[out]*/ DWORD* pdwCodePages);
|
|
STDMETHOD(MapFont)(/*[in]*/ HDC hDC, /*[in]*/ DWORD dwCodePages, /*[in]*/ HFONT hSrcFont, /*[out]*/ HFONT* phDestFont);
|
|
STDMETHOD(ReleaseFont)(/*[in]*/ HFONT hFont);
|
|
STDMETHOD(ResetFontMapping)(void);
|
|
|
|
protected:
|
|
static int CALLBACK GetFontCodePagesEnumFontProc(const LOGFONT *lplf, const TEXTMETRIC *lptm, DWORD dwFontType, LPARAM lParam);
|
|
|
|
// MapFont() support functions
|
|
class CFontMappingInfo
|
|
{
|
|
public:
|
|
CFontMappingInfo(void) : hDestFont(NULL) {}
|
|
~CFontMappingInfo(void) {if (hDestFont) ::DeleteObject(hDestFont);}
|
|
|
|
HDC hDC;
|
|
int iCP;
|
|
HFONT hDestFont;
|
|
TCHAR szFaceName[LF_FACESIZE];
|
|
LOGFONT lfSrcFont;
|
|
LOGFONT lfDestFont;
|
|
UINT auCodePage[32 + 1]; // +1 for end mark
|
|
DWORD adwCodePages[32 + 1];
|
|
};
|
|
|
|
typedef HRESULT (CMLFLink::*PFNGETFACENAME)(CFontMappingInfo& fmi);
|
|
|
|
HRESULT MapFontCodePages(CFontMappingInfo& fmi, PFNGETFACENAME pfnGetFaceName);
|
|
static int CALLBACK MapFontEnumFontProc(const LOGFONT* lplf, const TEXTMETRIC*, DWORD, LPARAM lParam);
|
|
HRESULT GetFaceNameRegistry(CFontMappingInfo& fmi);
|
|
HRESULT GetFaceNameGDI(CFontMappingInfo& fmi);
|
|
HRESULT GetFaceNameMIME(CFontMappingInfo& fmi);
|
|
HRESULT GetFaceNameRealizeFont(CFontMappingInfo& fmi);
|
|
HRESULT VerifyFaceMap(CFontMappingInfo& fmi);
|
|
|
|
// Font Mapping Cache
|
|
class CFontMappingCache
|
|
{
|
|
class CFontMappingCacheEntry
|
|
{
|
|
friend class CFontMappingCache;
|
|
|
|
protected:
|
|
CFontMappingCacheEntry* m_pPrev;
|
|
CFontMappingCacheEntry* m_pNext;
|
|
|
|
int m_nLockCount;
|
|
|
|
UINT m_uSrcCodePage;
|
|
LONG m_lSrcHeight;
|
|
LONG m_lSrcWidth;
|
|
LONG m_lSrcEscapement;
|
|
LONG m_lSrcOrientation;
|
|
LONG m_lSrcWeight;
|
|
BYTE m_bSrcItalic;
|
|
BYTE m_bSrcUnderline;
|
|
BYTE m_bSrcStrikeOut;
|
|
BYTE m_bSrcPitchAndFamily;
|
|
TCHAR m_szSrcFaceName[LF_FACESIZE];
|
|
|
|
HFONT m_hDestFont;
|
|
};
|
|
|
|
public:
|
|
CFontMappingCache(void);
|
|
~CFontMappingCache(void);
|
|
HRESULT FindEntry(UINT uCodePage, const LOGFONT& lfSrcFont, HFONT* phDestFont);
|
|
HRESULT UnlockEntry(HFONT hDestFont);
|
|
HRESULT AddEntry(UINT uCodePage, const LOGFONT& lfSrcFont, HFONT hDestFont);
|
|
HRESULT FlushEntries(void);
|
|
|
|
protected:
|
|
CRITICAL_SECTION m_cs;
|
|
CFontMappingCacheEntry* m_pEntries;
|
|
CFontMappingCacheEntry* m_pFree;
|
|
int m_cEntries;
|
|
};
|
|
|
|
// Code Page Table Cache
|
|
class CCodePagesCache
|
|
{
|
|
public:
|
|
CCodePagesCache(void);
|
|
~CCodePagesCache(void);
|
|
inline HRESULT Load(void);
|
|
inline operator PBYTE(void) const;
|
|
inline BYTE* GetCodePageBits(BOOL bCodePagesExt);
|
|
|
|
protected:
|
|
HRESULT RealLoad(void);
|
|
|
|
protected:
|
|
CRITICAL_SECTION m_cs;
|
|
BYTE* m_pbBuf;
|
|
BYTE* m_pbBufExt;
|
|
};
|
|
|
|
static CFontMappingCache* m_pFontMappingCache;
|
|
static CCodePagesCache* m_pCodePagesCache;
|
|
|
|
// For NT5 system font link
|
|
typedef struct tagFLinkFont {
|
|
WCHAR szFaceName[LF_FACESIZE];
|
|
LPWSTR pmszFaceName;
|
|
} FLINKFONT, *PFLINKFONT;
|
|
|
|
UINT m_uiFLinkFontNum;
|
|
PFLINKFONT m_pFlinkTable;
|
|
|
|
void FreeFlinkTable(void);
|
|
HRESULT CreateNT5FontLinkTable(void);
|
|
HRESULT GetNT5FLinkFontCodePages(HDC hDC, LOGFONTW* plfEnum, DWORD * lpdwCodePages);
|
|
static int CALLBACK GetFontCodePagesEnumFontProcW(const LOGFONTW *lplf, const TEXTMETRICW *lptm, DWORD dwFontType, LPARAM lParam);
|
|
static int CALLBACK VerifyFontSizeEnumFontProc(const LOGFONT *lplf, const TEXTMETRIC *lptm, DWORD dwFontType, LPARAM lParam);
|
|
};
|
|
|
|
class CMultiLanguage2;
|
|
|
|
class ATL_NO_VTABLE CMLFLink2 :
|
|
#ifdef UNIX // Unix VTable isn't portable, we need to use CMultiLanguage
|
|
public CComTearOffObjectBase<CMultiLanguage>,
|
|
#else
|
|
public CComTearOffObjectBase<CMultiLanguage2>,
|
|
#endif
|
|
public IMLangFontLink2
|
|
{
|
|
IMLangFontLink * m_pIMLFLnk;
|
|
|
|
public:
|
|
BEGIN_COM_MAP(CMLFLink2)
|
|
COM_INTERFACE_ENTRY(IMLangFontLink2)
|
|
END_COM_MAP()
|
|
|
|
CMLFLink2(void)
|
|
{
|
|
DllAddRef();
|
|
CComCreator< CComPolyObject< CMLFLink > >::CreateInstance( NULL, IID_IMLangFontLink, (void **)&m_pIMLFLnk );
|
|
}
|
|
|
|
~CMLFLink2(void)
|
|
{
|
|
if (m_pIMLFLnk)
|
|
{
|
|
m_pIMLFLnk->Release();
|
|
m_pIMLFLnk = NULL;
|
|
}
|
|
DllRelease();
|
|
}
|
|
|
|
// IMLangCodePages
|
|
STDMETHOD(GetCharCodePages)(/*[in]*/ WCHAR chSrc, /*[out]*/ DWORD* pdwCodePages)
|
|
{
|
|
if (m_pIMLFLnk)
|
|
return m_pIMLFLnk->GetCharCodePages(chSrc, pdwCodePages);
|
|
else
|
|
return E_FAIL;
|
|
}
|
|
STDMETHOD(CodePageToCodePages)(/*[in]*/ UINT uCodePage, /*[out]*/ DWORD* pdwCodePages)
|
|
{
|
|
if (m_pIMLFLnk)
|
|
return m_pIMLFLnk->CodePageToCodePages(uCodePage, pdwCodePages);
|
|
else
|
|
return E_FAIL;
|
|
}
|
|
STDMETHOD(CodePagesToCodePage)(/*[in]*/ DWORD dwCodePages, /*[in]*/ UINT uDefaultCodePage, /*[out]*/ UINT* puCodePage)
|
|
{
|
|
if (m_pIMLFLnk)
|
|
return m_pIMLFLnk->CodePagesToCodePage(dwCodePages, uDefaultCodePage, puCodePage);
|
|
else
|
|
return E_FAIL;
|
|
}
|
|
// IMLangFontLink
|
|
STDMETHOD(GetFontCodePages)(/*[in]*/ HDC hDC, /*[in]*/ HFONT hFont, /*[out]*/ DWORD* pdwCodePages)
|
|
{
|
|
if (m_pIMLFLnk)
|
|
return m_pIMLFLnk->GetFontCodePages(hDC, hFont, pdwCodePages);
|
|
else
|
|
return E_FAIL;
|
|
}
|
|
|
|
STDMETHOD(ReleaseFont)(/*[in]*/ HFONT hFont)
|
|
{
|
|
if (m_pIMLFLnk)
|
|
return m_pIMLFLnk->ReleaseFont(hFont);
|
|
else
|
|
return E_FAIL;
|
|
}
|
|
|
|
// IMLangFontLink2
|
|
STDMETHOD(ResetFontMapping)(void);
|
|
STDMETHOD(GetStrCodePages)(/*[in, size_is(cchSrc)]*/ const WCHAR* pszSrc, /*[in]*/ long cchSrc, /*[in]*/ DWORD dwPriorityCodePages, /*[out]*/ DWORD* pdwCodePages, /*[out]*/ long* pcchCodePages);
|
|
STDMETHOD(MapFont)(/*[in]*/ HDC hDC, /*[in]*/ DWORD dwCodePages, /*[in]*/ WCHAR chSrc, /*[out]*/ HFONT* pFont);
|
|
STDMETHOD(GetFontUnicodeRanges)(/*[in]*/ HDC hDC, /*[in,out]*/ UINT *puiRanges, /*[out]*/ UNICODERANGE* pUranges);
|
|
STDMETHOD(GetScriptFontInfo)(SCRIPT_ID sid, DWORD dwFlags, UINT *puiFonts, SCRIPTFONTINFO* pScriptFont);
|
|
STDMETHOD(CodePageToScriptID)(UINT uiCodePage, SCRIPT_ID *pSid);
|
|
|
|
// Font Mapping Cache2 for MapFont
|
|
class CFontMappingCache2
|
|
{
|
|
protected:
|
|
TCHAR szFontDataFilePath[MAX_PATH];
|
|
public:
|
|
CFontMappingCache2(void);
|
|
~CFontMappingCache2(void);
|
|
int fetchCharSet(BYTE *pCharset, int iURange);
|
|
BOOL GetNonCpFontUnicodeRanges(TCHAR *szFontName, int iFontIndex);
|
|
BOOL SetFontScripts(void);
|
|
BOOL SetFontTable(void);
|
|
BOOL GetFontURangeBits(TCHAR *szFontName, DWORD *pdwURange);
|
|
BOOL IsFontUpdated(void);
|
|
HRESULT UnicodeRanges(LPTSTR pszFont, UINT *puiRanges, UNICODERANGE* pURanges);
|
|
HRESULT SetFontUnicodeRanges(void);
|
|
HRESULT MapFontFromCMAP(HDC hDC, WCHAR wchar, HFONT hSrcFont, HFONT *phDestFont);
|
|
HRESULT LoadFontDataFile(void);
|
|
HRESULT SaveFontDataFile(void);
|
|
HRESULT EnsureFontTable(BOOL bUpdateURangeTable);
|
|
static int CALLBACK MapFontExEnumFontProc(const LOGFONT* plfFont, const TEXTMETRIC* lptm, DWORD FontType, LPARAM lParam);
|
|
static int CALLBACK SetFontScriptsEnumFontProc(const LOGFONT* plfFont, const TEXTMETRIC* lptm, DWORD FontType, LPARAM lParam);
|
|
};
|
|
|
|
static CFontMappingCache2* m_pFontMappingCache2;
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMLFLink inline functions
|
|
|
|
HRESULT CMLFLink::CCodePagesCache::Load(void)
|
|
{
|
|
if (m_pbBuf && m_pbBufExt)
|
|
return S_OK;
|
|
else
|
|
return RealLoad();
|
|
}
|
|
|
|
BYTE * CMLFLink::CCodePagesCache::GetCodePageBits(BOOL bCodePagesExt)
|
|
{
|
|
if (bCodePagesExt)
|
|
return m_pbBufExt;
|
|
else
|
|
return m_pbBuf;
|
|
}
|
|
|
|
CMLFLink::CCodePagesCache::operator PBYTE(void) const
|
|
{
|
|
return m_pbBuf;
|
|
}
|
|
|
|
#endif //__MLFLINK_H_
|