2016-09-02 17:29:33 +08:00
|
|
|
|
// override.cpp - <20>L<EFBFBD><4C><EFBFBD>C<EFBFBD><43>TextOut
|
|
|
|
|
// 2006/09/27
|
|
|
|
|
|
|
|
|
|
#include "override.h"
|
|
|
|
|
#include "ft.h"
|
|
|
|
|
#include "fteng.h"
|
|
|
|
|
#include "supinfo.h"
|
|
|
|
|
#include "undocAPI.h"
|
|
|
|
|
|
|
|
|
|
#include <malloc.h> // _alloca
|
|
|
|
|
#include <mbctype.h> // _getmbcp
|
|
|
|
|
|
|
|
|
|
#pragma comment(lib, "Gdi32.lib")
|
|
|
|
|
#pragma comment(lib, "User32.lib")
|
|
|
|
|
#pragma comment(lib, "WindowsCodecs.lib")
|
|
|
|
|
#pragma comment (lib, "dwrite.lib")
|
|
|
|
|
|
|
|
|
|
#if defined(_DEBUG)
|
|
|
|
|
void Dbg_TractGetTextExtent(LPCSTR lpString, int cbString, LPSIZE lpSize);
|
|
|
|
|
void Dbg_TractGetTextExtent(LPCWSTR lpString, int cbString, LPSIZE lpSize);
|
|
|
|
|
void Dbg_TraceExtTextOutW(int nXStart, int nYStart, UINT fuOptions, LPCWSTR lpString, int cbString, const int* lpDx);
|
|
|
|
|
void Dbg_TraceScriptItemize(const WCHAR* pwcInChars, int cInChars);
|
|
|
|
|
void Dbg_TraceScriptShape(const WCHAR* pwcChars, int cChars, const SCRIPT_ANALYSIS* psa, const WORD* pwOutGlyphs, int cGlyphs);
|
|
|
|
|
#else
|
|
|
|
|
#define Dbg_TraceExtTextOutW(x,y,f,s,c,p)
|
|
|
|
|
#define Dbg_TractGetTextExtent(s,c,p)
|
|
|
|
|
#define Dbg_TraceScriptItemize(s,c)
|
|
|
|
|
#define Dbg_TraceScriptShape(s,c,p,g,o)
|
|
|
|
|
#endif
|
|
|
|
|
#define CCH_MAX_STACK 256
|
|
|
|
|
|
|
|
|
|
typedef HRESULT (WINAPI * __D2D1CreateFactory)(
|
|
|
|
|
D2D1_FACTORY_TYPE factoryType,
|
|
|
|
|
REFIID riid,
|
|
|
|
|
const D2D1_FACTORY_OPTIONS *pFactoryOptions,
|
|
|
|
|
void **ppIFactory);
|
|
|
|
|
typedef HRESULT (WINAPI* __DWriteCreateFactory)(
|
|
|
|
|
__in DWRITE_FACTORY_TYPE factoryType,
|
|
|
|
|
__in REFIID iid,
|
|
|
|
|
__out IUnknown **factory
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CFontCache FontCache;
|
|
|
|
|
CDCArray DCArray;
|
|
|
|
|
wstring nullstring;
|
|
|
|
|
CHashedStringList FontNameList(256, true);//snowie!!
|
|
|
|
|
BOOL g_ccbRender = true;
|
|
|
|
|
BOOL g_ccbCache = true;
|
|
|
|
|
HFONT g_alterGUIFont = NULL;
|
|
|
|
|
HFONT g_alterSysFont = NULL;
|
|
|
|
|
|
|
|
|
|
//BOOL FreeTypeGetTextExtentPoint(HDC hdc, LPCSTR lpString, int cbString, LPSIZE lpSize, const FREETYPE_PARAMS* params);
|
|
|
|
|
|
|
|
|
|
HFONT GetCurrentFont(HDC hdc)
|
|
|
|
|
{
|
|
|
|
|
HFONT hCurFont = (HFONT)GetCurrentObject(hdc, OBJ_FONT);
|
|
|
|
|
if (!hCurFont) {
|
|
|
|
|
// NULL<4C>̏ꍇ<CC8F><EA8D87>System<65><6D><EFBFBD>ݒ肵<DD92>Ă<EFBFBD><C482><EFBFBD>
|
|
|
|
|
hCurFont = (HFONT)GetStockObject(SYSTEM_FONT);
|
|
|
|
|
}
|
|
|
|
|
return hCurFont;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<2F>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>ͨ<EFBFBD><CDA8>ʾDC<44><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ
|
|
|
|
|
BOOL IsValidDC(HDC hdc)
|
|
|
|
|
{
|
|
|
|
|
if (GetDeviceCaps(hdc, TECHNOLOGY) != DT_RASDISPLAY) {
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL IsProcessExcluded()
|
|
|
|
|
{
|
|
|
|
|
// if (GetModuleHandle(NULL) == GetModuleHandle(_T("gdi++.exe"))) {
|
|
|
|
|
// return TRUE;
|
|
|
|
|
// }
|
|
|
|
|
|
2016-09-27 15:02:20 +08:00
|
|
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstanceNoInit();
|
2016-09-02 17:29:33 +08:00
|
|
|
|
if (pSettings->IsInclude()) {
|
|
|
|
|
if (pSettings->IsProcessIncluded()) {
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pSettings->IsProcessExcluded()) {
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL IsProcessUnload()
|
|
|
|
|
{
|
|
|
|
|
// if (GetModuleHandle(NULL) == GetModuleHandle(_T("gdi++.exe"))) {
|
|
|
|
|
// return TRUE;
|
|
|
|
|
// }
|
|
|
|
|
|
2016-09-27 15:02:20 +08:00
|
|
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstanceNoInit();
|
2016-09-02 17:29:33 +08:00
|
|
|
|
if (pSettings->IsInclude()) {
|
|
|
|
|
if (pSettings->IsProcessIncluded()) {
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pSettings->IsProcessUnload()) {
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL IsExeUnload(LPCTSTR lpApp)
|
|
|
|
|
{
|
2016-09-27 15:02:20 +08:00
|
|
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstanceNoInit();
|
2016-09-02 17:29:33 +08:00
|
|
|
|
if (pSettings->IsInclude()) {
|
|
|
|
|
if (pSettings->IsExeInclude(lpApp)) {
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pSettings->IsExeUnload(lpApp)) {
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<2F><EFBFBD><D882>グ<EFBFBD><E382B0><EFBFBD>Z
|
|
|
|
|
int div_ceil(int a, int b)
|
|
|
|
|
{
|
|
|
|
|
if(a % b)
|
|
|
|
|
return (a>0)? (a/b+1): (a/b-1);
|
|
|
|
|
return a / b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename _TCHAR> //<2F><EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD>ʧ<EFBFBD>ܵ<EFBFBD>ʱ<EFBFBD><EFBFBD>false<73><65><EFBFBD>ɵ<EFBFBD><C9B5><EFBFBD><EFBFBD>߸<EFBFBD><DFB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Windowsԭ<73><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD>̰߳<DFB3>ȫ<EFBFBD><C8AB>
|
|
|
|
|
BOOL _GetTextExtentPoint32AorW(HDC hdc, _TCHAR* lpString, int cbString, LPSIZE lpSize)
|
|
|
|
|
{
|
|
|
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|
|
|
|
if (pSettings->WidthMode() == SETTING_WIDTHMODE_GDI32
|
|
|
|
|
|| !IsValidDC(hdc) || !lpString || cbString <= 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FREETYPE_PARAMS params(0, hdc);
|
|
|
|
|
|
|
|
|
|
if(FreeTypeGetTextExtentPoint(hdc, lpString, cbString, lpSize, ¶ms)) {
|
|
|
|
|
Dbg_TractGetTextExtent(lpString, cbString, lpSize);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//firefox
|
|
|
|
|
/*
|
|
|
|
|
BOOL WINAPI IMPL_GetTextExtentPoint32A(HDC hdc, LPCSTR lpString, int cbString, LPSIZE lpSize)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
//CCriticalSectionLock __lock;
|
|
|
|
|
return _GetTextExtentPoint32AorW(hdc, lpString, cbString, lpSize) || ORIG_GetTextExtentPoint32A(hdc, lpString, cbString, lpSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_GetTextExtentPoint32W(HDC hdc, LPCWSTR lpString, int cbString, LPSIZE lpSize)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
//CCriticalSectionLock __lock;
|
|
|
|
|
return _GetTextExtentPoint32AorW(hdc, lpString, cbString, lpSize) || ORIG_GetTextExtentPoint32W(hdc, lpString, cbString, lpSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_GetTextExtentPointA(HDC hdc, LPCSTR lpString, int cbString, LPSIZE lpSize)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
//CCriticalSectionLock __lock;
|
|
|
|
|
return _GetTextExtentPoint32AorW(hdc, lpString, cbString, lpSize) || ORIG_GetTextExtentPoint32A(hdc, lpString, cbString, lpSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_GetTextExtentPointW(HDC hdc, LPCWSTR lpString, int cbString, LPSIZE lpSize)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
//CCriticalSectionLock __lock;
|
|
|
|
|
return _GetTextExtentPoint32AorW(hdc, lpString, cbString, lpSize) || ORIG_GetTextExtentPoint32W(hdc, lpString, cbString, lpSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_GetCharWidthW(HDC hdc, UINT iFirstChar, UINT iLastChar, LPINT lpBuffer)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|
|
|
|
if (pSettings->WidthMode() == SETTING_WIDTHMODE_GDI32
|
|
|
|
|
|| !IsValidDC(hdc) || !lpBuffer || !FreeTypeGetCharWidth(hdc, iFirstChar, iLastChar, lpBuffer)) {
|
|
|
|
|
return ORIG_GetCharWidthW(hdc, iFirstChar, iLastChar, lpBuffer);
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_GetCharWidth32W(HDC hdc, UINT iFirstChar, UINT iLastChar, LPINT lpBuffer)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
TRACE(_T("GetCharWidth32W(%u, %u, {...})\n"), iFirstChar, iLastChar);
|
|
|
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|
|
|
|
if (pSettings->WidthMode() == SETTING_WIDTHMODE_GDI32
|
|
|
|
|
|| !IsValidDC(hdc) || !lpBuffer || !FreeTypeGetCharWidth(hdc, iFirstChar, iLastChar, lpBuffer)) {
|
|
|
|
|
return ORIG_GetCharWidth32W(hdc, iFirstChar, iLastChar, lpBuffer);
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}*/
|
|
|
|
|
/*
|
|
|
|
|
extern PFNLdrGetProcedureAddress LdrGetProcedureAddress;
|
|
|
|
|
int MyGetProcAddress(HMODULE dll, LPSTR funcname)
|
|
|
|
|
{
|
|
|
|
|
ANSI_STRING dumy;
|
|
|
|
|
dumy.Length = strlen(funcname);
|
|
|
|
|
dumy.MaximumLength = strlen(funcname);
|
|
|
|
|
dumy.Buffer = funcname;
|
|
|
|
|
int nRet;
|
|
|
|
|
LdrGetProcedureAddress(dll,&dumy,0,(void**)&nRet);
|
|
|
|
|
return nRet;
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
LONG WINAPI IMPL_LdrLoadDll(IN PWCHAR PathToFile OPTIONAL, IN ULONG Flags OPTIONAL, IN UNICODE_STRING2* ModuleFileName, OUT HANDLE* ModuleHandle)
|
|
|
|
|
{
|
|
|
|
|
static bool bFisrtTimeHook = GetModuleHandle(_T("d2d1.dll"))!=0;
|
|
|
|
|
if (!bD2D1Loaded)
|
|
|
|
|
{
|
|
|
|
|
wstring filename = wstring(ModuleFileName->Buffer);
|
|
|
|
|
int last_slash=filename.find_last_of('\\');
|
|
|
|
|
if (last_slash!=-1)
|
|
|
|
|
filename.erase(0,last_slash+1); //ɾ<><C9BE>·<EFBFBD><C2B7>
|
|
|
|
|
if (_wcsicmp(filename.c_str(), L"d2d1.dll")==0) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>d2d1.dll
|
|
|
|
|
{
|
|
|
|
|
bD2D1Loaded = true;
|
|
|
|
|
LONG result = ORIG_LdrLoadDll(PathToFile, Flags, ModuleFileName, ModuleHandle);
|
|
|
|
|
HookD2D1((HMODULE)*ModuleHandle);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
if (bFisrtTimeHook)
|
|
|
|
|
{
|
|
|
|
|
bFisrtTimeHook = false;
|
|
|
|
|
bD2D1Loaded = true;
|
|
|
|
|
HookD2D1(GetModuleHandle(_T("d2d1.dll")));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ORIG_LdrLoadDll(PathToFile, Flags, ModuleFileName, ModuleHandle);
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
2017-03-23 10:18:56 +08:00
|
|
|
|
/*
|
2016-09-02 17:29:33 +08:00
|
|
|
|
BOOL WINAPI IMPL_CreateProcessInternalW( HANDLE hToken, LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, \
|
|
|
|
|
DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation , PHANDLE hNewToken)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
CCriticalSectionLock __lock;
|
|
|
|
|
return _CreateProcessInternalW(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation, hNewToken, ORIG_CreateProcessInternalW);
|
2017-03-23 10:18:56 +08:00
|
|
|
|
}*/
|
2016-09-02 17:29:33 +08:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
BOOL WINAPI IMPL_nCreateProcessA(LPCSTR lpApp, LPSTR lpCmd, LPSECURITY_ATTRIBUTES pa, LPSECURITY_ATTRIBUTES ta, BOOL bInherit, DWORD dwFlags, LPVOID lpEnv, LPCSTR lpDir, LPSTARTUPINFOA psi, LPPROCESS_INFORMATION ppi)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
CCriticalSectionLock __lock;
|
|
|
|
|
TRACE(_T("CreateProcessA(\"%hs\", \"%hs\", ...)\n"), lpApp, lpCmd);
|
|
|
|
|
return _CreateProcessAorW(lpApp, lpCmd, pa, ta, bInherit, dwFlags, lpEnv, lpDir, psi, ppi, ORIG_nCreateProcessA);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_nCreateProcessW(LPCWSTR lpApp, LPWSTR lpCmd, LPSECURITY_ATTRIBUTES pa, LPSECURITY_ATTRIBUTES ta, BOOL bInherit, DWORD dwFlags, LPVOID lpEnv, LPCWSTR lpDir, LPSTARTUPINFOW psi, LPPROCESS_INFORMATION ppi)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
CCriticalSectionLock __lock;
|
|
|
|
|
TRACE(_T("CreateProcessW(\"%ls\", \"%ls\", ...)\n"), lpApp, lpCmd);
|
|
|
|
|
return _CreateProcessAorW(lpApp, lpCmd, pa, ta, bInherit, dwFlags, lpEnv, lpDir, psi, ppi, ORIG_nCreateProcessW);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_CreateProcessAsUserA(HANDLE hToken, LPCSTR lpApp, LPSTR lpCmd, LPSECURITY_ATTRIBUTES pa, LPSECURITY_ATTRIBUTES ta, BOOL bInherit, DWORD dwFlags, LPVOID lpEnv, LPCSTR lpDir, LPSTARTUPINFOA psi, LPPROCESS_INFORMATION ppi)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
CCriticalSectionLock __lock;
|
|
|
|
|
TRACE(_T("CreateProcessA(\"%hs\", \"%hs\", ...)\n"), lpApp, lpCmd);
|
|
|
|
|
return _CreateProcessAsUserAorW(hToken, lpApp, lpCmd, pa, ta, bInherit, dwFlags, lpEnv, lpDir, psi, ppi, ORIG_CreateProcessAsUserA);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_CreateProcessAsUserW(HANDLE hToken, LPCWSTR lpApp, LPWSTR lpCmd, LPSECURITY_ATTRIBUTES pa, LPSECURITY_ATTRIBUTES ta, BOOL bInherit, DWORD dwFlags, LPVOID lpEnv, LPCWSTR lpDir, LPSTARTUPINFOW psi, LPPROCESS_INFORMATION ppi)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
CCriticalSectionLock __lock;
|
|
|
|
|
TRACE(_T("CreateProcessW(\"%ls\", \"%ls\", ...)\n"), lpApp, lpCmd);
|
|
|
|
|
return _CreateProcessAsUserAorW(hToken, lpApp, lpCmd, pa, ta, bInherit, dwFlags, lpEnv, lpDir, psi, ppi, ORIG_CreateProcessAsUserW);
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
HOOK_DEFINE(user32.dll, DWORD, GetTabbedTextExtentA, (HDC hdc, LPCSTR lpString, int nCount, int nTabPositions, CONST LPINT lpnTabStopPositions), (hdc, lpString, nCount, nTabPositions, lpnTabStopPositions))
|
|
|
|
|
HOOK_DEFINE(user32.dll, DWORD, GetTabbedTextExtentW, (HDC hdc, LPCWSTR lpString, int nCount, int nTabPositions, CONST LPINT lpnTabStopPositions), (hdc, lpString, nCount, nTabPositions, lpnTabStopPositions))
|
|
|
|
|
HOOK_DEFINE(gdi32.dll, BOOL, GetTextExtentExPointA, (HDC hdc, LPCSTR lpszStr, int cchString, int nMaxExtent, LPINT lpnFit, LPINT lpDx, LPSIZE lpSize), (hdc, lpszStr, cchString, nMaxExtent, lpnFit, lpDx, lpSize))
|
|
|
|
|
HOOK_DEFINE(gdi32.dll, BOOL, GetTextExtentExPointW, (HDC hdc, LPCWSTR lpszStr, int cchString, int nMaxExtent, LPINT lpnFit, LPINT lpDx, LPSIZE lpSize), (hdc, lpszStr, cchString, nMaxExtent, lpnFit, lpDx, lpSize))
|
|
|
|
|
HOOK_DEFINE(gdi32.dll, BOOL, GetTextExtentExPointI, (HDC hdc, LPWORD pgiIn, int cgi, int nMaxExtent, LPINT lpnFit, LPINT lpDx, LPSIZE lpSize), (hdc, pgiIn, cgi, nMaxExtent, lpnFit, lpDx, lpSize))
|
|
|
|
|
HOOK_DEFINE(gdi32.dll, BOOL, GetTextExtentPointA, (HDC hdc, LPCSTR lpString, int cbString, LPSIZE lpSize), (hdc, lpString, cbString, lpSize))
|
|
|
|
|
HOOK_DEFINE(gdi32.dll, BOOL, GetTextExtentPointW, (HDC hdc, LPCWSTR lpString, int cbString, LPSIZE lpSize), (hdc, lpString, cbString, lpSize))
|
|
|
|
|
HOOK_DEFINE(gdi32.dll, BOOL, GetTextExtentPointI, (HDC hdc, LPWORD pgiIn, int cgi, LPSIZE lpSize), (hdc, pgiIn, cgi, lpSize))
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
HFONT WINAPI IMPL_CreateFontA(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD fdwCharSet, DWORD fdwOutputPrecision, DWORD fdwClipPrecision, DWORD fdwQuality, DWORD fdwPitchAndFamily, LPCSTR lpszFace)
|
|
|
|
|
{
|
|
|
|
|
LOGFONTA lf = {
|
|
|
|
|
nHeight,
|
|
|
|
|
nWidth,
|
|
|
|
|
nEscapement,
|
|
|
|
|
nOrientation,
|
|
|
|
|
fnWeight,
|
|
|
|
|
!!fdwItalic,
|
|
|
|
|
!!fdwUnderline,
|
|
|
|
|
!!fdwStrikeOut,
|
|
|
|
|
(BYTE)fdwCharSet,
|
|
|
|
|
(BYTE)fdwOutputPrecision,
|
|
|
|
|
(BYTE)fdwClipPrecision,
|
|
|
|
|
(BYTE)fdwQuality,
|
|
|
|
|
(BYTE)fdwPitchAndFamily,
|
|
|
|
|
};
|
|
|
|
|
if (lpszFace)
|
|
|
|
|
strncpy(lf.lfFaceName, lpszFace, LF_FACESIZE - 1);
|
|
|
|
|
return IMPL_CreateFontIndirectA(&lf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HFONT WINAPI IMPL_CreateFontW(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD fdwCharSet, DWORD fdwOutputPrecision, DWORD fdwClipPrecision, DWORD fdwQuality, DWORD fdwPitchAndFamily, LPCWSTR lpszFace)
|
|
|
|
|
{
|
|
|
|
|
LOGFONTW lf = {
|
|
|
|
|
nHeight,
|
|
|
|
|
nWidth,
|
|
|
|
|
nEscapement,
|
|
|
|
|
nOrientation,
|
|
|
|
|
fnWeight,
|
|
|
|
|
!!fdwItalic,
|
|
|
|
|
!!fdwUnderline,
|
|
|
|
|
!!fdwStrikeOut,
|
|
|
|
|
(BYTE)fdwCharSet,
|
|
|
|
|
(BYTE)fdwOutputPrecision,
|
|
|
|
|
(BYTE)fdwClipPrecision,
|
|
|
|
|
(BYTE)fdwQuality,
|
|
|
|
|
(BYTE)fdwPitchAndFamily,
|
|
|
|
|
};
|
|
|
|
|
if (lpszFace)
|
|
|
|
|
wcsncpy(lf.lfFaceName, lpszFace, LF_FACESIZE - 1);
|
|
|
|
|
return IMPL_CreateFontIndirectW(&lf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HFONT WINAPI IMPL_CreateFontIndirectA(CONST LOGFONTA *lplfA)
|
|
|
|
|
{
|
|
|
|
|
if(!lplfA) {
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|
|
|
|
if (pSettings->IsFontExcluded(lplfA->lfFaceName)) {
|
|
|
|
|
return ORIG_CreateFontIndirectA(lplfA);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LOGFONT lf = {
|
|
|
|
|
lplfA->lfHeight,
|
|
|
|
|
lplfA->lfWidth,
|
|
|
|
|
lplfA->lfEscapement,
|
|
|
|
|
lplfA->lfOrientation,
|
|
|
|
|
lplfA->lfWeight,
|
|
|
|
|
lplfA->lfItalic,
|
|
|
|
|
lplfA->lfUnderline,
|
|
|
|
|
lplfA->lfStrikeOut,
|
|
|
|
|
lplfA->lfCharSet,
|
|
|
|
|
lplfA->lfOutPrecision,
|
|
|
|
|
lplfA->lfClipPrecision,
|
|
|
|
|
lplfA->lfQuality,
|
|
|
|
|
lplfA->lfPitchAndFamily,
|
|
|
|
|
};
|
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, lplfA->lfFaceName, LF_FACESIZE, lf.lfFaceName, LF_FACESIZE);
|
|
|
|
|
|
|
|
|
|
LOGFONT* lplf = &lf;
|
|
|
|
|
if (pSettings->CopyForceFont(lf, lf)) {
|
|
|
|
|
lplf = &lf;
|
|
|
|
|
}
|
|
|
|
|
HFONT hf = IMPL_CreateFontIndirectW(lplf);
|
|
|
|
|
// if(hf && lplf && !pSettings->LoadOnDemand()) {
|
|
|
|
|
// AddFontToFT(lplf->lfFaceName, lplf->lfWeight, !!lplf->lfItalic);
|
|
|
|
|
// }
|
|
|
|
|
return hf;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
//Snowie!!
|
|
|
|
|
LPCWSTR GetCachedFont(HFONT lFont)
|
|
|
|
|
{
|
|
|
|
|
CFontCache::const_iterator it= FontCache.find(lFont);
|
|
|
|
|
if (it==FontCache.end())
|
|
|
|
|
return NULL;
|
|
|
|
|
else
|
|
|
|
|
return it->second->lpRealName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPCWSTR GetCachedFontLocale(HFONT lFont)
|
|
|
|
|
{
|
|
|
|
|
CFontCache::const_iterator it= FontCache.find(lFont);
|
|
|
|
|
if (it==FontCache.end())
|
|
|
|
|
return NULL;
|
|
|
|
|
else
|
|
|
|
|
return it->second->lpGDIName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AddToCachedFont(HFONT lfont, LPWSTR lpFaceName, LPWSTR lpGDIName)
|
|
|
|
|
{
|
|
|
|
|
if (!lfont) return; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿսڵ<D5BD>
|
|
|
|
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_CACHEDFONT);
|
|
|
|
|
if (GetCachedFont(lfont)) return; //<2F>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
FontCache[lfont] = new CFontSubResult(lpFaceName, lpGDIName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DeleteCachedFont(HFONT lfont)
|
|
|
|
|
{
|
|
|
|
|
if (!lfont) return; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>
|
|
|
|
|
CCriticalSectionLock __lock(CCriticalSectionLock::CS_CACHEDFONT);
|
|
|
|
|
CFontCache::iterator it= FontCache.find(lfont);
|
|
|
|
|
if (it!=FontCache.end())
|
|
|
|
|
{
|
|
|
|
|
delete it->second;
|
|
|
|
|
FontCache.erase(it);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-08 13:45:52 +08:00
|
|
|
|
int WINAPI IMPL_GetTextFaceAliasW(HDC hdc, int nLen, LPWSTR lpAliasW)
|
2016-09-02 17:29:33 +08:00
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
2016-09-08 13:45:52 +08:00
|
|
|
|
int bResult = ORIG_GetTextFaceAliasW(hdc, nLen, lpAliasW);
|
2016-09-02 17:29:33 +08:00
|
|
|
|
//LOGFONT lf, lf2;
|
|
|
|
|
//StringCchCopy(lf.lfFaceName, LF_FACESIZE, lpAliasW);
|
|
|
|
|
//LOGFONT * lplf = &lf;
|
|
|
|
|
LPCWSTR fontcache=GetCachedFont(GetCurrentFont(hdc));
|
|
|
|
|
if (fontcache){
|
|
|
|
|
StringCchCopy(lpAliasW, LF_FACESIZE, fontcache);
|
|
|
|
|
bResult = wcslen(fontcache)+1;
|
|
|
|
|
}
|
|
|
|
|
return bResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DWORD WINAPI IMPL_GetGlyphOutlineW(__in HDC hdc, __in UINT uChar, __in UINT fuFormat, __out LPGLYPHMETRICS lpgm, __in DWORD cjBuffer, __out_bcount_opt(cjBuffer) LPVOID pvBuffer, __in CONST MAT2 *lpmat2)
|
|
|
|
|
{
|
|
|
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|
|
|
|
DWORD ret= ORIG_GetGlyphOutlineW(hdc, uChar, fuFormat, lpgm, cjBuffer, pvBuffer, lpmat2);
|
|
|
|
|
if (pSettings->EnableClipBoxFix() && (!cjBuffer || !pvBuffer)) {
|
|
|
|
|
if (!(fuFormat & (GGO_BITMAP | GGO_GRAY2_BITMAP | GGO_GRAY4_BITMAP | GGO_GRAY8_BITMAP | GGO_NATIVE))) {
|
|
|
|
|
//lpgm->gmptGlyphOrigin.x -= 1;
|
|
|
|
|
//lpgm->gmptGlyphOrigin.y += 1;
|
|
|
|
|
//lpgm->gmBlackBoxX += 3;
|
|
|
|
|
//lpgm->gmBlackBoxY += 2;
|
2016-09-29 15:37:23 +08:00
|
|
|
|
static int n = (int)ceil(2.0*pSettings->ScreenDpi() / 96);
|
2016-09-23 22:20:33 +08:00
|
|
|
|
lpgm->gmptGlyphOrigin.y += n;
|
|
|
|
|
lpgm->gmBlackBoxY += n*2;
|
2016-09-02 17:29:33 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// TEXTMETRIC tm;
|
|
|
|
|
// GetTextMetrics(hdc, &tm);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DWORD WINAPI IMPL_GetGlyphOutlineA(__in HDC hdc, __in UINT uChar, __in UINT fuFormat, __out LPGLYPHMETRICS lpgm, __in DWORD cjBuffer, __out_bcount_opt(cjBuffer) LPVOID pvBuffer, __in CONST MAT2 *lpmat2)
|
|
|
|
|
{
|
|
|
|
|
//fuFormat |= GGO_UNHINTED;
|
|
|
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|
|
|
|
DWORD ret= ORIG_GetGlyphOutlineA(hdc, uChar, fuFormat, lpgm, cjBuffer, pvBuffer, lpmat2);
|
|
|
|
|
// if (pSettings->EnableClipBoxFix())
|
|
|
|
|
// {
|
|
|
|
|
// lpgm->gmptGlyphOrigin.y+=1;
|
|
|
|
|
// lpgm->gmBlackBoxY+=1;
|
|
|
|
|
// }
|
|
|
|
|
if (pSettings->EnableClipBoxFix() && (!cjBuffer || !pvBuffer)) {
|
|
|
|
|
if (!(fuFormat & (GGO_BITMAP | GGO_GRAY2_BITMAP | GGO_GRAY4_BITMAP | GGO_GRAY8_BITMAP | GGO_NATIVE))) {
|
|
|
|
|
//lpgm->gmptGlyphOrigin.x -= 1;
|
|
|
|
|
//lpgm->gmptGlyphOrigin.y += 1;
|
|
|
|
|
//lpgm->gmBlackBoxX += 3;
|
|
|
|
|
//lpgm->gmBlackBoxY += 2;
|
2016-09-29 15:37:23 +08:00
|
|
|
|
static int n = (int)ceil(2.0*pSettings->ScreenDpi() / 96);
|
2016-09-23 22:20:33 +08:00
|
|
|
|
lpgm->gmptGlyphOrigin.y += n;
|
|
|
|
|
lpgm->gmBlackBoxY += n;
|
2016-09-02 17:29:33 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int WINAPI IMPL_GetTextFaceW( __in HDC hdc, __in int c, __out_ecount_part_opt(c, return) LPWSTR lpName)
|
|
|
|
|
{
|
|
|
|
|
int nSize = ORIG_GetTextFaceW(hdc, c, lpName);
|
|
|
|
|
LPCWSTR fontcache=GetCachedFontLocale(GetCurrentFont(hdc));
|
|
|
|
|
|
|
|
|
|
if (fontcache){
|
|
|
|
|
int len=Min(LF_FACESIZE, c);
|
|
|
|
|
StringCchCopy(lpName, len, fontcache);
|
|
|
|
|
nSize = (int)wcslen(fontcache)>len? len: wcslen(fontcache) + 1;
|
|
|
|
|
}
|
|
|
|
|
return nSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int WINAPI IMPL_GetTextFaceA( __in HDC hdc, __in int c, __out_ecount_part_opt(c, return) LPSTR lpName)
|
|
|
|
|
{
|
|
|
|
|
int nSize = ORIG_GetTextFaceA(hdc, c, lpName);
|
|
|
|
|
LPCWSTR fontcache=GetCachedFontLocale(GetCurrentFont(hdc));
|
|
|
|
|
if (fontcache){
|
|
|
|
|
//int len=Min(LF_FACESIZE, c);
|
|
|
|
|
size_t _Dsize = 2 * wcslen(fontcache) + 1;
|
|
|
|
|
char *_Dest = new char[_Dsize];
|
|
|
|
|
memset(_Dest,0,_Dsize);
|
|
|
|
|
int len =wcstombs(_Dest, fontcache, _Dsize);
|
|
|
|
|
StringCchCopyA(lpName, LF_FACESIZE, _Dest);
|
|
|
|
|
delete[] _Dest;
|
|
|
|
|
nSize = len+1;
|
|
|
|
|
}
|
|
|
|
|
return nSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGDIOBJ WINAPI IMPL_GetStockObject(__in int i)
|
|
|
|
|
{
|
|
|
|
|
switch (i)
|
|
|
|
|
{
|
|
|
|
|
case DEFAULT_GUI_FONT:
|
|
|
|
|
{
|
|
|
|
|
static const CGdippSettings* pSetting = CGdippSettings::GetInstance();
|
|
|
|
|
if (g_alterGUIFont)
|
|
|
|
|
return g_alterGUIFont;
|
|
|
|
|
else
|
|
|
|
|
return ORIG_GetStockObject(i);
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
case SYSTEM_FONT:
|
|
|
|
|
{
|
|
|
|
|
if (g_alterSysFont)
|
|
|
|
|
return g_alterSysFont;
|
|
|
|
|
break;
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
default: return ORIG_GetStockObject(i);
|
|
|
|
|
}
|
|
|
|
|
return ORIG_GetStockObject(i);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_BeginPath(HDC hdc)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
BOOL ret=ORIG_BeginPath(hdc);
|
|
|
|
|
if (ret)
|
|
|
|
|
{
|
|
|
|
|
DCArray.insert(hdc);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_EndPath(HDC hdc)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
BOOL ret=ORIG_EndPath(hdc);
|
|
|
|
|
if (ret)
|
|
|
|
|
{
|
|
|
|
|
DCArray.erase(hdc);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_AbortPath(HDC hdc)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
BOOL ret=ORIG_AbortPath(hdc);
|
|
|
|
|
if (ret)
|
|
|
|
|
{
|
|
|
|
|
DCArray.erase(hdc);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int WINAPI IMPL_GetObjectA(__in HANDLE h, __in int c, __out_bcount_opt(c) LPVOID pv)
|
|
|
|
|
{
|
|
|
|
|
int ret = ORIG_GetObjectA(h, c, pv);
|
|
|
|
|
if (ret==sizeof(LOGFONTA))
|
|
|
|
|
{
|
|
|
|
|
LPCWSTR fontcache = GetCachedFont((HFONT)h);
|
|
|
|
|
if (fontcache && pv)
|
|
|
|
|
{
|
|
|
|
|
size_t _Dsize = 2 * wcslen(fontcache) + 1;
|
|
|
|
|
char *_Dest = new char[_Dsize];
|
|
|
|
|
memset(_Dest,0,_Dsize);
|
|
|
|
|
wcstombs(_Dest,fontcache,_Dsize);
|
|
|
|
|
StringCchCopyA(((LOGFONTA*)pv)->lfFaceName, LF_FACESIZE, _Dest);
|
|
|
|
|
delete []_Dest;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int WINAPI IMPL_GetObjectW(__in HANDLE h, __in int c, __out_bcount_opt(c) LPVOID pv)
|
|
|
|
|
{
|
|
|
|
|
int ret = ORIG_GetObjectW(h, c, pv);
|
|
|
|
|
if (ret==sizeof(LOGFONTW))
|
|
|
|
|
{
|
|
|
|
|
LPCWSTR fontcache = GetCachedFont((HFONT)h);
|
|
|
|
|
if (fontcache && pv)
|
|
|
|
|
{
|
|
|
|
|
StringCchCopyW(((LOGFONTW*)pv)->lfFaceName, LF_FACESIZE, fontcache);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HFONT WINAPI IMPL_CreateFontIndirectExW(CONST ENUMLOGFONTEXDV *penumlfex)
|
|
|
|
|
{
|
2016-09-08 13:45:52 +08:00
|
|
|
|
if (!penumlfex) return NULL;
|
2016-09-02 17:29:33 +08:00
|
|
|
|
TRACE(L"Creating font \"%s\"\n", penumlfex->elfEnumLogfontEx.elfLogFont.lfFaceName);
|
|
|
|
|
{
|
|
|
|
|
if (penumlfex->elfEnumLogfontEx.elfLogFont.lfClipPrecision == FONT_MAGIC_NUMBER)
|
|
|
|
|
{
|
|
|
|
|
TRACE(L"Engine font, Ignored, ");
|
|
|
|
|
((ENUMLOGFONTEXDV *)penumlfex)->elfEnumLogfontEx.elfLogFont.lfClipPrecision = 0;
|
|
|
|
|
return ORIG_CreateFontIndirectExW(penumlfex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
GetEnvironmentVariableW(L"MACTYPE_FONTSUBSTITUTES_ENV", NULL, 0);
|
|
|
|
|
if (GetLastError()!=ERROR_ENVVAR_NOT_FOUND)
|
|
|
|
|
return ORIG_CreateFontIndirectExW(penumlfex);*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!penumlfex) {
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|
|
|
|
if (pSettings->IsFontExcluded(penumlfex->elfEnumLogfontEx.elfLogFont.lfFaceName)) {
|
|
|
|
|
TRACE(L"Font exception! ");
|
|
|
|
|
return ORIG_CreateFontIndirectExW(penumlfex);
|
|
|
|
|
//TRACE(L"Handle = %x\n" , (int)h);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ENUMLOGFONTEXDV mfont(*penumlfex);
|
|
|
|
|
LOGFONT& lf = mfont.elfEnumLogfontEx.elfLogFont;
|
|
|
|
|
LOGFONT lfOrg(lf);
|
|
|
|
|
BOOL bForced = false;
|
|
|
|
|
if (bForced = pSettings->CopyForceFont(lf, lfOrg)) {
|
|
|
|
|
/*
|
|
|
|
|
mfont->elfEnumLogfontEx.elfLogFont.lfHeight = lf.lfHeight;
|
|
|
|
|
// mfont->elfEnumLogfontEx.elfLogFont.lfWidth = lfOrg.lfWidth;
|
|
|
|
|
mfont->elfEnumLogfontEx.elfLogFont.lfWidth = lf.lfWidth;
|
|
|
|
|
mfont->elfEnumLogfontEx.elfLogFont.lfEscapement = lf.lfEscapement;
|
|
|
|
|
mfont->elfEnumLogfontEx.elfLogFont.lfOrientation = lf.lfOrientation;
|
|
|
|
|
mfont->elfEnumLogfontEx.elfLogFont.lfWeight = lf.lfWeight;
|
|
|
|
|
mfont->elfEnumLogfontEx.elfLogFont.lfItalic = lf.lfItalic;
|
|
|
|
|
mfont->elfEnumLogfontEx.elfLogFont.lfUnderline = lf.lfUnderline;
|
|
|
|
|
mfont->elfEnumLogfontEx.elfLogFont.lfStrikeOut = lf.lfStrikeOut;
|
|
|
|
|
mfont->elfEnumLogfontEx.elfLogFont.lfCharSet = lf.lfCharSet;
|
|
|
|
|
mfont->elfEnumLogfontEx.elfLogFont.lfOutPrecision = 0;
|
|
|
|
|
mfont->elfEnumLogfontEx.elfLogFont.lfClipPrecision = 0;
|
|
|
|
|
mfont->elfEnumLogfontEx.elfLogFont.lfQuality = 0;
|
|
|
|
|
mfont->elfEnumLogfontEx.elfLogFont.lfPitchAndFamily = 0;
|
|
|
|
|
StringCchCopy(mfont->elfEnumLogfontEx.elfLogFont.lfFaceName, LF_FACESIZE, lf.lfFaceName);*/
|
|
|
|
|
|
|
|
|
|
TRACE(L"Font substitutes to \"%s\"\n", lf.lfFaceName);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
TRACE(L"Normal font\n");
|
|
|
|
|
//bypass = true;
|
|
|
|
|
HFONT hf = ORIG_CreateFontIndirectExW(&mfont);
|
|
|
|
|
//ORIG_CreateFontIndirectExW(
|
|
|
|
|
//if(hf && lplf && !pSettings->LoadOnDemand()) {
|
|
|
|
|
// AddFontToFT(lplf->lfFaceName, lplf->lfWeight, !!lplf->lfItalic);
|
|
|
|
|
//}
|
|
|
|
|
if (hf && bForced) {
|
|
|
|
|
AddToCachedFont(hf, (WCHAR*)penumlfex->elfEnumLogfontEx.elfLogFont.lfFaceName, (WCHAR *)lfOrg.lfFaceName);
|
|
|
|
|
}
|
|
|
|
|
//bypass = false;
|
|
|
|
|
TRACE(L"Create font %s handle %x\n", lfOrg.lfFaceName, (int)hf);
|
|
|
|
|
return hf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_DeleteObject(HGDIOBJ hObject)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
if (hObject == g_alterGUIFont) //<2F>ҵ<EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>壬<EFBFBD><E5A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷŵ<CDB7>
|
|
|
|
|
return true;
|
|
|
|
|
BOOL bResult = ORIG_DeleteObject(hObject);
|
|
|
|
|
if (bResult) DeleteCachedFont((HFONT)hObject);
|
|
|
|
|
return bResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HFONT WINAPI IMPL_CreateFontIndirectW(CONST LOGFONTW *lplf) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>hook<6F><6B>ֻΪ<D6BB><CEAA><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>뷨
|
|
|
|
|
{
|
|
|
|
|
ENUMLOGFONTEXDVW envlf = {0};
|
|
|
|
|
memcpy(&envlf.elfEnumLogfontEx.elfLogFont, lplf, sizeof(LOGFONTW));
|
|
|
|
|
return IMPL_CreateFontIndirectExW(&envlf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
BOOL WINAPI IMPL_DrawStateA(HDC hdc, HBRUSH hbr, DRAWSTATEPROC lpOutputFunc, LPARAM lData, WPARAM wData, int x, int y, int cx, int cy, UINT uFlags)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
int cchW;
|
|
|
|
|
LPWSTR lpStringW;
|
|
|
|
|
|
|
|
|
|
if(lData && uFlags & DSS_DISABLED) {
|
|
|
|
|
switch(uFlags & 0x0f) {
|
|
|
|
|
case DST_TEXT:
|
|
|
|
|
case DST_PREFIXTEXT:
|
|
|
|
|
lpStringW = _StrDupAtoW((LPCSTR)lData, wData ? wData : -1, &cchW);
|
|
|
|
|
if(lpStringW) {
|
|
|
|
|
BOOL ret = IMPL_DrawStateW(hdc, hbr, lpOutputFunc, (LPARAM)lpStringW, cchW, x, y, cx, cy, uFlags);
|
|
|
|
|
free(lpStringW);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ORIG_DrawStateA(hdc, hbr, lpOutputFunc, lData, wData, x, y, cx, cy, uFlags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<2F>D<EFBFBD>F<EFBFBD>`<60><><EFBFBD><EFBFBD>DrawText<78>֓<EFBFBD><D693><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//DrawText<78>͓<EFBFBD><CD93><EFBFBD><EFBFBD><EFBFBD>ExtTextOut<75><74><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂Ŗ<CC82><C596><EFBFBD><EFBFBD>Ȃ<EFBFBD>
|
|
|
|
|
BOOL WINAPI IMPL_DrawStateW(HDC hdc, HBRUSH hbr, DRAWSTATEPROC lpOutputFunc, LPARAM lData, WPARAM wData, int x, int y, int cx, int cy, UINT uFlags)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
if(lData && uFlags & DSS_DISABLED) {
|
|
|
|
|
switch(uFlags & 0x0f) {
|
|
|
|
|
case DST_TEXT:
|
|
|
|
|
case DST_PREFIXTEXT:
|
|
|
|
|
{
|
|
|
|
|
//wData==0<>̎<EFBFBD><CC8E>ɕ<EFBFBD><C995><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>v<EFBFBD>Z
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>API<50>ƈ<EFBFBD><C688><EFBFBD><EFBFBD><EFBFBD>-1<>̎<EFBFBD><CC8E>ł͂Ȃ<CD82>
|
|
|
|
|
if(wData == 0) {
|
|
|
|
|
wData = wcslen((LPCWSTR)lData);
|
|
|
|
|
}
|
|
|
|
|
RECT rect = { x, y, x + 10000, y + 10000 };
|
|
|
|
|
//<2F>ǂ<EFBFBD><C782><EFBFBD><EFBFBD><EFBFBD>3DHighLight<68>̏<EFBFBD><CC8F><EFBFBD>1px<70><78><EFBFBD>炵<EFBFBD><E782B5>3DShadow<6F><77><EFBFBD>d<EFBFBD>˂Ă<CB82><C482>炵<EFBFBD><E782B5>
|
|
|
|
|
int oldbm = SetBkMode(hdc, TRANSPARENT);
|
|
|
|
|
COLORREF oldfg = SetTextColor(hdc, GetSysColor(COLOR_3DHIGHLIGHT));
|
|
|
|
|
//DrawState<74><65>DrawText<78>ł<EFBFBD>prefix<69>̃t<CC83><74><EFBFBD>O<EFBFBD><4F><EFBFBD>t(API<50>̐v<DD8C>_<EFBFBD><5F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
|
|
|
|
const UINT uDTFlags = DT_SINGLELINE | DT_NOCLIP | (uFlags & DST_PREFIXTEXT ? 0 : DT_NOPREFIX);
|
|
|
|
|
|
|
|
|
|
OffsetRect(&rect, 1, 1);
|
|
|
|
|
DrawTextW(hdc, (LPCWSTR)lData, wData, &rect, uDTFlags);
|
|
|
|
|
SetTextColor(hdc, GetSysColor(COLOR_3DSHADOW));
|
|
|
|
|
OffsetRect(&rect, -1, -1);
|
|
|
|
|
DrawTextW(hdc, (LPCWSTR)lData, wData, &rect, uDTFlags);
|
|
|
|
|
SetTextColor(hdc, oldfg);
|
|
|
|
|
SetBkMode(hdc, oldbm);
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ORIG_DrawStateW(hdc, hbr, lpOutputFunc, lData, wData, x, y, cx, cy, uFlags);
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FreeTypeFontEngine;
|
|
|
|
|
extern FreeTypeFontEngine* g_pFTEngine;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOL __stdcall IMPL_RemoveFontResourceExW(__in LPCWSTR name, __in DWORD fl, __reserved PVOID pdv)
|
|
|
|
|
{
|
|
|
|
|
g_pFTEngine->RemoveFont(name);
|
|
|
|
|
return ORIG_RemoveFontResourceExW(name, fl, pdv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
BOOL __stdcall IMPL_RemoveFontResourceW(__in LPCWSTR lpFileName)
|
|
|
|
|
{
|
|
|
|
|
g_pFTEngine->RemoveFont(lpFileName);
|
|
|
|
|
return ORIG_RemoveFontResourceW(lpFileName);
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_TextOutA(HDC hdc, int nXStart, int nYStart, LPCSTR lpString, int cbString)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
return IMPL_ExtTextOutA(hdc, nXStart, nYStart, NULL, NULL, lpString, cbString, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_TextOutW(HDC hdc, int nXStart, int nYStart, LPCWSTR lpString, int cbString)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
return IMPL_ExtTextOutW(hdc, nXStart, nYStart, NULL, NULL, lpString, cbString, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AnsiDxToUnicodeDx(LPCSTR lpStringA, int cbString, const int* lpDxA, int* lpDxW, int ACP)
|
|
|
|
|
{
|
|
|
|
|
LPCSTR lpEndA = lpStringA + cbString;
|
|
|
|
|
while(lpStringA < lpEndA) {
|
|
|
|
|
*lpDxW = *lpDxA++;
|
|
|
|
|
if(IsDBCSLeadByteEx(ACP, *lpStringA)) {
|
|
|
|
|
*lpDxW += *lpDxA++;
|
|
|
|
|
lpStringA++;
|
|
|
|
|
}
|
|
|
|
|
lpDxW++;
|
|
|
|
|
lpStringA++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ANSI->Unicode<64>ɕϊ<C995><CF8A><EFBFBD><EFBFBD><EFBFBD>ExtTextOutW<74>ɓ<EFBFBD><C993><EFBFBD><EFBFBD><EFBFBD>ExtTextOutA
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_ExtTextOutA(HDC hdc, int nXStart, int nYStart, UINT fuOptions, CONST RECT *lprc, LPCSTR lpString, UINT cbString, CONST INT *lpDx)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
if (!hdc || !lpString || !cbString || !g_ccbRender || !(fuOptions & ETO_IGNORELANGUAGE)) {
|
|
|
|
|
return ORIG_ExtTextOutA(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//However, if the ANSI version of ExtTextOut is called with ETO_GLYPH_INDEX,
|
|
|
|
|
//the function returns TRUE even though the function does nothing.
|
|
|
|
|
//<2F>Ƃ肠<C682><E882A0><EFBFBD><EFBFBD><EFBFBD>I<EFBFBD><49><EFBFBD>W<EFBFBD>i<EFBFBD><69><EFBFBD>ɔ<EFBFBD><C994><EFBFBD>
|
|
|
|
|
if (fuOptions & ETO_GLYPH_INDEX)
|
|
|
|
|
return ORIG_ExtTextOutA(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
|
|
|
|
|
//HDBENCH<43>`<60>[<5B>g
|
|
|
|
|
// if (lpString && cbString == 7 && pSettings->IsHDBench() && (memcmp(lpString, "HDBENCH", 7) == 0 || memcmp(lpString, " ", 7) == 0))
|
|
|
|
|
// return ORIG_ExtTextOutA(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
|
|
|
|
|
LPWSTR lpszUnicode;
|
|
|
|
|
int bufferLength;
|
|
|
|
|
BOOL result;
|
|
|
|
|
WCHAR szStack[CCH_MAX_STACK];
|
|
|
|
|
int dxStack[CCH_MAX_STACK];
|
|
|
|
|
int nACP = GdiGetCodePage(hdc);//CP_ACP;
|
|
|
|
|
//DWORD nCharset = GetTextCharsetInfo(hdc, NULL, 0);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
switch (nCharset)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SYMBOL_CHARSET:
|
|
|
|
|
{
|
|
|
|
|
nACP = CP_SYMBOL;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case MAC_CHARSET:
|
|
|
|
|
{
|
|
|
|
|
nACP = CP_MACCP;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case OEM_CHARSET:
|
|
|
|
|
{
|
|
|
|
|
nACP = CP_OEMCP;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
CHARSETINFO Cs={0,CP_ACP,0};
|
|
|
|
|
TranslateCharsetInfo((DWORD*)nCharset, &Cs, TCI_SRCCHARSET);
|
|
|
|
|
nACP = Cs.ciACP;
|
|
|
|
|
}
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lpszUnicode = _StrDupExAtoW(lpString, cbString, szStack, CCH_MAX_STACK, &bufferLength, nACP);
|
|
|
|
|
if(!lpszUnicode) {
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>s<EFBFBD><73>: <20>ꉞ<EFBFBD>I<EFBFBD><49><EFBFBD>W<EFBFBD>i<EFBFBD><69><EFBFBD>ɓ<EFBFBD><C993><EFBFBD><EFBFBD>Ƃ<EFBFBD>
|
|
|
|
|
return ORIG_ExtTextOutA(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int* lpDxW = NULL;
|
|
|
|
|
result = FALSE;
|
|
|
|
|
if(lpDx && cbString && _getmbcp()) {
|
|
|
|
|
if (cbString < CCH_MAX_STACK) {
|
|
|
|
|
lpDxW = dxStack;
|
|
|
|
|
ZeroMemory(lpDxW, sizeof(int) * cbString);
|
|
|
|
|
} else {
|
|
|
|
|
lpDxW = (int*)calloc(sizeof(int), cbString);
|
|
|
|
|
if (!lpDxW) {
|
|
|
|
|
goto CleanUp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (nACP!=CP_SYMBOL)
|
|
|
|
|
{
|
|
|
|
|
AnsiDxToUnicodeDx(lpString, cbString, lpDx, lpDxW, nACP);
|
|
|
|
|
lpDx = lpDxW;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = IMPL_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, (LPCWSTR)lpszUnicode, bufferLength, lpDx);
|
|
|
|
|
|
|
|
|
|
CleanUp:
|
|
|
|
|
if (lpszUnicode != szStack)
|
|
|
|
|
free(lpszUnicode);
|
|
|
|
|
if (lpDxW != dxStack)
|
|
|
|
|
free(lpDxW);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
|
ETOE_OK = 0,
|
|
|
|
|
ETOE_CREATEDC = 1,
|
|
|
|
|
ETOE_SETFONT = 2,
|
|
|
|
|
ETOE_CREATEDIB = 3,
|
|
|
|
|
ETOE_FREETYPE = 4,
|
|
|
|
|
ETOE_INVALIDARG = 11,
|
|
|
|
|
ETOE_ROTATION = 12,
|
|
|
|
|
ETOE_LARGESIZE = 13,
|
|
|
|
|
ETOE_INVALIDHDC = 14,
|
|
|
|
|
ETOE_ROTATEFONT = 15,
|
|
|
|
|
ETOE_NOAREA = 16,
|
|
|
|
|
ETOE_GETTEXTEXTENT = 17,
|
|
|
|
|
ETOE_MONO = 18,
|
|
|
|
|
ETOE_GENERAL = 19,
|
|
|
|
|
} ExtTextOut_ErrorCode;
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD>O<EFBFBD><4F><EFBFBD>h<EFBFBD>L
|
|
|
|
|
#define ETO_TRY() ExtTextOut_ErrorCode error = ETOE_OK; {
|
|
|
|
|
#define ETO_THROW(code) error = (code); goto _EXCEPTION_THRU
|
|
|
|
|
#define ETO_CATCH() } _EXCEPTION_THRU:
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
BOOL FreeTypeGetTextExtentPoint(HDC hdc, LPCSTR lpString, int cbString, LPSIZE lpSize, const FREETYPE_PARAMS* params)
|
|
|
|
|
{
|
|
|
|
|
WCHAR szStack[CCH_MAX_STACK];
|
|
|
|
|
|
|
|
|
|
int cchStringW;
|
|
|
|
|
LPWSTR lpStringW = _StrDupExAtoW(lpString, cbString, szStack, CCH_MAX_STACK, &cchStringW);
|
|
|
|
|
if(!lpStringW) {
|
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL ret = FreeTypeGetTextExtentPoint(hdc, lpStringW, cchStringW, lpSize, params);
|
|
|
|
|
if (lpStringW != szStack)
|
|
|
|
|
free(lpStringW);
|
|
|
|
|
return ret;
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CETOBitmap
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
CBitmapCache& m_cache;
|
|
|
|
|
HDC m_hdc;
|
|
|
|
|
HBITMAP m_hPrevBmp;
|
|
|
|
|
HBITMAP m_hBmp;
|
|
|
|
|
BYTE* m_lpPixels;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
CETOBitmap(CBitmapCache& cache)
|
|
|
|
|
: m_cache(cache)
|
|
|
|
|
, m_hdc(NULL)
|
|
|
|
|
, m_hPrevBmp(NULL)
|
|
|
|
|
, m_hBmp(NULL)
|
|
|
|
|
, m_lpPixels(NULL)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
HDC CreateDC(HDC dc)
|
|
|
|
|
{
|
|
|
|
|
m_hdc = m_cache.CreateDC(dc);
|
|
|
|
|
return m_hdc;
|
|
|
|
|
}
|
|
|
|
|
bool CreateDIBandSelect(int cx, int cy)
|
|
|
|
|
{
|
|
|
|
|
m_hBmp = m_cache.CreateDIB(cx, cy, &m_lpPixels);
|
|
|
|
|
if (!m_hBmp) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
m_hPrevBmp = SelectBitmap(m_hdc, m_hBmp);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
void RestoreBitmap()
|
|
|
|
|
{
|
|
|
|
|
if (m_hPrevBmp) {
|
|
|
|
|
SelectBitmap(m_hdc, m_hPrevBmp);
|
|
|
|
|
m_hPrevBmp = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
extern ControlIder CID;
|
|
|
|
|
// ȡ<><C8A1>Windows<77><73>ExtTextOutW
|
2016-10-26 15:04:17 +08:00
|
|
|
|
BOOL WINAPI IMPL_ExtTextOutW(HDC hdc, int nXStart, int nYStart, UINT fuOptions, CONST RECT *lprc, LPCWSTR lpString, UINT cbString, CONST INT *SyslpDx)
|
2016-09-02 17:29:33 +08:00
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter; //<2F><><EFBFBD>ڰ<EFBFBD>ȫ<EFBFBD>˳<EFBFBD><CBB3>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
|
2016-10-26 15:04:17 +08:00
|
|
|
|
INT* lpDx = const_cast<INT*>(SyslpDx);
|
|
|
|
|
|
2016-09-02 17:29:33 +08:00
|
|
|
|
if (!hdc || !lpString || !cbString || !g_ccbRender) { //û<><C3BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD>Windows<77><73><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ֹͣ<CDA3><D6B9>Ⱦ
|
|
|
|
|
return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
}
|
|
|
|
|
if (!(fuOptions & ETO_GLYPH_INDEX) && cbString==1 && *lpString==32) //<2F>ո<EFBFBD>
|
|
|
|
|
return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions | ETO_IGNORELANGUAGE, lprc, lpString, cbString, lpDx); //<2F>ո<EFBFBD><D5B8>Ͳ<EFBFBD><CDB2>ô<EFBFBD><C3B4><EFBFBD><EFBFBD>ˡ<EFBFBD><CBA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
|
|
|
|
|
|
|
|
|
CThreadLocalInfo* pTLInfo = g_TLInfo.GetPtr();
|
|
|
|
|
if(!pTLInfo) {
|
|
|
|
|
return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (DCArray.find(hdc)!=DCArray.end())
|
|
|
|
|
return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
2016-10-26 15:04:17 +08:00
|
|
|
|
CAutoVectorPtr<INT> newdx;
|
|
|
|
|
if (!lpDx) {
|
|
|
|
|
newdx.Allocate(cbString);
|
|
|
|
|
SIZE p = { 0 };
|
|
|
|
|
BOOL r = false;
|
|
|
|
|
if (fuOptions & ETO_GLYPH_INDEX)
|
|
|
|
|
r = GetTextExtentExPointI(hdc, (LPWORD)lpString, cbString, 0, NULL, newdx, &p);
|
|
|
|
|
else
|
|
|
|
|
r = GetTextExtentExPointW(hdc, lpString, cbString, 0, NULL, newdx, &p);
|
|
|
|
|
if (r) {
|
|
|
|
|
for (int i = cbString - 1; i > 0; --i) {
|
|
|
|
|
newdx[i] -= newdx[i - 1];
|
|
|
|
|
}
|
|
|
|
|
lpDx = newdx;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
newdx.Free();
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-09-02 17:29:33 +08:00
|
|
|
|
|
|
|
|
|
if (!(fuOptions & ETO_GLYPH_INDEX) && !(fuOptions & ETO_IGNORELANGUAGE) && !lpDx && CID.myiscomplexscript(lpString,cbString)) //complex script
|
|
|
|
|
return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
|
|
|
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance(); //<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ʵ<EFBFBD><CAB5>
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
#ifndef _DEBUG //debugģʽ<C4A3>´˲<C2B4><CBB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (pSettings->FontLoader()==SETTING_FONTLOADER_WIN32)
|
|
|
|
|
{
|
|
|
|
|
if (!(fuOptions & ETO_GLYPH_INDEX) //<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ
|
|
|
|
|
&& !(fuOptions & ETO_IGNORELANGUAGE) && ScriptIsComplex(lpString, cbString, SIC_COMPLEX) == S_OK) {
|
|
|
|
|
return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (!(fuOptions & ETO_GLYPH_INDEX) && / *iswcntrl(lpString[0])* /CID.myiswcntrl(lpString[0])) {
|
|
|
|
|
return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pTLInfo->InExtTextOut()) { //<2F><><EFBFBD>쳣֮<ECB3A3><D6AE><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>ԭִ<D4AD><D6B4>
|
|
|
|
|
return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XFORM xfm;
|
|
|
|
|
static XFORM stdXfm = {1.0,0,0,1.0,0,0};
|
|
|
|
|
bool bZoomedDC = false;
|
|
|
|
|
CDCTransformer* DCTrans = NULL;
|
|
|
|
|
if (GetTransform)
|
|
|
|
|
{
|
|
|
|
|
GetTransform(hdc, GT_WORLD_TO_DEVICE, &xfm);
|
|
|
|
|
if (memcmp(&xfm, &stdXfm, sizeof(XFORM)-sizeof(FLOAT)*2)) //(xfm.eM11!=1.0 || xfm.eM22!=1.0) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>
|
|
|
|
|
{
|
|
|
|
|
bool bZoomInOut = (xfm.eM12==0 && xfm.eM21==0 && xfm.eM11>0 && xfm.eM22>0); //ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (!bZoomInOut)
|
|
|
|
|
return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bZoomedDC = true;
|
|
|
|
|
DCTrans = new CDCTransformer;
|
|
|
|
|
DCTrans->init(xfm);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
int mm = GetMapMode(hdc);
|
|
|
|
|
if (mm!=MM_TEXT)
|
|
|
|
|
{
|
|
|
|
|
SIZE size;
|
|
|
|
|
GetWindowExtEx(hdc, &size);
|
|
|
|
|
if (size.cx!=1 || size.cy!=1)
|
|
|
|
|
return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
}
|
|
|
|
|
if (GetGraphicsMode(hdc)==GM_ADVANCED)
|
|
|
|
|
{
|
|
|
|
|
XFORM xfm;
|
|
|
|
|
GetWorldTransform(hdc, &xfm);
|
|
|
|
|
if (xfm.eM11!=1.0 || xfm.eM22!=1.0)
|
|
|
|
|
return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
//if (GetROP2(hdc)!=13)
|
|
|
|
|
// return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
//if (GetStretchBltMode(hdc)!=BLACKONWHITE)
|
|
|
|
|
// return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
SIZE size;
|
|
|
|
|
if (fuOptions & ETO_GLYPH_INDEX)
|
|
|
|
|
GetTextExtentPointI(hdc,(LPWORD)lpString, cbString,&size);
|
|
|
|
|
else
|
|
|
|
|
GetTextExtentPoint(hdc, lpString, cbString, &size);
|
|
|
|
|
if (!size.cx)
|
|
|
|
|
return ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);*/
|
|
|
|
|
|
|
|
|
|
COwnedCriticalSectionLock __lock2(1, COwnedCriticalSectionLock::OCS_DC); //<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD>ֹ<EFBFBD><D6B9>ͻ
|
|
|
|
|
CBitmapCache& cache = pTLInfo->BitmapCache();
|
|
|
|
|
CETOBitmap bmp(cache);
|
|
|
|
|
|
|
|
|
|
HDC hCanvasDC = NULL;
|
|
|
|
|
HFONT hPrevFont = NULL;
|
|
|
|
|
HFONT hMyCurFont = NULL;
|
|
|
|
|
HFONT hZoomedFont = NULL, hOldMDCFont = NULL;
|
|
|
|
|
BOOL bForceFont = false;
|
|
|
|
|
int * outlpDx = NULL;
|
|
|
|
|
FT_Referenced_Glyph* GlyphArray = new FT_Referenced_Glyph[cbString];
|
|
|
|
|
FT_DRAW_STATE* ftDrawState = new FT_DRAW_STATE[cbString];
|
|
|
|
|
memset(GlyphArray, 0, sizeof(FT_Referenced_Glyph)*cbString);
|
|
|
|
|
memset(ftDrawState, 0, sizeof(FT_DRAW_STATE)*cbString);
|
|
|
|
|
OUTLINETEXTMETRIC* otm = NULL;
|
|
|
|
|
|
|
|
|
|
ETO_TRY();
|
|
|
|
|
//<2F><><EFBFBD>ñ<EFBFBD>־<EFBFBD><D6BE>
|
|
|
|
|
pTLInfo->InExtTextOut(true);
|
|
|
|
|
|
|
|
|
|
POINT curPos = { nXStart, nYStart }; //<2F><>¼<EFBFBD><C2BC>ʼ<EFBFBD><CABC>λ<EFBFBD><CEBB>
|
|
|
|
|
POINT destPos;
|
|
|
|
|
SIZE drawSize;
|
|
|
|
|
|
|
|
|
|
HFONT hCurFont = NULL;
|
|
|
|
|
BOOL bShadow = FALSE;
|
|
|
|
|
|
|
|
|
|
UINT align;
|
|
|
|
|
SIZE textSize;
|
|
|
|
|
SIZE realSize = { 0 };
|
|
|
|
|
|
|
|
|
|
//================<3D>ж<EFBFBD><D0B6>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA>Ч<EFBFBD><D0A7>DC=====================
|
|
|
|
|
if (!IsValidDC(hdc)) {
|
|
|
|
|
ETO_THROW(ETOE_INVALIDHDC); // hdc is invalid
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int nSize=GetOutlineTextMetrics(hdc, 0, NULL);
|
|
|
|
|
if (!nSize) {
|
|
|
|
|
//nSize = sizeof(OUTLINETEXTMETRIC);
|
|
|
|
|
ETO_THROW(ETOE_INVALIDHDC);
|
|
|
|
|
} //<2F><>ʱ50-100ms
|
|
|
|
|
|
|
|
|
|
otm = (OUTLINETEXTMETRIC*)malloc(nSize);
|
|
|
|
|
memset(otm, 0, nSize);
|
|
|
|
|
otm->otmSize = nSize;
|
|
|
|
|
TEXTMETRIC& tm = otm->otmTextMetrics;
|
|
|
|
|
LOGFONT lf = { 0 };
|
|
|
|
|
wstring strFamilyName;
|
|
|
|
|
GetOutlineTextMetrics(hdc, nSize, otm);
|
|
|
|
|
/*
|
|
|
|
|
if (!GetOutlineTextMetrics(hdc, nSize, otm)) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
|
|
|
|
{
|
|
|
|
|
GetTextMetrics(hdc, &tm); //<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
|
|
|
|
WCHAR buff[LF_FACESIZE];
|
|
|
|
|
ORIG_GetTextFace(hdc, LF_FACESIZE, buff);
|
|
|
|
|
strFamilyName = buff;
|
|
|
|
|
}
|
|
|
|
|
else*/
|
|
|
|
|
|
|
|
|
|
strFamilyName = (LPWSTR)((DWORD_PTR)otm+(DWORD_PTR)otm->otmpFamilyName); //<2F><><EFBFBD><EFBFBD>TTF<54><46>Ϣ
|
|
|
|
|
|
|
|
|
|
const bool bVertical = pSettings->FontLoader()==SETTING_FONTLOADER_FREETYPE? strFamilyName.c_str()[0]==L'@' :false;
|
|
|
|
|
|
2016-09-08 13:45:52 +08:00
|
|
|
|
int nFontHeight = bZoomedDC ? DCTrans->TransformYAB(tm.tmHeight) : tm.tmHeight;
|
|
|
|
|
if ((pSettings->MaxHeight() && nFontHeight > pSettings->MaxHeight()) || (pSettings->MinHeight() && nFontHeight < pSettings->MinHeight())) {
|
|
|
|
|
ETO_THROW(ETOE_INVALIDHDC); //Font size too small or too big.
|
2016-09-02 17:29:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pSettings->IsFontExcluded(strFamilyName.c_str())) { //<2F>Ƚ<EFBFBD><C8BD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ų<EFBFBD><C5B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
ETO_THROW(ETOE_INVALIDHDC);
|
|
|
|
|
} //20-50ms
|
|
|
|
|
|
|
|
|
|
//====================end================================
|
|
|
|
|
|
|
|
|
|
hCanvasDC = bmp.CreateDC(hdc);
|
|
|
|
|
if(!hCanvasDC) {
|
|
|
|
|
ETO_THROW(ETOE_CREATEDC);
|
|
|
|
|
} //0ms
|
|
|
|
|
|
|
|
|
|
align = GetTextAlign(hdc); //<2F><><EFBFBD>ö<EFBFBD><C3B6>뷽ʽ
|
|
|
|
|
//if (pTLInfo->InUniscribe() && !(fuOptions & ETO_IGNORELANGUAGE))
|
|
|
|
|
// align &= ~TA_UPDATECP;
|
|
|
|
|
if(align & TA_UPDATECP) {
|
|
|
|
|
GetCurrentPositionEx(hdc, &curPos);
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
if (!align && lpDx && !fuOptions) //optimized
|
|
|
|
|
{
|
|
|
|
|
// ETO_THROW(ETOE_FREETYPE);
|
|
|
|
|
}//0ms*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hCurFont = GetCurrentFont(hdc); //<2F><><EFBFBD>õ<EFBFBD>ǰdc<64><63><EFBFBD><EFBFBD><EFBFBD>壬ע<E5A3AC><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD><EFBFBD>Ǵ<EFBFBD><C7B4><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (!hCurFont) { //<2F><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
|
|
|
|
|
ETO_THROW(ETOE_SETFONT);
|
|
|
|
|
}
|
|
|
|
|
TRACE(L"Draw text \"%s\", font=\"%s\", handle=%x\n", lpString, strFamilyName.c_str(), (int)hCurFont);
|
|
|
|
|
if (!ORIG_GetObjectW(hCurFont, sizeof(LOGFONT), &lf)) {
|
|
|
|
|
ETO_THROW(ETOE_SETFONT);
|
|
|
|
|
}//30ms
|
|
|
|
|
StringCchCopy(lf.lfFaceName, LF_FACESIZE, (LPWSTR)((DWORD_PTR)otm+(DWORD_PTR)otm->otmpFaceName)); //<2F><><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƹ<EFBFBD><C6B8>ƹ<EFBFBD>ȥ
|
|
|
|
|
if (lf.lfEscapement != 0) {
|
|
|
|
|
ETO_THROW(ETOE_ROTATEFONT);// rotated font
|
|
|
|
|
}
|
|
|
|
|
hPrevFont = SelectFont(hCanvasDC, hCurFont);
|
|
|
|
|
if (!hPrevFont)
|
|
|
|
|
{
|
|
|
|
|
hMyCurFont = CreateFontIndirect(&lf);
|
|
|
|
|
hPrevFont = SelectFont(hCanvasDC, hMyCurFont);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lf.lfHeight >= 0) {
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>û<EFBFBD><C3BB>ָ<EFBFBD><D6B8><EFBFBD>߶Ⱦ<DFB6>ʹ<EFBFBD><CAB9>tm<74>еĸ߶<C4B8>
|
|
|
|
|
lf.lfHeight = -(tm.tmHeight-tm.tmInternalLeading); //optimized
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bZoomedDC)
|
|
|
|
|
{
|
|
|
|
|
//DCTrans->SetSourceOffset(curPos.x, curPos.y);
|
|
|
|
|
curPos.x = DCTrans->TransformXAB(curPos.x);
|
|
|
|
|
curPos.y = DCTrans->TransformYAB(curPos.y);
|
|
|
|
|
lf.lfHeight = DCTrans->TransformYAB(lf.lfHeight);
|
|
|
|
|
lf.lfWidth = DCTrans->TransformXAB(lf.lfWidth);
|
|
|
|
|
tm.tmHeight = abs(DCTrans->TransformYAB(tm.tmHeight));
|
|
|
|
|
tm.tmInternalLeading = abs(DCTrans->TransformYAB(tm.tmInternalLeading));
|
|
|
|
|
tm.tmAscent = DCTrans->TransformYAB(tm.tmAscent);
|
|
|
|
|
tm.tmDescent = DCTrans->TransformYAB(tm.tmDescent);
|
|
|
|
|
tm.tmAveCharWidth = DCTrans->TransformXAB(tm.tmAveCharWidth);
|
|
|
|
|
// if (!DCTrans->TransformMode() && !lf.lfWidth && DCTrans->MirrorX())
|
|
|
|
|
// lf.lfWidth = tm.tmAveCharWidth;
|
2016-09-26 13:45:43 +08:00
|
|
|
|
if (lpDx && cbString) //firefoxʹ<78><CAB9>ETO_PDY<44><59>y<EFBFBD><79><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2016-09-02 17:29:33 +08:00
|
|
|
|
{
|
2016-09-27 10:24:48 +08:00
|
|
|
|
int szDx=fuOptions&ETO_PDY ? cbString*2:cbString;
|
2016-09-02 17:29:33 +08:00
|
|
|
|
outlpDx = new int[szDx];
|
2016-09-27 10:24:48 +08:00
|
|
|
|
DCTrans->TransformlpDx(lpDx, outlpDx, szDx); //lpDx has a size of cbString -1
|
2016-09-02 17:29:33 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
FREETYPE_PARAMS params(fuOptions & ~ETO_OPAQUE, hdc, &lf, otm, &strFamilyName);
|
|
|
|
|
if (bZoomedDC)
|
|
|
|
|
params.charExtra = DCTrans->TransformXAB(params.charExtra);
|
|
|
|
|
SetTextCharacterExtra(hCanvasDC, params.charExtra);
|
|
|
|
|
BITMAP bm;
|
|
|
|
|
HBITMAP hbmpSrc = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
|
|
|
|
|
|
|
|
|
|
if(hbmpSrc && ORIG_GetObjectW(hbmpSrc, sizeof(BITMAP), &bm) && bm.bmBitsPixel == 1) {
|
|
|
|
|
//<2F>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>ɫ<EFBFBD><C9AB>Ⱦ<EFBFBD><C8BE>ʽ
|
|
|
|
|
ETO_THROW(ETOE_MONO); //<2F><><EFBFBD><EFBFBD>Ⱦ<EFBFBD><C8BE>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>
|
|
|
|
|
//params.ftOptions |= FTO_MONO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!params.IsMono() && pSettings->EnableShadow()) {
|
|
|
|
|
bShadow = true;
|
|
|
|
|
}
|
|
|
|
|
int xs = 0, ys=0;
|
|
|
|
|
if (bShadow) {
|
|
|
|
|
const int* shadow = pSettings->GetShadowParams();
|
|
|
|
|
xs = shadow[0], ys = shadow[1];
|
|
|
|
|
params.alpha = shadow[2] | shadow[3];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
params.alpha = 1;
|
|
|
|
|
|
|
|
|
|
int width=0;
|
|
|
|
|
|
|
|
|
|
FreeTypeDrawInfo FTInfo(params, bZoomedDC ? hCanvasDC : hdc, (LOGFONT*)&lf, &cache, bZoomedDC ? outlpDx : lpDx, cbString, xs, ys);
|
|
|
|
|
|
|
|
|
|
lf.lfQuality = 0; //magic number means this is a non scaled font;
|
|
|
|
|
if (lf.lfWidth)
|
|
|
|
|
++lf.lfQuality;
|
|
|
|
|
if (bZoomedDC)
|
|
|
|
|
{
|
|
|
|
|
hZoomedFont = CreateFontIndirect(&lf);
|
|
|
|
|
if (!DCTrans->TransformMode() || lf.lfWidth)
|
|
|
|
|
++lf.lfQuality; //scaled font
|
|
|
|
|
hOldMDCFont = SelectFont(hCanvasDC, hZoomedFont);
|
|
|
|
|
SetGraphicsMode(hCanvasDC, GM_ADVANCED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!FreeTypeGetGlyph(FTInfo, lpString, cbString, width, GlyphArray, ftDrawState))
|
|
|
|
|
{
|
|
|
|
|
ETO_THROW(ETOE_FREETYPE);
|
|
|
|
|
}
|
|
|
|
|
if (FTInfo.xBase<0) //<2F><><EFBFBD><EFBFBD><EFBFBD>и<EFBFBD><D0B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
|
|
|
|
{
|
|
|
|
|
width-=FTInfo.xBase; //<2F><><EFBFBD>ӻ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>
|
|
|
|
|
FTInfo.x -= FTInfo.xBase; //<2F><><EFBFBD>ӹ<EFBFBD><D3B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
curPos.x+=FTInfo.xBase; //<2F>ƶ<EFBFBD><C6B6><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
|
|
|
|
for (int i=0;i<cbString;++i)
|
|
|
|
|
FTInfo.Dx[i]-=FTInfo.xBase; //<2F><EFBFBD><DEB8><EFBFBD><EFBFBD>ֻ<EFBFBD>ͼ<EFBFBD><CDBC>λ<D7BC><CEBB>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*if (bZoomedDC && DCTrans->MirrorX()) //<2F><><EFBFBD>ҷ<EFBFBD><D2B7><EFBFBD><EFBFBD><EFBFBD>RGB<47><42>BGRҪ<52>෴
|
|
|
|
|
for (int i=0; i<cbString; ++i)
|
|
|
|
|
{
|
|
|
|
|
switch (FTInfo.AAModes[i])
|
|
|
|
|
{
|
|
|
|
|
case 2:
|
|
|
|
|
FTInfo.AAModes[i] = 3;
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
FTInfo.AAModes[i] = 2;
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
FTInfo.AAModes[i] = 5;
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
FTInfo.AAModes[i] = 4;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}*/
|
|
|
|
|
//POINT destSize; //LP<4C>µĴ<C2B5>С<EFBFBD><D0A1><EFBFBD><EFBFBD>ʼλ<CABC><CEBB>
|
|
|
|
|
/*
|
|
|
|
|
if (bZoomedDC)
|
|
|
|
|
{
|
|
|
|
|
if (hOldMDCFont)
|
|
|
|
|
{
|
|
|
|
|
SelectFont(hCanvasDC, hOldMDCFont);
|
|
|
|
|
DeleteFont(hZoomedFont);
|
|
|
|
|
hZoomedFont = NULL;
|
|
|
|
|
hOldMDCFont = NULL;
|
|
|
|
|
}
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
textSize.cx = width;
|
|
|
|
|
textSize.cy = FTInfo.y + tm.tmHeight;
|
|
|
|
|
realSize.cx = FTInfo.x;
|
|
|
|
|
realSize.cy = FTInfo.y + tm.tmHeight;
|
|
|
|
|
|
|
|
|
|
//******************
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
RECT rc = { 0 };
|
|
|
|
|
const UINT horiz = align & (TA_LEFT|TA_RIGHT|TA_CENTER);
|
|
|
|
|
const UINT vert = align & (TA_BASELINE|TA_TOP|TA_BOTTOM);
|
|
|
|
|
|
|
|
|
|
switch (horiz) {
|
|
|
|
|
case TA_CENTER:
|
|
|
|
|
rc.left = curPos.x - div_ceil(textSize.cx, 2);
|
|
|
|
|
rc.right = curPos.x + div_ceil(textSize.cx, 2);
|
|
|
|
|
//no move
|
|
|
|
|
break;
|
|
|
|
|
case TA_RIGHT:
|
|
|
|
|
rc.left = curPos.x - textSize.cx;
|
|
|
|
|
rc.right = curPos.x;
|
|
|
|
|
curPos.x -= realSize.cx;//move pos
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
rc.left = curPos.x;
|
|
|
|
|
rc.right = curPos.x + textSize.cx;
|
|
|
|
|
curPos.x += realSize.cx;//move pos
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (vert) {
|
|
|
|
|
case TA_BASELINE:
|
|
|
|
|
rc.top = curPos.y - tm.tmAscent;
|
|
|
|
|
rc.bottom = curPos.y + tm.tmDescent + FTInfo.y;
|
|
|
|
|
//trace(L"ascent=%d descent=%d\n", metric.tmAscent, metric.tmDescent);
|
|
|
|
|
break;
|
|
|
|
|
case TA_BOTTOM:
|
|
|
|
|
rc.top = curPos.y - textSize.cy;
|
|
|
|
|
rc.bottom = curPos.y;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
rc.top = curPos.y;
|
|
|
|
|
rc.bottom = curPos.y + textSize.cy;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
//rc.bottom++;
|
|
|
|
|
destPos.x = rc.left;
|
|
|
|
|
destPos.y = rc.top;
|
|
|
|
|
drawSize.cx = textSize.cx;
|
|
|
|
|
drawSize.cy = rc.bottom - rc.top;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//trace(L"MovedCursor=%d %d\n", curPos.x, curPos.y);
|
|
|
|
|
//trace(L"TargetRect=%d %d %d %d\n", rc.left, rc.top, rc.right, rc.bottom);
|
|
|
|
|
//trace(L"DestPos=%dx%d Size=%dx%d\n", destPos.x, destPos.y, destSize.cx, destSize.cy);
|
|
|
|
|
//trace(L"CanvasPos=%dx%d Size=%dx%d\n", canvasPos.x, canvasPos.y, canvasSize.cx, canvasSize.cy);
|
|
|
|
|
|
|
|
|
|
if(drawSize.cx < 1 || drawSize.cy < 1) {
|
|
|
|
|
ETO_THROW(ETOE_NOAREA); //throw no area
|
|
|
|
|
}
|
|
|
|
|
//drawSize.cx += tm.tmMaxCharWidth; //<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
//bitmap
|
|
|
|
|
|
|
|
|
|
if (!bmp.CreateDIBandSelect(drawSize.cx+4, drawSize.cy+4)) {
|
|
|
|
|
ETO_THROW(ETOE_CREATEDIB);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int xorg=0, yorg=0;
|
|
|
|
|
if (lprc && (fuOptions & ETO_CLIPPED)) {
|
|
|
|
|
const RECT rcBlt = { destPos.x, destPos.y, destPos.x + drawSize.cx, destPos.y + drawSize.cy };
|
|
|
|
|
RECT rcClip = { 0 };
|
|
|
|
|
if (bZoomedDC)
|
|
|
|
|
{
|
|
|
|
|
RECT rcTrans;
|
|
|
|
|
DCTrans->TransformRectAB(lprc, &rcTrans);
|
|
|
|
|
IntersectRect(&rcClip, &rcBlt, &rcTrans);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
IntersectRect(&rcClip, &rcBlt, lprc);
|
|
|
|
|
xorg = rcClip.left-destPos.x; //<2F><><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB>
|
|
|
|
|
yorg = rcClip.top-destPos.y;
|
|
|
|
|
destPos.x = rcClip.left;
|
|
|
|
|
destPos.y = rcClip.top;
|
|
|
|
|
drawSize.cx = rcClip.right-rcClip.left;
|
|
|
|
|
drawSize.cy = rcClip.bottom-rcClip.top;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const BOOL fillrect = (lprc && (fuOptions & ETO_OPAQUE));
|
|
|
|
|
//clear bitmap
|
|
|
|
|
|
|
|
|
|
if(fillrect || GetBkMode(hdc) == OPAQUE) {
|
|
|
|
|
COLORREF bgcolor = GetBkColor(hdc); //<2F><><EFBFBD><EFBFBD><EFBFBD>Ƃ<EFBFBD><C682><EFBFBD><EFBFBD><EFBFBD><EFBFBD>w<EFBFBD>i<EFBFBD>F<EFBFBD><46>
|
|
|
|
|
//if ((bgcolor>>24)%2 || (bgcolor>>28)%2)
|
|
|
|
|
// bgcolor = 0;
|
|
|
|
|
if ((bgcolor>>24)%2 || (bgcolor>>28)%2)
|
|
|
|
|
bgcolor = GetPaletteColor(hdc, bgcolor);
|
|
|
|
|
SetBkMode(hCanvasDC, OPAQUE);
|
|
|
|
|
SetBkColor(hCanvasDC, bgcolor);
|
|
|
|
|
|
|
|
|
|
RECT rc = { xorg, yorg, drawSize.cx+ xorg, drawSize.cy+ yorg };
|
|
|
|
|
if (bZoomedDC)
|
|
|
|
|
{
|
|
|
|
|
rc.right+=2;
|
|
|
|
|
rc.bottom+=2;
|
|
|
|
|
}
|
|
|
|
|
cache.FillSolidRect(bgcolor, &rc);
|
|
|
|
|
|
|
|
|
|
if(fillrect) {
|
|
|
|
|
//FillRect(hdc, lprc, (HBRUSH)GetCurrentObject(hdc, OBJ_BRUSH));
|
|
|
|
|
ORIG_ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, lprc, NULL, 0, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!bZoomedDC)
|
|
|
|
|
{
|
|
|
|
|
if (!(BitBlt(hCanvasDC, xorg, yorg, drawSize.cx, drawSize.cy, hdc, destPos.x, destPos.y, SRCCOPY)))
|
|
|
|
|
{
|
|
|
|
|
ETO_THROW(ETOE_FREETYPE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SetWorldTransform(hCanvasDC, DCTrans->GetTransform());
|
|
|
|
|
if (!(BitBlt(hCanvasDC, DCTrans->TransformXCoordinateBA(xorg), DCTrans->TransformYCoordinateBA(yorg),
|
|
|
|
|
DCTrans->TransformXCoordinateBA(drawSize.cx+4), DCTrans->TransformYCoordinateBA(drawSize.cy+4), hdc,
|
|
|
|
|
DCTrans->TransformXCoordinateBA(destPos.x), DCTrans->TransformYCoordinateBA(destPos.y), SRCCOPY)))
|
|
|
|
|
{
|
|
|
|
|
SetWorldTransform(hCanvasDC, &stdXfm);
|
|
|
|
|
ETO_THROW(ETOE_FREETYPE);
|
|
|
|
|
}
|
|
|
|
|
SetWorldTransform(hCanvasDC, &stdXfm);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//setup
|
|
|
|
|
SetTextAlign(hCanvasDC, TA_LEFT | TA_TOP);
|
|
|
|
|
//debug
|
|
|
|
|
//Dbg_TraceExtTextOutW(nXStart, nYStart, fuOptions, lpString, cbString, lpDx);
|
|
|
|
|
|
|
|
|
|
//textout
|
|
|
|
|
SetTextColor(hCanvasDC, FTInfo.params->color);
|
|
|
|
|
SetBkMode(hCanvasDC, TRANSPARENT);
|
|
|
|
|
FTInfo.hdc = hCanvasDC;
|
|
|
|
|
|
|
|
|
|
if (!FreeTypeTextOut(hCanvasDC, cache, lpString, cbString, FTInfo, GlyphArray, ftDrawState)) {
|
|
|
|
|
ETO_THROW(ETOE_FREETYPE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//blt + clipping
|
|
|
|
|
/*
|
|
|
|
|
if(lprc && (fuOptions & ETO_CLIPPED)) {
|
|
|
|
|
//TRACE(_T("ClipRect={%d %d %d %d}, pos = (%d,%d)\n"), lprc->left, lprc->top, lprc->right, lprc->bottom,
|
|
|
|
|
// nXStart, nYStart);
|
|
|
|
|
//trace(L"ClipRect=%d %d %d %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
|
|
|
|
|
const RECT rcBlt = { destPos.x, destPos.y, destPos.x + drawSize.cx, destPos.y + drawSize.cy };
|
|
|
|
|
RECT rcClip = { 0 };
|
|
|
|
|
IntersectRect(&rcClip, &rcBlt, lprc);
|
|
|
|
|
BitBlt(hdc, rcClip.left, rcClip.top, rcClip.right - rcClip.left, rcClip.bottom - rcClip.top,
|
|
|
|
|
hCanvasDC, rcClip.left - rcBlt.left, rcClip.top - rcBlt.top, SRCCOPY);
|
|
|
|
|
} else {*/
|
|
|
|
|
if (!bZoomedDC)
|
|
|
|
|
BitBlt(hdc, destPos.x, destPos.y, drawSize.cx, drawSize.cy, hCanvasDC, xorg, yorg, SRCCOPY);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SetWorldTransform(hCanvasDC, DCTrans->GetTransform());
|
|
|
|
|
BitBlt(hdc, DCTrans->TransformXCoordinateBA(destPos.x), DCTrans->TransformYCoordinateBA(destPos.y),
|
|
|
|
|
DCTrans->TransformXCoordinateBA(drawSize.cx), DCTrans->TransformYCoordinateBA(drawSize.cy), hCanvasDC,
|
|
|
|
|
DCTrans->TransformXCoordinateBA(xorg), DCTrans->TransformYCoordinateBA(yorg), SRCCOPY);
|
|
|
|
|
SetWorldTransform(hCanvasDC, &stdXfm);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
//GdiFlush();
|
|
|
|
|
if(align & TA_UPDATECP) {
|
|
|
|
|
if (!bZoomedDC)
|
|
|
|
|
MoveToEx(hdc, curPos.x, curPos.y, NULL);
|
|
|
|
|
else
|
|
|
|
|
MoveToEx(hdc, DCTrans->TransformXCoordinateBA(curPos.x), DCTrans->TransformYCoordinateBA(curPos.y), NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ETO_CATCH();
|
|
|
|
|
if (otm)
|
|
|
|
|
free(otm);
|
|
|
|
|
bmp.RestoreBitmap();
|
|
|
|
|
if (hOldMDCFont)
|
|
|
|
|
{
|
|
|
|
|
SelectFont(hCanvasDC, hOldMDCFont);
|
|
|
|
|
DeleteFont(hZoomedFont);
|
|
|
|
|
hZoomedFont = NULL;
|
|
|
|
|
hOldMDCFont = NULL;
|
|
|
|
|
}
|
|
|
|
|
if(hPrevFont) {
|
|
|
|
|
SelectFont(hCanvasDC, hPrevFont);
|
|
|
|
|
}
|
|
|
|
|
if (hMyCurFont)
|
|
|
|
|
DeleteFont(hMyCurFont);
|
|
|
|
|
{
|
|
|
|
|
//CCriticalSectionLock __lock;
|
|
|
|
|
for (UINT i=0;i<cbString;i++)
|
|
|
|
|
{
|
|
|
|
|
if (GlyphArray[i])
|
|
|
|
|
{
|
|
|
|
|
FT_Done_Ref_Glyph(&GlyphArray[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete[] GlyphArray;
|
|
|
|
|
delete[] ftDrawState;
|
|
|
|
|
if (DCTrans)
|
|
|
|
|
delete DCTrans;
|
|
|
|
|
if (outlpDx)
|
|
|
|
|
delete[] outlpDx;
|
|
|
|
|
if(error == ETOE_OK) {
|
|
|
|
|
pTLInfo->InExtTextOut(false);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
int ret = ORIG_ExtTextOutW(hdc, nXStart, nYStart, fuOptions, lprc, lpString, cbString, lpDx);
|
|
|
|
|
pTLInfo->InExtTextOut(false);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI IMPL_MySetProcessMitigationPolicy(
|
2016-09-01 14:59:16 +08:00
|
|
|
|
_In_ PROCESS_MITIGATION_POLICY MitigationPolicy,
|
|
|
|
|
_In_ PVOID lpBuffer,
|
2016-09-02 17:29:33 +08:00
|
|
|
|
_In_ SIZE_T dwLength
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
if (MitigationPolicy == ProcessDynamicCodePolicy) {
|
|
|
|
|
PPROCESS_MITIGATION_DYNAMIC_CODE_POLICY(lpBuffer)->ProhibitDynamicCode = false;
|
|
|
|
|
}
|
|
|
|
|
return ORIG_MySetProcessMitigationPolicy(MitigationPolicy, lpBuffer, dwLength);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
HRESULT WINAPI IMPL_ScriptItemize(
|
|
|
|
|
const WCHAR* pwcInChars,
|
|
|
|
|
int cInChars,
|
|
|
|
|
int cMaxItems,
|
|
|
|
|
const SCRIPT_CONTROL* psControl,
|
|
|
|
|
const SCRIPT_STATE* psState,
|
|
|
|
|
SCRIPT_ITEM* pItems,
|
|
|
|
|
int* pcItems
|
|
|
|
|
) {
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
HRESULT hr = ORIG_ScriptItemize(pwcInChars, cInChars, cMaxItems, psControl, psState, pItems, pcItems);
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
|
return hr;
|
|
|
|
|
Dbg_TraceScriptItemize(pwcInChars, cInChars);
|
|
|
|
|
//<2F>ّ̎<D991><CC8E>Z<EFBFBD><5A><EFBFBD>N<EFBFBD>^<5E>Ŏn<C58E>܂<EFBFBD><DC82><EFBFBD><EFBFBD>s<EFBFBD>P<EFBFBD><50>(<28><><EFBFBD><EFBFBD>)<29><><EFBFBD>T<EFBFBD><54>
|
|
|
|
|
//<2F>ŏI<C58F><49><EFBFBD>s<EFBFBD>P<EFBFBD>ʂ̒<CA82><CC92><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߂̍<DF82><CC8D>ڂ<EFBFBD>*pcItems<6D>̒l<CC92>Ɋ܂܂<DC82><DC82>Ȃ<EFBFBD><C882><EFBFBD><EFBFBD>Ƃɒ<C682><C992><EFBFBD>
|
|
|
|
|
for (int i = 1; i < *pcItems; ++i) {
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F0969E82><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882><EFBFBD><EFBFBD>s<EFBFBD>P<EFBFBD>ʂ̓X<CD83>L<EFBFBD>b<EFBFBD>v
|
|
|
|
|
const int iCharPos = pItems[i].iCharPos;
|
|
|
|
|
if (pItems[i + 1].iCharPos - iCharPos < 2)
|
|
|
|
|
continue; //<2F>ّ̎<D991><CC8E>Z<EFBFBD><5A><EFBFBD>N<EFBFBD>^<5E>̕\<5C><><EFBFBD>ɂ͏<C982><CD8F>Ȃ<EFBFBD><C882>Ƃ<EFBFBD>Unicode<64>R<EFBFBD>[<5B>h<EFBFBD>|<7C>C<EFBFBD><43><EFBFBD>g2<67><EFBFBD><C282>K<EFBFBD>v
|
|
|
|
|
if (pwcInChars[iCharPos] != 0xDB40)
|
|
|
|
|
continue; //<2F><><EFBFBD>ʃT<CA83><54><EFBFBD>Q<EFBFBD>[<5B>g<EFBFBD>̒l<CC92><6C><EFBFBD>͈͊O
|
|
|
|
|
if (pwcInChars[iCharPos + 1] - 0xDD00 >= 0xF0)
|
|
|
|
|
continue; //<2F><><EFBFBD>ʃT<CA83><54><EFBFBD>Q<EFBFBD>[<5B>g<EFBFBD>̒l<CC92><6C><EFBFBD>͈͊O
|
|
|
|
|
//<2F>ّ̎<D991><CC8E>Z<EFBFBD><5A><EFBFBD>N<EFBFBD>^<5E><>1<EFBFBD>O<C291>̎<EFBFBD><CC8E>s<EFBFBD>P<EFBFBD>ʂɈړ<C988><DA93><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
pItems[i].iCharPos += 2;
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD>ɂȂ<C982><C882><EFBFBD><EFBFBD>ꍇ<EFBFBD>͎<EFBFBD><CD8E>s<EFBFBD>P<EFBFBD>ʂ<EFBFBD><CA82>̂<EFBFBD><CC82>̂<EFBFBD><CC82>폜<EFBFBD><ED8F9C><EFBFBD><EFBFBD>
|
|
|
|
|
if (pItems[i + 1].iCharPos <= pItems[i].iCharPos) {
|
|
|
|
|
memmove(&pItems[i], &pItems[i + 1], (*pcItems - i) * sizeof SCRIPT_ITEM);
|
|
|
|
|
--*pcItems;
|
|
|
|
|
--i; //<2F>폜<EFBFBD><ED8F9C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂<CC82><C282>܍<C282><DC8D>킹
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return hr;
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
//HFONT dummy=NULL;
|
|
|
|
|
/*
|
|
|
|
|
int WINAPI IMPL_GdipCreateFontFamilyFromName(const WCHAR *name, void *fontCollection, void **FontFamily)
|
|
|
|
|
{
|
|
|
|
|
LOGFONT lf={};
|
|
|
|
|
memset(&lf, 0, sizeof lf);
|
|
|
|
|
StringCchCopy(lf.lfFaceName, LF_FACESIZE, name);
|
|
|
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|
|
|
|
if (pSettings->CopyForceFont(lf, lf))
|
|
|
|
|
{
|
|
|
|
|
//dummy = CreateFont(1,0,0,0,0,0,0,0,DEFAULT_CHARSET,0,0,0,0,lf.lfFaceName);
|
|
|
|
|
return ORIG_GdipCreateFontFamilyFromName(lf.lfFaceName, fontCollection, FontFamily);
|
|
|
|
|
}
|
|
|
|
|
return ORIG_GdipCreateFontFamilyFromName(name, fontCollection, FontFamily);
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
HRESULT WINAPI IMPL_ScriptShape(
|
|
|
|
|
HDC hdc,
|
|
|
|
|
SCRIPT_CACHE* psc,
|
|
|
|
|
const WCHAR* pwcChars,
|
|
|
|
|
int cChars,
|
|
|
|
|
int cMaxGlyphs,
|
|
|
|
|
SCRIPT_ANALYSIS* psa,
|
|
|
|
|
WORD* pwOutGlyphs,
|
|
|
|
|
WORD* pwLogClust,
|
|
|
|
|
SCRIPT_VISATTR* psva,
|
|
|
|
|
int* pcGlyphs
|
|
|
|
|
) {
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
Dbg_TraceScriptShape(pwcChars, cChars, psa, NULL, 0);
|
|
|
|
|
//<2F><><EFBFBD>s<EFBFBD>P<EFBFBD>ʂ̖<CA82><CC96><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ّ̎<D991><CC8E>V<EFBFBD>[<5B>P<EFBFBD><50><EFBFBD>X<EFBFBD>łȂ<C582><C882><EFBFBD><EFBFBD>Ή<EFBFBD><CE89><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD>
|
|
|
|
|
WORD vsindex;
|
|
|
|
|
if (cChars < 3 || cMaxGlyphs < 1 || pwcChars[cChars - 2] != 0xDB40 || (vsindex = pwcChars[cChars - 1] - 0xDD00) >= 0xF0)
|
|
|
|
|
return ORIG_ScriptShape(hdc, psc, pwcChars, cChars, cMaxGlyphs, psa, pwOutGlyphs, pwLogClust, psva, pcGlyphs);
|
|
|
|
|
|
|
|
|
|
if (!hdc)
|
|
|
|
|
return E_PENDING; //<2F><><EFBFBD><EFBFBD><EFBFBD>ɂ<EFBFBD>HDC<44><43><EFBFBD>K<EFBFBD>v
|
|
|
|
|
|
|
|
|
|
//<2F>ّ̎<D991><CC8E>Z<EFBFBD><5A><EFBFBD>N<EFBFBD>^<5E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ăV<C483>F<EFBFBD>[<5B>s<EFBFBD><73><EFBFBD>O<EFBFBD>G<EFBFBD><47><EFBFBD>W<EFBFBD><57><EFBFBD>ɓn<C993><6E>
|
|
|
|
|
HRESULT hr = ORIG_ScriptShape(hdc, psc, pwcChars, cChars - 2, cMaxGlyphs - 1, psa, pwOutGlyphs, pwLogClust, psva, pcGlyphs);
|
|
|
|
|
if (FAILED(hr) || psa->fNoGlyphIndex)
|
|
|
|
|
return hr;
|
|
|
|
|
Dbg_TraceScriptShape(pwcChars, cChars, psa, pwOutGlyphs, *pcGlyphs);
|
|
|
|
|
|
|
|
|
|
//<2F>ŏI<C58F>O<EFBFBD><4F><EFBFBD>t<EFBFBD><74><EFBFBD>u<EFBFBD><75><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
WORD high;
|
|
|
|
|
WORD low = pwcChars[cChars - 3] - 0xDC00;
|
|
|
|
|
int baseChar;
|
|
|
|
|
if (cChars >= 4 && (high = pwcChars[cChars - 4] - 0xD800) < 0x400 && low < 0x400)
|
|
|
|
|
baseChar = ((high << 10) | low) + 0x10000;
|
|
|
|
|
else
|
|
|
|
|
baseChar = pwcChars[cChars - 3];
|
|
|
|
|
if (*pcGlyphs > 0) {
|
|
|
|
|
FreeTypeSubstGlyph(hdc, vsindex, baseChar, cChars, psa, pwOutGlyphs, pwLogClust, psva, pcGlyphs);
|
|
|
|
|
}
|
|
|
|
|
Dbg_TraceScriptShape(pwcChars, cChars, psa, pwOutGlyphs, *pcGlyphs);
|
|
|
|
|
|
|
|
|
|
return hr;
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
HRESULT WINAPI IMPL_ScriptTextOut(
|
|
|
|
|
const HDC hdc,
|
|
|
|
|
SCRIPT_CACHE* psc,
|
|
|
|
|
int x,
|
|
|
|
|
int y,
|
|
|
|
|
UINT fuOptions,
|
|
|
|
|
const RECT* lprc,
|
|
|
|
|
const SCRIPT_ANALYSIS* psa,
|
|
|
|
|
const WCHAR* pwcReserved,
|
|
|
|
|
int iReserved,
|
|
|
|
|
const WORD* pwGlyphs,
|
|
|
|
|
int cGlyphs,
|
|
|
|
|
const int* piAdvance,
|
|
|
|
|
const int* piJustify,
|
|
|
|
|
const GOFFSET* pGoffset
|
|
|
|
|
) {
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
CThreadLocalInfo* pTLInfo = g_TLInfo.GetPtr();
|
|
|
|
|
if (pTLInfo)
|
|
|
|
|
pTLInfo->InUniTextOut(true);
|
|
|
|
|
|
|
|
|
|
HRESULT hr = ORIG_ScriptTextOut(hdc, psc, x, y, fuOptions, lprc, psa, pwcReserved, iReserved,
|
|
|
|
|
pwGlyphs, cGlyphs, piAdvance, piJustify, pGoffset);
|
|
|
|
|
|
|
|
|
|
if (pTLInfo)
|
|
|
|
|
pTLInfo->InUniTextOut(false);
|
|
|
|
|
|
|
|
|
|
return hr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT WINAPI IMPL_ScriptStringOut(
|
|
|
|
|
__in SCRIPT_STRING_ANALYSIS ssa,
|
|
|
|
|
__in int iX,
|
|
|
|
|
__in int iY,
|
|
|
|
|
__in UINT uOptions,
|
|
|
|
|
__in const RECT *prc,
|
|
|
|
|
__in int iMinSel,
|
|
|
|
|
__in int iMaxSel,
|
|
|
|
|
__in BOOL fDisabled
|
|
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
CThreadLocalInfo* pTLInfo = g_TLInfo.GetPtr();
|
|
|
|
|
if (pTLInfo)
|
|
|
|
|
pTLInfo->InUniscribe(true);
|
|
|
|
|
|
|
|
|
|
HRESULT hr = ORIG_ScriptStringOut(ssa, iX, iY, uOptions, prc, iMinSel, iMaxSel, fDisabled);
|
|
|
|
|
|
|
|
|
|
if (pTLInfo)
|
|
|
|
|
pTLInfo->InUniscribe(false);
|
|
|
|
|
|
|
|
|
|
return hr;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
int WINAPI IMPL_GetTextFace(HDC hdc, int c, LPWSTR lpName)
|
|
|
|
|
{
|
|
|
|
|
//CThreadCounter __counter;
|
|
|
|
|
BOOL bResult = ORIG_GetTextFace(hdc, c, lpName);
|
|
|
|
|
wstring fontcache=GetCachedFont(GetCurrentFont(hdc));
|
|
|
|
|
if (fontcache.size()){
|
|
|
|
|
StringCchCopy(lpName, c, fontcache.c_str());
|
|
|
|
|
}
|
|
|
|
|
return bResult;
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//EOF
|