Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1221 lines
30 KiB

/*++
Copyright (c) 1996 - 1999 Microsoft Corporation
Module Name:
dlutils.c
Abstract:
Download Modules utilts functions.
Environment:
Windows NT Unidrv driver
Revision History:
06/02/97 -ganeshp-
Created
--*/
#include "font.h"
#define HASH(num,tablesize) (num % tablesize)
PDLGLYPH
PDLGNewGlyph (
DL_MAP *pDL
)
/*++
Routine Description:
Arguments:
pDL Pointer to DownloadMap for the downloaded font.
Return Value:
Pointer to the new DLGLYPH for success and NULL for failure.
Note:
06/02/97 -ganeshp-
Created it.
--*/
{
GLYPHTAB *pGlyphTab;
PDLGLYPH pDLGlyph = NULL;
if (pGlyphTab = pDL->GlyphTab.pGLTNext)
{
//
//Go to the end of the List.
//
while (pGlyphTab && !pGlyphTab->cEntries)
pGlyphTab = pGlyphTab->pGLTNext;
}
//
//Allocate a new Chunk, if we need a new one.
//
if (!pGlyphTab)
{
INT cEntries = pDL->cHashTableEntries / 2; // Half the size of hash table.
if (pGlyphTab = (GLYPHTAB *)MemAllocZ( sizeof(GLYPHTAB) +
cEntries * sizeof(DLGLYPH) ))
{
PVOID pTemp;
//
//Skip the header.
//
pGlyphTab->pGlyph = (PDLGLYPH)(pGlyphTab + 1);
pGlyphTab->cEntries = cEntries;
//
//Add in the begining of the list.
//
pTemp = pDL->GlyphTab.pGLTNext;
pDL->GlyphTab.pGLTNext = pGlyphTab;
pGlyphTab->pGLTNext = pTemp;
}
else
ERR(("Unifont!PDLGNewGlyph:Can't Allocate the Glyph Chunk.\n"));
}
//
//If the chunk has available entries, return the new pointer.
//
if (pGlyphTab && pGlyphTab->cEntries)
{
pDLGlyph = pGlyphTab->pGlyph;
pGlyphTab->pGlyph++;
pGlyphTab->cEntries--;
}
//
// Initialize the hTTGlyphs to Invalid.
//
if (NULL != pDLGlyph)
pDLGlyph->hTTGlyph = HGLYPH_INVALID;
return pDLGlyph;
}
PDLGLYPH
PDLGHashGlyph (
DL_MAP *pDL,
HGLYPH hTTGlyph
)
/*++
Routine Description:
This routine searches the Hash table for a given Glyph. If the
Glyph is not found in the Has table it creats an entry and add
that into the list. The new entry is not filled.
Arguments:
pDL Pointer to DownloadMap Structure for the downloaded font.
hTTGlyph True Type Glyph Handle.
Return Value:
Pointer to the DLGLYPH for success and NULL for failure.
Note:
06/02/97 -ganeshp-
Created it.
--*/
{
INT iHashedEntry;
BOOL bFound;
PDLGLYPH pDLHashedGlyph = NULL,
pDLG = NULL;
if (pDL->cHashTableEntries)
{
//
// Hashing is done on TT handle.
//
iHashedEntry = HASH(hTTGlyph,pDL->cHashTableEntries);
pDLG = pDLHashedGlyph = pDL->GlyphTab.pGlyph + iHashedEntry;
//
//Proceed if the pointer is valid
//
if (pDLHashedGlyph)
{
//
// Check if this is the Glyph we are interested in.
// We should test if this glyph is new glyph or not.
//
if (!GLYPHDOWNLOADED(pDLHashedGlyph) )
{
//
// If this is a new glyph which is not downloaded then return
// this pointer.
//
bFound = TRUE;
}
else if (pDLHashedGlyph->hTTGlyph != hTTGlyph)
{
pDLG = pDLHashedGlyph->pNext;
bFound = FALSE;
//
// Not the same Glyph, It's a Collision. Search the Linked list.
//
while (pDLG)
{
if (pDLG->hTTGlyph == hTTGlyph)
{
bFound = TRUE;
break;
}
else
pDLG = pDLG->pNext;
}
//
// If the Glyph is found in the linked list, return the pointer;
// else create a new Glyph and add at the linked list. We add in
// the begining.
//
if (!bFound)
{
if ( pDLG = PDLGNewGlyph(pDL) )
{
PDLGLYPH pTemp;
//
// Don't Fill in the Glyph. All the fields are set
// by the DownLoad Glyph function.
//
//
// Add the New Glyph at the begining of the list.
//
pTemp = pDLHashedGlyph->pNext;
pDLHashedGlyph->pNext = pDLG;
pDLG->pNext = pTemp;
}
else
{
pDLG = NULL;
ERR(("Unifont!PDLGHashGlyph:Can't Create the Glyph.\n"));
}
}
}
}
}
ASSERTMSG(pDLG,("Unifont!PDLGHashGlyph:ERROR Null Hashed Glyph.\n"));
return pDLG;
}
DL_MAP_LIST *
PNewDLMapList()
/*++
Routine Description:
Allocate and initialise a new DL_MAP_LIST structure. These
are placed in a linked list (by our caller).
Arguments: None
Return Value:
The address of the structure, or NULL on failure.
Note:
3/5/1997 -ganeshp-
Created it.
--*/
{
DL_MAP_LIST *pdml;
/*
* Little to do: if we can allocate the storage, then set it to 0.
*/
if( pdml = (DL_MAP_LIST *)MemAllocZ(sizeof( DL_MAP_LIST ) ) )
return pdml;
else
return NULL;
}
DL_MAP *
PNewDLMap (
PFONTPDEV pFontPDev,
INT *iFontIndex
)
/*++
Routine Description:
This routine return a new DL_MAP pointer.
Arguments:
pFontPDev Font Modules's PDEV.
iFontIndex Index of the new DL_MAP. The index is used to
identify the downloaded font.Filled by this function.
Zero is first index.
Return Value:
Pointer to DL_MAP for success and NULL for failure
Note:
06/02/97 -ganeshp-
Created it.
--*/
{
DL_MAP_LIST *pdml; // The linked list of font information
DL_MAP *pdm; // Individual map element
pdml = pFontPDev->pvDLMap;
*iFontIndex = 0;
pdm = NULL;
//
// If no DL List, create one.
//
if( pdml == NULL )
{
//
// None there, so create an initial one.
//
if( pdml = PNewDLMapList() )
{
pFontPDev->pvDLMap = pdml;
}
else
{
ERR(("Unifont!PNewDLMap(1):Can't Allocate the DL_MAP_LIST Chunk.\n"));
}
}
//
// The list should be not null. else return NULL.
//
if (pdml)
{
for( pdml = pFontPDev->pvDLMap; pdml->pDMLNext; pdml = pdml->pDMLNext )
{
//
// While looking for the end, also count the number we pass.
//
*iFontIndex += pdml->cEntries;
}
if( pdml->cEntries >= DL_MAP_CHUNK )
{
if( !(pdml->pDMLNext = PNewDLMapList()) )
{
ERR(("Unifont!PNewDLMap(2):Can't Allocate the DL_MAP_LIST Chunk.\n"));
return NULL;
}
//
// The new current model.
//
pdml = pdml->pDMLNext;
//
// Add in the full one.
//
*iFontIndex += DL_MAP_CHUNK;
}
pdm = &pdml->adlm[ pdml->cEntries ];
//
// Increment the iFontIndex first as the it is 0 based.
// For 1st entry the index will be 0.
//
*iFontIndex += pdml->cEntries;
pdml->cEntries++;
}
return pdm;
}
VOID
VFreeDLMAP (
DL_MAP *pdm
)
/*++
Routine Description:
This function fress DL_MAP structure contents - but NOT the map.
Arguments:
pdm Pointer to DL_MAP structure whose contents has to be freed.
Return Value:
Nothing.
Note:
01/15/97 -ganeshp-
Created it.
--*/
{
FONTMAP *pFM;
PVOID pTemp;
GLYPHTAB *pGT;
ULONG_PTR iTTUniq;
/*
* Simply free the storage contained within the FONTMAP structure.
*/
if (pdm )
{
if (pFM = pdm->pfm)
{
//
// Try to Free what we allocated.
//
MEMFREEANDRESET((LPSTR)pFM->pIFIMet );
if (pFM->pfnFreePFM)
{
//
// Free The pfm by calling the helper function.
//
pFM->pfnFreePFM(pFM);
}
else
{
ERR(("UniFont!VFreeDLMAP: NUll pfnFreePFM function pointer, Can't free pFM\n"));
//
// Try to Free what we know about.
//
MemFree( (LPSTR)pFM);
}
}
//
// Free the Glyph Table.
//
pGT = pdm->GlyphTab.pGLTNext;
while (pGT)
{
pTemp = pGT->pGLTNext;
MemFree((LPSTR)pGT);
pGT = pTemp;
}
//
// Now free the base hash table.
//
MEMFREEANDRESET( (LPSTR)pdm->GlyphTab.pGlyph );
//
// Zero the memory and make cGlyphs to -1 so that it's not used.
// Save the iTTUniq for future reference.
//
iTTUniq = pdm->iTTUniq;
ZeroMemory(pdm, sizeof(DL_MAP));
pdm->iTTUniq = iTTUniq;
pdm->cGlyphs = -1;
}
return;
}
VOID
VFreeDL(
PDEV *pPDev
)
/*++
Routine Description:
Function to free up all the downloaded information. Basically
work through the list, calling VFreeDLMAP for each entry.
Arguments:
pPDev Access to our data.
Return Value:
Nothing.
Note:
01/15/97 -ganeshp-
Created it.
--*/
{
DL_MAP_LIST *pdml; /* The linked list of font information */
PFONTPDEV pFontPDev = PFDV; /* It's used a few times */
if( pdml = pFontPDev->pvDLMap )
{
/*
* There is downloaded data, so off we go.
*/
INT iI;
/*
* Scan through each of the arrays of header data.
*/
while( pdml )
{
DL_MAP_LIST *pdmlTmp = NULL;
/*
* Scan through each entry in the array of header data.
*/
for( iI = 0; iI < pdml->cEntries; ++iI )
VFreeDLMAP( &pdml->adlm[ iI ] );
pdmlTmp = pdml;
//
// Remember the next one
//
pdml = pdml->pDMLNext;
MemFree((LPSTR)pdmlTmp);
}
}
//
// Reset Download specific variables.
//
pFontPDev->pvDLMap = NULL;
pFontPDev->iNextSFIndex = pFontPDev->iFirstSFIndex;
pFontPDev->iUsedSoftFonts = 0;
pFontPDev->ctl.iFont = INVALID_FONT;
pFontPDev->ctl.iSoftFont = -1;
return;
}
DL_MAP *
PGetDLMapFromIdx (
PFONTPDEV pFontPDev,
INT iFontIndex
)
/*++
Routine Description:
This routine return a DL_MAP pointer, given it's index..
Arguments:
pFontPDev Font PDEV.
iFontIndex Index of the DL_MAP. The index is used to
identify the downloaded font. Zero is first index.
Return Value:
Pointer to DL_MAP for success and NULL for failure
Note:
06/02/97 -ganeshp-
Created it.
--*/
{
DL_MAP_LIST *pdml; // The linked list of font information
DL_MAP *pdm; // Individual map element
pdml = pFontPDev->pvDLMap;
pdm = NULL;
//
// If the index is negative that means this is a new font. So we should
// search sequentially.
//
if (iFontIndex < 0)
return NULL;
//
// The list should be not null. else return NULL.
//
while( pdml )
{
//
// Is this chunk the one containing the entry?
//
if( iFontIndex >= pdml->cEntries )
{
//
// Not this one, so onto the next.
//
iFontIndex -= pdml->cEntries;
pdml = pdml->pDMLNext;
}
else
{
//
// We got it!
//
pdm = &pdml->adlm[ iFontIndex ];
break;
}
}
return pdm;
}
BOOL
BSameDLFont (
PFONTPDEV pFontPDev,
FONTOBJ *pfo,
DL_MAP *pdm
)
/*++
Routine Description:
This routine finds out if input DL_MAP represents the FONTOBJ or not.
Arguments:
pFontPDev Font Modules's PDEV.
pfo FontObj.
pdm Individual download map element.
Return Value:
TRUE if DL_MAP represents FONTOBJ else FALSE.
Note:
06/02/97 -ganeshp-
Created it.
--*/
{
//
// The checks are different for download TT as outline and download
// as TT OutLine. For Download a Bitmap we check iUniq and for download
// as TT Outline we have to use iTTUniq. If the same printer can support
// both format we may download the font as any one of the format.
//
FONTMAP *pfm = pdm->pfm;
if (pfm)
{
if (pfm->dwFontType == FMTYPE_TTBITMAP)
{
return ((pdm->iUniq == pfo->iUniq) && (pdm->iTTUniq == pfo->iTTUniq));
}
else if (pfm->dwFontType == FMTYPE_TTOUTLINE)
{
//
// The truetype font is equivalent if the iTTUniq is the same *and*
// the font-type field matches.
//
PFONTMAP_TTO pFMTTO = (PFONTMAP_TTO) pdm->pfm->pSubFM;
return (pdm->iTTUniq == pfo->iTTUniq) &&
(pFMTTO->flFontType == pfo->flFontType);
}
else
if (pfm->dwFontType == FMTYPE_TTOEM)
{
PFONTMAP_TTOEM pTTOEM = pfm->pSubFM;
ASSERT(pTTOEM);
//
// TrueType Outline for OEM
//
if (pTTOEM->dwFlags & UFOFLAG_TTDOWNLOAD_TTOUTLINE)
{
return (pdm->iTTUniq == pfo->iTTUniq) &&
(pTTOEM->flFontType == pfo->flFontType);
}
else
//
// Bitmap for OEM
//
if (pTTOEM->dwFlags & UFOFLAG_TTDOWNLOAD_BITMAP)
{
return ((pdm->iUniq == pfo->iUniq) &&
(pdm->iTTUniq == pfo->iTTUniq));
}
}
}
return FALSE;
}
DL_MAP *
PGetDLMap (
PFONTPDEV pFontPDev,
FONTOBJ *pfo
)
/*++
Routine Description:
This routine searches a FontObj in DL_MAP_LIST.If the FONTOBJ is found
(Means this font has been downloaded), then this function return the
DL_MAP pointer. If FONTOBJ can't be found (New font which is not
downloaded), a new DL_MAP * is returned. In Case of error we return
NULL. In that case we shouldn't download. A Bad DL_MAP is marked by
having cGlyphs value to -1. This function will also set pvConsumer field
of pfo, if a new DL_MAP is returned.
Arguments:
pFontPDev Font Modules's PDEV.
pfo FontObj.
Return Value:
Pointer to DL_MAP for success and NULL if no match.
Note:
06/02/97 -ganeshp-
Created it.
--*/
{
DL_MAP *pdm; // Individual download map element.
BOOL bFound; // The font is found or not in the list.
INT iFontIndex; // Download Font Index in DL_MAP List.
//
// All we have to do is look into the DL_MAP list and find a DL_MAP with
// same signature. For optimization purposes we tag the pvConsumer field
// with the FontIndex, which is index into the list. For example for first
// downloaded font pvConsumer is set to 1. As pvConsumer field is not
// cached for each DC, we will use this field with caution. So if pvConsumer
// is > 0, then we get the DL_MAP using pvConsumer and then check iUniq and
// iTTUniq. We only use the DL_MAP if these fields also match. Else we do
// an exausitive linear search in DL_MAP list. This approach will optimize
// for normal printing, because most of the time only one job is getting
// printed.
//
bFound = FALSE;
if( iFontIndex = PtrToLong(pfo->pvConsumer) )
{
/*
* As we control the pvConsumer field, we have the choice
* of what to put in there. SO, we decide as follows:
* > 0 - index into our data structures for good DL_MAP.
* 0 - virgin data, so look to see what to do.
* < 0 - Index into our data str for Bad FONT. NO download.
* In this case cGlyphs field is -1.
*/
if( iFontIndex < 0 )
{
//
// This seems like a bad font. In that case verify.
// Make the fontIndex +ve and 0 Based.
//
iFontIndex = (-iFontIndex);
--iFontIndex;
}
else
{
//
// pvConsumer is 1 based.
//
--iFontIndex;
}
if ( pdm = PGetDLMapFromIdx (pFontPDev, iFontIndex))
{
//
// Do not process this one, if we had encountered problem in past.
// Make sure that the we are dealing with same TT font.
//
if (pdm->cGlyphs == -1 && (pdm->iTTUniq == pfo->iTTUniq))
{
//
// Set the pvConsumer to a -ve index. make it 1 based first.
//
pfo->pvConsumer = (PLONG_PTR)IntToPtr((-(iFontIndex +1)));
return NULL;
}
//
// We have found a DL_MAP for this font. So now verify it.
//
if ( BSameDLFont (pFontPDev, pfo, pdm ) )
{
//
// This DL_MAP matches the font. So return the pointer.
//
bFound = TRUE;
}
}
}
//
// If the font is not cached, search sequentially through the list.
//
if (!bFound)
{
DL_MAP_LIST *pdml; // The linked list of font information
INT iI;
//
// This case happens when the pvConsumer field is not correct
// for this DC. The GDI doesn't gaurantee that the pvConsumer
// will be reset for each job.So we need to do a linear search.
//
pdml = pFontPDev->pvDLMap;
iFontIndex = 1;
while (pdml)
{
for( iI = 0; iI < pdml->cEntries; ++iI )
{
pdm = &pdml->adlm[ iI ];
if ( BSameDLFont (pFontPDev, pfo, pdm ) )
{
//
// This DL_MAP matches the font. So return the pointer.
// we also need to reset pvConsumer. iFontIndex is
// one base same as pvConsumer.
//
bFound = TRUE;
pfo->pvConsumer = (PLONG_PTR)IntToPtr(iFontIndex);
break;
}
iFontIndex++;
}
//
// Check if we have found the correct font or not.
//
if (bFound)
break;
else
pdml = pdml->pDMLNext;
}
}
//
// Both cached and sequential search failed. So this is a new one.
// Try downloading.
//
if (!bFound)
{
INT iFontIndex; // Download Font Index in DL_MAP List.
//
// The fontobj doesn't match the DL_MAP, or this is a new font.
// So get a new one.
//
if (!(pdm = PNewDLMap (pFontPDev,&(iFontIndex)) ))
{
ERR(("UniFont!PGetDLMap:Can't Create a new DL_MAP.\n"));
iFontIndex = -1;
}
//
// FontIndex returned by PNewDLMap is 0 based, but pvConsumer is one
// base. So add one.
//
pfo->pvConsumer = (PLONG_PTR)IntToPtr((iFontIndex + 1));
}
return pdm;
}
BOOL
BInitDLMap (
PDEV *pPDev,
FONTOBJ *pfo,
DL_MAP *pdm
)
/*++
Routine Description:
Initializes a DL_MAP structure.
Arguments:
pPDev Pointer to PDEV.
pfo FontObj.
pdm DL_MPA to be initialized.
Return Value:
TRUE success and FALSE for failure.
Note:
06/09/97 -ganeshp-
Created it.
--*/
{
BOOL bRet = FALSE;
DWORD iGlyphPerSoftFont; // Total number of glyph per downloaded font.
FONTINFO fi; // Details about this font.
PFONTPDEV pFontPDev = pPDev->pFontPDev;
INT iDL_ID;
pdm->iUniq = pfo->iUniq;
pdm->iTTUniq = pfo->iTTUniq;
FONTOBJ_vGetInfo( pfo, sizeof( fi ), &fi );
//
// Trunction may happen. But we are fine. We won't download if the number
// glyphs or max size are more than MAXWORD.
//
pdm->cTotalGlyphs = (WORD)fi.cGlyphsSupported;
pdm->wMaxGlyphSize = (WORD)fi.cjMaxGlyph1;
//
// In GPD if the DLSymbolSet has valid value, then we have to set
// the Min and Max Glyph IDs, using the Symbol Set, else we will use
// the GPD entries,dwMinGlyphID and dwMaxGlyphID.
//
if (pPDev->pGlobals->dlsymbolset != UNUSED_ITEM)
{
if (pPDev->pGlobals->dlsymbolset == DLSS_PC8)
{
//
// Symbol Set is DLSS_PC8.
//
pdm->wNextDLGId =
pdm->wFirstDLGId = 32;
pdm->wLastDLGId = 255;
}
else
{
//
// Symbol Set is DLSS_ROMAN8.
//
pdm->wNextDLGId =
pdm->wFirstDLGId = 33;
pdm->wLastDLGId = 127;
}
}
else
{
//
// DLsymbolset Not defined. Use Min and Max Glyph Ids.
//
pdm->wFirstDLGId = pdm->wNextDLGId
= (WORD)pPDev->pGlobals->dwMinGlyphID;
pdm->wLastDLGId = (WORD)pPDev->pGlobals->dwMaxGlyphID;
if( !(pFontPDev->flFlags & FDV_ROTATE_FONT_ABLE ))
{
//
// If the printer can't rotate font then we assume that it only
// supports Roman 8 limited character set. This hack is needed for
// old PCL printers.
//
pdm->wFirstDLGId = pdm->wNextDLGId
= 33;
pdm->wLastDLGId = 127;
}
}
//
// Find out that font is bounded or not. We do this by finding out
// how many glyphs we can download per soft font. Add 1 as range is
// inclusive.
//
iGlyphPerSoftFont = (pdm->wLastDLGId - pdm->wFirstDLGId) +1;
if (iGlyphPerSoftFont < MIN_GLYPHS_PER_SOFTFONT)
{
//
// This is an error condition. Basically we don't want to download
// if there are less than 64 glyphs per downloaded font.return FALSE.
//
ERR(("UniFont:BInitDLMap:Can't download any glyph,bad GPD values\n"));
goto ErrorExit;;
}
else
{
//
// There are more than 64 glyphs per downloded font. So find out
// if it's bounded or unbounded. If the number of Glyphs is >255
// then the font is unbounded else it's bounded.
//
if (iGlyphPerSoftFont > 255)
pdm->wFlags |= DLM_UNBOUNDED;
else
pdm->wFlags |= DLM_BOUNDED;
}
if( (iDL_ID = IGetDL_ID( pPDev )) < 0 )
{
//
// We have run out of soft fonts - must not use any more.
//
ERR(("UniFont:BInitDLMap:Can't download Font, No IDs available\n"));
goto ErrorExit;;
}
pdm->wBaseDLFontid = (WORD)iDL_ID;
//
// Hashtable is allocated based upon the number of Glyphs in the font.
//
if (pdm->cTotalGlyphs >= 1024)
pdm->cHashTableEntries = HASHTABLESIZE_3;
else if (pdm->cTotalGlyphs >= 512)
pdm->cHashTableEntries = HASHTABLESIZE_2;
else
pdm->cHashTableEntries = HASHTABLESIZE_1;
//
// Now allocate the Glyph Table. We only allocate the hash table.
//
if (pdm->GlyphTab.pGlyph = (DLGLYPH *)MemAllocZ(
pdm->cHashTableEntries * sizeof(DLGLYPH)) )
{
INT iIndex;
PDLGLYPH pGlyph;
//
// Set the hTTGlyph to HGLYPH_INVALID as 0 is a valid handle for HGLYPH.
// Also set the cGlyphs(Number of downloded Glyphs) to 0.
//
pGlyph = pdm->GlyphTab.pGlyph;
for (iIndex = 0; iIndex < pdm->cHashTableEntries; iIndex++,pGlyph++)
pGlyph->hTTGlyph = HGLYPH_INVALID;
bRet = TRUE;
}
else
{
//
// Error case. DL_MAP will be freeed by the caller, IDownloadFont.
//
ERR(("UniFont:BInitDLMap:Can't Allocate Glyph Hash table\n"));
}
ErrorExit:
return bRet;
}
INT
IGetDL_ID(
PDEV *pPDev
)
/*++
Routine Description:
Returns the font index to use for the next download font. Verifies
that the number is within range.
Arguments:
pPDev Pointer to PDEV
Return Value:
Font index if OK, else -1 on error (over limit).
Note:
3/5/1997 -ganeshp-
Created it.
--*/
{
PFONTPDEV pFontPDev = pPDev->pFontPDev;
INT iSFIndex;
if( pFontPDev->iNextSFIndex > pFontPDev->iLastSFIndex ||
pFontPDev->iUsedSoftFonts >= pFontPDev->iMaxSoftFonts )
{
ERR(( "softfont limit reached (%d/%d, %d/%d)\n",
pFontPDev->iNextSFIndex, pFontPDev->iLastSFIndex,
pFontPDev->iUsedSoftFonts, pFontPDev->iMaxSoftFonts ));
return -1; /* Too many - stop now */
}
/*
* We'll definitely use this one, so add to the used count.
*/
pFontPDev->iUsedSoftFonts++;
iSFIndex = pFontPDev->iNextSFIndex++;
return iSFIndex;
}
BOOL
BPrintADLGlyph(
PDEV *pPDev,
TO_DATA *pTod,
PDLGLYPH pdlGlyph
)
/*++
Routine Description:
This functions output a single downloaded Glyph.
Arguments:
pPDev Unidriver PDEV
pTod Textout Data.
pdlGlyph Download Glyph information
Return Value:
TRUE for success and FALSE for failure.
Note:
8/12/1997 -ganeshp-
Created it.
--*/
{
FONTMAP *pFM; // FontMap of interest
DL_MAP *pdm; // Details of this downloaded font.
FONTPDEV *pFontPDev; // Font PDev.
BOOL bRet; // Return Value of this function.
WORD wDLGlyphID; // Downloaded Glyph ID.
//
// Make sure that parameters are valid.
//
if (NULL == pPDev ||
NULL == pTod ||
NULL == pdlGlyph )
{
return FALSE;
}
//
// Initialize locals
//
bRet = TRUE;
pFontPDev = PFDV;
pFM = pTod->pfm;
wDLGlyphID = pdlGlyph->wDLGlyphID;
//
// Get pdm
//
if (pFM->dwFontType == FMTYPE_TTOUTLINE)
{
PFONTMAP_TTO pFMTO = (PFONTMAP_TTO) pFM->pSubFM;
pdm = (DL_MAP*) pFMTO->pvDLData;
}
else if (pFM->dwFontType == FMTYPE_TTBITMAP)
{
PFONTMAP_TTB pFMTB = (PFONTMAP_TTB) pFM->pSubFM;
pdm = pFMTB->u.pvDLData;
}
else if (pFM->dwFontType == FMTYPE_TTOEM)
{
PFONTMAP_TTOEM pFMTOEM = (PFONTMAP_TTOEM) pFM->pSubFM;
pdm = pFMTOEM->u.pvDLData;
}
else
{
ASSERTMSG(FALSE, ("Incorrect font type %d in BPrintADLGlyph.\n",
pFM->dwFontType));
pdm = NULL;
bRet = FALSE;
}
//
// Before sending a glyph we have to make sure that this glyph is in
// selected soft font. We have to do this only for segmented fonts, i.e
// multiple softfonts for one system fonts. If BaseFontId is not same as
// CurrFontId, that means the font has atleat two softfonts associated.
// Then we need to check for currently selected SoftFont. If the fontid of
// the glyph is different that the selected one, we need to select the new
// softfontid.
//
// GLYPH_IN_NEW_SOFTFONT is defined as :
// if ( (pdm->wFlags & DLM_BOUNDED) &&
// (pdm->wBaseDLFontid != pdm->wCurrFontId) &&
// (pdlGlyph->wDLFontId != (WORD)(pFontPDev->ctl.iSoftFont)) )
//
if (bRet && GLYPH_IN_NEW_SOFTFONT(pFontPDev, pdm, pdlGlyph))
{
//
// Need to select the new softfont.We do this by setting pfm->ulDLIndex
// to new softfontid.
//
pFM->ulDLIndex = pdlGlyph->wDLFontId;
BNewFont(pPDev, pTod->iFace, pFM, 0);
}
//
// The Soft font selection is done. So now sent the downloaded Glyph Id.
// We have to be a bit careful about the size of the Glyph ID. If the
// Glyphs ID is less than 256, then we need to send a BYTE else a WORD.
//
if (bRet)
{
if (wDLGlyphID > 0xFF)
{
//
// Send as WORD.
//
SWAB (wDLGlyphID);
bRet = WriteSpoolBuf( pPDev, (BYTE*)&wDLGlyphID, sizeof( wDLGlyphID ) )
== sizeof( wDLGlyphID );
}
else
{
//
// Send as Byte.
//
BYTE bData;
bData = (BYTE)wDLGlyphID;
bRet = WriteSpoolBuf( pPDev, &bData, sizeof( bData ) ) ==
sizeof( bData );
}
}
return bRet;
}