// 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, 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, #else public CComTearOffObjectBase, #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_