mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
466 lines
14 KiB
466 lines
14 KiB
/*++
|
|
*
|
|
* 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);
|
|
|
|
|
|
// 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;
|
|
|
|
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);
|
|
|
|
if (psz14)
|
|
{
|
|
// Capitalize the string for faster compares.
|
|
|
|
strncpy(achCapString, psz14, LF_FACESIZE);
|
|
_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 ( !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 ( !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 ( !strcmp(achCapString, szSymbol) ||
|
|
!strcmp(achCapString, szZapfDingbats) ||
|
|
!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) && !strcmp(achCapString, szMavisCourier))
|
|
{
|
|
iWidth = 13;
|
|
}
|
|
}
|
|
|
|
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));
|
|
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.
|
|
|
|
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 ( !strcmp(achCapString, szHelv) )
|
|
{
|
|
logfont.lfPitchAndFamily |= ( (logfont.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 ( !strcmp(achCapString, szTmsRmn) )
|
|
{
|
|
logfont.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 ( !strcmp(achCapString, szSymbol) ||
|
|
!strcmp(achCapString, szZapfDingbats) ||
|
|
!strcmp(achCapString, szZapf_Dingbats) )
|
|
{
|
|
logfont.lfCharSet = SYMBOL_CHARSET;
|
|
}
|
|
}
|
|
}
|
|
|
|
ul = GETHFONT16(CreateFontIndirect(&logfont));
|
|
|
|
FREEARGPTR(parg16);
|
|
|
|
RETURN(ul);
|
|
}
|
|
|
|
|
|
LPSTR lpMSSansSerif = "MS Sans Serif";
|
|
LPSTR lpMSSerif = "MS Serif";
|
|
|
|
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 (!strcmp(pEnumLogFont->elfLogFont.lfFaceName, lpMSSansSerif)) {
|
|
strcpy(pEnumLogFont->elfLogFont.lfFaceName, "Helv");
|
|
lpFaceNameT = lpMSSansSerif;
|
|
}
|
|
else if (!strcmp(pEnumLogFont->elfLogFont.lfFaceName, lpMSSerif)) {
|
|
strcpy(pEnumLogFont->elfLogFont.lfFaceName, "Tms Rmn");
|
|
lpFaceNameT = lpMSSerif;
|
|
}
|
|
}
|
|
}
|
|
|
|
CallAgain:
|
|
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 (((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);
|
|
if (ulLast > 0xff)
|
|
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);
|
|
}
|