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.
 
 
 
 
 
 

398 lines
11 KiB

/******************************Module*Header*******************************\
* Module Name: fdfc.c
*
* Various font context functions. Adapted from BodinD's bitmap font driver.
*
* Copyright (c) 1990-1995 Microsoft Corporation
\**************************************************************************/
#include "fd.h"
#define MIN(A,B) ((A) < (B) ? (A) : (B))
#define MAX(A,B) ((A) > (B) ? (A) : (B))
#if defined(_AMD64_) || defined(_IA64_)
#define MUL16(ef) {ef *= 16; }
#define lCvt(ef, l) ((LONG) (ef * l))
#else
#define MUL16(ef) {if (ef.lMant != 0) ef.lExp += 4; }
LONG lCvt(EFLOAT ef,LONG l);
#endif
/******************************Private*Routine*****************************\
* BOOL bInitXform
*
* Initialize the coefficients of the transforms for the given font context.
* It also transforms and saves various measurements of the font in the
* context.
*
* History:
* 25-Feb-1992 -by- Wendy Wu [wendywu]
* Wrote it.
\**************************************************************************/
BOOL bInitXform(PFONTCONTEXT pfc, XFORMOBJ *pxo)
{
// !!! bFloatToFix should be replaced with a compare and a type cast.
// Dont update the coefficeints in the font context yet since overflows
// might occur.
VECTORFL vtflTmp;
POINTL ptl;
XFORML xfm;
// Get the transform elements.
XFORMOBJ_iGetXform(pxo,&xfm);
// Convert elements of the matrix from IEEE float to our EFLOAT.
vEToEF(xfm.eM11, &pfc->efM11);
vEToEF(xfm.eM12, &pfc->efM12);
vEToEF(xfm.eM21, &pfc->efM21);
vEToEF(xfm.eM22, &pfc->efM22);
// The path we are to construct takes 1/16 pixel per unit. So lets
// multiply this factor in the transform.
MUL16(pfc->efM11)
MUL16(pfc->efM12)
MUL16(pfc->efM21)
MUL16(pfc->efM22)
//
// These are the special cases for which we need to clip bottom and right
// edges. Below is the lower case letter e all posible 90 rotations and
// flips.
//
//
// *** *** ** ***** *** *** ***** **
// * * * * * * * * * * * * * * * * * *
// ***** ***** * * * * * * ***** ***** * * * * * *
// * * * * * * * * * * * * * * * * * *
// *** *** ***** ** *** *** ** *****
//
// case 1 case 2 case 6 case 5 case 3 case 4 case 7 case 8
//
//
if (bIsZero(pfc->efM12) && bIsZero(pfc->efM21))
{
pfc->flags |= FC_SCALE_ONLY;
if (!bPositive(pfc->efM11))
pfc->flags |= FC_X_INVERT;
if( bPositive(pfc->efM11 ) )
{
pfc->flags |= (bPositive(pfc->efM22)) ? FC_ORIENT_1 : FC_ORIENT_2;
}
else
{
pfc->flags |= (bPositive(pfc->efM22)) ? FC_ORIENT_4 : FC_ORIENT_3;
}
}
if( bIsZero(pfc->efM22) && bIsZero(pfc->efM11) )
{
if( bPositive(pfc->efM21 ) )
{
pfc->flags |= (bPositive(pfc->efM12)) ? FC_ORIENT_5 : FC_ORIENT_6;
}
else
{
pfc->flags |= (bPositive(pfc->efM12)) ? FC_ORIENT_7 : FC_ORIENT_8;
}
}
// Transform the base and the side vectors. Should never overflow.
ptl.x = 1;
ptl.y = 0;
bXformUnitVector(&ptl,
&xfm,
&pfc->vtflBase,
&pfc->pteUnitBase,
(pfc->flags & FC_SIM_EMBOLDEN) ? &pfc->ptqUnitBase : NULL,
&pfc->efBase);
pfc->fxEmbolden = 0;
if (pfc->flags & FC_SIM_EMBOLDEN)
{
// emboldening shift for vector fonts in not always one with vector fonts
// It is computed as 1 * efBase. This is win31 compatible way of doing this
pfc->fxEmbolden = ((lCvt(pfc->efBase, 1) + 8) & 0xfffffff0);
if (pfc->fxEmbolden < 24)
{
// primitive "hinting", do not let it become zero
pfc->fxEmbolden = 16;
pfc->pfxBaseOffset.x = FXTOL(pfc->ptqUnitBase.x.HighPart + 8);
pfc->pfxBaseOffset.y = FXTOL(pfc->ptqUnitBase.y.HighPart + 8);
// resolve mult of 45 degrees situations:
if ((pfc->pfxBaseOffset.x == pfc->pfxBaseOffset.y) ||
(pfc->pfxBaseOffset.x == -pfc->pfxBaseOffset.y) )
{
pfc->pfxBaseOffset.y = 0;
}
pfc->pfxBaseOffset.x = LTOFX(pfc->pfxBaseOffset.x);
pfc->pfxBaseOffset.y = LTOFX(pfc->pfxBaseOffset.y);
ASSERTDD(pfc->pfxBaseOffset.x || pfc->pfxBaseOffset.y, "x zero and y zero\n");
ASSERTDD((pfc->pfxBaseOffset.x && pfc->pfxBaseOffset.y) == 0, "x * y not zero\n");
}
else
{
pfc->pfxBaseOffset.x = lCvt(pfc->vtflBase.x, 1);
pfc->pfxBaseOffset.y = lCvt(pfc->vtflBase.y, 1);
}
}
// Transform the side vector.
ptl.x = 0;
ptl.y = -1;
bXformUnitVector(&ptl, &xfm, &vtflTmp,
&pfc->pteUnitSide, NULL, &pfc->efSide);
pfc->fxInkTop = fxLTimesEf(&pfc->efSide, pfc->pifi->fwdWinAscender);
pfc->fxInkBottom = -fxLTimesEf(&pfc->efSide, pfc->pifi->fwdWinDescender);
pfc->fxItalic = 0;
if (pfc->flags & FC_SIM_ITALICIZE)
{
pfc->fxItalic
= (fxLTimesEf(
&pfc->efBase,
(pfc->pifi->fwdWinAscender + pfc->pifi->fwdWinDescender + 1)/2
) + 8) & 0xfffffff0 ;
}
return(TRUE);
}
/******************************Public*Routine******************************\
* HFC vtfdOpenFontContext
*
* Open a font context. Store font transform and other requests for
* the realization of this font.
*
* History:
* 27-Feb-1992 -by- Wendy Wu [wendywu]
* Adapted from bmfd.
\**************************************************************************/
HFC vtfdOpenFontContext(FONTOBJ *pfo)
{
PFONTFILE pff = (PFONTFILE)pfo->iFile;
PFONTCONTEXT pfc;
BYTE *pjView;
DWORD dwFirstCharOffset;
#ifdef DEBUGSIM
DbgPrint("vtfdOpenFontContext, ulFont = %ld\n", ulFont);
#endif // DEBUGSIM
if (pff == (PFONTFILE) NULL)
return(HFC_INVALID);
// iFace is 1 based:
if ((pfo->iFace < 1L) || (pfo->iFace > pff->cFace)) // pfo->iFace values are 1 based
return(HFC_INVALID);
// increase the reference count of the font file, WE DO THIS ONLY WHEN
// WE ARE SURE that can not fail any more
// need to grab a sem for we will be looking into cRef now.
if (pff->cRef == 0)
{
// need to remap the file into the memory again and update pointers:
UINT i;
if (!EngMapFontFileFD(pff->iFile,(PULONG*)&pff->pvView, &pff->cjView))
{
WARNING("somebody removed the file\n");
return (HFC_INVALID);
}
for (i = 0; i < pff->cFace; i++)
{
pff->afd[i].re.pvResData = (PVOID) (
(BYTE*)pff->pvView + pff->afd[i].re.dpResData
);
}
}
// remember this so that we do not have to read from the file
// after we allocate the memory for the font context. This simplifies
// clean up code in case of exception, i.e. disappearing font files.
pjView = pff->afd[pfo->iFace-1].re.pvResData;
dwFirstCharOffset = READ_DWORD(pjView + OFF_BitsOffset);
// Allocate memory for the font context.
if ((pfc = pfcAlloc()) == (PFONTCONTEXT)NULL)
{
if (pff->cRef == 0)
{
EngUnmapFontFileFD(pff->iFile);
}
return(HFC_INVALID);
}
// we MUST NOT not touch the memory mapped file past this point
// until the end of the routine. This is important for the
// proper clean up code in case of exception. [bodind]
pfc->pre = &pff->afd[pfo->iFace-1].re;
pfc->pifi = pff->afd[pfo->iFace-1].pifi;
// SET wendywu style flags
pfc->flags = 0;
if (pfo->flFontType & FO_SIM_BOLD)
pfc->flags |= FC_SIM_EMBOLDEN;
if (pfo->flFontType & FO_SIM_ITALIC)
pfc->flags |= FC_SIM_ITALICIZE;
pfc->dpFirstChar = dwFirstCharOffset;
// !!! Vector font file doesn't have the byte filler. Win31 bug?
//pfc->ajCharTable = pjView + OFF_jUnused20;
// Store the transform matrix.
if ( !bInitXform(pfc, FONTOBJ_pxoGetXform(pfo)) )
{
WARNING("vtfdOpenFontContext transform out of range\n");
if (pff->cRef == 0)
{
EngUnmapFontFileFD(pff->iFile);
}
vFree(pfc);
return(HFC_INVALID);
}
// State that the hff passed to this function is the FF selected in
// this font context.
pfc->pff = pff;
(pff->cRef)++;
return((HFC)pfc);
}
/******************************Public*Routine******************************\
* vtfdDestroyFont
*
* Driver can release all resources associated with this font realization
* (embodied in the FONTOBJ).
*
* History:
* 02-Sep-1992 -by- Gilman Wong [gilmanw]
* Wrote it.
\**************************************************************************/
VOID
vtfdDestroyFont (
FONTOBJ *pfo
)
{
//
// For the vector font driver, this is simply closing the font context.
// We cleverly store the font context handle in the FONTOBJ pvProducer
// field.
//
EngAcquireSemaphore(ghsemVTFD);
vtfdCloseFontContext((HFC) pfo->pvProducer);
EngReleaseSemaphore(ghsemVTFD);
}
/******************************Public*Routine******************************\
* BOOL vtfdCloseFontContext
*
* Close the font context and update the context link for the associated
* font file.
*
* History:
* 27-Feb-1992 -by- Wendy Wu [wendywu]
* Adapted from bmfd.
\**************************************************************************/
BOOL vtfdCloseFontContext(HFC hfc)
{
BOOL bRet;
if (hfc != HFC_INVALID)
{
//
// decrement the reference count for the corresponding FONTFILE
//
if (PFC(hfc)->pff->cRef > 0L)
{
(PFC(hfc)->pff->cRef)--;
//
// if this file is going out of use we can close it to save memory
//
if (PFC(hfc)->pff->cRef == 0L)
{
// if FF_EXCEPTION_IN_PAGE_ERROR is set
// and the font type is TYPE_FNT or TYPE_DLL16
// the font file must have been unmapped in vVtfdMarkFontGone
if (!(PFC(hfc)->pff->fl & FF_EXCEPTION_IN_PAGE_ERROR) ||
!((PFC(hfc)->pff->iType == TYPE_FNT) || (PFC(hfc)->pff->iType == TYPE_DLL16)))
{
EngUnmapFontFileFD(PFC(hfc)->pff->iFile);
}
PFC(hfc)->pff->fl &= ~FF_EXCEPTION_IN_PAGE_ERROR;
}
//
// free the memory associated with hfc
//
vFree(PFC(hfc));
bRet = TRUE;
}
else
{
WARNING("vtfdCloseFontContext: cRef <= 0\n");
bRet = FALSE;
}
}
else
{
bRet = FALSE;
}
return bRet;
}