|
|
/*++
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; }
|