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.
1744 lines
51 KiB
1744 lines
51 KiB
|
|
/*++
|
|
|
|
Copyright (c) 1996 - 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
download.c
|
|
|
|
Abstract:
|
|
|
|
Functions associated with downloading fonts to printers. This
|
|
specifically applies to LaserJet style printers. There are really
|
|
two sets of functions here: those for downloading fonts supplied
|
|
by the user (and installed with the font installer), and those
|
|
we generate internally to cache TT style fonts in the printer.
|
|
|
|
|
|
Environment:
|
|
|
|
Windows NT Unidrv driver
|
|
|
|
Revision History:
|
|
|
|
01/11/97 -ganeshp-
|
|
Created
|
|
|
|
--*/
|
|
|
|
#include "font.h"
|
|
|
|
#define DL_BUF_SZ 4096 /* Size of data chunks for download */
|
|
|
|
//
|
|
// Local function prototypes.
|
|
//
|
|
|
|
|
|
IFIMETRICS*
|
|
pGetIFI(
|
|
PDEV *pPDev,
|
|
FONTOBJ *pfo,
|
|
BOOL bScale
|
|
);
|
|
|
|
BOOL
|
|
BDownLoadAsTT(
|
|
PDEV *pPDev,
|
|
FONTOBJ *pfo,
|
|
STROBJ *pstro,
|
|
DL_MAP *pdm,
|
|
INT iMode
|
|
);
|
|
|
|
BOOL
|
|
BDownLoadAsBmp(
|
|
PDEV *pPDev,
|
|
FONTOBJ *pfo,
|
|
STROBJ *pstro,
|
|
DL_MAP *pdm,
|
|
INT iMode
|
|
);
|
|
|
|
BOOL
|
|
BDownLoadOEM(
|
|
PDEV *pPDev,
|
|
FONTOBJ *pfo,
|
|
STROBJ *pstro,
|
|
DL_MAP *pdm,
|
|
INT iMode
|
|
);
|
|
//
|
|
// Macro Definition.
|
|
//
|
|
#ifdef WINNT_40
|
|
|
|
#else
|
|
|
|
#endif //WINNT_40
|
|
#define GETWIDTH(pPtqD) ((pPtqD->x.HighPart + 8) / 16)
|
|
|
|
//
|
|
// Main functions
|
|
//
|
|
|
|
|
|
BOOL
|
|
BDLSecondarySoftFont(
|
|
PDEV *pPDev,
|
|
FONTOBJ *pfo,
|
|
STROBJ *pstro,
|
|
DL_MAP *pdm
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This routine download the secondary soft font. If the True type font has
|
|
more Glyphs that what we can download in soft font then we download a
|
|
secondary font after we use all the glyphs in the current soft font. This
|
|
function also sets the new soft font index(pFM->ulDLIndex) to be used.
|
|
|
|
Arguments:
|
|
pPDev Pointer to PDEV
|
|
pfo The font of interest.
|
|
pdm Individual download font map element
|
|
|
|
Return Value:
|
|
TRUE for success and FALSE for failure
|
|
|
|
Note:
|
|
|
|
6/11/1997 -ganeshp-
|
|
Created it.
|
|
--*/
|
|
{
|
|
BOOL bRet;
|
|
FONTMAP *pFM;
|
|
|
|
//
|
|
// Initialization of Locals .
|
|
//
|
|
bRet = FALSE;
|
|
pFM = pdm->pfm;
|
|
|
|
|
|
//
|
|
// PFM->ulDLIndex is used to download new soft font and is set in following
|
|
// download functions.
|
|
//
|
|
if (pFM->dwFontType == FMTYPE_TTBITMAP)
|
|
{
|
|
if (!BDownLoadAsBmp(pPDev, pfo, pstro,pdm,DL_SECONDARY_SOFT_FONT) )
|
|
{
|
|
ERR(("UniFont!BDLSecondarySoftFont:BDownLoadAsBmp Failed\n"));
|
|
goto ErrorExit;
|
|
|
|
}
|
|
|
|
}
|
|
else if (pFM->dwFontType == FMTYPE_TTOUTLINE)
|
|
{
|
|
if (!BDownLoadAsTT(pPDev, pfo, pstro,pdm,DL_SECONDARY_SOFT_FONT) )
|
|
{
|
|
ERR(("UniFont!BDLSecondarySoftFont:BDownLoadAsTT Failed\n"));
|
|
goto ErrorExit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (pFM->dwFontType == FMTYPE_TTOEM)
|
|
{
|
|
if (!BDownLoadOEM(pPDev, pfo, pstro,pdm,DL_SECONDARY_SOFT_FONT) )
|
|
{
|
|
ERR(("UniFont!BDLSecondarySoftFont:BDownLoadAsOEM Failed\n"));
|
|
goto ErrorExit;
|
|
|
|
}
|
|
}
|
|
//
|
|
// Reset the iSoftfont to -1, so that we send select font command, before
|
|
// outputting the Character.
|
|
//
|
|
PFDV->ctl.iSoftFont = -1;
|
|
|
|
bRet = TRUE;
|
|
|
|
ErrorExit:
|
|
return bRet;
|
|
}
|
|
|
|
|
|
BOOL
|
|
BDownloadGlyphs(
|
|
TO_DATA *ptod,
|
|
STROBJ *pstro,
|
|
DL_MAP *pdm
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
pPDev Pointer to PDEV
|
|
pdm DL_MAP struct, all about downloading is in this structure.
|
|
|
|
Return Value:
|
|
TRUE for success and FALSE for failure
|
|
|
|
Note:
|
|
|
|
6/9/1997 -ganeshp-
|
|
Created it.
|
|
--*/
|
|
{
|
|
PDEV *pPDev; // Our PDevice
|
|
FONTOBJ *pfo; // Font OBJ
|
|
GLYPHPOS *pgp; // Value passed from gre
|
|
FONTMAP *pFM; // Font's details
|
|
ULONG cGlyphs; // Number of glyphs to process
|
|
ULONG cGlyphIndex; // Index to the current glyph.
|
|
WORD wWidth; // Width of the Glyph.
|
|
BOOL bMore; // Getting glyphs from engine loop
|
|
PDLGLYPH *ppdlGlyph; // array of DLGLYPHs pointers.
|
|
DWORD dwMem; // Memory require to download the glyph.
|
|
DWORD dwTotalEnumGlyphs;
|
|
POINTQF *pPtqD; // Advance Width Array.
|
|
BOOL bRet; // Return Value
|
|
PWCHAR pwchUnicode;
|
|
|
|
//
|
|
// Initialize Local variables.
|
|
//
|
|
pPDev = ptod->pPDev;
|
|
pfo = ptod->pfo;
|
|
pFM = ptod->pfm;
|
|
dwTotalEnumGlyphs =
|
|
cGlyphs =
|
|
cGlyphIndex =
|
|
dwMem = 0;
|
|
pPtqD = NULL;
|
|
|
|
ASSERTMSG((pPDev && pfo && pstro && pFM),\
|
|
("\nUniFont!BDownloadGlyphs: Wrong values in ptod.\n"));
|
|
|
|
bRet = FALSE;
|
|
|
|
//
|
|
// Allocate the array for DLGLYPHs.
|
|
//
|
|
if (!( ppdlGlyph = MemAllocZ( pstro->cGlyphs * sizeof(DLGLYPH *)) ))
|
|
{
|
|
ERR(("UniFont:BDownloadGlyphs: MemAlloc for ppdlGlyph failed\n"));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
ptod->apdlGlyph = ppdlGlyph;
|
|
|
|
//
|
|
// First Job is to do the enumeration of the glyphs. and then
|
|
// start downloading.
|
|
//
|
|
|
|
#ifndef WINNT_40 // NT 5.0
|
|
|
|
if (pPtqD = MemAllocZ( pstro->cGlyphs * sizeof(POINTQF)) )
|
|
{
|
|
//
|
|
// Memory Allocation succeded for width array. So call GDI to get
|
|
// the width.
|
|
//
|
|
if (!STROBJ_bGetAdvanceWidths(pstro, 0, pstro->cGlyphs, pPtqD))
|
|
{
|
|
ERR(("UniFont:BDownloadGlyphs: STROBJ_bGetAdvanceWidths failed\n"));
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERR(("UniFont:BDownloadGlyphs:Memory allocation for width array failed\n"));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
#endif //!WINNT_40
|
|
|
|
pwchUnicode = pstro->pwszOrg;
|
|
STROBJ_vEnumStart(pstro);
|
|
|
|
do
|
|
{
|
|
#ifndef WINNT_40 // NT 5.0
|
|
|
|
bMore = STROBJ_bEnumPositionsOnly( pstro, &cGlyphs, &pgp );
|
|
|
|
#else // NT 4.0
|
|
|
|
bMore = STROBJ_bEnum( pstro, &cGlyphs, &pgp );
|
|
|
|
#endif //!WINNT_40
|
|
|
|
dwTotalEnumGlyphs += cGlyphs;
|
|
|
|
while ( cGlyphs )
|
|
{
|
|
|
|
PDLGLYPH pdlg;
|
|
HGLYPH hTTGlyph;
|
|
|
|
#ifdef WINNT_40 // NT 4.0
|
|
|
|
GLYPHDATA *pgd;
|
|
|
|
if( !FONTOBJ_cGetGlyphs( ptod->pfo, FO_GLYPHBITS, (ULONG)1,
|
|
&pgp->hg, &pgd ) )
|
|
{
|
|
ERR(( "UniFont:BDownloadGlyphs:FONTOBJ_cGetGlyphs fails\n" ))
|
|
goto ErrorExit;
|
|
}
|
|
pPtqD = &(pgd->ptqD);
|
|
|
|
#endif //WINNT_40
|
|
|
|
hTTGlyph = pgp->hg;
|
|
//
|
|
// search the Glyph in hash table.
|
|
//
|
|
pdlg = *ppdlGlyph = PDLGHashGlyph (pdm,hTTGlyph );
|
|
|
|
if (pdlg)
|
|
{
|
|
//
|
|
// We have got a valid Glyph. Check if this is already
|
|
// downloaded or not.
|
|
//
|
|
if (!GLYPHDOWNLOADED(pdlg))
|
|
{
|
|
//
|
|
// If the glyph is not downloaded,then fill Glyph structure
|
|
// and download the Glyph.
|
|
//
|
|
|
|
if (pdm->wFlags & DLM_UNBOUNDED)
|
|
{
|
|
//
|
|
// Unbounded font. We just have to make sure that
|
|
// download glyphID is valid. If it's not valid then
|
|
// we fail the call.
|
|
//
|
|
if (pdm->wNextDLGId > pdm->wLastDLGId)
|
|
{
|
|
ERR(("UniFont:BDownloadGlyphs:Unbounded Font,no more Glyph Ids\n"));
|
|
goto ErrorExit;
|
|
|
|
}
|
|
//
|
|
// Fill in the Glyph structure. We only set wDLGlyphID.
|
|
// The new Glyph definition has FontId also. So set that
|
|
// one also.
|
|
//
|
|
pdlg->wDLGlyphID = pdm->wNextDLGId;
|
|
pdlg->wDLFontId = pdm->wBaseDLFontid;
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Bounded font. It's a bit tricky. We have to do the
|
|
// same test for avaiable Glyph IDs. If there is no more
|
|
// glyph Ids, then we have to download a secondary
|
|
// soft font and reset the cGlyphs and wNextDlGId.
|
|
//
|
|
if (pdm->wNextDLGId > pdm->wLastDLGId)
|
|
{
|
|
if ( BDLSecondarySoftFont(pPDev, pfo, pstro,pdm) )
|
|
{
|
|
//
|
|
// Reset the Glyph Ids values.
|
|
//
|
|
pdm->wNextDLGId = pdm->wFirstDLGId;
|
|
pdm->wCurrFontId = (WORD)pdm->pfm->ulDLIndex;
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Failure case. Fail the Call.
|
|
//
|
|
ERR(("UniFont:BDownloadGlyphs:Bounded Font,Sec. Font DL failed\n"));
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
//
|
|
// Set the Glyph ID and Font ID in the DLGLYPH.
|
|
//
|
|
pdlg->wDLFontId = pdm->wCurrFontId;
|
|
pdlg->wDLGlyphID = pdm->wNextDLGId;
|
|
|
|
}
|
|
|
|
//
|
|
// All error checkings are done, so download now. Set the
|
|
// width to zero and then pass the address to downloading
|
|
// function. The downloading function should fill a width
|
|
// value else it remains zero.
|
|
//
|
|
|
|
if (pFM->ulDLIndex == -1)
|
|
{
|
|
ASSERTMSG(FALSE, ("pFM->ulDLIndex == -1") );
|
|
goto ErrorExit;
|
|
}
|
|
|
|
pdlg->wWidth = 0;
|
|
pdlg->wchUnicode = *(pwchUnicode + cGlyphIndex);
|
|
wWidth = 0;
|
|
|
|
dwMem = pFM->pfnDownloadGlyph(pPDev, pFM, hTTGlyph,
|
|
pdlg->wDLGlyphID, &wWidth);
|
|
if (dwMem)
|
|
{
|
|
//
|
|
// All success in downloading the glyph.Mark it
|
|
// downloaded. This is done by setting the hTTGlyph to
|
|
// True Type Glyph Handle.
|
|
//
|
|
pdlg->hTTGlyph = hTTGlyph;
|
|
|
|
//
|
|
// If the download function returns the width use it,
|
|
// else use the width from GDI.
|
|
//
|
|
|
|
if (wWidth)
|
|
pdlg->wWidth = wWidth;
|
|
else
|
|
{
|
|
#ifndef WINNT_40 //NT 5.0
|
|
|
|
pdlg->wWidth = (WORD)GETWIDTH((pPtqD + cGlyphIndex));
|
|
|
|
#else // NT 4.0
|
|
|
|
pdlg->wWidth = GETWIDTH(pPtqD);
|
|
|
|
#endif //!WINNT_40
|
|
|
|
}
|
|
|
|
pdm->cGlyphs++;
|
|
pdm->wNextDLGId++;
|
|
|
|
//
|
|
// Update memory consumption before return.
|
|
//
|
|
PFDV->dwFontMemUsed += dwMem;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Failure case. Fail the Call.
|
|
//
|
|
ERR(("UniFont:BDownloadGlyphs:Glyph Download failed\n"));
|
|
goto ErrorExit;
|
|
|
|
}
|
|
}
|
|
else // Glyph is already downloaded.
|
|
{
|
|
//
|
|
// If Glyph is already downloaded and we are downloading as
|
|
// TT outline we need to update the width to current point
|
|
// size.
|
|
//
|
|
|
|
if( (pFM->dwFontType == FMTYPE_TTOUTLINE) ||
|
|
( (pFM->dwFontType == FMTYPE_TTOEM) &&
|
|
(((PFONTMAP_TTOEM)(pFM->pSubFM))->dwFlags & UFOFLAG_TTDOWNLOAD_TTOUTLINE)
|
|
)
|
|
)
|
|
{
|
|
#ifndef WINNT_40 //NT 5.0
|
|
|
|
pdlg->wWidth = (WORD)GETWIDTH((pPtqD + cGlyphIndex));
|
|
|
|
#else // NT 4.0
|
|
|
|
pdlg->wWidth = GETWIDTH(pPtqD);
|
|
|
|
#endif //!WINNT_40
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pgp++;
|
|
ppdlGlyph++;
|
|
cGlyphIndex++;
|
|
cGlyphs --;
|
|
}
|
|
else
|
|
{
|
|
ERR(("UniFont:BDownloadGlyphs: PDLGHashGlyph failed\n"));
|
|
goto ErrorExit;
|
|
|
|
}
|
|
}
|
|
|
|
} while( bMore );
|
|
|
|
if (dwTotalEnumGlyphs != pstro->cGlyphs)
|
|
{
|
|
ERR(("UniFont:BDownloadGlyphs: STROBJ_bEnum failed to enumurate all glyphs\n"));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
bRet = TRUE;
|
|
//
|
|
// ReSet the pFM->ulDLIndex to first Glyph's softfont ID.
|
|
//
|
|
pFM->ulDLIndex = (pdm->wFlags & DLM_UNBOUNDED)?
|
|
(pdm->wBaseDLFontid):
|
|
(ptod->apdlGlyph[0]->wDLFontId);
|
|
|
|
ErrorExit:
|
|
//
|
|
// If there is a failure then free the DLGLYPH array.
|
|
//
|
|
if (!bRet && ptod->apdlGlyph)
|
|
{
|
|
MEMFREEANDRESET(ptod->apdlGlyph );
|
|
|
|
}
|
|
|
|
#ifndef WINNT_40 // NT 5.0
|
|
|
|
MEMFREEANDRESET(pPtqD );
|
|
|
|
#endif //!WINNT_40
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL
|
|
BDownLoadOEM(
|
|
PDEV *pPDev,
|
|
FONTOBJ *pfo,
|
|
STROBJ *pstro,
|
|
DL_MAP *pdm,
|
|
INT iMode
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
pPDev Pointer to PDEV
|
|
pfo The font of interest.
|
|
pstro The "width" of fixed pitch font glyphs.
|
|
pdm Individual download font map element
|
|
|
|
Return Value:
|
|
TRUE for success and FALSE for failure
|
|
|
|
Note:
|
|
|
|
6/11/1997 -ganeshp-
|
|
Created it.
|
|
--*/
|
|
{
|
|
PI_UNIFONTOBJ pUFObj;
|
|
PFONTMAP_TTOEM pfmTTOEM; // Bitmap download fontmap.
|
|
IFIMETRICS *pIFI;
|
|
PFONTPDEV pFontPDev;
|
|
PFONTMAP pfm;
|
|
|
|
DWORD dwMem;
|
|
|
|
//
|
|
// Initialize local variables.
|
|
//
|
|
pFontPDev = pPDev->pFontPDev;
|
|
pUFObj = pFontPDev->pUFObj;
|
|
dwMem = 0;
|
|
|
|
//
|
|
// Get FONTMAP
|
|
//
|
|
|
|
if (iMode == DL_BASE_SOFT_FONT)
|
|
{
|
|
pdm->pfm =
|
|
pfm = PfmInitPFMOEMCallback(pPDev, pfo);
|
|
}
|
|
else
|
|
{
|
|
pfm = pdm->pfm;
|
|
ASSERTMSG((pfm),("NULL pFM for Secondary Font"));
|
|
}
|
|
|
|
if (!pUFObj || !pfm)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (pfm)
|
|
{
|
|
if (iMode == DL_BASE_SOFT_FONT)
|
|
{
|
|
pfm->pIFIMet =
|
|
pIFI = pGetIFI(pPDev, pfo, TRUE);
|
|
}
|
|
else
|
|
{
|
|
pIFI = pfm->pIFIMet;
|
|
}
|
|
|
|
if (pUFObj->dwFlags & (UFOFLAG_TTDOWNLOAD_BITMAP|
|
|
UFOFLAG_TTDOWNLOAD_TTOUTLINE) &&
|
|
pIFI)
|
|
{
|
|
if (iMode == DL_BASE_SOFT_FONT)
|
|
{
|
|
pdm->cGlyphs = -1;
|
|
|
|
if (pIFI->flInfo & FM_INFO_CONSTANT_WIDTH)
|
|
{
|
|
if (pstro->ulCharInc == 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
pIFI->fwdMaxCharInc =
|
|
pIFI->fwdAveCharWidth = (FWORD)pstro->ulCharInc;
|
|
}
|
|
|
|
pfm->wFirstChar = 0;
|
|
pfm->wLastChar = 0xffff;
|
|
|
|
pfm->wXRes = (WORD)pPDev->ptGrxRes.x;
|
|
pfm->wYRes = (WORD)pPDev->ptGrxRes.y;
|
|
|
|
if (!(pFontPDev->flFlags & FDV_ALIGN_BASELINE))
|
|
pfm->syAdj = pIFI->fwdWinAscender;
|
|
|
|
pfm->flFlags = FM_SENT | FM_SOFTFONT | FM_GEN_SFONT;
|
|
|
|
if (pUFObj->dwFlags & UFOFLAG_TTDOWNLOAD_TTOUTLINE)
|
|
pfm->flFlags |= FM_SCALABLE;
|
|
|
|
pfm->ulDLIndex = pdm->wCurrFontId = pdm->wBaseDLFontid;
|
|
pfmTTOEM = pfm->pSubFM;
|
|
pfmTTOEM->u.pvDLData = pdm;
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Things are different for Secondary Download.Get a new ID.
|
|
//
|
|
|
|
if( (pfm->ulDLIndex = IGetDL_ID( pPDev )) == -1 )
|
|
{
|
|
ERR(( "UniFont!BDownLoadAsBmp:Out of Soft Font Limit,- FONT NOT DOWNLOADED\n"));
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
//
|
|
// Send the SETFONTID command. This commands assigns the id to the
|
|
// font being downloaded.
|
|
//
|
|
|
|
|
|
if( (dwMem = pfm->pfnDownloadFontHeader( pPDev, pfm)) == 0 )
|
|
{
|
|
//
|
|
// Failed to download font header.
|
|
//
|
|
ERR(("UniFont!BDownloadAsOEM:pfnDownloadFontHeader failed.\n"));
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Adjust the Memory
|
|
//
|
|
pFontPDev->dwFontMemUsed += dwMem;
|
|
|
|
if (iMode == DL_BASE_SOFT_FONT)
|
|
{
|
|
pfm->dwFontType = FMTYPE_TTOEM;
|
|
pdm->cGlyphs = 0;
|
|
pfmTTOEM->dwDLSize = dwMem;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
BOOL
|
|
BDownLoadAsTT(
|
|
PDEV *pPDev,
|
|
FONTOBJ *pfo,
|
|
STROBJ *pstro,
|
|
DL_MAP *pdm,
|
|
INT iMode
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
pPDev Pointer to PDEV
|
|
pfo The font of interest.
|
|
pstro The "width" of fixed pitch font glyphs.
|
|
pdm Individual download font map element
|
|
iMode Mode of downloading, primary or secondary.
|
|
|
|
Return Value:
|
|
TRUE for success and FALSE for failure
|
|
|
|
Note:
|
|
|
|
6/11/1997 -ganeshp-
|
|
Created it.
|
|
--*/
|
|
{
|
|
FONTMAP *pFM; // The FONTMAP structure we build up
|
|
BOOL bRet; // The value we return
|
|
PFONTPDEV pFontPDev; // Font Modules's PDEV
|
|
IFIMETRICS *pIFI; // IFI metrics for this font.
|
|
PFONTMAP_TTO pfmTTO; // Bitmap download fontmap.
|
|
DWORD dwMem; // For recording memory consumption
|
|
|
|
//
|
|
// Initialize the Local Variables.
|
|
//
|
|
|
|
pFontPDev = pPDev->pFontPDev;
|
|
bRet = FALSE;
|
|
dwMem = 0;
|
|
|
|
//
|
|
// First Initialize the FontMap.
|
|
//
|
|
if (iMode == DL_BASE_SOFT_FONT)
|
|
{
|
|
pFM = InitPFMTTOutline(pPDev,pfo);
|
|
pdm->pfm = pFM;
|
|
}
|
|
else
|
|
{
|
|
pFM = pdm->pfm;
|
|
ASSERTMSG((pFM),("\nUniFont!BDownLoadAsTT:NULL pFM for Secondary Font"));
|
|
}
|
|
|
|
if ( pFM )
|
|
{
|
|
|
|
//
|
|
// Check if we can download the font or not, using the present available
|
|
// memory.
|
|
//
|
|
|
|
if (iMode == DL_BASE_SOFT_FONT)
|
|
{
|
|
pFM->pIFIMet =
|
|
pIFI = pGetIFI( pPDev, pfo, FALSE );
|
|
}
|
|
else
|
|
{
|
|
pIFI = pFM->pIFIMet;
|
|
}
|
|
|
|
if ( pIFI && pFM->pfnCheckCondition(pPDev,pfo,pstro,pIFI) )
|
|
{
|
|
//
|
|
// There is enough memory to download. So prepare to download.
|
|
// The first step is to get the IFIMETRICS and validate it.
|
|
//
|
|
|
|
if (iMode == DL_BASE_SOFT_FONT)
|
|
{
|
|
|
|
//
|
|
// Initialize to not download.After successful download we
|
|
// set cGlyphs to 0.
|
|
//
|
|
pdm->cGlyphs = -1;
|
|
|
|
if( pIFI->flInfo & FM_INFO_CONSTANT_WIDTH )
|
|
{
|
|
//
|
|
// Fixed pitch fonts are not handled.Fixed
|
|
// pitch fonts should be downloaded as bitmap only.
|
|
// So return Error.
|
|
//
|
|
|
|
WARNING(( "UniFont!BDownLoadAsTT:Fixded Pitch Font are not downloaded as Outlie.\n"));
|
|
goto ErrorExit;
|
|
|
|
}
|
|
|
|
pFM->wFirstChar = 0;
|
|
pFM->wLastChar = 0xffff;
|
|
pFM->wXRes = (WORD)pPDev->ptGrxRes.x;
|
|
pFM->wYRes = (WORD)pPDev->ptGrxRes.y;
|
|
if( !(pFontPDev->flFlags & FDV_ALIGN_BASELINE) )
|
|
pFM->syAdj = pIFI->fwdWinAscender;
|
|
pFM->flFlags = FM_SENT | FM_SOFTFONT |
|
|
FM_GEN_SFONT | FM_SCALABLE;
|
|
|
|
//
|
|
// wBaseDLFontid is already initialized by BInitDLMap function.
|
|
//
|
|
pFM->ulDLIndex = pdm->wCurrFontId = pdm->wBaseDLFontid;
|
|
|
|
//
|
|
// Initialize the TT Outline specific fields.
|
|
//
|
|
|
|
pfmTTO = pFM->pSubFM;
|
|
pfmTTO->pvDLData = pdm;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Things are different for Secondary Download. We have to get
|
|
// a new fontID.
|
|
//
|
|
|
|
if( (pFM->ulDLIndex = IGetDL_ID( pPDev )) == -1 )
|
|
{
|
|
ERR(( "UniFont!BDownLoadAsTT:Out of Soft Font Limit,- FONT NOT DOWNLOADED\n"));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
//
|
|
// Send the SETFONTID command. This commands assigns the id to the
|
|
// font being downloaded. And set the flag that this command is
|
|
// already sent. We need to send this command while downloading
|
|
// glyphs also. The download glyph code will check this flag, and
|
|
// send the command only if not sent ( which will happen next time,
|
|
// when same font is used).
|
|
//
|
|
|
|
BUpdateStandardVar(pPDev, pFM, 0, 0, STD_NFID);
|
|
WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SETFONTID));
|
|
pFontPDev->flFlags |= FDV_SET_FONTID;
|
|
|
|
if( (dwMem = pFM->pfnDownloadFontHeader( pPDev, pFM)) == 0 )
|
|
{
|
|
//
|
|
// Some sort of hiccup while downloading the header.So fail.
|
|
//
|
|
ERR(("UniFont!BDownLoadAsBmp:Err while downloading header,- FONT NOT DOWNLOADED\n"));
|
|
goto ErrorExit;
|
|
|
|
}
|
|
//
|
|
// Update memory consumption before return.
|
|
//
|
|
pFontPDev->dwFontMemUsed += dwMem;
|
|
|
|
if (iMode == DL_BASE_SOFT_FONT)
|
|
{
|
|
//
|
|
// Successful download.So mark it current.
|
|
//
|
|
pFM->dwFontType = FMTYPE_TTOUTLINE;
|
|
|
|
//
|
|
// Set cGlyphs to 0 to mark that font is Downloaded OK.
|
|
//
|
|
|
|
pdm->cGlyphs = 0;
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
ERR(( "UniFont!BDownLoadAsTT:NULL IFI or pfnCheckCondition failed.\n") );
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// The PFM could not be found or created for this truetype font.
|
|
// Return FALSE to allow some other rendering method to occur.
|
|
//
|
|
WARNING(( "UniFont!BDownLoadAsTT:Fontmap couldn't be created or found.\n") );
|
|
goto ErrorExit;
|
|
}
|
|
//
|
|
// All success, so return TRUE;
|
|
//
|
|
bRet = TRUE;
|
|
ErrorExit:
|
|
return bRet;
|
|
}
|
|
|
|
BOOL
|
|
BDownLoadAsBmp(
|
|
PDEV *pPDev,
|
|
FONTOBJ *pfo,
|
|
STROBJ *pstro,
|
|
DL_MAP *pdm,
|
|
INT iMode
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
pPDev Pointer to PDEV
|
|
pfo The font of interest.
|
|
pstro The "width" of fixed pitch font glyphs.
|
|
pdm Individual download font map element
|
|
iMode Mode of downloading, primary or secondary.
|
|
|
|
Return Value:
|
|
TRUE for success and FALSE for failure
|
|
|
|
Note:
|
|
|
|
6/11/1997 -ganeshp-
|
|
Created it.
|
|
--*/
|
|
{
|
|
FONTMAP *pFM; // The FONTMAP structure we build up
|
|
BOOL bRet; // The value we return
|
|
PFONTPDEV pFontPDev; // Font Modules's PDEV
|
|
IFIMETRICS *pIFI; // IFI metrics for this font.
|
|
PFONTMAP_TTB pfmTTB; // Bitmap download fontmap.
|
|
DWORD dwMem; // For recording memory consumption
|
|
|
|
//
|
|
// Initialize the Local Variables.
|
|
//
|
|
|
|
pFontPDev = pPDev->pFontPDev;
|
|
bRet = FALSE;
|
|
dwMem = 0;
|
|
|
|
//
|
|
// First Initialize the FontMap.
|
|
//
|
|
if (iMode == DL_BASE_SOFT_FONT)
|
|
{
|
|
pFM = InitPFMTTBitmap(pPDev,pfo);
|
|
pdm->pfm = pFM;
|
|
}
|
|
else
|
|
{
|
|
pFM = pdm->pfm;
|
|
ASSERTMSG((pFM),("\nUniFont!BDownLoadAsBmp:NULL pFM for Secondary Font"));
|
|
}
|
|
|
|
if ( pFM )
|
|
{
|
|
|
|
//
|
|
// Check if we can download the font or not, using the present available
|
|
// memory.
|
|
//
|
|
|
|
if (iMode == DL_BASE_SOFT_FONT)
|
|
{
|
|
pFM->pIFIMet =
|
|
pIFI = pGetIFI( pPDev, pfo, TRUE );
|
|
}
|
|
else
|
|
{
|
|
pIFI = pFM->pIFIMet;
|
|
}
|
|
|
|
if ( pIFI && pFM->pfnCheckCondition(pPDev,pfo,pstro,pIFI) )
|
|
{
|
|
//
|
|
// There is enough memory to download. So prepare to download.
|
|
// The first step is to get the IFIMETRICS and validate it.
|
|
//
|
|
|
|
if (iMode == DL_BASE_SOFT_FONT)
|
|
{
|
|
|
|
//
|
|
// Initialize to not download.After successful download we
|
|
// set cGlyphs to 0.
|
|
//
|
|
pdm->cGlyphs = -1;
|
|
|
|
if( pIFI->flInfo & FM_INFO_CONSTANT_WIDTH )
|
|
{
|
|
//
|
|
// Fixed pitch fonts are handled a little differently.Fixed
|
|
// pitch fonts should be downloaded as bitmap only.
|
|
//
|
|
|
|
if( pstro->ulCharInc == 0 )
|
|
{
|
|
ERR(( "UniFont!BDownLoadAsBmp:Fixed pitch font,ulCharInc == 0 - FONT NOT DOWNLOADED\n"));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
pIFI->fwdMaxCharInc = (FWORD)pstro->ulCharInc;
|
|
pIFI->fwdAveCharWidth = (FWORD)pstro->ulCharInc;
|
|
}
|
|
|
|
pFM->wFirstChar = 0;
|
|
pFM->wLastChar = 0xffff;
|
|
pFM->wXRes = (WORD)pPDev->ptGrxRes.x;
|
|
pFM->wYRes = (WORD)pPDev->ptGrxRes.y;
|
|
if( !(pFontPDev->flFlags & FDV_ALIGN_BASELINE) )
|
|
pFM->syAdj = pIFI->fwdWinAscender;
|
|
pFM->flFlags = FM_SENT | FM_SOFTFONT | FM_GEN_SFONT;
|
|
|
|
//
|
|
// wBaseDLFontid is already initialized by BInitDLMap function.
|
|
//
|
|
pFM->ulDLIndex = pdm->wCurrFontId = pdm->wBaseDLFontid;
|
|
|
|
//
|
|
// Initialize the TT Bitmap specific fields.
|
|
//
|
|
|
|
pfmTTB = pFM->pSubFM;
|
|
pfmTTB->u.pvDLData = pdm;
|
|
}
|
|
else
|
|
{
|
|
INT iID = IGetDL_ID( pPDev );
|
|
|
|
//
|
|
// Things are different for Secondary Download.Get a new ID.
|
|
//
|
|
|
|
if( iID < 0 )
|
|
{
|
|
ERR(( "UniFont!BDownLoadAsBmp:Out of Soft Font Limit,- FONT NOT DOWNLOADED\n"));
|
|
goto ErrorExit;
|
|
}
|
|
pFM->ulDLIndex = iID;
|
|
|
|
|
|
}
|
|
|
|
//
|
|
// Send the SETFONTID command. This commands assigns the id to the
|
|
// font being downloaded. And set the flag that this command is
|
|
// already sent. We need to send this command while downloading
|
|
// glyphs also. The download glyph code will check this flag, and
|
|
// send the command only if not sent ( which will happen next time,
|
|
// when same font is used).
|
|
//
|
|
|
|
BUpdateStandardVar(pPDev, pFM, 0, 0, STD_NFID);
|
|
WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SETFONTID));
|
|
pFontPDev->flFlags |= FDV_SET_FONTID;
|
|
|
|
if( (dwMem = pFM->pfnDownloadFontHeader( pPDev, pFM)) == 0 )
|
|
{
|
|
//
|
|
// Some sort of hiccup while downloading the header.So fail.
|
|
//
|
|
ERR(( "UniFont!BDownLoadAsBmp:Err while downloading header,- FONT NOT DOWNLOADED\n") );
|
|
goto ErrorExit;
|
|
|
|
}
|
|
//
|
|
// Update memory consumption before return.
|
|
//
|
|
pFontPDev->dwFontMemUsed += dwMem;
|
|
|
|
if (iMode == DL_BASE_SOFT_FONT)
|
|
{
|
|
//
|
|
// Successful download.So mark it current.
|
|
//
|
|
pFM->dwFontType = FMTYPE_TTBITMAP;
|
|
|
|
//
|
|
// Set cGlyphs to 0 to mark that font is Downloaded OK.
|
|
//
|
|
|
|
pdm->cGlyphs = 0;
|
|
|
|
pfmTTB->dwDLSize = dwMem;
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
ERR(( "UniFont!BDownLoadAsBmp:NULL IFI or pfnCheckCondition failed.\n") );
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
//
|
|
// All success. So return TRUE
|
|
//
|
|
bRet = TRUE;
|
|
ErrorExit:
|
|
return bRet;
|
|
}
|
|
|
|
|
|
INT
|
|
IDownloadFont(
|
|
TO_DATA *ptod,
|
|
STROBJ *pstro,
|
|
INT *piRot
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This function downloads the font and the glyphs. If the font is
|
|
already downloaded, it uses that. It goes through all the glyphs
|
|
and downloads the new one. This function also intializes pfm, iFace
|
|
and apdlGlyph members of TO_DATA.
|
|
|
|
Arguments:
|
|
ptod TextOut Data pointer to fill the DLGLYPH array.
|
|
pstro The "width" of fixed pitch font glyphs.
|
|
piRot Rotation angle in multiple 90 degree.This is output param
|
|
and used by textout call to set the text rotation.
|
|
|
|
Return Value:
|
|
Download font index if font is/can be downloaded; else < 0.
|
|
The index is 0 based, i.e first downloaded font has index 0.
|
|
|
|
Note:
|
|
|
|
6/9/1997 -ganeshp-
|
|
Created it.
|
|
--*/
|
|
{
|
|
|
|
DL_MAP *pdm; // Individual download font map element
|
|
INT iRet; // The value we return: # of entry
|
|
PFONTPDEV pFontPDev; // Font Modules's PDEV
|
|
BOOL bError; // Set if we have an error.
|
|
PDEV *pPDev; // Pdev
|
|
FONTOBJ *pfo; // FontOBJ to be used
|
|
|
|
//
|
|
// Initialization of Local Variables.
|
|
// Default for iRet is Failure set to -1.
|
|
//
|
|
|
|
iRet = -1;
|
|
bError = FALSE;
|
|
pPDev = ptod->pPDev;
|
|
pfo = ptod->pfo;
|
|
|
|
pFontPDev = pPDev->pFontPDev;
|
|
|
|
/*
|
|
* FIRST test is to check for font rotations. If there is any,
|
|
* we do NOT download this font, as the complications of keeping
|
|
* track with how (or if) the printer allows it are far too great,
|
|
* and, in any event, it is not likely to gain us much, given the
|
|
* relative infrequency of this event. Also check to see if the
|
|
* printer can rotate fonts or not.
|
|
*
|
|
*/
|
|
|
|
//
|
|
// Use &pFontPDev->ctl to set correct font size. Also check the rotation.
|
|
//
|
|
*piRot = ISetScale( &pFontPDev->ctl, FONTOBJ_pxoGetXform( pfo ), FALSE , (pFontPDev->flText & TC_CR_ANY)?TRUE:FALSE);
|
|
|
|
if(!(pFontPDev->dwSelBits & FDH_PORTRAIT) )
|
|
return -1;
|
|
|
|
//
|
|
// Printer can't rotate text
|
|
//
|
|
if ((!(pFontPDev->flText & (TC_CR_ANY|TC_CR_90)) ||
|
|
(NULL == COMMANDPTR(pPDev->pDriverInfo, CMD_SETSIMPLEROTATION) &&
|
|
NULL == COMMANDPTR(pPDev->pDriverInfo, CMD_SETANYROTATION)))
|
|
&& *piRot)
|
|
return -1;
|
|
|
|
//
|
|
// Printer can rotate 90 rotation
|
|
//
|
|
if ((!(pFontPDev->flText & TC_CR_90) ||
|
|
NULL == COMMANDPTR(pPDev->pDriverInfo, CMD_SETSIMPLEROTATION))
|
|
&& *piRot / 5 != 0)
|
|
return -1;
|
|
|
|
|
|
//
|
|
// Get the DL_MAP for this FONTOBJ. The functions sets pvConsumer to
|
|
// 1 based the font index.
|
|
//
|
|
|
|
if (pdm = PGetDLMap (pFontPDev,pfo))
|
|
{
|
|
//
|
|
// Given a DL_MAP, Check if it is downloaded or not. If the
|
|
// DL_MAP.cGlyphs > 0 and DL_MAP.pfm is not NULL then this
|
|
// font is downloaded.
|
|
// If This font is Downloaded, return the index. The index
|
|
// is saved in pvConsumer, which is one based. We convert it
|
|
// to zero based.
|
|
//
|
|
|
|
iRet = (INT)PtrToLong(pfo->pvConsumer) - 1;
|
|
|
|
|
|
if (! (FONTDOWNLOADED(pdm)) )
|
|
{
|
|
//
|
|
// Font is a not downloaded. So start the process of downloading.
|
|
// The first job is to fill the DL_MAP structure.
|
|
//
|
|
if (BInitDLMap(pPDev,pfo,pdm))
|
|
{
|
|
//
|
|
// Check what method is preferred to download the font. Try the
|
|
// preferred method first and then the other method.If OEM
|
|
// handles the download then call the OEM download routine.
|
|
//
|
|
|
|
if (pFontPDev->flFlags & FDV_DLTT_OEMCALLBACK)
|
|
{
|
|
//
|
|
// OEM download.
|
|
//
|
|
|
|
if (!BDownLoadOEM(pPDev, pfo, pstro, pdm, DL_BASE_SOFT_FONT))
|
|
{
|
|
ERR(("UniFont!IDownloadFont:BDownLoadOEM Failed!!\n"));
|
|
bError = TRUE;
|
|
iRet = -1;
|
|
VFreeDLMAP(pdm);
|
|
pdm->cGlyphs = 0;
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if (pFontPDev->flFlags & FDV_DLTT_ASTT_PREF)
|
|
{
|
|
//
|
|
// Try downloading the Bitmap as True Type Outline.
|
|
//
|
|
//
|
|
|
|
if (!BDownLoadAsTT(pPDev,pfo,pstro,pdm,DL_BASE_SOFT_FONT))
|
|
{
|
|
//
|
|
// If download as TT fails, we should try to download as
|
|
// Bitmap. So we free the allocated buffers and then
|
|
// mark the DL_MAP as new, by setting cGlyphs to 0.
|
|
//
|
|
|
|
WARNING(("UniFont!IDownloadFont:BDownLoadAsTT Failed\n"));
|
|
|
|
iRet = -1;
|
|
VFreeDLMAP( pdm );
|
|
pdm->cGlyphs = 0;
|
|
|
|
//
|
|
// Decrement the Font id as we haven't downloaded the
|
|
// font yet. So reuse it.
|
|
//
|
|
|
|
pFontPDev->iUsedSoftFonts--;
|
|
pFontPDev->iNextSFIndex--;
|
|
|
|
}
|
|
|
|
}
|
|
if ((pFontPDev->flFlags & FDV_DLTT_BITM_PREF) ||
|
|
((pFontPDev->flFlags & FDV_DLTT_ASTT_PREF) && (iRet < 0)) )
|
|
{
|
|
//
|
|
// If Downlaod as TT Ouline failed, then try to download as
|
|
// bitmap. So initialize the DL_MAP again.
|
|
//
|
|
if (iRet == -1)
|
|
{
|
|
if (!BInitDLMap(pPDev,pfo,pdm))
|
|
{
|
|
//
|
|
// BInitDLMap Failed
|
|
//
|
|
ERR(("UniFont!IDownloadFont:BInitDLMap Failed for Bitmap Download\n"));
|
|
bError = TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
if (!bError)
|
|
{
|
|
//
|
|
// If the preffered format is Bitmap or we have incountered
|
|
// an error while downloading as TT outline; then we try to
|
|
// download as Bitmap. Reset iRet to Font Index.
|
|
//
|
|
|
|
iRet = (INT)PtrToLong(pfo->pvConsumer) - 1;
|
|
if (!BDownLoadAsBmp(pPDev,pfo,pstro,pdm,DL_BASE_SOFT_FONT))
|
|
{
|
|
ERR(("UniFont!IDownloadFont:BDownLoadAsBmp Failed\n"));
|
|
bError = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
// 300 dpi mode. We disabled TT downloading if text and graphics
|
|
// resolutions are not same in intrface.c.
|
|
//
|
|
if (!(pFontPDev->flFlags & FDV_DLTT_BITM_PREF) &&
|
|
!(pFontPDev->flFlags & FDV_DLTT_ASTT_PREF) )
|
|
bError = TRUE;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// BInitDLMap Failed
|
|
//
|
|
ERR(("UniFont!IDownloadFont:BInitDLMap Failed\n"));
|
|
bError = TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
if ( pdm != NULL &&
|
|
pdm->pfm != NULL &&
|
|
pdm->pfm->dwFontType == FMTYPE_TTOUTLINE &&
|
|
NONSQUARE_FONT(pFontPDev->pxform))
|
|
{
|
|
//
|
|
// There could be one font, which is scaled differently.
|
|
// PCL5e can't scale x and y independently.
|
|
// Need to print as graphics.
|
|
// So we only set iRet.
|
|
//
|
|
WARNING(("UniFont!IDownloadFont:Err in downloading Glyphs\n"));
|
|
iRet = -1;
|
|
}
|
|
|
|
//
|
|
// Now we are done with downloading. if iRet is >= 0 (successful
|
|
// downloading), then try downloading all the glyphs.
|
|
// bDownloadGlyphs will also set download glyph array, apdlGlyph.
|
|
//
|
|
|
|
if ((iRet >= 0) && !bError )
|
|
{
|
|
VERBOSE(("\nUniFont!IDownloadFont:Font downloaded successfully\n"));
|
|
ptod->pfm = pdm->pfm;
|
|
//
|
|
// iFace is -ve to identify that this is a TT SoftFont.
|
|
//
|
|
ptod->iFace = -iRet;
|
|
|
|
//
|
|
// OEM callback initialization
|
|
//
|
|
if (pFontPDev->pUFObj)
|
|
{
|
|
PFONTMAP_TTOEM pFMOEM;
|
|
|
|
//
|
|
// Make sure that this PFM is for OEM.
|
|
//
|
|
if (ptod->pfm->dwFontType == FMTYPE_TTOEM)
|
|
{
|
|
pFMOEM = (PFONTMAP_TTOEM) ptod->pfm->pSubFM;
|
|
pFMOEM->flFontType = pfo->flFontType;
|
|
}
|
|
|
|
pFontPDev->pUFObj->ulFontID = ptod->pfm->ulDLIndex;
|
|
|
|
//
|
|
// Initialize UFOBJ TrueType font bold/italic simulation
|
|
//
|
|
if (pFontPDev->pUFObj->dwFlags & UFOFLAG_TTDOWNLOAD_TTOUTLINE)
|
|
{
|
|
if (pfo->flFontType & FO_SIM_BOLD)
|
|
pFontPDev->pUFObj->dwFlags |= UFOFLAG_TTOUTLINE_BOLD_SIM;
|
|
|
|
|
|
if (pfo->flFontType & FO_SIM_ITALIC)
|
|
pFontPDev->pUFObj->dwFlags |= UFOFLAG_TTOUTLINE_ITALIC_SIM;
|
|
|
|
|
|
if (NULL != pFontPDev->pIFI &&
|
|
'@' == *((PBYTE)pFontPDev->pIFI + pFontPDev->pIFI->dpwszFamilyName))
|
|
|
|
{
|
|
pFontPDev->pUFObj->dwFlags |= UFOFLAG_TTOUTLINE_VERTICAL;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now we are downloading the glyphs, So select the font. This is
|
|
// done by calling BNewFont.
|
|
//
|
|
BNewFont(pPDev, ptod->iFace, ptod->pfm, 0);
|
|
|
|
if ( !BDownloadGlyphs(ptod, pstro, pdm ))
|
|
{
|
|
//
|
|
// There is some error in downloading Glyphcs. So don't
|
|
// download. But this not an error. So we only set iRet.
|
|
//
|
|
WARNING(("UniFont!IDownloadFont:Err in downloading Glyphs\n"));
|
|
iRet = -1;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (bError)
|
|
{
|
|
//
|
|
// There is some error. So free everything. If pvConsumer is positive
|
|
// then make it negative, to mark it bad.
|
|
//
|
|
if (pfo->pvConsumer > 0)
|
|
{
|
|
pfo->pvConsumer = (PINT_PTR)(-(INT_PTR)pfo->pvConsumer);
|
|
}
|
|
|
|
VFreeDLMAP( pdm );
|
|
iRet = -1;
|
|
|
|
}
|
|
//
|
|
// Clear the Set Font ID flag. This flag is set per textout
|
|
//
|
|
pFontPDev->flFlags &= ~FDV_SET_FONTID;
|
|
|
|
return iRet;
|
|
|
|
}
|
|
|
|
|
|
#define CONVERT_COUNT 7
|
|
|
|
IFIMETRICS *
|
|
pGetIFI(
|
|
PDEV *pPDev,
|
|
FONTOBJ *pfo,
|
|
BOOL bScale
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Given a pointer to a FONTOBJ, return a pointer to the IFIMETRICS
|
|
of the font. If this is a TT font, the metrics will be converted
|
|
with current scaling information. The IFIMETRICS data is allocated
|
|
on the heap, and it is the caller's repsonsibility to free it.
|
|
|
|
Arguments:
|
|
|
|
pPDev pointer to PDEVICE
|
|
pfo FONTOBJ,The font of interest
|
|
bScale TRUE for scaling IFIMETRICS else FALSE
|
|
|
|
Return Value:
|
|
address of IFIMETRICS, else NULL for failure.
|
|
|
|
Note:
|
|
|
|
3/5/1997 -ganeshp-
|
|
Created it.
|
|
--*/
|
|
|
|
{
|
|
IFIMETRICS *pIFI; /* Obtained from engine */
|
|
IFIMETRICS *pIFIRet; /* Returned to caller */
|
|
XFORMOBJ *pxo; /* For adjusting scalable font metrics */
|
|
|
|
|
|
POINTL aptlIn[ CONVERT_COUNT ]; /* Input values to xform */
|
|
POINTL aptlOut[ CONVERT_COUNT ]; /* Output values from xform */
|
|
|
|
pIFI = ((FONTPDEV*)pPDev->pFontPDev)->pIFI;
|
|
|
|
if( pIFI == NULL )
|
|
return NULL; /* May happen when journalling is in progress */
|
|
|
|
/*
|
|
* We need to make a copy of this, since we are going to clobber it.
|
|
* This may not be required if we are dealing with a bitmap font, but
|
|
* it is presumed most likely to be a TrueType font.
|
|
*/
|
|
|
|
if( pIFIRet = (IFIMETRICS *)MemAllocZ(pIFI->cjThis ) )
|
|
{
|
|
/*
|
|
* First copy the IFIMETRICS as is. Then, if a scalable font,
|
|
* we need to adjust the various sizes with the appropriate
|
|
* transform.
|
|
*/
|
|
CopyMemory( pIFIRet, pIFI, pIFI->cjThis );
|
|
|
|
|
|
if( bScale &&
|
|
(pIFIRet->flInfo &
|
|
(FM_INFO_ISOTROPIC_SCALING_ONLY |
|
|
FM_INFO_ANISOTROPIC_SCALING_ONLY |
|
|
FM_INFO_ARB_XFORMS)) &&
|
|
(pxo = FONTOBJ_pxoGetXform( pfo )))
|
|
{
|
|
/*
|
|
* Scalable, and transform available, so go do the
|
|
* transformations to get the font size in device pels.
|
|
*
|
|
***********************************************************
|
|
* ONLY SOME FIELDS ARE TRANSFORMED, AS WE USE ONLY A FEW.
|
|
***********************************************************
|
|
*/
|
|
|
|
ZeroMemory( aptlIn, sizeof( aptlIn ) ); /* Zero default */
|
|
|
|
aptlIn[ 0 ].y = pIFI->fwdTypoAscender;
|
|
aptlIn[ 1 ].y = pIFI->fwdTypoDescender;
|
|
aptlIn[ 2 ].y = pIFI->fwdTypoLineGap;
|
|
aptlIn[ 3 ].x = pIFI->fwdMaxCharInc;
|
|
aptlIn[ 4 ].x = pIFI->rclFontBox.left;
|
|
aptlIn[ 4 ].y = pIFI->rclFontBox.top;
|
|
aptlIn[ 5 ].x = pIFI->rclFontBox.right;
|
|
aptlIn[ 5 ].y = pIFI->rclFontBox.bottom;
|
|
aptlIn[ 6 ].x = pIFI->fwdAveCharWidth;
|
|
|
|
/*
|
|
* Perform the transform, and verify that there is no
|
|
* rotation component. Return NULL (failure) if any of
|
|
* this fails.
|
|
*/
|
|
|
|
if( !XFORMOBJ_bApplyXform( pxo, XF_LTOL, CONVERT_COUNT,
|
|
aptlIn, aptlOut )
|
|
#if 0
|
|
||
|
|
aptlOut[ 0 ].x || aptlOut[ 1 ].x ||
|
|
aptlOut[ 2 ].x || aptlOut[ 3 ].y
|
|
#endif
|
|
)
|
|
{
|
|
MemFree((LPSTR)pIFIRet );
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/* Simply install the new values into the output IFIMETRICS */
|
|
|
|
pIFIRet->fwdTypoAscender = (FWORD) aptlOut[0].y;
|
|
pIFIRet->fwdTypoDescender = (FWORD) aptlOut[1].y;
|
|
pIFIRet->fwdTypoLineGap = (FWORD) aptlOut[2].y;
|
|
|
|
pIFIRet->fwdWinAscender = pIFIRet->fwdTypoAscender;
|
|
pIFIRet->fwdWinDescender = -pIFIRet->fwdTypoDescender;
|
|
|
|
pIFIRet->fwdMacAscender = pIFIRet->fwdTypoAscender;
|
|
pIFIRet->fwdMacDescender = pIFIRet->fwdTypoDescender;
|
|
pIFIRet->fwdMacLineGap = pIFIRet->fwdTypoLineGap;
|
|
|
|
pIFIRet->fwdMaxCharInc = (FWORD)aptlOut[3].x;
|
|
|
|
/*
|
|
* PCL is fussy about the limits of the character cell.
|
|
* We allow some slop here by expanding the rclFontBox by
|
|
* one pel on each corner.
|
|
*/
|
|
pIFIRet->rclFontBox.left = aptlOut[ 4 ].x - 1;
|
|
pIFIRet->rclFontBox.top = aptlOut[ 4 ].y + 1;
|
|
pIFIRet->rclFontBox.right = aptlOut[ 5 ].x + 1;
|
|
pIFIRet->rclFontBox.bottom = aptlOut[ 5 ].y - 1;
|
|
pIFIRet->fwdAveCharWidth = (FWORD)aptlOut[ 6 ].x;
|
|
|
|
VERBOSE(("\n UniFont!pGetIFI:pIFI->fwdTypoAscender = %d,pIFI->fwdTypoDescender = %d\n",pIFI->fwdTypoAscender,pIFI->fwdTypoDescender));
|
|
VERBOSE(("UniFont!pGetIFI:pIFI->fwdWinAscender = %d, pIFI->fwdWinDescender = %d\n", pIFI->fwdWinAscender,pIFI->fwdWinDescender ));
|
|
VERBOSE(("UniFont!pGetIFI:pIFI->rclFontBox.top = %d,pIFI->rclFontBox.bottom = %d\n", pIFI->rclFontBox.top, pIFI->rclFontBox.bottom));
|
|
VERBOSE(("UniFont!pGetIFI: AFTER SCALING THE FONT\n"));
|
|
VERBOSE(("UniFont!pGetIFI:pIFIRet->fwdTypoAscender = %d,pIFIRet->fwdTypoDescender = %d\n",pIFIRet->fwdTypoAscender,pIFIRet->fwdTypoDescender));
|
|
VERBOSE(("UniFont!pGetIFI:pIFIRet->fwdWinAscender = %d, pIFIRet->fwdWinDescender = %d\n", pIFIRet->fwdWinAscender,pIFIRet->fwdWinDescender ));
|
|
VERBOSE(("UniFont!pGetIFI:pIFIRet->rclFontBox.top = %d,pIFIRet->rclFontBox.bottom = %d\n", pIFIRet->rclFontBox.top, pIFIRet->rclFontBox.bottom));
|
|
|
|
}
|
|
}
|
|
|
|
return pIFIRet;
|
|
|
|
}
|
|
|
|
#undef CONVERT_COUNT
|
|
|
|
BOOL
|
|
BSendDLFont(
|
|
PDEV *pPDev,
|
|
FONTMAP *pFM
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Called to download an existing softfont. Checks to see if the
|
|
font has been downloaded, and if so, does nothing. Otherwise
|
|
goes through the motions of downloading.
|
|
|
|
Arguments:
|
|
pPDev Pointer to PDEV
|
|
pFM The particular font of interest.
|
|
|
|
Return Value:
|
|
TRUE/FALSE; FALSE only if there is a problem during the load.
|
|
|
|
Note:
|
|
|
|
3/4/1997 -ganeshp-
|
|
Created it.
|
|
--*/
|
|
|
|
{
|
|
|
|
FONTMAP_DEV *pFMDev;
|
|
PFONTPDEV pFontPDev = pPDev->pFontPDev;
|
|
PDATA_HEADER pDataHeader;
|
|
PBYTE pDownloadData;
|
|
DWORD dwLeft; // Bytes remaining to send
|
|
/*
|
|
* First see if it has already been downloaded!
|
|
*/
|
|
|
|
if( pFM->flFlags & (FM_SENT | FM_GEN_SFONT) )
|
|
return TRUE;
|
|
|
|
pFMDev = (PFONTMAP_DEV)pFM->pSubFM;
|
|
|
|
if (!(pDataHeader = FIGetVarData( pFontPDev->hUFFFile, pFMDev->dwResID)) ||
|
|
pDataHeader->dwSignature != DATA_VAR_SIG ||
|
|
pDataHeader->dwDataSize == 0 )
|
|
return FALSE;
|
|
|
|
dwLeft = pDataHeader->dwDataSize;
|
|
pDownloadData = ((PBYTE)pDataHeader + pDataHeader->wSize);
|
|
|
|
/*
|
|
* Check if there is memory to fit this font. These are all
|
|
* approximations, but it is better than running out of memory
|
|
* in the printer.
|
|
*/
|
|
|
|
if( (pFontPDev->dwFontMemUsed + PCL_FONT_OH + dwLeft) > pFontPDev->dwFontMem )
|
|
return FALSE;
|
|
|
|
/*
|
|
* Time to be serious about downloading. UniDrive provides some
|
|
* of the control stuff we need. As well, we need to select an ID.
|
|
* The font itself is memory mapped, so we need only to shuffle it
|
|
* off to WriteSpoolBuf().
|
|
*/
|
|
|
|
pFM->ulDLIndex = IGetDL_ID( pPDev ); /* Down load index to use */
|
|
|
|
if( pFM->ulDLIndex == -1 )
|
|
return FALSE; /* Have run out of slots! */
|
|
|
|
/*
|
|
* Downloading is quite simple. First send an identifying command
|
|
* (to label the font for future selection) and then copy the font
|
|
* data (in the *.fi_ file) to the printer.
|
|
*/
|
|
|
|
BUpdateStandardVar(pPDev, pFM, 0, 0, STD_STD|STD_NFID);
|
|
WriteChannel( pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SETFONTID) );
|
|
|
|
while( dwLeft )
|
|
{
|
|
|
|
DWORD cjSize; /* Number of bytes to send */
|
|
|
|
cjSize = min( dwLeft, DL_BUF_SZ );
|
|
|
|
if( WriteSpoolBuf( pPDev, pDownloadData, cjSize ) != (int)cjSize )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if( pPDev->fMode & PF_ABORTED )
|
|
break;
|
|
|
|
dwLeft -= cjSize;
|
|
pDownloadData += cjSize;
|
|
}
|
|
|
|
/*
|
|
* If dwLeft is 0, then everything completed as expected. Under these
|
|
* conditions, we flag the data as having been sent, and thus available
|
|
* for use. Even if we failed, we should assume we have consumed
|
|
* all the font's memory and adjust our records accordingly.
|
|
*/
|
|
|
|
if( dwLeft == 0 )
|
|
pFM->flFlags |= FM_SENT; /* Now done */
|
|
|
|
/*
|
|
* Account for memory used by this font.
|
|
*/
|
|
|
|
pFontPDev->dwFontMemUsed += PCL_FONT_OH + pDataHeader->dwDataSize;
|
|
|
|
return dwLeft == 0;
|
|
|
|
}
|
|
|
|
|
|
DWORD
|
|
DwGetTTGlyphWidth(
|
|
FONTPDEV *pFontPDev,
|
|
FONTOBJ *pfo,
|
|
HGLYPH hTTGlyph)
|
|
/*++
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
pFontPDev Font PDevice
|
|
pfo Fontobj
|
|
hTTGlyph Glyph handle
|
|
|
|
Return Value:
|
|
Character width
|
|
|
|
Note:
|
|
|
|
--*/
|
|
{
|
|
DLGLYPH *pdlg;
|
|
DL_MAP *pdm;
|
|
DWORD dwRet;
|
|
|
|
if (!pfo || !pFontPDev)
|
|
return 0;
|
|
|
|
if (!(pdm = PGetDLMap (pFontPDev,pfo)) ||
|
|
!(pdlg = PDLGHashGlyph (pdm, hTTGlyph)))
|
|
{
|
|
dwRet = 0;
|
|
}
|
|
else
|
|
{
|
|
dwRet = pdlg->wWidth;
|
|
}
|
|
|
|
|
|
return dwRet;
|
|
}
|