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.
1358 lines
42 KiB
1358 lines
42 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: enumgdi.cxx
|
|
*
|
|
* Enumeration routines.
|
|
* hefs
|
|
* Created: 28-Mar-1992 16:18:45
|
|
* Author: Gilman Wong [gilmanw]
|
|
*
|
|
* Copyright (c) 1992-199 Microsoft Corporation
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
// gaclrEnumColorTable
|
|
//
|
|
// Colors used for GreEnumPens and GreEnumBrushes. This color table is
|
|
// set up so that:
|
|
//
|
|
// - the first 2 entries are for monochrome devices
|
|
//
|
|
// - the first 8 entries are for 8-color devices
|
|
//
|
|
// - the first 16 are for 4 BPP color devices
|
|
//
|
|
// - the first 20 are for 8 BPP and up color devices
|
|
|
|
static COLORREF
|
|
gaclrEnumColorTable[] = { 0x00000000, // black
|
|
0x00ffffff, // white (monochrome)
|
|
|
|
0x000000ff, // red
|
|
0x0000ff00, // green
|
|
0x0000ffff, // yellow
|
|
0x00ff0000, // blue
|
|
0x00ff00ff, // magenta
|
|
0x00ffff00, // cyan (EGA hi-intensity)
|
|
|
|
0x00808080, // dark grey
|
|
0x00c0c0c0, // light grey
|
|
0x00000080, // red
|
|
0x00008000, // green
|
|
0x00008080, // yellow
|
|
0x00800000, // blue
|
|
0x00800080, // magenta
|
|
0x00808000, // cyan (EGA lo-intensity)
|
|
|
|
0x00c0dcc0, // money green
|
|
0x00f0c8a4, // cool blue
|
|
0x00f0fbff, // off white
|
|
0x00a4a0a0 // med grey (extra colors)
|
|
};
|
|
|
|
static ULONG gulEnumColorTableSize = sizeof(gaclrEnumColorTable) / sizeof(COLORREF);
|
|
|
|
#define ECT_1BPP 2 // use this many colors for 1 BPP
|
|
#define ECT_EGA 8 // use this many colors for EGA
|
|
#define ECT_4BPP 16 // use this many colors for 4 BPP
|
|
#define ECT_8BPP min(gulEnumColorTableSize, 256) // use this many colors for 8 BPP
|
|
|
|
|
|
#define ENUM_FILTER_NONE 0
|
|
#define ENUM_FILTER_TT 1
|
|
#define ENUM_FILTER_NONTT 2
|
|
|
|
// gaulEnumPenStyles
|
|
//
|
|
// Pen styles used for GreEnumPens.
|
|
|
|
static ULONG
|
|
gaulPenStyles[] = { PS_SOLID,
|
|
PS_DASH,
|
|
PS_DOT,
|
|
PS_DASHDOT,
|
|
PS_DASHDOTDOT
|
|
};
|
|
|
|
static ULONG gulPenStylesTableSize = sizeof(gaulPenStyles) / sizeof(ULONG);
|
|
|
|
|
|
// gaulEnumBrushStyles
|
|
//
|
|
// Brush hatch styles used for GreEnumBrushes.
|
|
|
|
ULONG
|
|
gaulHatchStyles[] = { HS_HORIZONTAL,
|
|
HS_VERTICAL,
|
|
HS_FDIAGONAL,
|
|
HS_BDIAGONAL,
|
|
HS_CROSS,
|
|
HS_DIAGCROSS
|
|
};
|
|
|
|
static ULONG gulHatchStylesTableSize = sizeof(gaulHatchStyles) / sizeof(ULONG);
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* NtGdiEnumObjects()
|
|
*
|
|
*
|
|
* Returns:
|
|
* Number of objects copied into the return buffer. If buffer is NULL,
|
|
* then the object capacity needed for the buffer is returned. If an
|
|
* error occurs, then ERROR is returned.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
ULONG
|
|
APIENTRY
|
|
NtGdiEnumObjects(
|
|
HDC hdc,
|
|
int iObjectType,
|
|
ULONG cjBuf,
|
|
PVOID pvBuf
|
|
)
|
|
{
|
|
ULONG cRet = ERROR;
|
|
|
|
if ( (cjBuf == 0) == (pvBuf == (PVOID) NULL) )
|
|
{
|
|
// Create and validate DC user object.
|
|
|
|
DCOBJ dco(hdc);
|
|
|
|
if (dco.bValid())
|
|
{
|
|
PDEVOBJ pdo(dco.hdev());
|
|
|
|
// For color devices, we grab the colors out of the
|
|
// gaclrEnumColorTable color table. For better results, a
|
|
// driver should implement DrvEnumObj.
|
|
|
|
ULONG cclrDevice = pdo.GdiInfoNotDynamic()->ulNumColors;
|
|
ULONG cObjects;
|
|
|
|
//
|
|
// Determine the number of colors to grab out of the table.
|
|
//
|
|
|
|
if ( cclrDevice >= ECT_8BPP )
|
|
cclrDevice = ECT_8BPP;
|
|
else if ( cclrDevice >= ECT_4BPP )
|
|
cclrDevice = ECT_4BPP;
|
|
else if ( cclrDevice >= ECT_EGA )
|
|
cclrDevice = ECT_EGA;
|
|
else if ( cclrDevice >= ECT_1BPP )
|
|
cclrDevice = ECT_1BPP;
|
|
|
|
|
|
switch (iObjectType)
|
|
{
|
|
case OBJ_PEN:
|
|
cObjects = cjBuf / sizeof(LOGPEN);
|
|
cRet = cclrDevice * gulPenStylesTableSize;
|
|
|
|
break;
|
|
|
|
case OBJ_BRUSH:
|
|
cObjects = cjBuf / sizeof(LOGBRUSH);
|
|
cRet = cclrDevice * (gulHatchStylesTableSize + 1); // the "1" is the solid brush
|
|
|
|
break;
|
|
|
|
default:
|
|
WARNING("NtGdiEnumObjects(): bad object type\n");
|
|
return cRet;
|
|
}
|
|
|
|
//
|
|
// If the buffer is big enough, return the data
|
|
//
|
|
|
|
if (cObjects >= cRet)
|
|
{
|
|
__try
|
|
{
|
|
ProbeForWrite(pvBuf, cjBuf, sizeof(DWORD));
|
|
|
|
COLORREF *pclr;
|
|
COLORREF *pclrEnd = gaclrEnumColorTable + cclrDevice;
|
|
|
|
PULONG pulPenStyle;
|
|
PULONG pulPenStyleEnd = gaulPenStyles + gulPenStylesTableSize;
|
|
|
|
PULONG pulHatchStyle;
|
|
PULONG pulHatchStyleEnd = gaulHatchStyles + gulHatchStylesTableSize;
|
|
|
|
PLOGPEN plpBuf = ((PLOGPEN)pvBuf);
|
|
PLOGBRUSH plbBuf = ((PLOGBRUSH)pvBuf);
|
|
|
|
switch (iObjectType)
|
|
{
|
|
case OBJ_PEN:
|
|
|
|
//
|
|
// Fill buffer will LOGPENs of all styles, in all colors.
|
|
//
|
|
|
|
for (pulPenStyle = gaulPenStyles; pulPenStyle < pulPenStyleEnd; pulPenStyle += 1)
|
|
{
|
|
for (pclr = gaclrEnumColorTable;
|
|
pclr < pclrEnd;
|
|
pclr += 1)
|
|
{
|
|
// Fill in the LOGPEN fields.
|
|
|
|
plpBuf->lopnWidth.x = 0; // nominal width
|
|
plpBuf->lopnWidth.y = 0; // ignored
|
|
plpBuf->lopnStyle = (UINT) *pulPenStyle;
|
|
plpBuf->lopnColor = *pclr;
|
|
|
|
// Next LOGPEN.
|
|
|
|
plpBuf += 1;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case OBJ_BRUSH:
|
|
|
|
//
|
|
// Fill buffer will LOGBRUSHs of BS_SOLID style, in all colors.
|
|
//
|
|
|
|
for (pclr = gaclrEnumColorTable; pclr < pclrEnd; pclr += 1)
|
|
{
|
|
// Fill in the LOGBRUSH fields.
|
|
|
|
plbBuf->lbStyle = BS_SOLID;
|
|
plbBuf->lbColor = *pclr;
|
|
plbBuf->lbHatch = 0;
|
|
|
|
// Next LOGBRUSH.
|
|
|
|
plbBuf += 1;
|
|
}
|
|
|
|
//
|
|
// Now fill the buffer with LOGBRUSHs of BS_HATCH, in all
|
|
// hatch styles and colors.
|
|
//
|
|
|
|
for (pulHatchStyle = gaulHatchStyles; pulHatchStyle < pulHatchStyleEnd; pulHatchStyle += 1)
|
|
{
|
|
for (pclr = gaclrEnumColorTable;
|
|
pclr < pclrEnd;
|
|
pclr += 1)
|
|
{
|
|
// Fill in the LOGBRUSH fields.
|
|
|
|
plbBuf->lbStyle = BS_HATCHED;
|
|
plbBuf->lbColor = *pclr;
|
|
plbBuf->lbHatch = *pulHatchStyle;
|
|
|
|
// Next LOGBRUSH.
|
|
|
|
plbBuf += 1;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
WARNING("NtGdiEnumObjects(): bad object type 2\n");
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
// SetLastError(GetExceptionCode());
|
|
cRet = ERROR;
|
|
}
|
|
}
|
|
else if (cObjects)
|
|
{
|
|
//
|
|
// If the buffer is not large enough (and it is not zero)
|
|
// then return an error,
|
|
//
|
|
|
|
cRet = ERROR;
|
|
}
|
|
}
|
|
}
|
|
|
|
return cRet;
|
|
}
|
|
|
|
BOOL bScanFamily(
|
|
FHOBJ *pfho1, ULONG ulFilter1,
|
|
FHOBJ *pfho2, ULONG ulFilter2,
|
|
FHOBJ *pfho3, ULONG ulFilter3,
|
|
EFSOBJ *pefsmo,
|
|
ULONG iEnumType,
|
|
EFFILTER_INFO *peffi,
|
|
PWSZ pwszName
|
|
);
|
|
|
|
BOOL bScanFamilyAndFace(
|
|
FHOBJ *pfhoEngFamily,
|
|
FHOBJ *pfhoEngFace,
|
|
FHOBJ *pfhoDevFamily,
|
|
FHOBJ *pfhoDevFace,
|
|
EFSOBJ *pefsmo,
|
|
ULONG iEnumType,
|
|
EFFILTER_INFO *peffi,
|
|
PWSZ pwszName
|
|
);
|
|
|
|
|
|
#define EFS_DEFAULT 32
|
|
|
|
/******************************Public*Routine******************************\
|
|
* HEFS hefsEngineOnly
|
|
*
|
|
* Enumerates engine fonts only.
|
|
*
|
|
* PFEs are accumulated in an EFSTATE (EnumFont State) object. If a non-NULL
|
|
* pwszName is specified, then only fonts that match the given name are added
|
|
* to the EFS. If a NULL pwszFace is specified, then one font of each name is
|
|
* added to the EFS.
|
|
*
|
|
* If any of the filtering flags in the EFFILTER_INFO structure are specified,
|
|
* then PFEs are tested in additional filtering stages before they are added
|
|
* to the EFS.
|
|
*
|
|
* The EFS is allocated by this function. It is the responsibility of the
|
|
* caller to ensure that the EFS is eventually freed.
|
|
*
|
|
* Returns:
|
|
* Handle to allocated EFS object, HEFS_INVALID if an error occurs.
|
|
*
|
|
* History:
|
|
*
|
|
* 19-Aug-1996 -by- Xudong Wu [TessieW]
|
|
* Add enumeration for Private PFT.
|
|
*
|
|
* 07-Aug-1992 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
HEFS hefsEngineOnly (
|
|
PWSZ pwszName, // enumerate this font family
|
|
ULONG lfCharSet,
|
|
ULONG iEnumType, // TRUE if processing EnumFonts()
|
|
EFFILTER_INFO *peffi, // filtering information
|
|
PUBLIC_PFTOBJ &pfto, // public PFT user object
|
|
PUBLIC_PFTOBJ &pftop, // private PFT user object
|
|
ULONG *pulCount
|
|
)
|
|
{
|
|
// ulEnumFontOpen, the caller, has already grabbed the ghsemPublicPFT,
|
|
// so the font hash tables are stable.
|
|
|
|
// Create and validate FHOBJ for engine (family list).
|
|
|
|
FHOBJ fhoEngineFamily(&pfto.pPFT->pfhFamily);
|
|
|
|
if ( !fhoEngineFamily.bValid() )
|
|
{
|
|
WARNING("gdisrv!hefsEnumFontsState(): cannot lock engine font hash (family)\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
// Create and validate FHOBJ for engine (face list).
|
|
|
|
FHOBJ fhoEngineFace(&pfto.pPFT->pfhFace);
|
|
|
|
if ( !fhoEngineFace.bValid() )
|
|
{
|
|
WARNING("gdisrv!hefsEnumFontsState(): cannot lock engine font hash (face)\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
// For NULL pwszName, an example of each family needs to be enumerated. In
|
|
// other words, we scan ACROSS the names.
|
|
|
|
if (pwszName == (PWSZ) NULL)
|
|
{
|
|
// Allocate a new EFSTATE for the enumeration. Use total number
|
|
// of lists as a hint for the initial size. This is reasonable
|
|
// since we will probably enumerate back all of the list heads.
|
|
|
|
EFSMEMOBJ efsmo(fhoEngineFamily.cLists(), iEnumType);
|
|
|
|
if ( !efsmo.bValid() )
|
|
{
|
|
WARNING("win32k!GreEnumFontOpen(): could not allocate enumeration state\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
// Enumerate engine fonts in public PFT.
|
|
// For Win3.1 compatability Non-TT,TT.
|
|
|
|
if ( !bScanFamily(&fhoEngineFamily, ENUM_FILTER_NONTT, &fhoEngineFamily, ENUM_FILTER_TT,
|
|
(FHOBJ*)NULL, 0, &efsmo, iEnumType, peffi, NULL) )
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
// Scan through private PFT if gpPFTPrivate!=NULL
|
|
|
|
if (pftop.pPFT != NULL)
|
|
{
|
|
FHOBJ fhoPrivateFamily(&pftop.pPFT->pfhFamily);
|
|
|
|
if ( !fhoPrivateFamily.bValid() )
|
|
{
|
|
WARNING("win32k!hefsEngineOnly(): cannot lock private font hash (family)\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
if ( !bScanFamily(&fhoPrivateFamily, ENUM_FILTER_NONTT, &fhoPrivateFamily, ENUM_FILTER_TT,
|
|
(FHOBJ*)NULL, 0, &efsmo, iEnumType, peffi, NULL) )
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
}
|
|
|
|
*pulCount = efsmo.cjEfdwTotal();
|
|
|
|
// Keep the EFSTATE around.
|
|
|
|
efsmo.vKeepIt();
|
|
|
|
// Return the EFSOBJ handle.
|
|
|
|
return efsmo.hefs();
|
|
}
|
|
|
|
// For non-NULL pwszName, all the fonts of a particular family are enumerated.
|
|
// In other words, we scan DOWN a name.
|
|
|
|
else
|
|
{
|
|
// Allocate a new EFSTATE. Use a default size.
|
|
|
|
EFSMEMOBJ efsmo(EFS_DEFAULT, iEnumType);
|
|
|
|
if ( !efsmo.bValid() )
|
|
{
|
|
WARNING("gdisrv!hefsEnumFontsState(): could not allocate enumeration state\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
if (!bScanFamilyAndFace(&fhoEngineFamily, &fhoEngineFace, (FHOBJ*)NULL, (FHOBJ*)NULL,
|
|
&efsmo, iEnumType, peffi, pwszName))
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
|
|
// Scan through the Privat PFT with family name lists.
|
|
|
|
if (pftop.pPFT != NULL)
|
|
{
|
|
FHOBJ fhoPrivateFamily(&pftop.pPFT->pfhFamily);
|
|
FHOBJ fhoPrivateFace(&pftop.pPFT->pfhFace);
|
|
|
|
if (!fhoPrivateFamily.bValid() || !fhoPrivateFace.bValid())
|
|
{
|
|
WARNING("win32k!hefsEngineOnly(): cannot lock private font hash\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
if (!bScanFamilyAndFace(&fhoPrivateFamily, &fhoPrivateFace, (FHOBJ*)NULL, (FHOBJ*)NULL,
|
|
&efsmo, iEnumType, peffi, pwszName))
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
}
|
|
|
|
|
|
// Repeat with the alternate facename (if any). Since a LOGFONT can
|
|
// map via the alternate facenames, it is appropriate to enumerate the
|
|
// alternate facename fonts as if they really had this face name.
|
|
|
|
PFONTSUB pfsub = pfsubAlternateFacename(pwszName);
|
|
PWSZ pwszAlt = pfsub ? (PWSZ)pfsub->fcsAltFace.awch : NULL;
|
|
|
|
if ( pwszAlt != (PWSZ) NULL )
|
|
{
|
|
// Enumerate engine fonts.
|
|
|
|
if (!bScanFamilyAndFace(&fhoEngineFamily, &fhoEngineFace, (FHOBJ*)NULL, (FHOBJ*)NULL,
|
|
&efsmo, iEnumType, peffi, pwszAlt))
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
|
|
// Enumerate the private fonts.
|
|
|
|
if (pftop.pPFT != NULL)
|
|
{
|
|
FHOBJ fhoPrivateFamily(&pftop.pPFT->pfhFamily);
|
|
FHOBJ fhoPrivateFace(&pftop.pPFT->pfhFace);
|
|
|
|
if (!fhoPrivateFamily.bValid() || !fhoPrivateFace.bValid())
|
|
{
|
|
WARNING("win32k!hefsEngineOnly(): cannot lock private font hash\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
if (!bScanFamilyAndFace(&fhoPrivateFamily, &fhoPrivateFace, (FHOBJ*)NULL, (FHOBJ*)NULL,
|
|
&efsmo, iEnumType, peffi, pwszAlt))
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
}
|
|
|
|
// Inform the enumeration state that an alternate name was used.
|
|
|
|
efsmo.vUsedAltName(pfsub);
|
|
}
|
|
|
|
*pulCount = efsmo.cjEfdwTotal();
|
|
|
|
// Keep the EFSTATE around.
|
|
|
|
efsmo.vKeepIt();
|
|
|
|
// Return the EFSOBJ handle.
|
|
|
|
return efsmo.hefs();
|
|
}
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* HEFS hefsDeviceAndEngine
|
|
*
|
|
* Enumerates device and engine fonts.
|
|
*
|
|
* PFEs are accumulated in an EFSTATE (EnumFont State) object. If a non-NULL
|
|
* pwszName is specified, then only fonts that match the given name are added
|
|
* to the EFS. If a NULL pwszFace is specified, then one font of each name is
|
|
* added to the EFS.
|
|
*
|
|
* If any of the filtering flags in the EFFILTER_INFO structure are specified,
|
|
* then PFEs are tested in additional filtering stages before they are added
|
|
* to the EFS.
|
|
*
|
|
* The EFS is allocated by this function. It is the responsibility of the
|
|
* caller to ensure that the EFS is eventually freed.
|
|
*
|
|
* Returns:
|
|
* Handle to allocated EFS object, HEFS_INVALID if an error occurs.
|
|
*
|
|
*
|
|
* History:
|
|
*
|
|
* 18-Sept-1996 -by- Xudong Wu [TessieW]
|
|
* Add the enumeration for private PFT.
|
|
*
|
|
* 07-Aug-1992 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
HEFS hefsDeviceAndEngine (
|
|
PWSZ pwszName, // enumerate this font family
|
|
ULONG lfCharSet,
|
|
ULONG iEnumType,
|
|
EFFILTER_INFO *peffi, // filtering information
|
|
PUBLIC_PFTOBJ &pfto, // public PFT user object
|
|
PUBLIC_PFTOBJ &pftop, // private PFT user object
|
|
PFFOBJ &pffoDevice, // PFFOBJ for device fonts
|
|
PDEVOBJ &pdo, // PDEVOBJ for device
|
|
ULONG *pulCount
|
|
)
|
|
{
|
|
// ulEnumFontOpen, the caller, has already grabbed the ghsemPublicPFT,
|
|
// so the font hash tables are stable.
|
|
|
|
// Create and validate FHOBJ for device (family list).
|
|
|
|
FHOBJ fhoDeviceFamily(&pffoDevice.pPFF->pfhFamily);
|
|
|
|
if ( !fhoDeviceFamily.bValid() )
|
|
{
|
|
WARNING("gdisrv!hefsEnumFontsState(): cannot lock device font hash (family)\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
// Create and validate FHOBJ for engine (family list).
|
|
|
|
FHOBJ fhoEngineFamily(&pfto.pPFT->pfhFamily);
|
|
|
|
if ( !fhoEngineFamily.bValid() )
|
|
{
|
|
WARNING("gdisrv!hefsEnumFontsState(): cannot lock engine font hash (family)\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
|
|
|
|
// Create and validate FHOBJ for device (face list).
|
|
|
|
FHOBJ fhoDeviceFace(&pffoDevice.pPFF->pfhFace);
|
|
|
|
if ( !fhoDeviceFace.bValid() )
|
|
{
|
|
WARNING("gdisrv!hefsEnumFontsState(): cannot lock device font hash (face)\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
// Create and validate FHOBJ for engine (face list).
|
|
|
|
FHOBJ fhoEngineFace(&pfto.pPFT->pfhFace);
|
|
|
|
if ( !fhoEngineFace.bValid() )
|
|
{
|
|
WARNING("gdisrv!hefsEnumFontsState(): cannot lock engine font hash (face)\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
|
|
|
|
// For NULL pwszName, an example of each family needs to be enumerated. In
|
|
// other words, we scan ACROSS the names.
|
|
|
|
if (pwszName == (PWSZ) NULL)
|
|
{
|
|
// Allocate a new EFSTATE for the enumeration. Use total number of lists
|
|
// as a hint for the initial size. This is reasonable since we will probably
|
|
// enumerate back all of the list heads.
|
|
|
|
ASSERTGDI(peffi->bNonTrueTypeFilter == FALSE, "ERROR not FALSE");
|
|
|
|
EFSMEMOBJ efsmo(fhoDeviceFamily.cLists() + fhoEngineFamily.cLists(), iEnumType);
|
|
|
|
if ( !efsmo.bValid() )
|
|
{
|
|
WARNING("gdisrv!hefsEnumFontsState(): could not allocate enumeration state\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
//
|
|
// Enumerate device and engine fonts.
|
|
//
|
|
|
|
if (pdo.flTextCaps() & TC_RA_ABLE)
|
|
{
|
|
//
|
|
// For Win3.1 compatability Enum Device,Non-TT,TT
|
|
// This is for Displays and PaintJets under 3.1
|
|
//
|
|
|
|
if ( !bScanFamily(&fhoDeviceFamily, ENUM_FILTER_NONE, &fhoEngineFamily, ENUM_FILTER_NONTT,
|
|
&fhoEngineFamily, ENUM_FILTER_TT, &efsmo, iEnumType, peffi, NULL) )
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
// scan through private PFT if gpPFTPrivate!=NULL
|
|
|
|
if (pftop.pPFT != NULL)
|
|
{
|
|
FHOBJ fhoPrivateFamily(&pftop.pPFT->pfhFamily);
|
|
|
|
if ( !fhoPrivateFamily.bValid() )
|
|
{
|
|
WARNING("win32k!hefsDeviceAndEngine(): cannot lock private font hash (family)\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
if ( !bScanFamily(&fhoPrivateFamily, ENUM_FILTER_NONTT, &fhoPrivateFamily, ENUM_FILTER_TT,
|
|
(FHOBJ*)NULL, 0, &efsmo, iEnumType, peffi, NULL) )
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
}
|
|
}
|
|
#if 0
|
|
|
|
// If we ever need this, this is how Postscript should do it. We would
|
|
// need to call the driver at Enable Printer time to see if it's Postscript
|
|
// and set a bit for quick checking here.
|
|
|
|
else if (pdo.bPostScript())
|
|
{
|
|
//
|
|
// For Win3.1 compatability Enum TT,Device,Non-TT,
|
|
//
|
|
|
|
if (!bScanFamily(&fhoEngineFamily, ENUM_FILTER_TT, &fhoDeviceFamily, ENUM_FILTER_NONE,
|
|
&fhoEngineFamily, ENUM_FILTER_NONTT, &efsmo, iEnumType, peffi, NULL) )
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
// scan throught private PFT if gpPFTPrivate!=NULL
|
|
|
|
if (pftop.pPFT != NULL)
|
|
{
|
|
FHOBJ fhoPrivateFamily(&pftop.pPFT->pfhFamily);
|
|
|
|
if ( !fhoPrivateFamily.bValid() )
|
|
{
|
|
WARNING("win32k!hefsDeviceAndEngine(): cannot lock private font hash (family)\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
if ( !bScanFamily(&fhoPrivateFamily, ENUM_FILTER_TT, &fhoPrivateFamily, ENUM_FILTER_NONTT,
|
|
(FHOBJ*)NULL, 0, &efsmo, iEnumType, peffi, NULL) )
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
//
|
|
// Win3.1 compatability.
|
|
// Enum Device, TT, Non-TT.
|
|
//
|
|
|
|
if ( !bScanFamily(&fhoDeviceFamily, ENUM_FILTER_NONE, &fhoEngineFamily, ENUM_FILTER_TT,
|
|
&fhoEngineFamily, ENUM_FILTER_NONTT, &efsmo, iEnumType, peffi, NULL) )
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
if (pftop.pPFT != NULL)
|
|
{
|
|
FHOBJ fhoPrivateFamily(&pftop.pPFT->pfhFamily);
|
|
|
|
if ( !fhoPrivateFamily.bValid() )
|
|
{
|
|
WARNING("win32k!hefsDeviceAndEngine(): cannot lock private font hash (family)\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
if ( !bScanFamily(&fhoPrivateFamily, ENUM_FILTER_TT, &fhoPrivateFamily, ENUM_FILTER_NONTT,
|
|
(FHOBJ*)NULL, 0, &efsmo, iEnumType, peffi, NULL) )
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
}
|
|
}
|
|
|
|
*pulCount = efsmo.cjEfdwTotal();
|
|
|
|
// Keep the EFSTATE around.
|
|
|
|
efsmo.vKeepIt();
|
|
|
|
// Return the EFSOBJ handle.
|
|
|
|
return efsmo.hefs();
|
|
}
|
|
else
|
|
{
|
|
// For non-NULL pwszName, all the fonts of a particular family are enumerated.
|
|
// In other words, we scan DOWN a name.
|
|
|
|
// Allocate a new EFSTATE. Use a default size.
|
|
|
|
EFSMEMOBJ efsmo(EFS_DEFAULT, iEnumType);
|
|
|
|
if ( !efsmo.bValid() )
|
|
{
|
|
WARNING("gdisrv!hefsEnumFontsState(): could not allocate enumeration state\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
// Enumerate device and engine fonts.
|
|
|
|
if (!bScanFamilyAndFace(&fhoEngineFamily, &fhoEngineFace, &fhoDeviceFamily, &fhoDeviceFace,
|
|
&efsmo, iEnumType, peffi, pwszName))
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
// Enumerate the private fonts if any
|
|
|
|
if (pftop.pPFT != NULL)
|
|
{
|
|
FHOBJ fhoPrivateFamily(&pftop.pPFT->pfhFamily);
|
|
FHOBJ fhoPrivateFace(&pftop.pPFT->pfhFace);
|
|
|
|
if (!fhoPrivateFamily.bValid() || !fhoPrivateFace.bValid())
|
|
{
|
|
WARNING("win32k!hefsDeviceAndEngine(): cannot lock private font hash\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
if (!bScanFamilyAndFace(&fhoPrivateFamily, &fhoPrivateFace, (FHOBJ*)NULL, (FHOBJ*)NULL,
|
|
&efsmo, iEnumType, peffi, pwszName))
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
}
|
|
|
|
// Repeat with the alternate facename (if any). Since a LOGFONT can
|
|
// map via the alternate facenames, it is appropriate to enumerate the
|
|
// alternate facename fonts as if they really had this face name.
|
|
//
|
|
// However, to be Win 3.1 compatible, we will NOT do this if the device
|
|
// is a non-display device.
|
|
//
|
|
// It appears that Windows 95 no longer does this. Additionally, we need
|
|
// to enumerate manufactured EE names (i.e. Arial Cyr, Arial Grk, etc)
|
|
// on printer DC's as well now. If we don't we break Word Perfect 94 a 16 bit
|
|
// winstone application.
|
|
//
|
|
//
|
|
// if ( pdo.bDisplayPDEV() )
|
|
{
|
|
PFONTSUB pfsub = pfsubAlternateFacename(pwszName);
|
|
PWSZ pwszAlt = pfsub ? (PWSZ)pfsub->fcsAltFace.awch : NULL;
|
|
|
|
if ( pwszAlt != (PWSZ) NULL )
|
|
{
|
|
// Enumerate device and engine fonts.
|
|
|
|
if (!bScanFamilyAndFace(&fhoEngineFamily, &fhoEngineFace, &fhoDeviceFamily, &fhoDeviceFace,
|
|
&efsmo, iEnumType, peffi, pwszAlt))
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
// Enumerate private fonts if any
|
|
|
|
if (pftop.pPFT != NULL)
|
|
{
|
|
FHOBJ fhoPrivateFamily(&pftop.pPFT->pfhFamily);
|
|
FHOBJ fhoPrivateFace(&pftop.pPFT->pfhFace);
|
|
|
|
if (!fhoPrivateFamily.bValid() || !fhoPrivateFace.bValid())
|
|
{
|
|
WARNING("win32k!hefsDeviceAndEngine(): cannot lock private font hash\n");
|
|
return HEFS_INVALID;
|
|
}
|
|
|
|
if (!bScanFamilyAndFace(&fhoPrivateFamily, &fhoPrivateFace, (FHOBJ*)NULL, (FHOBJ*)NULL,
|
|
&efsmo, iEnumType, peffi, pwszAlt))
|
|
{
|
|
return HEFS_INVALID;
|
|
}
|
|
}
|
|
|
|
// Inform the enumeration state that an alternate name was used.
|
|
|
|
efsmo.vUsedAltName(pfsub);
|
|
}
|
|
}
|
|
|
|
*pulCount = efsmo.cjEfdwTotal();
|
|
|
|
// Keep the EFSTATE around.
|
|
|
|
efsmo.vKeepIt();
|
|
|
|
// Return the EFSOBJ handle.
|
|
|
|
return efsmo.hefs();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* ULONG ulEnumFontOpen
|
|
*
|
|
* First phase of the enumeration. Fonts from the engine and device are
|
|
* chosen and saved in a EFSTATE (font enumeration state) object. A handle
|
|
* to this object is passed back. The caller can use this handle to
|
|
* initiate the second pass in which the data is sent back over the client
|
|
* server interface in chunks.
|
|
*
|
|
* This function is also responsible for determining what types of filters
|
|
* will be applied in choosing fonts for the enumeration. Filters which
|
|
* are controllable are:
|
|
*
|
|
* TrueType filtering non-TrueType fonts are discarded
|
|
*
|
|
* Raster filering raster fonts are discarded
|
|
*
|
|
* Aspect ratio filtering fonts not matching resolution are discarded
|
|
*
|
|
* Returns:
|
|
* EFS handle (as a ULONG) if successful, HEFS_INVALID (0) otherwise.
|
|
*
|
|
* Note:
|
|
* The function may still return valid HEFS even if the EFSTATE is empty.
|
|
*
|
|
* History:
|
|
* 08-Aug-1992 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
ULONG_PTR GreEnumFontOpen (
|
|
HDC hdc, // device to enumerate on
|
|
ULONG iEnumType, // EnumFonts, EnumFontFamilies or EnumFontFamiliesEx
|
|
FLONG flWin31Compat, // Win 3.1 compatibility flags
|
|
ULONG cwchMax, // maximum name length (for paranoid CSR code)
|
|
PWSZ pwszName, // font name to enumerate
|
|
ULONG lfCharSet,
|
|
ULONG *pulCount
|
|
)
|
|
{
|
|
DONTUSE(cwchMax);
|
|
|
|
HEFS hefsRet = HEFS_INVALID;
|
|
|
|
//
|
|
// Create and validate user object for DC.
|
|
//
|
|
DCOBJ dco(hdc);
|
|
|
|
if(!dco.bValid())
|
|
{
|
|
WARNING("gdisrv!ulEnumFontOpen(): cannot access DC\n");
|
|
SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
|
|
|
|
return ((ULONG_PTR) hefsRet);
|
|
}
|
|
|
|
//
|
|
// Get PDEV user object. We also need to make
|
|
// sure that we have loaded device fonts before we go off to the font mapper.
|
|
// This must be done before the semaphore is locked.
|
|
//
|
|
PDEVOBJ pdo(dco.hdev());
|
|
ASSERTGDI (
|
|
pdo.bValid(),
|
|
"gdisrv!ulEnumFontOpen(): cannot access PDEV\n");
|
|
|
|
if (!pdo.bGotFonts())
|
|
pdo.bGetDeviceFonts();
|
|
|
|
// Stabilize public PFT.
|
|
|
|
SEMOBJ so(ghsemPublicPFT);
|
|
|
|
// Compute font enumeration filter info.
|
|
|
|
EFFILTER_INFO effi;
|
|
|
|
effi.lfCharSetFilter = lfCharSet;
|
|
effi.bNonTrueTypeFilter = FALSE;
|
|
|
|
//
|
|
// If not raster capable, then use raster font filtering.
|
|
//
|
|
//
|
|
// If it weren't hacked, we might be able to get this info
|
|
// from GetDeviceCaps(). As it is, we will assume only
|
|
// plotters are non-raster capable.
|
|
//
|
|
|
|
effi.bRasterFilter = (pdo.ulTechnology() == DT_PLOTTER);
|
|
|
|
effi.bEngineFilter = (pdo.ulTechnology() == DT_CHARSTREAM);
|
|
|
|
//
|
|
// Aspect ratio filter (use device's logical x and y resolutions).
|
|
//
|
|
// Note: [Windows 3.1 compatiblity] Aspect ratio filtering is turned ON for
|
|
// non-display devices. This is because most printers in Win 3.1
|
|
// do aspect ratio filtering. And since the Win 3.1 DDI gives
|
|
// enumeration to the drivers, display bitmap fonts usually are not
|
|
// enumerated on these devices. The NT DDI, however, gives the graphics
|
|
// engine control over enumeration. So we need to provide this
|
|
// compatibility here. Hopefully, all devices in Win3.1 do this
|
|
// filtering, because we do now.
|
|
//
|
|
// Note that we check the PDEV directly rather than the DC because
|
|
// DCOBJ::bDisplay() is not TRUE for display ICs (just display DCs
|
|
// which are DCTYPE_DIRECT).
|
|
//
|
|
effi.bAspectFilter = (BOOL) ( (dco.pdc->flFontMapper() & ASPECT_FILTERING)
|
|
|| !pdo.bDisplayPDEV() );
|
|
|
|
effi.ptlDeviceAspect.x = pdo.ulLogPixelsX();
|
|
effi.ptlDeviceAspect.y = pdo.ulLogPixelsY();
|
|
|
|
//
|
|
// If set for TrueType only, use TrueType filtering.
|
|
//
|
|
effi.bTrueTypeFilter = ((gulFontInformation & FE_FILTER_TRUETYPE) != 0);
|
|
|
|
//
|
|
// Set the Win3.1 compatibility flag.
|
|
//
|
|
effi.bTrueTypeDupeFilter = (BOOL) (flWin31Compat & GACF_TTIGNORERASTERDUPE);
|
|
|
|
// assume failure
|
|
|
|
hefsRet = 0;
|
|
|
|
{
|
|
// Find the device PFF
|
|
|
|
DEVICE_PFTOBJ pftoDevice;
|
|
PFF *pPFF;
|
|
if (pPFF = pftoDevice.pPFFGet(dco.hdev()))
|
|
{
|
|
PFFOBJ pffoDev(pPFF);
|
|
if (pffoDev.bValid())
|
|
{
|
|
PUBLIC_PFTOBJ pftoPublic;
|
|
PUBLIC_PFTOBJ pftoPrivate(gpPFTPrivate);
|
|
|
|
hefsRet =
|
|
hefsDeviceAndEngine(
|
|
pwszName
|
|
, lfCharSet
|
|
, iEnumType
|
|
, &effi
|
|
, pftoPublic
|
|
, pftoPrivate
|
|
, pffoDev
|
|
, pdo
|
|
, pulCount
|
|
);
|
|
}
|
|
else
|
|
{
|
|
WARNING("ulEnumFontOpen: invalid pffoDev\n");
|
|
}
|
|
}
|
|
}
|
|
if (!hefsRet)
|
|
{
|
|
PUBLIC_PFTOBJ pftoPublic;
|
|
PUBLIC_PFTOBJ pftoPrivate(gpPFTPrivate);
|
|
|
|
// If no device font PFFOBJ was found, do enumeration without a PFFOBJ.
|
|
// pulls all the fonts into an enumeration state.
|
|
|
|
hefsRet = hefsEngineOnly(pwszName,
|
|
lfCharSet,
|
|
iEnumType,
|
|
&effi,
|
|
pftoPublic,
|
|
pftoPrivate,
|
|
pulCount);
|
|
}
|
|
|
|
return ((ULONG_PTR) hefsRet);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BOOL bEnumFontChunk
|
|
*
|
|
* Second phase of the enumeration. HPFEs are pulled out of the enumeration
|
|
* state one-by-one, converted into an ENUMFONTDATA structure, and put into
|
|
* the return buffer. The size of the return buffer is determined by the
|
|
* client side and determines the granularity of the "chunking".
|
|
*
|
|
* This function signals the client side that the enumeration data has been
|
|
* exhausted by returning FALSE. Note that it is possible that in the pass
|
|
* pass through here that the EFSTATE may already be empty. The caller must
|
|
* check both the function return value and the pcefdw value.
|
|
*
|
|
* Note:
|
|
* Caller should set *pcefd to the capacity of the pefp buffer.
|
|
* Upon return, iEnumType will set pefb.cefp to the number of
|
|
* ENUMFONTDATA structures copied into the pefb.aefd array.
|
|
*
|
|
* Also, pefdw is user memory, which might be asynchronously changed
|
|
* at any time. So, we cannot trust any values read from that buffer.
|
|
*
|
|
* Returns:
|
|
* TRUE if there are more to go, FALSE otherwise,
|
|
*
|
|
* History:
|
|
* 08-Aug-1992 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL bEnumFontChunk(
|
|
HDC hdc, // device to enumerate on
|
|
ULONG_PTR idEnum,
|
|
COUNT cjEfdwTotal, // (in) capacity of buffer
|
|
COUNT *pcjEfdw, // (out) number of ENUMFONTDATAs returned
|
|
PENUMFONTDATAW pefdw // return buffer
|
|
)
|
|
{
|
|
// Initialize position in buffer in which to copy data
|
|
|
|
PENUMFONTDATAW pefdwCur = pefdw;
|
|
*pcjEfdw = 0;
|
|
|
|
|
|
// Validate DC and EnumFontState. If either fail lock bug out.
|
|
|
|
DCOBJ dco(hdc);
|
|
EFSOBJ efso((HEFS) idEnum);
|
|
|
|
if ((!efso.bValid()) || (!dco.bValid()))
|
|
{
|
|
WARNING("gdisrv!bEnumFontChunk(): bad HEFS or DC handle\n");
|
|
return FALSE;
|
|
}
|
|
|
|
// since as of 4.0 we do not go through this a chunk at the time
|
|
// we must have
|
|
|
|
if (cjEfdwTotal != efso.cjEfdwTotal())
|
|
{
|
|
WARNING("gdisrv!bEnumFontChunk(): efso.cjEfdwTotal() problem\n");
|
|
return FALSE;
|
|
}
|
|
|
|
ASSERTGDI(cjEfdwTotal >= efso.cefe() * CJ_EFDW0,
|
|
"cjEfdwTotal NOT BIG enough \n");
|
|
|
|
// Counter to track number of ENUMFONTDATAW structures copied into buffer.
|
|
|
|
COUNT cjEfdwCopied = 0;
|
|
EFENTRY *pefe;
|
|
|
|
// Before we access PFEs, grab the ghsemPublicPFT so no one can delete
|
|
// PFE while we are in the loop (note that PFEs can get deleted
|
|
// once we are outside of this--like between chunks!).
|
|
|
|
SEMOBJ so(ghsemPublicPFT);
|
|
|
|
// In each font file, try each font face
|
|
// We are sure that we will not overwrite the buffer because
|
|
// the size of buffer is big enough to take all the enumfont data.
|
|
|
|
while((pefe = efso.pefeEnumNext()))
|
|
{
|
|
// Create a PFE Collect user object. We're using real handle instead of
|
|
// pointers because someone may have deleted by the time we get
|
|
// around to enumerating.
|
|
|
|
// Get the PFE through PFE Collect object.
|
|
|
|
HPFECOBJ pfeco(pefe->hpfec);
|
|
PFEOBJ pfeo(pfeco.GetPFE(pefe->iFont));
|
|
|
|
SIZE_T cjEfdwCur = 0;
|
|
|
|
// Validate user object and copy data into buffer. Because PFE
|
|
// may have been deleted between chunks, we need to check validity.
|
|
|
|
PWSZ pwszFamilyOverride = NULL;
|
|
BOOL bCharSetOverride = FALSE;
|
|
ULONG lfCharSetOverride = DEFAULT_CHARSET;
|
|
|
|
if (efso.pwszFamilyOverride())
|
|
{
|
|
pwszFamilyOverride = efso.pwszFamilyOverride();
|
|
|
|
if (pefe->fjOverride & FJ_CHARSETOVERRIDE)
|
|
{
|
|
bCharSetOverride = TRUE;
|
|
lfCharSetOverride = pefe->jCharSetOverride;
|
|
}
|
|
else
|
|
{
|
|
bCharSetOverride = efso.bCharSetOverride();
|
|
lfCharSetOverride = (ULONG)efso.jCharSetOverride();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pefe->fjOverride & FJ_FAMILYOVERRIDE)
|
|
{
|
|
pwszFamilyOverride = gpfsTable[pefe->iOverride].awchOriginal;
|
|
}
|
|
if (pefe->fjOverride & FJ_CHARSETOVERRIDE)
|
|
{
|
|
bCharSetOverride = TRUE;
|
|
lfCharSetOverride = pefe->jCharSetOverride;
|
|
}
|
|
}
|
|
|
|
if
|
|
(
|
|
pfeo.bValid() &&
|
|
(cjEfdwCur = cjCopyFontDataW(
|
|
dco,
|
|
pefdwCur,
|
|
pfeo,
|
|
pefe->efsty,
|
|
pwszFamilyOverride,
|
|
lfCharSetOverride,
|
|
bCharSetOverride,
|
|
efso.iEnumType()
|
|
))
|
|
)
|
|
{
|
|
cjEfdwCopied += (ULONG) cjEfdwCur;
|
|
pefdwCur = (ENUMFONTDATAW *)((BYTE*)pefdwCur + cjEfdwCur);
|
|
}
|
|
}
|
|
|
|
*pcjEfdw = cjEfdwCopied;
|
|
|
|
// we are done: pefe has to be zero:
|
|
|
|
ASSERTGDI(!pefe, "not all fonts are enumerated yet\n");
|
|
ASSERTGDI(cjEfdwCopied <= cjEfdwTotal, "cjEfdwCopied > cjEfdwTotal\n");
|
|
|
|
// true means success, it used to mean that there are more fonts to come for
|
|
// enumeration. Now, we do not do "chunking" any more. Assert above makes sure
|
|
// that this is the case [bodind]
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*************************Public*Routine********************************\
|
|
* BOOL bScanTheList()
|
|
*
|
|
* Scan through the font hash table using the given filter mode
|
|
*
|
|
* History:
|
|
*
|
|
* 07-Nov-1996 -by- Xudong Wu [TessieW]
|
|
* Wrote it.
|
|
*
|
|
************************************************************************/
|
|
|
|
BOOL bScanTheList(
|
|
FHOBJ *pfho,
|
|
ULONG ulFilter,
|
|
EFSOBJ *pefsmo,
|
|
ULONG iEnumType,
|
|
EFFILTER_INFO *peffi,
|
|
PWSZ pwszName
|
|
)
|
|
{
|
|
BOOL bRet;
|
|
|
|
if (pwszName)
|
|
{
|
|
bRet = pfho->bScanLists(pefsmo, pwszName, iEnumType, peffi);
|
|
}
|
|
else
|
|
{
|
|
BOOL bTempFilter;
|
|
if (ulFilter == ENUM_FILTER_TT)
|
|
{
|
|
bTempFilter = peffi->bTrueTypeFilter;
|
|
peffi->bTrueTypeFilter = TRUE;
|
|
}
|
|
else if (ulFilter == ENUM_FILTER_NONTT)
|
|
{
|
|
peffi->bNonTrueTypeFilter = TRUE;
|
|
}
|
|
|
|
bRet = pfho->bScanLists(pefsmo, iEnumType, peffi);
|
|
|
|
if (ulFilter == ENUM_FILTER_TT)
|
|
{
|
|
peffi->bTrueTypeFilter = bTempFilter;
|
|
}
|
|
else if (ulFilter == ENUM_FILTER_NONTT)
|
|
{
|
|
peffi->bNonTrueTypeFilter = FALSE;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*************************Public*Routine********************************\
|
|
* BOOL bScanFamily()
|
|
*
|
|
* Scan through the family font hash table in the different filter
|
|
* order given by the input flag.
|
|
*
|
|
* History:
|
|
*
|
|
* 23-Oct-1996 -by- Xudong Wu [TessieW]
|
|
* Wrote it.
|
|
*
|
|
************************************************************************/
|
|
|
|
BOOL bScanFamily(
|
|
FHOBJ *pfho1, ULONG ulFilter1,
|
|
FHOBJ *pfho2, ULONG ulFilter2,
|
|
FHOBJ *pfho3, ULONG ulFilter3,
|
|
EFSOBJ *pefsmo,
|
|
ULONG iEnumType,
|
|
EFFILTER_INFO *peffi,
|
|
PWSZ pwszName
|
|
)
|
|
{
|
|
return
|
|
(
|
|
(!pfho1 || bScanTheList(pfho1, ulFilter1, pefsmo, iEnumType, peffi, pwszName))
|
|
&&
|
|
(!pfho2 || bScanTheList(pfho2, ulFilter2, pefsmo, iEnumType, peffi, pwszName))
|
|
&&
|
|
(!pfho3 || bScanTheList(pfho3, ulFilter3, pefsmo, iEnumType, peffi, pwszName))
|
|
);
|
|
}
|
|
|
|
|
|
/*************************Public*Routine********************************\
|
|
* BOOL bScanFamilyAndFace()
|
|
*
|
|
* Frist scan through the family font hash table. If no match is found,
|
|
* scan through the face font hash table.
|
|
*
|
|
* History:
|
|
*
|
|
* 23-Oct-1996 -by- Xudong Wu [TessieW]
|
|
* Wrote it.
|
|
*
|
|
************************************************************************/
|
|
|
|
BOOL bScanFamilyAndFace(
|
|
FHOBJ *pfhoEngFamily,
|
|
FHOBJ *pfhoEngFace,
|
|
FHOBJ *pfhoDevFamily,
|
|
FHOBJ *pfhoDevFace,
|
|
EFSOBJ *pefsmo,
|
|
ULONG iEnumType,
|
|
EFFILTER_INFO *peffi,
|
|
PWSZ pwszName
|
|
)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
if (bScanFamily(pfhoDevFamily, ENUM_FILTER_NONE,
|
|
pfhoEngFamily, ENUM_FILTER_NONE,
|
|
(FHOBJ *) NULL,
|
|
0, pefsmo, iEnumType, peffi, pwszName))
|
|
{
|
|
// If list is empty, try the face name lists, else we are done
|
|
|
|
if (pefsmo->bEmpty() )
|
|
{
|
|
bRet = bScanFamily(pfhoDevFace, ENUM_FILTER_NONE,
|
|
pfhoEngFace, ENUM_FILTER_NONE,
|
|
(FHOBJ*) NULL,
|
|
0, pefsmo, iEnumType, peffi, pwszName);
|
|
#if DBG
|
|
if (!bRet)
|
|
WARNING("win32k!bScanFamilyAndFace(): scan face failed\n");
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
|
|
}
|
|
#if DBG
|
|
else
|
|
{
|
|
WARNING("win32k!bScanFamilyAndFace(): scan family failed\n");
|
|
}
|
|
#endif
|
|
|
|
return bRet;
|
|
}
|