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.
1404 lines
40 KiB
1404 lines
40 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: pffobj.cxx
|
|
*
|
|
* Non-inline methods for physical font file objects.
|
|
*
|
|
* Copyright (c) 1991-1995 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
// Define the global PFT semaphore. This must be held to access any of the
|
|
// physical font information.
|
|
|
|
extern FLONG gflFontDebug;
|
|
|
|
extern "C" void FreeFileView(PFONTFILEVIEW *ppfv, ULONG cFiles);
|
|
extern "C" ULONG ComputeFileviewCheckSum( FILEVIEW* );
|
|
|
|
ULONG ComputeFileviewCheckSum( FILEVIEW *pfv )
|
|
{
|
|
ULONG sum;
|
|
PULONG pulCur,pulEnd;
|
|
|
|
pulCur = (PULONG) pfv->pvView;
|
|
|
|
__try
|
|
{
|
|
//!!! This is slow and may produce bad distributions but well leave it
|
|
//!!! for now. Later we can fix it.
|
|
|
|
for( sum = 0, pulEnd = pulCur + (pfv->cjView / sizeof(ULONG));
|
|
pulCur < pulEnd;
|
|
pulCur += 1 )
|
|
{
|
|
sum += 256 * sum + *pulCur;
|
|
}
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
WARNING("win32k: exception while computing font check sum\n");
|
|
|
|
//!!! NOT sure that this is ok solution, perhaps we should fail??
|
|
|
|
sum = 0; // oh well, not very unique.
|
|
}
|
|
|
|
return ( sum < 2 ) ? 2 : sum; // 0 is reserved for device fonts
|
|
// 1 is reserved for TYPE1 fonts
|
|
}
|
|
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* PFFMEMOBJ::PFFMEMOBJ
|
|
*
|
|
* Constructor for default sized physical font file memory object.
|
|
*
|
|
* cFonts = # fonts in file or device
|
|
* pwsz = pointer to upper case Unicode string containing the full
|
|
* path to the font file. This pointer is set to zero, by
|
|
* default for fonts loaded from a device.
|
|
*
|
|
* History:
|
|
* Thu 01-Sep-1994 06:29:47 by Kirk Olynyk [kirko]
|
|
* Put the size calculation logic in the constructor thereby modularizing
|
|
* and shrinking the code.
|
|
* Tue 09-Nov-1993 -by- Patrick Haluptzok [patrickh]
|
|
* Remove from handle manager
|
|
* 02-Jan-1991 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
PFFMEMOBJ::PFFMEMOBJ(
|
|
unsigned cFonts // number of fonts in file|device
|
|
, PWSZ pwsz // if font file this is an upper case path
|
|
, ULONG cwc // number of characters in the mul path above
|
|
, ULONG cFiles // number of files
|
|
, HFF hffFontFile // IFI driver's handle to file
|
|
, HDEV hdevDevice // physical device handle
|
|
, DHPDEV dhpdevDevice // driver's pdev handle
|
|
, PFT *pPFTParent // contains this pff
|
|
, FLONG fl // indicates if a permanent font
|
|
, FLONG flEmbed // embedding flag
|
|
, DWORD dwPidTid // Pid/Tid for embedded fonts
|
|
, PFONTFILEVIEW *ppfv // ptr to FILEVIEW structure
|
|
)
|
|
{
|
|
ULONG size = offsetof(PFF,aulData) + cFonts * sizeof(PFE*);
|
|
|
|
ASSERTGDI(hdevDevice, "PFFMEMOBJ passed NULL hdevDevice\n");
|
|
|
|
if (pwsz)
|
|
{
|
|
size += ALIGN4(cwc*sizeof(WCHAR));
|
|
}
|
|
|
|
if (pPFF = (PFF *) PALLOCMEM(size, 'ffpG'))
|
|
{
|
|
fs = 0;
|
|
|
|
pPFF->sizeofThis = size;
|
|
pPFF->pPFFPrev = 0;
|
|
pPFF->pPFFNext = 0;
|
|
pPFF->pwszPathname_ = 0;
|
|
pPFF->hff = hffFontFile;
|
|
pPFF->hdev = hdevDevice;
|
|
pPFF->dhpdev = dhpdevDevice;
|
|
pPFF->pPFT = pPFTParent;
|
|
pPFF->cwc = cwc;
|
|
pPFF->cFiles = cFiles;
|
|
pPFF->ppfv = ppfv;
|
|
|
|
// Wet the implicit stuff.
|
|
|
|
pPFF->cFonts = 0; // faces not loaded into table yet
|
|
pPFF->cRFONT = 0; // nothing realized from this file yet
|
|
pPFF->cLoaded = 1; // FILE must be loaded at least once
|
|
pPFF->flState = fl;
|
|
pPFF->pfhFace = 0;
|
|
pPFF->pfhFamily = 0;
|
|
pPFF->pfhUFI = 0;
|
|
pPFF->prfntList = 0; // initialize to NULL list
|
|
|
|
// Embedding
|
|
|
|
pPFF->flEmbed = flEmbed & AFRW_ADD_EMB_TID;
|
|
pPFF->ulID = (ULONG)dwPidTid;
|
|
|
|
// Now compute the UFI
|
|
|
|
if (ppfv != NULL)
|
|
{
|
|
ULONG *pulCur,*pulEnd,sum;
|
|
|
|
// ASSERTGDI(pfv->cRefCount, "PFFMEMOBJ, pfv->cRefCount == 0\n");
|
|
|
|
pPFF->ulCheckSum = 0;
|
|
|
|
#ifndef FE_SB
|
|
// we don't support remote printing in FE versions of NT 4.0 so don't
|
|
// bother taking the time to compute a checksum
|
|
|
|
for (ULONG iFile = 0; iFile < cFiles; iFile ++)
|
|
{
|
|
pPFF->ulCheckSum += ComputeFileviewCheckSum(&(ppfv[iFile]->fv));
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
// this is a device font so the checksum is always 0
|
|
|
|
pPFF->ulCheckSum = 0;
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
WARNING("invalid PFFMEMOBJ\n");
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* PFFMEMOBJ::~PFFMEMOBJ()
|
|
*
|
|
* Destructor for physical font file memory object.
|
|
*
|
|
* History:
|
|
* Tue 09-Nov-1993 -by- Patrick Haluptzok [patrickh]
|
|
* Remove from handle manager
|
|
*
|
|
* 02-Jan-1991 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
PFFMEMOBJ::~PFFMEMOBJ()
|
|
{
|
|
if ((fs & PFFMO_KEEPIT) == 0)
|
|
{
|
|
if (pPFF)
|
|
{
|
|
VFREEMEM(pPFF);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* PFFOBJ::bAddHash
|
|
*
|
|
* Adds the PFF and all its PFEs to the font hashing table. The font
|
|
* hashing tabled modified is in the PFT if a font driver managed font;
|
|
* otherwise, the font hashing table is in the PFF itself.
|
|
*
|
|
* The caller should hold the gpsemPublicPFT while calling this function.
|
|
*
|
|
* Returns:
|
|
* TRUE if successful, FALSE otherwise.
|
|
*
|
|
* History:
|
|
* 11-Mar-1993 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL PFFOBJ::bAddHash()
|
|
{
|
|
// Caller must hold the gpsemPublicPFT semaphore to protect access to
|
|
// the hash tables.
|
|
|
|
//
|
|
// Add the entry to the appropriate font hash tables
|
|
//
|
|
FONTHASH **ppfhFace, **ppfhFamily,**ppfhUFI;
|
|
|
|
if (!bDeviceFonts())
|
|
{
|
|
//
|
|
// Hash tables for the font driver loaded fonts exist off of
|
|
// the font table.
|
|
//
|
|
PUBLIC_PFTOBJ pfto;
|
|
ASSERTGDI(pfto.bValid(),"PFFOBJ::vAddHash -- invalid PFTOBJ\n");
|
|
|
|
ppfhFace = &(pfto.pPFT->pfhFace);
|
|
ppfhFamily = &(pfto.pPFT->pfhFamily);
|
|
ppfhUFI = &(pfto.pPFT->pfhUFI);
|
|
|
|
//
|
|
// If this is a TrueType font, increment the count.
|
|
//
|
|
if ( pPFF->hdev == (HDEV) gppdevTrueType )
|
|
{
|
|
gcTrueTypeFonts++; // protected by gpsemPublicPFT
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Hash tables for device fonts exist off of the PFF that
|
|
// encapsulates them.
|
|
//
|
|
|
|
#if DBG
|
|
if (gflFontDebug & DEBUG_FONTTABLE)
|
|
{
|
|
RIP("\n\n[kirko] PFFMEMOBJ::vAddHash -- Adding to the Driver's font hash table\n\n");
|
|
}
|
|
#endif
|
|
|
|
ppfhFace = &pPFF->pfhFace;
|
|
ppfhFamily = &pPFF->pfhFamily;
|
|
ppfhUFI = &pPFF->pfhUFI;
|
|
}
|
|
|
|
//
|
|
// Now that we have figured out where the tables are, add the PFEs to them.
|
|
//
|
|
FHOBJ fhoFamily(ppfhFamily);
|
|
FHOBJ fhoFace(ppfhFace);
|
|
FHOBJ fhoUFI(ppfhUFI);
|
|
|
|
ASSERTGDI(fhoFamily.bValid(), "bAddHashPFFOBJ(): fhoFamily not valid\n");
|
|
ASSERTGDI(fhoFace.bValid(), "bAddHashPFFOBJ(): fhoFace not valid\n");
|
|
ASSERTGDI(fhoUFI.bValid(), "bAddHashPFFOBJ(): fhoUFI not valid\n");
|
|
|
|
for (COUNT c = 0; c < pPFF->cFonts; c++)
|
|
{
|
|
PFEOBJ pfeo(((PFE **) (pPFF->aulData))[c]);
|
|
ASSERTGDI(pfeo.bValid(), "bAddHashPFFOBJ(): bad HPFE\n");
|
|
|
|
if (!fhoFamily.bInsert(pfeo))
|
|
{
|
|
WARNING("PFFOBJ::bAddHash -- fhoFamily.bInsert failed\n");
|
|
return FALSE;
|
|
}
|
|
|
|
#if DBG
|
|
if (gflFontDebug & DEBUG_FONTTABLE)
|
|
{
|
|
DbgPrint("PFFMEMOBJ::vAddHash(\"%ws\")\n",pfeo.pwszFamilyName());
|
|
}
|
|
// Need level 2 checking to see this.
|
|
if (gflFontDebug & DEBUG_FONTTABLE_EXTRA)
|
|
{
|
|
fhoFamily.vPrint((VPRINT) DbgPrint);
|
|
}
|
|
#endif
|
|
|
|
if( !fhoUFI.bInsert(pfeo) )
|
|
{
|
|
WARNING("PFFOBJ::bAddHash -- fhoUFI.bInsert failed\n");
|
|
return FALSE;
|
|
}
|
|
|
|
#if DBG
|
|
if (gflFontDebug & DEBUG_FONTTABLE)
|
|
{
|
|
UNIVERSAL_FONT_ID ufi;
|
|
pfeo.vUFI(&ufi);
|
|
DbgPrint("PFFMEMOBJ::vAddHash(\"%x\")\n",ufi.CheckSum);
|
|
}
|
|
// Need level 2 checking to see this.
|
|
if (gflFontDebug & DEBUG_FONTTABLE_EXTRA)
|
|
{
|
|
fhoUFI.vPrint((VPRINT) DbgPrint);
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Insert into facename hash only if the typographic face name
|
|
// is different from the typeographic family name. Case insensitive
|
|
// since searching in the font hash table is case insensitive.
|
|
//
|
|
|
|
if (_wcsicmp(pfeo.pwszFaceName(),pfeo.pwszFamilyName()))
|
|
{
|
|
if(!fhoFace.bInsert(pfeo))
|
|
{
|
|
WARNING("PFFMEMOBJ::vAddHash -- fhoFace.bInsert failed\n");
|
|
return FALSE;
|
|
}
|
|
|
|
#if DBG
|
|
if (gflFontDebug & DEBUG_FONTTABLE)
|
|
{
|
|
DbgPrint("gdisrv!PFFMEMOBJ::vAddHash(\"%ws\")\n",pfeo.pwszFaceName());
|
|
}
|
|
if (gflFontDebug & DEBUG_FONTTABLE_EXTRA)
|
|
{
|
|
fhoFace.vPrint((VPRINT) DbgPrint);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* PFFOBJ::vRemoveHash
|
|
*
|
|
* Removes the PFF and all its PFEs from the font hashing table, preventing
|
|
* the font from being enumerated or mapped.
|
|
*
|
|
* The caller should hold the gpsemPublicPFT while calling this function.
|
|
*
|
|
* History:
|
|
* 10-Mar-1993 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID PFFOBJ::vRemoveHash ()
|
|
{
|
|
// Caller must hold the gpsemPublicPFT semaphore to protect access to
|
|
// the hash tables.
|
|
|
|
if (bDeviceFonts())
|
|
{
|
|
//
|
|
// Hash tables for device fonts exist off of the PFF that
|
|
// encapsulates the device fonts. Font driver loaded fonts
|
|
// are handled later while deleting the PFEs.
|
|
//
|
|
|
|
//
|
|
// Kill the entire table for the device. No more processing
|
|
// of font hash table stuff is necssary for device fonts
|
|
// after we leave this scope.
|
|
//
|
|
|
|
FHOBJ fhoFace(&(pPFF->pfhFace));
|
|
if (fhoFace.bValid())
|
|
{
|
|
fhoFace.vFree();
|
|
}
|
|
|
|
FHOBJ fhoFamily(&(pPFF->pfhFamily));
|
|
if (fhoFamily.bValid())
|
|
{
|
|
fhoFamily.vFree();
|
|
}
|
|
|
|
FHOBJ fhoUFI(&(pPFF->pfhUFI));
|
|
if (fhoUFI.bValid())
|
|
{
|
|
fhoUFI.vFree();
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
PUBLIC_PFTOBJ pfto;
|
|
ASSERTGDI(pfto.bValid(),"vRemoveHashPFFOBJ(): invalid PFTOBJ\n");
|
|
|
|
//
|
|
// Hash tables for the font driver managed fonts exist off of
|
|
// the font table (PFT).
|
|
//
|
|
|
|
FHOBJ fhoFace(&(pfto.pPFT->pfhFace));
|
|
FHOBJ fhoFamily(&(pfto.pPFT->pfhFamily));
|
|
FHOBJ fhoUFI(&(pfto.pPFT->pfhUFI));
|
|
|
|
for (COUNT c = 0; c < pPFF->cFonts; c++)
|
|
{
|
|
PFEOBJ pfeo(((PFE **) (pPFF->aulData))[c]);
|
|
ASSERTGDI(pfeo.bValid(), "vRemoveHashPFFOBJ(): bad HPFE\n");
|
|
|
|
//
|
|
// Remove PFE from hash tables.
|
|
//
|
|
|
|
#ifdef FE_SB
|
|
if( !pfeo.bEUDC() )
|
|
{
|
|
#endif
|
|
fhoFace.vDelete(pfeo);
|
|
fhoFamily.vDelete(pfeo);
|
|
fhoUFI.vDelete(pfeo);
|
|
#ifdef FE_SB
|
|
}
|
|
#endif
|
|
|
|
#if DBG
|
|
if (gflFontDebug & DEBUG_FONTTABLE)
|
|
{
|
|
DbgPrint("gdisrv!vRemoveHashPFFOBJ() hpfe 0x%lx (\"%ws\")\n",
|
|
pfeo.ppfeGet(), pfeo.pwszFamilyName());
|
|
}
|
|
// Need level 2 checking to see this extra detail.
|
|
if (gflFontDebug & DEBUG_FONTTABLE_EXTRA)
|
|
{
|
|
fhoFamily.vPrint((VPRINT) DbgPrint);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//
|
|
// If this is a TrueType font, decrement the count.
|
|
//
|
|
if ( pPFF->hdev == (HDEV) gppdevTrueType )
|
|
{
|
|
gcTrueTypeFonts--; // protected by gpsemPublicPFT
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* BOOL PFFOBJ::bPermanent()
|
|
*
|
|
*
|
|
* Effects:
|
|
*
|
|
* Warnings:
|
|
*
|
|
* History:
|
|
* 06-Dec-1993 -by- Bodin Dresevic [BodinD]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
extern LPWSTR pwszBare( LPWSTR pwszPath );
|
|
extern UINT iHash(PWSZ pwsz,UINT c);
|
|
|
|
BOOL PFFOBJ::bPermanent()
|
|
{
|
|
// in the new version of the code every remote font is flagged at
|
|
// AddFontResourceTime. The difference in behavior from 3.51
|
|
// is that now fonts added by the applicaitons, if local, will not
|
|
// be removed at log on time.
|
|
|
|
if (pPFF->flState & PFF_STATE_REMOTE_FONT)
|
|
return FALSE;
|
|
else
|
|
return TRUE;
|
|
|
|
|
|
#if 0
|
|
// this is the old code, which I would still like to keep around for a while
|
|
|
|
// first check accelerator flags and see if the font is already
|
|
// marked as permanent one or as the one that has to be
|
|
// removed at logoff time as a remote font.
|
|
|
|
if (pPFF->flState & PFF_STATE_PERMANENT_FONT)
|
|
return TRUE;
|
|
|
|
if (pPFF->flState & PFF_STATE_REMOTE_FONT)
|
|
return FALSE;
|
|
|
|
|
|
// This is one of the fonts that have been added by an application
|
|
// such as winword or by an application that modifies the "Fonts" section
|
|
// of the registry such as control panel font applet or corel draw 5.0+.
|
|
// This must be a local
|
|
// font since all the remote fonts are flagged as remote at the time when
|
|
// they are added to the system. Now we will have to scan the "Fonts"
|
|
// section of the registry. If the font is found in the registry we will
|
|
// mark it permanent so as to accelerate the next logoff. If the font is not
|
|
// found in the registry this is a font that some application has added
|
|
// but forgot to remove when it quit. (Winword e.g.) Such a font, even though
|
|
// is local, will have to be removed at logoff time.
|
|
|
|
// BUGBUG Actually the main problem with this code is the fact that
|
|
// BUGBUG the registry entry may point to the .fot file while
|
|
// BUGBUG the PFT entry always points to the .ttf file. Here
|
|
// BUGBUG we are possibly comparing an .fot file name against a .ttf
|
|
// BUGBUG file name. These are clearly going to be different even if they
|
|
// BUGBUG refer to the same font. The right thing to do would be to
|
|
// BUGBUG to extract full ttf file path name from .fot. The problem is
|
|
// BUGBUG that we do not have SearchPathW machinery here to do this.
|
|
// BUGBUG That is why we will try to get away with simplified (and speedy)
|
|
// BUGBUG approach where we will not search the registry at logoff time
|
|
// BUGBUG and will keep all non remote fonts loaded.
|
|
|
|
LPWSTR pwszBareName = pwszBare( pwszPathname() );
|
|
|
|
for( pRHB = &pRHB[iHash( pwszBareName, cHashBuckets )]; pRHB != NULL; pRHB = pRHB->pRHB )
|
|
{
|
|
if( ( pRHB->pwszBareName != NULL ) &&
|
|
( !_wcsicmp( pwszBareName, pRHB->pwszBareName )) )
|
|
{
|
|
// case insensitive compare,
|
|
|
|
if (!_wcsicmp(pRHB->pwszPath, pwszPathname()))
|
|
{
|
|
pPFF->flState |= PFF_STATE_PERMANENT_FONT;
|
|
return(TRUE);
|
|
}
|
|
}
|
|
}
|
|
return FALSE;
|
|
|
|
#endif
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* PFFOBJ::pPFFcDelete
|
|
*
|
|
* Deletes the PFF and its PFEs. Information needed to call the driver
|
|
* to unload the font file and release driver allocated data is stored
|
|
* in the PFFCLEANUP structure. The PFFCLEANUP structure is allocated
|
|
* within this routine. It is the caller's responsibility to release
|
|
* the PFFCLEANUP structure (calling vCleanupFontFile() calls the drivers
|
|
* AND releases the structure).
|
|
*
|
|
* Returns:
|
|
* Pointer to PFFCLEANUP structure, NULL if no cleanup, -1 if error.
|
|
*
|
|
* History:
|
|
* 10-Mar-1993 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
PFFCLEANUP *PFFOBJ::pPFFC_Delete ()
|
|
{
|
|
//
|
|
// Allocate the PFFCLEANUP structure.
|
|
//
|
|
int cj;
|
|
PFFCLEANUP *pPFFC;
|
|
TRACE_FONT(("Entering PFFOBJ::pPFFC_Delete()\n\tpPFF=%-#x\n", pPFF));
|
|
|
|
cj = offsetof(PFFCLEANUP, apfec) + pPFF->cFonts * sizeof(PFECLEANUP);
|
|
|
|
if ((pPFFC = (PFFCLEANUP *) PALLOCMEM(cj,'cfpG')) == NULL )
|
|
{
|
|
WARNING("pPFFC_DeletePFFOBJ(): memory allocation failed\n");
|
|
return (PFFCLEANUP *) -1;
|
|
}
|
|
|
|
//
|
|
// Delete all the PFE entries.
|
|
//
|
|
for (COUNT c = 0; c < pPFF->cFonts; c++)
|
|
{
|
|
PFEOBJ pfeo(((PFE **) (pPFF->aulData))[c]);
|
|
ASSERTGDI(pfeo.bValid(), "pPFFC_DeletePFFOBJ(): bad HPFE (device font)\n");
|
|
|
|
//
|
|
// Delete the PFE. The vDelete function will copy the driver allocated
|
|
// resource information from the PFE into the PFECLEANUP structure.
|
|
// We will call DrvFree for these resources later (when we're not under
|
|
// semaphore).
|
|
//
|
|
pfeo.vDelete(&pPFFC->apfec[c]);
|
|
}
|
|
|
|
pPFFC->cpfec = pPFF->cFonts;
|
|
|
|
//
|
|
// Save stuff about the PFF also.
|
|
//
|
|
pPFFC->hff = pPFF->hff;
|
|
pPFFC->hdev = pPFF->hdev;
|
|
|
|
//
|
|
// Free object memory and invalidate pointer.
|
|
//
|
|
|
|
TRACE_FONT(("Freeing pPFF=%-#x\n",pPFF));
|
|
|
|
// If this was a remote font then we must delete the memory for the file.
|
|
// If this is a normal font then we must still delete the view.
|
|
|
|
FreeFileView(pPFF->ppfv, pPFF->cFiles);
|
|
|
|
VFREEMEM(pPFF);
|
|
|
|
pPFF = 0;
|
|
TRACE_FONT(("Exiting PFFOBJ::pPFFC_Delete\n\treturn value = %x\n", pPFFC));
|
|
return(pPFFC);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BOOL PFFOBJ::bDeleteLoadRef ()
|
|
*
|
|
* Remove a load reference. Caller must hold the gpsemPublicPFT semaphore.
|
|
*
|
|
* Returns:
|
|
* TRUE if caller should delete, FALSE if caller shouldn't delete.
|
|
*
|
|
* History:
|
|
* 23-Feb-1991 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL PFFOBJ::bDeleteLoadRef()
|
|
{
|
|
// gpsemPublicPFT protects the ref counts (cLoaded and cRFONT). Caller
|
|
// must grab the semaphore before calling this function.
|
|
|
|
// Decrement the load count. Must prevent underflow. Who knows if some
|
|
// app might not randomly go around doing extra RemoveFont calls. Isn't
|
|
// it too bad that we have to run APPS on our nice clean OS? :-)
|
|
|
|
BOOL bRet;
|
|
|
|
TRACE_FONT(("Enterning PFFOBJ::bDeleteLoadRef\n"
|
|
"\tpPFF=%-#x\n"
|
|
"\tcLoaded=%d\n",pPFF ,pPFF->cLoaded));
|
|
if (pPFF->cLoaded)
|
|
{
|
|
pPFF->cLoaded--;
|
|
}
|
|
if ( pPFF->cLoaded == 0 )
|
|
{
|
|
vKill(); // mark as "dead"
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
TRACE_FONT(("Exiting PFFOBJ::bDeleteLoadRef\n\treturn value = %d\n",bRet));
|
|
return( bRet );
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BOOL PFFOBJ::bDeleteRFONTRef ()
|
|
*
|
|
* Destroy the PFF physical font file object (message from a RFONT).
|
|
*
|
|
* Conditions that need to be met before deletion:
|
|
*
|
|
* must delete all RFONTs before PFF can be deleted (cRFONT must be zero)
|
|
* must delete all PFEs before deleting PFF
|
|
*
|
|
* After decrementing the cRFONT:
|
|
*
|
|
* If cRFONT != 0 OR flState != PFF_STATE_READY2DIE, just exit.
|
|
*
|
|
* If cRFONT == 0 and flState == PFF_STATE_READY2DIE, delete the PFF.
|
|
*
|
|
* Note:
|
|
* This function has the side effect of decrementing the RFONT count.
|
|
*
|
|
* Returns:
|
|
* TRUE if successful, FALSE if error occurs (which means PFF still lives!)
|
|
*
|
|
* Warning:
|
|
* This should only be called from RFONTOBJ::bDelete()
|
|
*
|
|
* History:
|
|
* 23-Feb-1991 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL PFFOBJ::bDeleteRFONTRef()
|
|
{
|
|
PFFCLEANUP *pPFFC = (PFFCLEANUP *) NULL;
|
|
|
|
{
|
|
// Need to stabilize table to access cRFONT and to modify font table.
|
|
|
|
SEMOBJ so(gpsemPublicPFT);
|
|
|
|
// Decrement the RFONT count.
|
|
|
|
ASSERTGDI(pPFF->cRFONT > 0,"bDeleteRFONTRefPFFOBJ(): bad ref count in PFF\n");
|
|
pPFF->cRFONT--;
|
|
|
|
// If load count is zero and no more RFONTs for this PFF, OK to delete.
|
|
|
|
if ( (pPFF->cLoaded == 0) && (pPFF->cRFONT == 0) )
|
|
{
|
|
// If the load count is zero, the PFF is already out of the PFT.
|
|
// It is now safe to delete the PFF.
|
|
|
|
pPFFC = pPFFC_Delete();
|
|
}
|
|
}
|
|
|
|
// Call the driver outside of the semaphore.
|
|
|
|
if (pPFFC == (PFFCLEANUP *) -1)
|
|
{
|
|
WARNING("bDeleteRFONTRefPFFOBJ(): error deleting PFF\n");
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
vCleanupFontFile(pPFFC); // function can handle NULL case
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vKill
|
|
*
|
|
* Puts the PFF and its PFEs to death. In other words, the PFF and PFEs are
|
|
* put in a dead state that prevents them from being mapped to or enumerated.
|
|
* It also means that the font file is in a state in which the system wants
|
|
* to delete it (load count is zero), but the deletion is delayed because
|
|
* RFONTs still exist which reference this PFF.
|
|
*
|
|
* History:
|
|
* 29-May-1992 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID PFFOBJ::vKill()
|
|
{
|
|
// Put into a dead state if not already there.
|
|
TRACE_FONT(("Entering PFFOBJ::vKill\n\tpPFF=%-#x\n", pPFF));
|
|
if ( !bDead() )
|
|
{
|
|
// Set state.
|
|
pPFF->flState |= PFF_STATE_READY2DIE;
|
|
|
|
// Run the list of PFEs and set each to death.
|
|
for (COUNT c = 0; c < pPFF->cFonts; c++)
|
|
{
|
|
PFEOBJ pfeo(((PFE **) (pPFF->aulData))[c]);
|
|
|
|
if (pfeo.bValid())
|
|
{
|
|
// Mark PFE as dead state.
|
|
|
|
pfeo.vKill();
|
|
}
|
|
else
|
|
{
|
|
WARNING("vDiePFFOBJ(): cannot make PFEOBJ\n");
|
|
}
|
|
}
|
|
}
|
|
TRACE_FONT(("Exiting PFFOBJ::vKill\n"));
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vRevive
|
|
*
|
|
* Restores the PFF and its PFEs to life. In other words, the states are
|
|
* cleared so that the PFF and PFEs are available for mapping and enumeration.
|
|
*
|
|
* History:
|
|
* 29-May-1992 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID PFFOBJ::vRevive ()
|
|
{
|
|
// If dead, then revive.
|
|
|
|
if ( bDead() )
|
|
{
|
|
// Reset state.
|
|
|
|
pPFF->flState &= ~PFF_STATE_READY2DIE;
|
|
|
|
// Run the list of PFEs and revive each one.
|
|
|
|
for (COUNT c = 0; c < pPFF->cFonts; c++)
|
|
{
|
|
PFEOBJ pfeo(((PFE **) (pPFF->aulData))[c]);
|
|
|
|
if (pfeo.bValid())
|
|
{
|
|
// Mark PFE as dead state.
|
|
|
|
pfeo.vRevive();
|
|
}
|
|
else
|
|
{
|
|
WARNING("vRevivePFFOBJ(): cannot make PFEOBJ\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BOOL PFFMEMOBJ::bLoadFontFileTable (
|
|
* PFDEVOBJ pfdoDriver,
|
|
* PWSZ pwszPathname,
|
|
* COUNT cFontsToLoad
|
|
* )
|
|
*
|
|
* Creates a PFE for each of the faces in a font file and loads the IFI
|
|
* metrics and mapping tables into each of the PFEs. The font file is
|
|
* uniquely identified by the driver, hoDriver, and IFI font file handle,
|
|
* hff, stored in the PFF object. However, rather than hitting the handle
|
|
* manager an extra time, a PFDEVOBJ is passed into this function.
|
|
*
|
|
* After all the PFE entries are added, the font files pathname is added
|
|
* to the end of the data buffer.
|
|
*
|
|
* It is assumed that the PFF ahpfe table has enough room for cFontsToLoad
|
|
* new HPFE handles as well as the font files pathname.
|
|
*
|
|
* Returns:
|
|
* TRUE if successful, FALSE if error.
|
|
*
|
|
* History:
|
|
* 16-Jan-1991 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL PFFMEMOBJ::bLoadFontFileTable (
|
|
PWSZ pwszPathname, // upper case
|
|
COUNT cFontsToLoad,
|
|
HANDLE hdc
|
|
#ifdef FE_SB
|
|
,PEUDCLOAD pEudcLoadData
|
|
#endif
|
|
)
|
|
{
|
|
ULONG iFont; // font face index
|
|
|
|
// Create PFE's for each of the fonts in the font file.
|
|
// (Note: iFont indices for IFI fonts are 1-based, not 0-based)
|
|
|
|
PDEVOBJ ppdo(hdev());
|
|
|
|
for (iFont = 1; iFont <= cFontsToLoad; iFont++)
|
|
{
|
|
FD_GLYPHSET *pfdg;
|
|
PIFIMETRICS pifi; // storage for the pointer to ifi
|
|
ULONG idGlyphSet, idMetrics;
|
|
|
|
// Grab the IFIMETRICS pointer.
|
|
|
|
if ( (pifi = (PIFIMETRICS) (*PPFNDRV(ppdo, QueryFont)) (
|
|
pPFF->dhpdev,
|
|
pPFF->hff,
|
|
iFont,
|
|
&idMetrics)) == (PIFIMETRICS) NULL )
|
|
{
|
|
WARNING("bLoadFontFileTablePFFMEMOBJ(): error getting metrics\n");
|
|
return (FALSE);
|
|
}
|
|
|
|
// Get the glyph mappings pointer.
|
|
|
|
if ( (pfdg = (FD_GLYPHSET *) (*PPFNDRV(ppdo, QueryFontTree)) (
|
|
pPFF->dhpdev,
|
|
pPFF->hff,
|
|
iFont,
|
|
QFT_GLYPHSET,
|
|
&idGlyphSet)) == (FD_GLYPHSET *) NULL )
|
|
{
|
|
// Failed to get the FD_GLYPHSET information. The entry is
|
|
// partially valid (IFIMETRICS), so lets invalidate the good part.
|
|
|
|
if (PPFNVALID(ppdo,Free))
|
|
{
|
|
(*PPFNDRV(ppdo,Free))(pifi, idMetrics);
|
|
}
|
|
|
|
WARNING("bLoadFontFileTablePFFMEMOBJ(): error getting glyphset\n");
|
|
|
|
return (FALSE);
|
|
}
|
|
|
|
// Put into a new PFE.
|
|
|
|
#ifdef FE_SB
|
|
if( bReadyToInitializeFontAssocDefault )
|
|
{
|
|
// This should be Base font, not be EUDC.
|
|
//
|
|
if ( pEudcLoadData == NULL )
|
|
{
|
|
// check this base font should be RE-load as default linked font ?
|
|
// if so, the pathname for this font will be registerd as default linked font.
|
|
FindDefaultLinkedFontEntry(
|
|
(PWSZ)(((BYTE*) pifi) + pifi->dpwszFamilyName),pwszPathname);
|
|
}
|
|
}
|
|
|
|
if (bAddEntry(iFont, pfdg, idGlyphSet, pifi, idMetrics, (HANDLE)0,
|
|
pEudcLoadData) == FALSE)
|
|
{
|
|
WARNING("gdisrv!_bAddEntry\n");
|
|
return(FALSE);
|
|
}
|
|
#else
|
|
if (bAddEntry(iFont, pfdg, idGlyphSet, pifi, idMetrics, (HANDLE) 0) == FALSE)
|
|
{
|
|
WARNING("gdisrv!_bAddEntry\n");
|
|
return(FALSE);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// Add filename at the end of the table.
|
|
|
|
pPFF->pwszPathname_ = pwszCalcPathname();
|
|
if (pPFF->cwc)
|
|
RtlCopyMemory(pPFF->pwszPathname_,
|
|
pwszPathname,
|
|
pPFF->cwc * sizeof(WCHAR));
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BOOL PFFMEMOBJ::bLoadDeviceFontTable (
|
|
*
|
|
* Creates a PFE object for each device font and stores the IFIMETRICS and
|
|
* FD_MAPPINGS (UNICODE->HGLYPH) structures of that font. The device is
|
|
* identified by the pair (ppdo, dhpdev). There are cFonts number of device
|
|
* fonts to load.
|
|
*
|
|
* Note:
|
|
* It is assumed that there is enough storage in the PFF for the number
|
|
* of device fonts requested.
|
|
*
|
|
* History:
|
|
* 18-Mar-1991 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL
|
|
PFFMEMOBJ::bLoadDeviceFontTable (
|
|
PDEVOBJ *ppdo // physical device
|
|
)
|
|
{
|
|
ULONG iFont; // font face index
|
|
ULONG cFonts = ppdo->cFonts();
|
|
|
|
|
|
if (cFonts)
|
|
{
|
|
//
|
|
// If the device has some fonts, allocate two FONTHASH strcutures
|
|
// and save the addresses of the tables on the PFF
|
|
//
|
|
|
|
FHMEMOBJ fhmoFace( &pPFF->pfhFace, FHT_FACE , cFonts);
|
|
FHMEMOBJ fhmoFamily(&pPFF->pfhFamily, FHT_FAMILY, cFonts);
|
|
FHMEMOBJ fhmoUFI(&pPFF->pfhUFI, FHT_UFI, cFonts);
|
|
}
|
|
|
|
// Create PFE's for each of the fonts in the font file
|
|
// (Note: iFont indices for device fonts are 1-based, not 0-based)
|
|
|
|
for (iFont = 1; iFont<=cFonts; iFont++)
|
|
{
|
|
PIFIMETRICS pifi; // pointer to font's IFIMETRICS
|
|
FD_GLYPHSET *pfdg; // pointer to font's GLYPHSETs
|
|
|
|
ULONG idifi; // driver id's
|
|
ULONG idfdg;
|
|
|
|
// Get pointer to metrics
|
|
|
|
if ( (pifi = (*PPFNDRV(*ppdo,QueryFont)) (
|
|
pPFF->dhpdev,
|
|
0,
|
|
iFont,
|
|
&idifi)) == NULL )
|
|
{
|
|
SAVE_ERROR_CODE(ERROR_CAN_NOT_COMPLETE);
|
|
#if DBG
|
|
DbgPrint("gdisrv!PFFMEMOBJ::bLoadDeviceFontTable(): error getting metrics \
|
|
for iFace = %ld\n", iFont);
|
|
#endif
|
|
return (FALSE);
|
|
}
|
|
|
|
// Get pointer to the UNICODE->HGLYPH mappings
|
|
|
|
if ( (pfdg = (FD_GLYPHSET *) (*PPFNDRV(*ppdo,QueryFontTree))(
|
|
pPFF->dhpdev,
|
|
0,
|
|
iFont,
|
|
QFT_GLYPHSET,
|
|
&idfdg)) == NULL )
|
|
{
|
|
// Failed to get the FD_GLYPHSET information. The entry is
|
|
// partially valid (IFIMETRICS), so lets invalidate the good part.
|
|
|
|
if (PPFNVALID(*ppdo,Free))
|
|
{
|
|
(*PPFNDRV(*ppdo,Free))(pifi, idifi);
|
|
}
|
|
|
|
SAVE_ERROR_CODE(ERROR_CAN_NOT_COMPLETE);
|
|
|
|
#if DBG
|
|
DbgPrint("gdisrv!PFFMEMOBJ::bLoadDeviceFontTable(): error getting UNICODE \
|
|
maps for iFace = %ld\n", iFont);
|
|
#endif
|
|
return (FALSE);
|
|
}
|
|
|
|
|
|
// Put into a new PFE
|
|
|
|
// add entry logs error
|
|
|
|
if (bAddEntry(iFont, pfdg, idfdg, pifi, idifi,(HANDLE)0) == FALSE)
|
|
{
|
|
WARNING("bLoadDeviceFontTable():adding PFE\n");
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BOOL PFFMEMOBJ::bAddEntry *
|
|
* *
|
|
* This function creates a new physical font entry object and adds it to the*
|
|
* end of the table. The iFont parameter identifies the font within this *
|
|
* file. The cjSize and pjMetrics identify a buffer containing face *
|
|
* information including the IFI metrics and the mapping structures *
|
|
* (defining the UNICODE->HGLYPH mapping). *
|
|
* *
|
|
* Returns FALSE if the function fails. *
|
|
* *
|
|
* History: *
|
|
* 02-Jan-1991 -by- Gilman Wong [gilmanw] *
|
|
* Wrote it. *
|
|
\**************************************************************************/
|
|
|
|
BOOL PFFMEMOBJ::bAddEntry
|
|
(
|
|
ULONG iFont, // index of the font (IFI or device)
|
|
FD_GLYPHSET *pfdg, // pointer to UNICODE->HGLYPH map
|
|
ULONG idfdg, // driver id for FD_GLYPHSET
|
|
PIFIMETRICS pifi, // pointer to IFIMETRICS
|
|
ULONG idifi, // driver id for IFIMETRICS
|
|
HANDLE hdc // handle of DC if this is a remote font
|
|
#ifdef FE_SB
|
|
,PEUDCLOAD pEudcLoadData // pointer to EUDCLOAD
|
|
#endif
|
|
)
|
|
{
|
|
|
|
// Allocate memory for a new PFE
|
|
|
|
PFEMEMOBJ pfemo;
|
|
|
|
// Validate new object, hmgr logs error if needed
|
|
|
|
if (!pfemo.bValid())
|
|
return (FALSE);
|
|
|
|
// Initialize the new PFE
|
|
|
|
#ifdef FE_SB
|
|
|
|
BOOL bEUDC = ( pEudcLoadData != NULL );
|
|
PPFE *pppfeEUDC = ((bEUDC) ? pEudcLoadData->pppfeData : NULL);
|
|
|
|
if( !pfemo.bInit(pPFFGet(), iFont, pfdg, idfdg, pifi, idifi, bDeviceFonts(), bEUDC ))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
if( bEUDC )
|
|
{
|
|
//
|
|
// This font file is loaded as EUDC font.
|
|
//
|
|
if( pEudcLoadData->LinkedFace == NULL )
|
|
{
|
|
//
|
|
// No face name is specified.
|
|
//
|
|
switch( iFont )
|
|
{
|
|
case 1:
|
|
pppfeEUDC[PFE_NORMAL] = pfemo.ppfeGet();
|
|
pppfeEUDC[PFE_VERTICAL] = pppfeEUDC[PFE_NORMAL];
|
|
break;
|
|
|
|
case 2:
|
|
//
|
|
// if more than one face name the second face must be an @face
|
|
//
|
|
if( pfemo.pwszFaceName()[0] == (WCHAR) '@' )
|
|
{
|
|
pppfeEUDC[PFE_VERTICAL] = pfemo.ppfeGet();
|
|
|
|
#if DBG
|
|
if( gflEUDCDebug & (DEBUG_FONTLINK_LOAD|DEBUG_FONTLINK_INIT) )
|
|
{
|
|
DbgPrint("EUDC font has vertical face %ws %x\n",
|
|
pfemo.pwszFaceName(), pppfeEUDC[PFE_VERTICAL] );
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
WARNING("bAddEntryPFFMEMOBJ -- second face not a @face.\n");
|
|
}
|
|
break;
|
|
|
|
default:
|
|
WARNING("bAddEntryPFFMEMOBJ -- too many faces in EUDC font.\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( iFont == 1 )
|
|
{
|
|
//
|
|
// link first face as default, because this font file might not
|
|
// contains user's specified face name, but the user want to link
|
|
// this font file. I don't know which is better link it as default
|
|
// or fail link.
|
|
//
|
|
pppfeEUDC[PFE_NORMAL] = pfemo.ppfeGet();
|
|
pppfeEUDC[PFE_VERTICAL] = pppfeEUDC[PFE_NORMAL];
|
|
}
|
|
else
|
|
{
|
|
ULONG iPfeOffset = PFE_NORMAL;
|
|
PWSTR pwszEudcFace = pfemo.pwszFaceName();
|
|
|
|
//
|
|
// Is this a vertical face ?
|
|
//
|
|
if( pwszEudcFace[0] == (WCHAR) '@' )
|
|
{
|
|
pwszEudcFace++; // skip '@'
|
|
iPfeOffset = PFE_VERTICAL;
|
|
}
|
|
|
|
//
|
|
// Is this a face that we want ?
|
|
//
|
|
if( _wcsicmp(pwszEudcFace,pEudcLoadData->LinkedFace) == 0 )
|
|
{
|
|
//
|
|
// Yes....., keep it.
|
|
//
|
|
pppfeEUDC[iPfeOffset] = pfemo.ppfeGet();
|
|
|
|
//
|
|
// if this is a PFE for Normal face, also keep it for Vertical face.
|
|
// after this, this value might be over-written by CORRRCT vertical
|
|
// face's PFE.
|
|
//
|
|
// NOTE :
|
|
// This code assume Normal face come faster than Vertical face...
|
|
//
|
|
if( iPfeOffset == PFE_NORMAL )
|
|
pppfeEUDC[PFE_VERTICAL] = pfemo.ppfeGet();
|
|
}
|
|
}
|
|
}
|
|
|
|
// mark the FaceNameEUDC pfe list as NULL
|
|
|
|
pfemo.vSetLinkedFontEntry( NULL );
|
|
}
|
|
else
|
|
{
|
|
|
|
// Here we see if there is an EUDC font for this family name.
|
|
|
|
PFLENTRY pFlEntry = FindBaseFontEntry(pfemo.pwszFamilyName());
|
|
|
|
if( pFlEntry != NULL )
|
|
{
|
|
//
|
|
// set eudc list..
|
|
//
|
|
|
|
pfemo.vSetLinkedFontEntry( pFlEntry );
|
|
|
|
#if DBG
|
|
if( gflEUDCDebug & DEBUG_FACENAME_EUDC )
|
|
{
|
|
PLIST_ENTRY p = pfemo.pGetLinkedFontList()->Flink;
|
|
|
|
DbgPrint("Found FaceName EUDC for %ws is ",pfemo.pwszFamilyName());
|
|
|
|
while( p != &(pFlEntry->linkedFontListHead) )
|
|
{
|
|
PPFEDATA ppfeData = CONTAINING_RECORD(p,PFEDATA,linkedFontList);
|
|
PFEOBJ pfeo( ppfeData->appfe[PFE_NORMAL] );
|
|
PFFOBJ pffo( pfeo.pPFF() );
|
|
|
|
DbgPrint(" %ws ",pffo.pwszPathname());
|
|
|
|
p = p->Flink;
|
|
}
|
|
|
|
DbgPrint("\n");
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
// mark the FaceNameEUDC pfe as NULL
|
|
|
|
pfemo.vSetLinkedFontEntry( NULL );
|
|
}
|
|
|
|
}
|
|
#else
|
|
if (!pfemo.bInit(pPFFGet(), iFont, pfdg, idfdg, pifi, idifi, bDeviceFonts()))
|
|
return FALSE;
|
|
#endif
|
|
|
|
// Put PFE pointer into the PFF's table
|
|
|
|
((PFE **) (pPFF->aulData))[pPFF->cFonts++] = pfemo.ppfeGet();
|
|
|
|
pfemo.vKeepIt();
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
#if DBG
|
|
/******************************Public*Routine******************************\
|
|
* VOID PFFOBJ::vDump ()
|
|
*
|
|
* Debugging code.
|
|
*
|
|
* History:
|
|
* Thu 02-Apr-1992 12:10:28 by Kirk Olynyk [kirko]
|
|
* DbgPrint supports %ws
|
|
*
|
|
* 25-Feb-1991 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID PFFOBJ::vDump ()
|
|
{
|
|
DbgPrint("\nContents of PFF, pPFF = 0x%lx\n", pPFFGet());
|
|
if (*(WCHAR *)pwszPathname())
|
|
{
|
|
DbgPrint("Filename = %ws\n", pwszPathname());
|
|
}
|
|
DbgPrint("flState = 0x%lx\n", pPFF->flState);
|
|
DbgPrint("cLoaded = %ld\n", pPFF->cLoaded);
|
|
DbgPrint("cRFONT = %ld\n", pPFF->cRFONT);
|
|
DbgPrint("hff = 0x%lx\n", pPFF->hff);
|
|
DbgPrint("cFonts = %ld\n", pPFF->cFonts);
|
|
DbgPrint("HPFE table\n");
|
|
for (ULONG i=0; i<pPFF->cFonts; i++)
|
|
DbgPrint(" 0x%lx\n", ((PFE **) (pPFF->aulData))[i]);
|
|
DbgPrint("\n");
|
|
}
|
|
#endif
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vCleanupFontFile
|
|
*
|
|
* Parses the PFFCLEANUP structure and calls the driver to release
|
|
* its resources and to unload the font file.
|
|
*
|
|
* History:
|
|
* 10-Mar-1993 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vCleanupFontFile(PFFCLEANUP *pPFFC)
|
|
{
|
|
//
|
|
// Quick out for NULL pPFFC case.
|
|
//
|
|
if (pPFFC == (PFFCLEANUP *) NULL)
|
|
return;
|
|
|
|
ASSERTGDI(pPFFC != (PFFCLEANUP *) -1, "vCleanupFontFile(): bad pPFFC\n");
|
|
|
|
//
|
|
// Create PDEV user object so we can call driver functions.
|
|
//
|
|
|
|
PDEVOBJ pdo(pPFFC->hdev);
|
|
|
|
//
|
|
// If it exists, call the DrvFree function on all id's.
|
|
//
|
|
if (PPFNVALID(pdo,Free))
|
|
{
|
|
for (COUNT c = 0; c < pPFFC->cpfec; c++)
|
|
{
|
|
#if DBG
|
|
IFIOBJ ifio(pPFFC->apfec[c].pifi);
|
|
TRACE_FONT(("vCleanupFontFile freeing IFIMETRICS:\"%ws\"\n", ifio.pwszFaceName()));
|
|
#endif
|
|
(*PPFNDRV(pdo,Free))(pPFFC->apfec[c].pfdg, pPFFC->apfec[c].idfdg);
|
|
(*PPFNDRV(pdo,Free))(pPFFC->apfec[c].pifi, pPFFC->apfec[c].idifi);
|
|
(*PPFNDRV(pdo,Free))(pPFFC->apfec[c].pkp , pPFFC->apfec[c].idkp );
|
|
}
|
|
}
|
|
|
|
//
|
|
// If font driver loaded font, call to unload font file.
|
|
//
|
|
if (pPFFC->hff != HFF_INVALID)
|
|
{
|
|
#if DBG
|
|
BOOL bOK =
|
|
#endif
|
|
(*PPFNDRV(pdo, UnloadFontFile))(pPFFC->hff);
|
|
ASSERTGDI(bOK, "PFFOBJ::vCleanupFontFile(): DrvUnloadFontFile failed\n");
|
|
|
|
// When the font file was loaded, we added a reference to the LDEV so
|
|
// that we would not remove the driver while a font was loaded by it.
|
|
// Now, however, we must remove that reference.
|
|
//
|
|
// We must hold the gpsemDriverMgmt while we do this to protect the
|
|
// ref count.
|
|
|
|
SEMOBJ soDrivers(gpsemDriverMgmt);
|
|
|
|
// BUGBUG this is broken
|
|
// ldo.vUnreference();
|
|
}
|
|
|
|
//
|
|
// Free the PFFCLEANUP structure.
|
|
//
|
|
VFREEMEM(pPFFC);
|
|
}
|
|
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* bEmbedOk()
|
|
*
|
|
* Based on the embedding flags and the process or task id of the client
|
|
* determines whether it is okay to unload and load this PFF.
|
|
*
|
|
* Returns TRUE if okay to unload/load or FALSE otherwise
|
|
*
|
|
* History:
|
|
* 14-Apr-1993 -by- Gerrit van Wingerden
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
|
|
BOOL PFFOBJ::bEmbedOk()
|
|
{
|
|
switch( pPFF->flEmbed )
|
|
{
|
|
case FM_INFO_TID_EMBEDDED:
|
|
|
|
if (pPFF->ulID != (ULONG) W32GetCurrentThread())
|
|
{
|
|
WARNING("bEmbedOkPFFOBJ: bad TID\n");
|
|
return(FALSE);
|
|
}
|
|
break;
|
|
|
|
case FM_INFO_PID_EMBEDDED:
|
|
|
|
if (pPFF->ulID != (ULONG) W32GetCurrentProcess())
|
|
{
|
|
WARNING("bEmbedOkPFFOBJ bad PID\n");
|
|
return(FALSE);
|
|
}
|
|
}
|
|
return(TRUE);
|
|
}
|