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.
 
 
 
 
 
 

428 lines
12 KiB

/*++
Copyright (c) 1996 - 1999 Microsoft Corporation
Module Name:
qfontdat.c
Abstract:
Implements the DrvQueryFontData function - returns information
about glyphs (size, position wrt box) or kerning information.
Environment:
Windows NT Unidrv driver
Revision History:
12/19/96 -ganeshp-
Created
--*/
#include "font.h"
/*
* The values for pteBase, pteSide in FD_DEVICEMETRICS, allowing
* for rotation by 90 degree multiples.
*/
#if defined(USEFLOATS) || defined(WINNT_40)
static const POINTE pteRotBase[] =
{
{ (FLOAT) 1.0, (FLOAT) 0.0 },
{ (FLOAT) 0.0, (FLOAT)-1.0 },
{ (FLOAT)-1.0, (FLOAT) 0.0 },
{ (FLOAT) 0.0, (FLOAT) 1.0 }
};
static const POINTE pteRotSide[] =
{
{ (FLOAT) 0.0, (FLOAT)-1.0 },
{ (FLOAT)-1.0, (FLOAT) 0.0 },
{ (FLOAT) 0.0, (FLOAT) 1.0 },
{ (FLOAT) 1.0, (FLOAT) 0.0 }
};
#else
static const POINTE pteRotBase[] =
{
{ (FLOATL) FLOATL_1_0, (FLOATL) FLOATL_0_0 },
{ (FLOATL) FLOATL_0_0, (FLOATL) FLOATL_1_0M },
{ (FLOATL) FLOATL_1_0M,(FLOATL) FLOATL_0_0 },
{ (FLOATL) FLOATL_0_0, (FLOATL) FLOATL_1_0 }
};
static const POINTE pteRotSide[] =
{
{ (FLOATL) FLOATL_0_0, (FLOATL) FLOATL_1_0M },
{ (FLOATL) FLOATL_1_0M,(FLOATL) FLOATL_0_0 },
{ (FLOATL) FLOATL_0_0, (FLOATL) FLOATL_1_0 },
{ (FLOATL) FLOATL_1_0, (FLOATL) FLOATL_0_0 }
};
#endif //defined(USEFLOATS) || defined(WINNT_40)
/* The X dimension rotation cases */
static const POINTL ptlXRot[] =
{
{ 1, 0 },
{ 0, -1 },
{ -1, 0 },
{ 0, 1 },
};
/* The Y dimension rotation cases */
static const POINTL ptlYRot[] =
{
{ 0, 1 },
{ 1, 0 },
{ 0, -1 },
{ -1, 0 },
};
LONG
FMQueryFontData(
PDEV *pPDev,
FONTOBJ *pfo,
ULONG iMode,
HGLYPH hg,
GLYPHDATA *pgd,
PVOID pv,
ULONG cjSize
)
/*++
Routine Description:
Return information about glyphs in the font, OR kerning data.
Arguments:
pPDev Really a pPDev
pfo The font of interest
iMode Glyphdata or kerning information
hg Handle to glyph
pgd Place to put metrics
pv Output area
cjSize Size of output area
Return Value:
Number of bytes needed or written, 0xffffffff for error.
Note:
12-29-96: Created it -ganeshp-
--*/
{
FONTPDEV *pFontPDev;
int iRot; /* Rotation multiple of 90 degrees */
LONG lRet; /* Value returned */
FONTMAP *pFM; /* Font data */
FONTMAP_DEV *pFMDev; /* Font data */
FONTCTL ctl; /* Font scale/rotation adjustments */
IFIMETRICS *pIFI;
XFORMOBJ *pxo;
LONG lAscender;
LONG lDescender;
FLOATOBJ fo;
pFontPDev = pPDev->pFontPDev;
lRet = FD_ERROR;
if( pfo->iFace < 1 || (int)pfo->iFace > pPDev->iFonts )
{
ERR(("Bad FONTOBJ, iFace is %d",pfo->iFace));
SetLastError( ERROR_INVALID_PARAMETER );
return lRet;
}
pFM = PfmGetDevicePFM( pPDev, pfo->iFace );
if( pFM == NULL )
return lRet;
VDBGDUMPFONTMAP(pFM);
pFMDev = pFM->pSubFM;
pIFI = pFM->pIFIMet; /* IFIMETRICS - useful to have */
if( pgd || pv )
{
/*
* Need to obtain a transform to adjust these numbers as to
* how the engine wants them.
*/
if( !(pxo = FONTOBJ_pxoGetXform( pfo )) )
{
ERR(( "UniFont!FMQueryFontData: FONTOBJ_pxoGetXform fails\n" ));
return lRet;
}
/* Can now obtain the transform! */
//Added Check for HP Intellifont
iRot = ISetScale( &ctl, pxo, ((pFM->flFlags & FM_SCALABLE) &&
(pFMDev->wDevFontType ==
DF_TYPE_HPINTELLIFONT)),
(pFontPDev->flText & TC_CR_ANY)?TRUE:FALSE);
if (pFontPDev->flText & TC_CR_ANY)
iRot = (iRot + 45) / 90;
/*
* There are some adjustments to make to the scale factors. One
* is to compensate for resolutions (these are coarse, integral
* adjustments), the others are to to do with Intellifont. First
* is the Intellifont point is 1/72.31 inches (!), and secondly
* the LaserJet only adjusts font size to the nearest 0.25 point,
* and hence when we round to that multiple, we need to adjust
* the width accordingly.
*/
if( pFM->flFlags & FM_SCALABLE )
{
int iPtSize, iAdjustedPtSize; /* For scale factor adjustment */
#ifdef USEFLOATS
/* The limited font size resolution */
iPtSize = (int)(0.5 + ctl.eYScale * pIFI->fwdUnitsPerEm * 7200) / pPDev->ptGrxRes.y;
/* if the tranform is very small (Less than a quarter of point size)
* then make it atleast a quarter point. This was causing AV in certain
* cases.
*/
if (iPtSize < 25)
{
iPtSize = 25;
}
iAdjustedPtSize = ((iPtSize + 12) / 25) * 25;
//Adjust the Scale Factor for quarter point adjustment.
ctl.eXScale = (ctl.eXScale * iAdjustedPtSize) / iPtSize;
ctl.eYScale = (ctl.eYScale * iAdjustedPtSize) / iPtSize;
#else
fo = ctl.eYScale;
FLOATOBJ_MulLong(&fo,pIFI->fwdUnitsPerEm);
FLOATOBJ_MulLong(&fo,7200);
#ifndef WINNT_40 //NT 5.0
FLOATOBJ_AddFloat(&fo,(FLOATL)FLOATL_00_50);
#else // NT 4.0
FLOATOBJ_AddFloat(&fo,(FLOAT)0.5);
#endif //!WINNT_40
iPtSize = FLOATOBJ_GetLong(&fo);
iPtSize /= pPDev->ptGrxRes.y;
/* if the trannform is very small (Less than a quarter of point size)
* then make it atleast a quarter point. This was causing AV in certain
* cases.
*/
if (iPtSize < 25)
{
iPtSize = 25;
}
iAdjustedPtSize = ((iPtSize + 12) / 25) * 25;
//Adjust the Scale Factor for quarter point adjustment.
FLOATOBJ_MulLong(&ctl.eXScale,iAdjustedPtSize);
FLOATOBJ_DivLong(&ctl.eXScale,iPtSize);
FLOATOBJ_MulLong(&ctl.eYScale,iAdjustedPtSize);
FLOATOBJ_DivLong(&ctl.eYScale,iPtSize);
#endif
}
}
/*
* precompute the lDescender and lAscender
*/
lDescender = LMulFloatLong(&ctl.eYScale,pIFI->fwdWinDescender);
lAscender = LMulFloatLong(&ctl.eYScale,pIFI->fwdWinAscender);
switch( iMode )
{
case QFD_GLYPHANDBITMAP: /* Glyph width etc data */
// size is now just the size of the bitmap, which in this
// case doesn't exist.
lRet = 0;
if( pgd )
{
int iWide; /* Glyph's width */
/*
* First get the width of this glyph, as this is needed
* in several places.The width returned by IGetGlyphWidth
* is not scaled in device units. To convert in device units
* multily with the scale factor calculated earlier.
*/
iWide = IGetGlyphWidth( pPDev, pFM, hg);
iWide = LMulFloatLong(&ctl.eXScale,iWide);
switch( iRot )
{
case 0:
pgd->rclInk.left = 0;
pgd->rclInk.top = lDescender;
pgd->rclInk.right = iWide;
pgd->rclInk.bottom = -lAscender;
break;
case 1:
pgd->rclInk.left = lDescender;
pgd->rclInk.top = iWide;
pgd->rclInk.right = -lAscender;
pgd->rclInk.bottom = 0;
break;
case 2:
pgd->rclInk.left = -iWide;
pgd->rclInk.top = -lAscender;
pgd->rclInk.right = 0;
pgd->rclInk.bottom = lDescender;
break;
case 3:
pgd->rclInk.left = lAscender;
pgd->rclInk.top = 0;
pgd->rclInk.right = -lDescender;
pgd->rclInk.bottom = -iWide;
break;
}
pgd->fxD = LTOFX( iWide );
pgd->ptqD.x.HighPart = pgd->fxD * ptlXRot[ iRot ].x;
pgd->ptqD.x.LowPart = 0;
pgd->ptqD.y.HighPart = pgd->fxD * ptlXRot[ iRot ].y;
pgd->ptqD.y.LowPart = 0;
pgd->fxA = 0;
pgd->fxAB = pgd->fxD;
pgd->fxInkTop = (FIX)LTOFX( lAscender );
pgd->fxInkBottom = -(FIX)LTOFX( lDescender );
pgd->hg = hg;
pgd->gdf.pgb = NULL;
}
break;
case QFD_MAXEXTENTS: /* Alternative form of the above */
lRet = sizeof( FD_DEVICEMETRICS );
if( pv )
{
LONG lTmp; /* Rotated case */
FD_DEVICEMETRICS *pdm = ((FD_DEVICEMETRICS *)pv);
/*
* Check that the size is reasonable!
*/
if( cjSize < sizeof( FD_DEVICEMETRICS ) )
{
SetLastError( ERROR_INSUFFICIENT_BUFFER );
ERR(( "rasdd!DrvQueryFontData: cjSize (%ld) too small\n", cjSize ));
return -1;
}
// BUG 757060 - set this to 0 explicitly, because some drivers
// were using this before it was set, and may have code paths that
// break if this is a reasonable value. Before this fix, the value
// was the 0xCD pattern, and on newer IA64 machines, requests for this
// much memory (>3GB) could be handled, but at the expense of locking up
// the machine for minutes or even hours.
pdm->cjGlyphMax = 0;
/*
* These are accelerator flags - it is not obvious to me
* that any of them are relevant to printer driver fonts.
*/
pdm->flRealizedType = 0;
/*
* Following fields set this as a normal type of font.
*/
pdm->pteBase = pteRotBase[ iRot ];
pdm->pteSide = pteRotSide[ iRot ];
pdm->cxMax = LMulFloatLong(&ctl.eXScale,pIFI->fwdMaxCharInc);
//
// DBCS fonts are not monospaced, have halfwidth glyphs and
// fullwidth glyphs.
//
if ( pFMDev->W.psWidth ||
IS_DBCSCHARSET(((IFIMETRICS*)pFM->pIFIMet)->jWinCharSet))
{
pdm->lD = 0; /* Proportionally spaced font */
}
else
{
pdm->lD = pdm->cxMax;
}
pdm->fxMaxAscender = (FIX)LTOFX( lAscender );
pdm->fxMaxDescender = (FIX)LTOFX( lDescender );
lTmp = -LMulFloatLong(&ctl.eYScale,pIFI->fwdUnderscorePosition);
pdm->ptlUnderline1.x = lTmp * ptlYRot[ iRot ].x;
pdm->ptlUnderline1.y = lTmp * ptlYRot[ iRot ].y;
lTmp = -LMulFloatLong(&ctl.eYScale,pIFI->fwdStrikeoutPosition);
pdm->ptlStrikeOut.x = lTmp * ptlYRot[ iRot ].x;
pdm->ptlStrikeOut.y = lTmp * ptlYRot[ iRot ].y;
lTmp = LMulFloatLong(&ctl.eYScale,pIFI->fwdUnderscoreSize);
pdm->ptlULThickness.x = lTmp * ptlYRot[ iRot ].x;
pdm->ptlULThickness.y = lTmp * ptlYRot[ iRot ].y;
lTmp = LMulFloatLong(&ctl.eYScale,pIFI->fwdStrikeoutSize);
pdm->ptlSOThickness.x = lTmp * ptlYRot[ iRot ].x;
pdm->ptlSOThickness.y = lTmp * ptlYRot[ iRot ].y;
}
break;
default:
ERR(( "Rasdd!DrvQueryFontData: unprocessed iMode value - %ld",iMode ));
SetLastError( ERROR_INVALID_PARAMETER );
break;
}
return lRet;
}