670 lines
21 KiB
C
670 lines
21 KiB
C
|
/*++
|
||
|
*
|
||
|
* WOW v1.0
|
||
|
*
|
||
|
* Copyright (c) 1991, Microsoft Corporation
|
||
|
*
|
||
|
* WGFONT.C
|
||
|
* WOW32 16-bit GDI API support
|
||
|
*
|
||
|
* History:
|
||
|
* Created 07-Mar-1991 by Jeff Parsons (jeffpar)
|
||
|
--*/
|
||
|
|
||
|
|
||
|
#include "precomp.h"
|
||
|
#pragma hdrstop
|
||
|
#include "wingdip.h"
|
||
|
|
||
|
MODNAME(wgfont.c);
|
||
|
|
||
|
extern int RemoveFontResourceTracking(LPCSTR psz, UINT id);
|
||
|
extern int AddFontResourceTracking(LPCSTR psz, UINT id);
|
||
|
|
||
|
|
||
|
// for Quickbooks v4 & v5 OCR font support
|
||
|
void LoadOCRFont(void);
|
||
|
char szOCRA[] = "OCR-A";
|
||
|
char szFonts[] = "\\FONTS";
|
||
|
char szOCRDotTTF[] = "\\OCR-A.TTF";
|
||
|
BOOL gfOCRFontLoaded = FALSE;
|
||
|
|
||
|
|
||
|
// a.k.a. WOWAddFontResource
|
||
|
ULONG FASTCALL WG32AddFontResource(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul;
|
||
|
PSZ psz1;
|
||
|
register PADDFONTRESOURCE16 parg16;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(ADDFONTRESOURCE16), parg16);
|
||
|
GETPSZPTR(parg16->f1, psz1);
|
||
|
|
||
|
// note: we will never get an hModule in the low word here.
|
||
|
// the 16-bit side resolves hModules to an lpsz before calling us
|
||
|
|
||
|
if( CURRENTPTD()->dwWOWCompatFlags & WOWCF_UNLOADNETFONTS )
|
||
|
{
|
||
|
ul = GETINT16(AddFontResourceTracking(psz1,(UINT)CURRENTPTD()));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ul = GETINT16(AddFontResourceA(psz1));
|
||
|
}
|
||
|
|
||
|
FREEPSZPTR(psz1);
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
RETURN(ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
#define PITCH_MASK ( FIXED_PITCH | VARIABLE_PITCH )
|
||
|
|
||
|
ULONG FASTCALL WG32CreateFont(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul;
|
||
|
PSZ psz14;
|
||
|
register PCREATEFONT16 parg16;
|
||
|
INT iWidth;
|
||
|
char achCapString[LF_FACESIZE];
|
||
|
BYTE lfCharSet;
|
||
|
BYTE lfPitchAndFamily;
|
||
|
#ifdef FE_SB
|
||
|
BOOL bUseAlternateFace = FALSE;
|
||
|
#endif
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(CREATEFONT16), parg16);
|
||
|
GETPSZPTR(parg16->f14, psz14);
|
||
|
|
||
|
// take careof compatiblity flags:
|
||
|
// if a specific width is specified and GACF_30AVGWIDTH compatiblity
|
||
|
// flag is set, scaledown the width by 7/8.
|
||
|
//
|
||
|
|
||
|
iWidth = INT32(parg16->f2);
|
||
|
if (iWidth != 0 &&
|
||
|
(W32GetAppCompatFlags((HAND16)NULL) & GACF_30AVGWIDTH)) {
|
||
|
iWidth = (iWidth * 7) / 8;
|
||
|
}
|
||
|
|
||
|
lfCharSet = BYTE32(parg16->f9);
|
||
|
lfPitchAndFamily = BYTE32(parg16->f13);
|
||
|
|
||
|
#ifdef FE_SB
|
||
|
if (psz14 && *psz14)
|
||
|
#else // !FE_SB
|
||
|
if (psz14)
|
||
|
#endif // !FE_SB
|
||
|
{
|
||
|
// Capitalize the string for faster compares.
|
||
|
|
||
|
WOW32_strncpy(achCapString, psz14, LF_FACESIZE);
|
||
|
WOW32_strupr(achCapString);
|
||
|
|
||
|
// Here we are going to implement a bunch of Win 3.1 hacks rather
|
||
|
// than contaminate the 32-bit engine. These same hacks can be found
|
||
|
// in WOW (in the CreateFont/CreateFontIndirect code).
|
||
|
//
|
||
|
// These hacks are keyed off the facename in the LOGFONT. String
|
||
|
// comparisons have been unrolled for maximal performance.
|
||
|
|
||
|
// Win 3.1 facename-based hack. Some apps, like
|
||
|
// Publisher, create a "Helv" font but have the lfPitchAndFamily
|
||
|
// set to specify FIXED_PITCH. To work around this, we will patch
|
||
|
// the pitch field for a "Helv" font to be variable.
|
||
|
|
||
|
if ( !WOW32_strcmp(achCapString, szHelv) )
|
||
|
{
|
||
|
lfPitchAndFamily |= ( (lfPitchAndFamily & ~PITCH_MASK) | VARIABLE_PITCH );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Win 3.1 hack for Legacy 2.0. When a printer does not enumerate
|
||
|
// a "Tms Rmn" font, the app enumerates and gets the LOGFONT for
|
||
|
// "Script" and then create a font with the name "Tms Rmn" but with
|
||
|
// the lfCharSet and lfPitchAndFamily taken from the LOGFONT for
|
||
|
// "Script". Here we will over the lfCharSet to be ANSI_CHARSET.
|
||
|
|
||
|
if ( !WOW32_strcmp(achCapString, szTmsRmn) )
|
||
|
{
|
||
|
lfCharSet = ANSI_CHARSET;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// If the lfFaceName is "Symbol", "Zapf Dingbats", or "ZapfDingbats",
|
||
|
// enforce lfCharSet to be SYMBOL_CHARSET. Some apps (like Excel) ask
|
||
|
// for a "Symbol" font but have the char set set to ANSI. PowerPoint
|
||
|
// has the same problem with "Zapf Dingbats".
|
||
|
|
||
|
if ( !WOW32_strcmp(achCapString, szSymbol) ||
|
||
|
!WOW32_strcmp(achCapString, szZapfDingbats) ||
|
||
|
!WOW32_strcmp(achCapString, szZapf_Dingbats) )
|
||
|
{
|
||
|
lfCharSet = SYMBOL_CHARSET;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Win3.1(Win95) hack for Mavis Beacon Teaches Typing 3.0
|
||
|
// The app uses a fixed width of 34*13 for the typing screen.
|
||
|
// NT returns 14 from GetTextExtent for Mavis Beacon Courier FP font (width of 14)
|
||
|
// while Win95 returns 13, thus long strings won't fit in the typing screen on NT.
|
||
|
// Force the width to 13.
|
||
|
|
||
|
if ( iWidth==14 && (INT32(parg16->f1)== 20) && !WOW32_strcmp(achCapString, szMavisCourier))
|
||
|
{
|
||
|
iWidth = 13;
|
||
|
}
|
||
|
|
||
|
#ifdef FE_SB
|
||
|
// WOWCF_FE_ICHITARO_ITALIC
|
||
|
// Ichitaro asks for System Mincho because WIFE fonts aren't installed
|
||
|
// we give it a proportional font which is can't handle. If we see
|
||
|
// this face name we will replace it with Ms Mincho
|
||
|
|
||
|
if (GetSystemDefaultLangID() == 0x411 &&
|
||
|
CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_ICHITARO_ITALIC )
|
||
|
{
|
||
|
if(!WOW32_strcmp(achCapString, szSystemMincho))
|
||
|
{
|
||
|
strcpy(achCapString, szMsMincho);
|
||
|
bUseAlternateFace = TRUE;
|
||
|
}
|
||
|
}
|
||
|
#endif // FE_SB
|
||
|
|
||
|
}
|
||
|
|
||
|
#ifdef FE_SB
|
||
|
ul = GETHFONT16(CreateFont(INT32(parg16->f1),
|
||
|
iWidth,
|
||
|
INT32(parg16->f3),
|
||
|
INT32(parg16->f4),
|
||
|
INT32(parg16->f5),
|
||
|
BYTE32(parg16->f6),
|
||
|
BYTE32(parg16->f7),
|
||
|
BYTE32(parg16->f8),
|
||
|
lfCharSet,
|
||
|
BYTE32(parg16->f10),
|
||
|
BYTE32(parg16->f11),
|
||
|
BYTE32(parg16->f12),
|
||
|
lfPitchAndFamily,
|
||
|
(bUseAlternateFace ? achCapString : psz14)
|
||
|
));
|
||
|
#else
|
||
|
ul = GETHFONT16(CreateFont(INT32(parg16->f1),
|
||
|
iWidth,
|
||
|
INT32(parg16->f3),
|
||
|
INT32(parg16->f4),
|
||
|
INT32(parg16->f5),
|
||
|
BYTE32(parg16->f6),
|
||
|
BYTE32(parg16->f7),
|
||
|
BYTE32(parg16->f8),
|
||
|
lfCharSet,
|
||
|
BYTE32(parg16->f10),
|
||
|
BYTE32(parg16->f11),
|
||
|
BYTE32(parg16->f12),
|
||
|
lfPitchAndFamily,
|
||
|
psz14));
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
FREEPSZPTR(psz14);
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
RETURN(ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WG32CreateFontIndirect(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul;
|
||
|
LOGFONT logfont;
|
||
|
register PCREATEFONTINDIRECT16 parg16;
|
||
|
char achCapString[LF_FACESIZE];
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(CREATEFONTINDIRECT16), parg16);
|
||
|
GETLOGFONT16(parg16->f1, &logfont);
|
||
|
|
||
|
// Capitalize the string for faster compares.
|
||
|
|
||
|
WOW32_strncpy(achCapString, logfont.lfFaceName, LF_FACESIZE);
|
||
|
CharUpperBuff(achCapString, LF_FACESIZE);
|
||
|
|
||
|
// Here we are going to implement a bunch of Win 3.1 hacks rather
|
||
|
// than contaminate the 32-bit engine. These same hacks can be found
|
||
|
// in WOW (in the CreateFont/CreateFontIndirect code).
|
||
|
//
|
||
|
// These hacks are keyed off the facename in the LOGFONT. String
|
||
|
// comparisons have been unrolled for maximal performance.
|
||
|
|
||
|
// Win 3.1 facename-based hack. Some apps, like
|
||
|
// Publisher, create a "Helv" font but have the lfPitchAndFamily
|
||
|
// set to specify FIXED_PITCH. To work around this, we will patch
|
||
|
// the pitch field for a "Helv" font to be variable.
|
||
|
|
||
|
if ( !WOW32_strcmp(achCapString, szHelv) )
|
||
|
{
|
||
|
logfont.lfPitchAndFamily |= ( (logfont.lfPitchAndFamily & ~PITCH_MASK) | VARIABLE_PITCH );
|
||
|
#ifdef FE_SB
|
||
|
//
|
||
|
// FE Win 3.1 facename-based hack. Some FE apps
|
||
|
// create a "Helv" font but have the lfCharSet
|
||
|
// set to DBCS charset (ex. SHIFTJIS_CHARSET).
|
||
|
// To work around this, we will wipe out the
|
||
|
// lfFaceName[0] with '\0' and let GDI picks a
|
||
|
// DBCS font for us.
|
||
|
//
|
||
|
if (IS_ANY_DBCS_CHARSET(logfont.lfCharSet))
|
||
|
logfont.lfFaceName[0]='\0';
|
||
|
#endif // FE_SB
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Win 3.1 hack for Legacy 2.0. When a printer does not enumerate
|
||
|
// a "Tms Rmn" font, the app enumerates and gets the LOGFONT for
|
||
|
// "Script" and then create a font with the name "Tms Rmn" but with
|
||
|
// the lfCharSet and lfPitchAndFamily taken from the LOGFONT for
|
||
|
// "Script". Here we will over the lfCharSet to be ANSI_CHARSET.
|
||
|
|
||
|
if ( !WOW32_strcmp(achCapString, szTmsRmn) )
|
||
|
{
|
||
|
logfont.lfCharSet = ANSI_CHARSET;
|
||
|
}
|
||
|
|
||
|
// for Quickbooks v4 & v5 OCR font support (see LoadOCRFont for details)
|
||
|
else if ( !WOW32_strcmp(achCapString, szOCRA) )
|
||
|
{
|
||
|
|
||
|
// Further localize this hack to QuickBooks. Most other apps won't
|
||
|
// know about this quirk in this particular font.
|
||
|
if(logfont.lfCharSet == SYMBOL_CHARSET) {
|
||
|
logfont.lfCharSet = DEFAULT_CHARSET;
|
||
|
|
||
|
if(!gfOCRFontLoaded) {
|
||
|
LoadOCRFont();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// If the lfFaceName is "Symbol", "Zapf Dingbats", or "ZapfDingbats",
|
||
|
// enforce lfCharSet to be SYMBOL_CHARSET. Some apps (like Excel) ask
|
||
|
// for a "Symbol" font but have the char set set to ANSI. PowerPoint
|
||
|
// has the same problem with "Zapf Dingbats".
|
||
|
|
||
|
if ( !WOW32_strcmp(achCapString, szSymbol) ||
|
||
|
!WOW32_strcmp(achCapString, szZapfDingbats) ||
|
||
|
!WOW32_strcmp(achCapString, szZapf_Dingbats) )
|
||
|
{
|
||
|
logfont.lfCharSet = SYMBOL_CHARSET;
|
||
|
}
|
||
|
|
||
|
#ifdef FE_SB
|
||
|
// WOWCF_FE_ICHITARO_ITALIC
|
||
|
// Ichitaro asks for System Mincho because WIFE fonts aren't installed
|
||
|
// we give it a proportional font which is can't handle. If we see
|
||
|
// this face name we will replace it with Ms Mincho
|
||
|
|
||
|
if (GetSystemDefaultLangID() == 0x411 &&
|
||
|
CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_ICHITARO_ITALIC )
|
||
|
{
|
||
|
if(!WOW32_strcmp(achCapString, szSystemMincho))
|
||
|
{
|
||
|
strcpy(logfont.lfFaceName, szMsMincho);
|
||
|
}
|
||
|
}
|
||
|
#endif // FE_SB
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ul = GETHFONT16(CreateFontIndirect(&logfont));
|
||
|
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
RETURN(ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
LPSTR lpMSSansSerif = "MS Sans Serif";
|
||
|
LPSTR lpMSSerif = "MS Serif";
|
||
|
LPSTR lpHelvetica = "Helvetica";
|
||
|
|
||
|
INT W32EnumFontFunc(LPENUMLOGFONT pEnumLogFont,
|
||
|
LPNEWTEXTMETRIC pNewTextMetric, INT nFontType, PFNTDATA pFntData)
|
||
|
{
|
||
|
INT iReturn;
|
||
|
PARM16 Parm16;
|
||
|
LPSTR lpFaceNameT = NULL;
|
||
|
|
||
|
WOW32ASSERT(pFntData);
|
||
|
|
||
|
// take care of compatibility flags:
|
||
|
// ORin DEVICE_FONTTYPE bit if the fonttype is truetype and the
|
||
|
// Compataibility flag GACF_CALLTTDEVICE is set.
|
||
|
//
|
||
|
|
||
|
if (nFontType & TRUETYPE_FONTTYPE) {
|
||
|
if (W32GetAppCompatFlags((HAND16)NULL) & GACF_CALLTTDEVICE) {
|
||
|
nFontType |= DEVICE_FONTTYPE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// take care of compatibility flags:
|
||
|
// replace Ms Sans Serif with Helv and
|
||
|
// replace Ms Serif with Tms Rmn
|
||
|
//
|
||
|
// only if the facename is NULL and the compat flag GACF_ENUMHELVNTMSRMN
|
||
|
// is set.
|
||
|
|
||
|
if (pFntData->vpFaceName == (VPVOID)NULL) {
|
||
|
if (W32GetAppCompatFlags((HAND16)NULL) & GACF_ENUMHELVNTMSRMN) {
|
||
|
if (!WOW32_strcmp(pEnumLogFont->elfLogFont.lfFaceName, lpMSSansSerif)) {
|
||
|
strcpy(pEnumLogFont->elfLogFont.lfFaceName, "Helv");
|
||
|
lpFaceNameT = lpMSSansSerif;
|
||
|
}
|
||
|
else if (!WOW32_strcmp(pEnumLogFont->elfLogFont.lfFaceName, lpHelvetica)) {
|
||
|
strcpy(pEnumLogFont->elfLogFont.lfFaceName, "Helv");
|
||
|
lpFaceNameT = lpMSSansSerif;
|
||
|
}
|
||
|
else if (!WOW32_strcmp(pEnumLogFont->elfLogFont.lfFaceName, lpMSSerif)) {
|
||
|
strcpy(pEnumLogFont->elfLogFont.lfFaceName, "Tms Rmn");
|
||
|
lpFaceNameT = lpMSSerif;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CallAgain:
|
||
|
|
||
|
// be sure allocation size matches stackfree16() size below
|
||
|
pFntData->vpLogFont = stackalloc16(sizeof(ENUMLOGFONT16)+sizeof(NEWTEXTMETRIC16));
|
||
|
|
||
|
pFntData->vpTextMetric = (VPVOID)((LPSTR)pFntData->vpLogFont + sizeof(ENUMLOGFONT16));
|
||
|
|
||
|
PUTENUMLOGFONT16(pFntData->vpLogFont, pEnumLogFont);
|
||
|
PUTNEWTEXTMETRIC16(pFntData->vpTextMetric, pNewTextMetric);
|
||
|
|
||
|
STOREDWORD(Parm16.EnumFontProc.vpLogFont, pFntData->vpLogFont);
|
||
|
STOREDWORD(Parm16.EnumFontProc.vpTextMetric, pFntData->vpTextMetric);
|
||
|
STOREDWORD(Parm16.EnumFontProc.vpData,pFntData->dwUserFntParam);
|
||
|
|
||
|
Parm16.EnumFontProc.nFontType = (SHORT)nFontType;
|
||
|
|
||
|
CallBack16(RET_ENUMFONTPROC, &Parm16, pFntData->vpfnEnumFntProc, (PVPVOID)&iReturn);
|
||
|
|
||
|
if(pFntData->vpLogFont) {
|
||
|
stackfree16(pFntData->vpLogFont,
|
||
|
(sizeof(ENUMLOGFONT16) + sizeof(NEWTEXTMETRIC16)));
|
||
|
}
|
||
|
|
||
|
if (((SHORT)iReturn) && lpFaceNameT) {
|
||
|
// if the callback returned true, now call with the actual facename
|
||
|
// Just to be sure, we again copy all the data for callback. This will
|
||
|
// take care of any apps which modify the passed in structures.
|
||
|
|
||
|
strcpy(pEnumLogFont->elfLogFont.lfFaceName, lpFaceNameT);
|
||
|
lpFaceNameT = (LPSTR)NULL;
|
||
|
goto CallAgain;
|
||
|
}
|
||
|
return (SHORT)iReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG W32EnumFontHandler( PVDMFRAME pFrame, BOOL fEnumFontFamilies )
|
||
|
{
|
||
|
ULONG ul = 0;
|
||
|
PSZ psz2;
|
||
|
FNTDATA FntData;
|
||
|
register PENUMFONTS16 parg16;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(ENUMFONTS16), parg16);
|
||
|
GETPSZPTR(parg16->f2, psz2);
|
||
|
|
||
|
FntData.vpfnEnumFntProc = DWORD32(parg16->f3);
|
||
|
FntData.dwUserFntParam = DWORD32(parg16->f4);
|
||
|
FntData.vpFaceName = DWORD32(parg16->f2);
|
||
|
|
||
|
|
||
|
if ( fEnumFontFamilies ) {
|
||
|
ul = GETINT16(EnumFontFamilies(HDC32(parg16->f1),
|
||
|
psz2,
|
||
|
(FONTENUMPROC)W32EnumFontFunc,
|
||
|
(LPARAM)&FntData));
|
||
|
} else {
|
||
|
ul = GETINT16(EnumFonts(HDC32(parg16->f1),
|
||
|
psz2,
|
||
|
(FONTENUMPROC)W32EnumFontFunc,
|
||
|
(LPARAM)&FntData));
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
FREEPSZPTR(psz2);
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
RETURN(ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WG32EnumFonts(PVDMFRAME pFrame)
|
||
|
{
|
||
|
return( W32EnumFontHandler( pFrame, FALSE ) );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WG32GetAspectRatioFilter(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul = 0;
|
||
|
SIZE size2;
|
||
|
register PGETASPECTRATIOFILTER16 parg16;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(GETASPECTRATIOFILTER16), parg16);
|
||
|
|
||
|
if (GETDWORD16(GetAspectRatioFilterEx(HDC32(parg16->f1), &size2))) {
|
||
|
ul = (WORD)size2.cx | (size2.cy << 16);
|
||
|
}
|
||
|
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
RETURN(ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WG32GetCharWidth(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul = 0L;
|
||
|
INT ci;
|
||
|
PINT pi4;
|
||
|
register PGETCHARWIDTH16 parg16;
|
||
|
INT BufferT[256];
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(GETCHARWIDTH16), parg16);
|
||
|
|
||
|
ci = WORD32(parg16->wLastChar) - WORD32(parg16->wFirstChar) + 1;
|
||
|
pi4 = STACKORHEAPALLOC(ci * sizeof(INT), sizeof(BufferT), BufferT);
|
||
|
|
||
|
if (pi4) {
|
||
|
ULONG ulLast = WORD32(parg16->wLastChar);
|
||
|
#ifdef FE_SB
|
||
|
/*
|
||
|
* If ulLast sets DBCS code (0x82xx), then below code is illigal.
|
||
|
*/
|
||
|
if (ulLast > 0xff && !(IsDBCSLeadByte(HIBYTE(ulLast))))
|
||
|
#else // !FE_SB
|
||
|
if (ulLast > 0xff)
|
||
|
#endif // !FE_SB
|
||
|
ulLast = 0xff;
|
||
|
|
||
|
ul = GETBOOL16(GetCharWidth(HDC32(parg16->hDC),
|
||
|
WORD32(parg16->wFirstChar),
|
||
|
ulLast,
|
||
|
pi4));
|
||
|
|
||
|
PUTINTARRAY16(parg16->lpIntBuffer, ci, pi4);
|
||
|
STACKORHEAPFREE(pi4, BufferT);
|
||
|
|
||
|
}
|
||
|
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
RETURN(ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
// a.k.a. WOWRemoveFontResource
|
||
|
ULONG FASTCALL WG32RemoveFontResource(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul;
|
||
|
PSZ psz1;
|
||
|
register PREMOVEFONTRESOURCE16 parg16;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(REMOVEFONTRESOURCE16), parg16);
|
||
|
|
||
|
GETPSZPTR(parg16->f1, psz1);
|
||
|
|
||
|
// note: we will never get an hModule in the low word here.
|
||
|
// the 16-bit side resolves hModules to an lpsz before calling us
|
||
|
|
||
|
|
||
|
if( CURRENTPTD()->dwWOWCompatFlags & WOWCF_UNLOADNETFONTS )
|
||
|
{
|
||
|
ul = GETBOOL16(RemoveFontResourceTracking(psz1,(UINT)CURRENTPTD()));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ul = GETBOOL16(RemoveFontResource(psz1));
|
||
|
}
|
||
|
|
||
|
FREEPSZPTR(psz1);
|
||
|
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
RETURN(ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
/* WG32GetCurLogFont
|
||
|
*
|
||
|
* This thunk implements the undocumented Win3.0 and Win3.1 API
|
||
|
* GetCurLogFont (GDI.411). Symantec QA4.0 uses it.
|
||
|
*
|
||
|
* HFONT GetCurLogFont (HDC)
|
||
|
* HDC hDC; // Device Context
|
||
|
*
|
||
|
* This function returns the current Logical font selected for the
|
||
|
* specified device context.
|
||
|
*
|
||
|
* To implement this undocumented API we will use the NT undocumented API
|
||
|
* GetHFONT.
|
||
|
*
|
||
|
* SudeepB 08-Mar-1996
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
extern HFONT APIENTRY GetHFONT (HDC hdc);
|
||
|
|
||
|
ULONG FASTCALL WG32GetCurLogFont(PVDMFRAME pFrame)
|
||
|
{
|
||
|
|
||
|
ULONG ul;
|
||
|
register PGETCURLOGFONT16 parg16;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(GETCURLOGFONT16), parg16);
|
||
|
|
||
|
ul = GETHFONT16 (GetHFONT(HDC32 (parg16->hDC)));
|
||
|
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
return (ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// This allows Quickbooks v4 & v5 to use their OCR-A.TTF font right after they
|
||
|
// install. At the end of installation on both versions, you are asked if you
|
||
|
// want to "restart" windows. If you click OK it logs you off of NT5, but does
|
||
|
// *not* reboot the system -- which the app is counting on to cause the OCR-A
|
||
|
// font to be loaded. The result on W2K is that whenever the app uses the OCR-A
|
||
|
// font, it will get mapped to wingdings instead.
|
||
|
//
|
||
|
// This is further complicated by the fact that the font file OCR-A.TTF doesn't
|
||
|
// specify the charset in the header. On Win3.1, Win95, & pre-NT5, unspecified
|
||
|
// charset's got mapped to the SYMBOL_CHARSET - therefore, Quickbooks specifies
|
||
|
// SYMBOL_CHARSET in its LOGFONT struct to accomodate this. (OCR-A apparently
|
||
|
// is licenced from Monotype Typography, Ltd. which presumably is why Intuit
|
||
|
// didn't fix the header issue in the font file).
|
||
|
//
|
||
|
// This changed on Win98 and W2K, unspecified charset's now get mapped to the
|
||
|
// DEFAULT_CHARSET. This was done so these fonts will always map to a default
|
||
|
// localized font that will always be readable. Hence, the hack where we change
|
||
|
// the charset from SYMBOL_CHARSET to DEFAULT_CHARSET in the LOGFONT struct.
|
||
|
//
|
||
|
// On v4, the install program copies OCR-A.FOT & OCR-A.TTF to the SYSTEM dir.
|
||
|
// Once you "restart" (not reboot) the system & log back on, the OCR-A font is
|
||
|
// added to the registry (as OCR-A.FOT) but the font files are still in the
|
||
|
// SYSTEM dir. Rebooting causes the fonts files to be moved to the FONTS dir,
|
||
|
// the registry entry is changed to OCR-A.TTF. (done by the "Font Sweeper")
|
||
|
//
|
||
|
// On v5, the install program copies the .ttf & .fot files to the FONTS dir
|
||
|
// but again, counts on the reboot to cause the fonts to be loaded. It puts
|
||
|
// correct registry entry (OCR-A.TTF) in the registry fonts section.
|
||
|
//
|
||
|
// The result of all this is:
|
||
|
// For either version of the app, without the charset hack, you will always get
|
||
|
// a wingding font instead of OCR-A. With the charset hack, you will get a
|
||
|
// readable font, such as Arial, until you reboot -- after which you will get
|
||
|
// OCR-A for v5 but Arial for v4. With this function (in conjunction with the
|
||
|
// charset hack) both version will always get OCR-A with or without rebooting.
|
||
|
//
|
||
|
// This function explicitly loads the OCR-A from the font files located in
|
||
|
// either the FONTS dir or the SYSTEM dir.
|
||
|
//
|
||
|
void LoadOCRFont(void)
|
||
|
{
|
||
|
char szFontPath[MAX_PATH];
|
||
|
DWORD dw;
|
||
|
int cb;
|
||
|
|
||
|
// get equivalent of "c:\windows" for this system
|
||
|
dw = GetWindowsDirectory(szFontPath, MAX_PATH);
|
||
|
|
||
|
// we're going to add a maximum of 18 chars "\SYSTEM\OCR-A.TTF"
|
||
|
if(dw && ((MAX_PATH - 18) > dw)) {
|
||
|
|
||
|
// build "c:\windows\FONTS\OCR-A.TTF" (QuickBooks v5)
|
||
|
strcat(szFontPath, szFonts);
|
||
|
strcat(szFontPath, szOCRDotTTF);
|
||
|
|
||
|
// If font file doesn't exist in FONTS dir, this must be QuickBooks v4
|
||
|
// The FR_PRIVATE flag means that the font will be unloaded when the vdm
|
||
|
// process goes away. The FR_NO_ENUM flag means that this instance of
|
||
|
// the font can't be enumerated by other processes (it might go away
|
||
|
// while the other processes are trying to use it).
|
||
|
cb = AddFontResourceEx(szFontPath, FR_PRIVATE | FR_NOT_ENUM, NULL);
|
||
|
if(!cb) {
|
||
|
|
||
|
// reset path to "c:\windows"
|
||
|
szFontPath[dw] = '\0';
|
||
|
|
||
|
// build "c:\windows\SYSTEM\OCR-A.TTF"
|
||
|
strcat(szFontPath, szSystem);
|
||
|
strcat(szFontPath, szOCRDotTTF);
|
||
|
|
||
|
cb = AddFontResourceEx(szFontPath, FR_PRIVATE | FR_NOT_ENUM, NULL);
|
||
|
|
||
|
// if it wasn't loaded from the SYSTEM dir either, punt
|
||
|
}
|
||
|
|
||
|
if(cb) {
|
||
|
|
||
|
// specify that the font is already loaded for the life of this VDM
|
||
|
gfOCRFontLoaded = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|