mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
477 lines
14 KiB
477 lines
14 KiB
/**************************** Module Header *********************************
|
|
* qfontdat.c
|
|
* Implements the DrvQueryFontData function - returns information
|
|
* about glyphs (size, position wrt box) or kerning information.
|
|
*
|
|
* Copyright (C) 1991 - 1993 Microsoft Corporation
|
|
*
|
|
****************************************************************************/
|
|
|
|
/* !!!LindsayH - trim the include file list */
|
|
|
|
#include <stddef.h>
|
|
#include <windows.h>
|
|
#include <winddi.h>
|
|
|
|
#include "win30def.h"
|
|
#include "udmindrv.h"
|
|
#include "udpfm.h"
|
|
#include "uddevice.h"
|
|
#include "pdev.h"
|
|
#include <libproto.h>
|
|
|
|
#include <ntrle.h>
|
|
|
|
#include "udresrc.h"
|
|
#include "udfnprot.h"
|
|
|
|
#include "rasdd.h"
|
|
|
|
/*
|
|
* The values for pteBase, pteSide in FD_DEVICEMETRICS, allowing
|
|
* for rotation by 90 degree multiples.
|
|
*/
|
|
|
|
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 }
|
|
};
|
|
|
|
|
|
/* 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 },
|
|
};
|
|
|
|
#ifndef USEFLOATS
|
|
|
|
LONG lMulFloatLong(
|
|
PFLOATOBJ pfo,
|
|
LONG l)
|
|
{
|
|
FLOATOBJ fo;
|
|
fo = *pfo;
|
|
FLOATOBJ_MulLong(&fo,l);
|
|
FLOATOBJ_AddFloat(&fo,(FLOAT)0.5);
|
|
return(FLOATOBJ_GetLong(&fo));
|
|
}
|
|
|
|
#endif
|
|
|
|
/************************ Function Header *********************************
|
|
* DrvQueryFontData
|
|
* Return information about glyphs in the font, OR kerning data.
|
|
*
|
|
* RETURNS:
|
|
* Number of bytes needed or written, 0xffffffff for error.
|
|
*
|
|
* HISTORY:
|
|
* 15:04 on Thu 27 May 1993 -by- Lindsay Harris [lindsayh]
|
|
* Handle 90 degree rotations for LJ III, 4 etc.
|
|
*
|
|
* 13:00 on Thu 08 Apr 1993 -by- Lindsay Harris [lindsayh]
|
|
* Enable QFD_MAXEXTENT code.
|
|
*
|
|
* 09:53 on Tue 30 Mar 1993 -by- Lindsay Harris [lindsayh]
|
|
* Lazy font loading.
|
|
*
|
|
* 15:13 on Sun 10 Jan 1993 -by- Lindsay Harris [lindsayh]
|
|
* Scale font metrics data to font definition
|
|
*
|
|
* 12:46 on Fri 04 Dec 1992 -by- Lindsay Harris [lindsayh]
|
|
* New HGLYPH usage.
|
|
*
|
|
* 13:22 on Fri 21 Aug 1992 -by- Lindsay Harris [lindsayh]
|
|
* Added scalable font support.
|
|
*
|
|
* 14:42 on Wed 13 Mar 1991 -by- Lindsay Harris [lindsayh]
|
|
* Made it work for fixed pitch fonts.
|
|
*
|
|
* 10:04 on Mon 11 Mar 1991 -by- Lindsay Harris [lindsayh]
|
|
* Skeleton to start with.
|
|
*
|
|
**************************************************************************/
|
|
|
|
LONG
|
|
DrvQueryFontData( dhpdev, pfo, iMode, hg, pgd, pv, cjSize )
|
|
DHPDEV dhpdev; /* Really a pPDev */
|
|
FONTOBJ *pfo; /* The font of interest */
|
|
ULONG iMode; /* Glyphdata or kerning information */
|
|
HGLYPH hg; /* Handle to glyph */
|
|
GLYPHDATA *pgd; /* Place to put metrics */
|
|
VOID *pv; /* Output area */
|
|
ULONG cjSize; /* Size of output area */
|
|
{
|
|
/*
|
|
* First version is for fixed pitch fonts, which are easy to do:
|
|
* the data is in the font's metrics!
|
|
*/
|
|
|
|
#define pPDev ((PDEV *)dhpdev)
|
|
#define pUDPDev ((UD_PDEV *)((PDEV *)dhpdev)->pUDPDev)
|
|
|
|
|
|
int iType; /* Type of glyph encoding & hence width */
|
|
int iRot; /* Rotation multiple of 90 degrees */
|
|
LONG lRet; /* Value returned */
|
|
FONTMAP *pFM; /* Font data */
|
|
|
|
OUTPUTCTL ctl; /* Font scale/rotation adjustments */
|
|
|
|
IFIMETRICS *pIFI;
|
|
|
|
XFORMOBJ *pxo;
|
|
LONG lAscender;
|
|
LONG lDescender;
|
|
|
|
|
|
NT_RLE *pntrle; /* The RLE stuff - may be needed */
|
|
UHG uhg; /* Defined access to HGLYPH contents */
|
|
|
|
#ifndef USEFLOATS
|
|
FLOATOBJ fo;
|
|
#endif
|
|
|
|
lRet = FD_ERROR;
|
|
|
|
#if DBG
|
|
if( pfo->iFace < 1 || (int)pfo->iFace > pUDPDev->cFonts )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
|
|
return lRet;
|
|
}
|
|
#endif
|
|
|
|
pFM = pfmGetIt( pPDev, pfo->iFace );
|
|
if( pFM == NULL )
|
|
return lRet;
|
|
|
|
|
|
pIFI = pFM->pIFIMet; /* IFIMETRICS - useful to have */
|
|
|
|
pntrle = pFM->pvntrle;
|
|
iType = pntrle->wType;
|
|
|
|
if( pgd || pv )
|
|
{
|
|
/*
|
|
* Need to obtain a transform to adjust these numbers as to
|
|
* how the engine wants them.
|
|
*/
|
|
|
|
|
|
if( !(pxo = FONTOBJ_pxoGetXform( pfo )) )
|
|
{
|
|
#if DBG
|
|
DbgPrint( "Rasdd!DrvQueryFontData(): FONTOBJ_pxoGetXform fails\n" );
|
|
#endif
|
|
return lRet;
|
|
}
|
|
|
|
/* Can now obtain the transform! */
|
|
|
|
/* iSetScale function checks for Intellifont type fonts
|
|
Make the call to it 'CaPSL aware, ie no special case for Intellifont
|
|
added Dec '93 Derry Durand [derryd]
|
|
*/
|
|
/* Changed 02/18/94 DerryD, PPDS uses 72 pts = 1 inch ( ie ATM fonts,
|
|
therefore no scale factor required
|
|
*/
|
|
|
|
//Added Check for HP Intellifont
|
|
iRot = iSetScale( &ctl, pxo,
|
|
(( (pUDPDev->pdh->fTechnology == GPC_TECH_CAPSL ) |
|
|
(pUDPDev->pdh->fTechnology == GPC_TECH_PPDS ) )
|
|
? FALSE : ((pFM->fFlags & FM_SCALABLE)&&
|
|
(pFM->wFontType == DF_TYPE_HPINTELLIFONT)) ) );
|
|
|
|
|
|
/*
|
|
* 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->fFlags & FM_SCALABLE )
|
|
{
|
|
|
|
int iPtSize; /* For scale factor adjustment */
|
|
/* !!!LindsayH - assumes it is always IntelliFont - OK for present */
|
|
|
|
/* .. well not anymore !... need to check if it is a CaPSL font, if so
|
|
then no need for this scale factor as CaPSL point = 1/72 of an inch
|
|
exactly - Derry Durand Dec '93 [derryd]
|
|
*/
|
|
//GP:04/26/94 This code is not required anymore as as the scaling
|
|
//for eXScale (for Intellifonts) are already done in iSetScale,
|
|
//which is called just before. The same code is present in
|
|
// DrvQueryAdvanceWidths in file qadvwidth.c and there the scaling
|
|
//is not done twice.DrvQueryFontData and DrvQueryAdvanceWidths should
|
|
//return same widths for charecters.
|
|
|
|
//if (pUDPDev->pdh->fTechnology != GPC_TECH_CAPSL )
|
|
/* The Intellifont adjustment */
|
|
//ctl.eXScale = ctl.eXScale * (FLOAT)72.0 / (FLOAT)72.31;
|
|
|
|
#ifdef USEFLOATS
|
|
|
|
/* The limited font size resolution */
|
|
iPtSize = (int)(0.5 + ctl.eYScale * pIFI->fwdUnitsPerEm * 7200) / pUDPDev->iygRes;
|
|
|
|
ctl.eXScale = (ctl.eXScale * ((iPtSize + 12) / 25) * 25) / iPtSize;
|
|
|
|
#else
|
|
|
|
fo = ctl.eYScale;
|
|
FLOATOBJ_MulLong(&fo,pIFI->fwdUnitsPerEm);
|
|
FLOATOBJ_MulLong(&fo,7200);
|
|
FLOATOBJ_AddFloat(&fo,(FLOAT)0.5);
|
|
iPtSize = FLOATOBJ_GetLong(&fo);
|
|
iPtSize /= pUDPDev->iygRes;
|
|
|
|
FLOATOBJ_MulLong(&ctl.eXScale,((iPtSize + 12) / 25));
|
|
FLOATOBJ_MulLong(&ctl.eXScale,25);
|
|
FLOATOBJ_DivLong(&ctl.eXScale,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.
|
|
*/
|
|
|
|
if( pFM->psWidth )
|
|
{
|
|
/* Proportional font - width varies per glyph */
|
|
|
|
|
|
uhg.hg = (HGLYPH)hg;
|
|
|
|
/*
|
|
* We need the index value from the HGLYPH. The
|
|
* index is the offset in the width table. For all
|
|
* but the >= 24 bit offset types, the index is
|
|
* included in the HGLYPH. For the 24 bit offset,
|
|
* the first WORD of the destination is the index,
|
|
* while for the 32 bit offset, it is the second WORD
|
|
* at the offset.
|
|
*/
|
|
|
|
switch( iType )
|
|
{
|
|
case RLE_DIRECT:
|
|
case RLE_PAIRED:
|
|
iWide = uhg.rd.wIndex;
|
|
break;
|
|
|
|
case RLE_LI_OFFSET:
|
|
iWide = uhg.rli.bIndex;
|
|
break;
|
|
|
|
case RLE_L_OFFSET:
|
|
iWide = (DWORD)uhg.hg & 0x00ffffff;
|
|
iWide = *((WORD *)((BYTE *)pntrle + iWide));
|
|
break;
|
|
|
|
case RLE_OFFSET:
|
|
iWide = (DWORD)uhg.hg + sizeof( WORD );
|
|
iWide = *((WORD *)((BYTE *)pntrle + iWide));
|
|
break;
|
|
}
|
|
|
|
iWide = *(pFM->psWidth + iWide) * pUDPDev->ixgRes / pFM->wXRes;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Fixed pitch fonts come from IFIMETRICS */
|
|
iWide = pIFI->fwdMaxCharInc;
|
|
}
|
|
|
|
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 */
|
|
|
|
|
|
#define pdm ((FD_DEVICEMETRICS *)pv)
|
|
|
|
/*
|
|
* Check that the size is reasonable!
|
|
*/
|
|
|
|
if( cjSize < sizeof( FD_DEVICEMETRICS ) )
|
|
{
|
|
SetLastError( ERROR_INSUFFICIENT_BUFFER );
|
|
|
|
#if DBG
|
|
DbgPrint( "rasdd!DrvQueryFontData: cjSize (%ld) too small\n",
|
|
cjSize );
|
|
#endif
|
|
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* 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);
|
|
|
|
if( pFM->psWidth )
|
|
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;
|
|
#undef pdm
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
default:
|
|
#if DBG
|
|
DbgPrint( "Rasdd!DrvQueryFontData: unprocessed iMode value - %ld",
|
|
iMode );
|
|
#endif
|
|
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
break;
|
|
}
|
|
|
|
return lRet;
|
|
}
|