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.
595 lines
14 KiB
595 lines
14 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: fdfc.c
|
|
*
|
|
* functions that deal with font contexts
|
|
*
|
|
* Created: 08-Nov-1990 12:42:34
|
|
* Author: Bodin Dresevic [BodinD]
|
|
*
|
|
* Copyright (c) 1990 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include "fd.h"
|
|
|
|
#define MAX_HORZ_SCALE 5
|
|
#define MAX_VERT_SCALE 255
|
|
|
|
#ifdef FE_SB // ROTATION: ulGetRotate() function body
|
|
|
|
/******************************Private*Routine*****************************\
|
|
*
|
|
* VOID vComputeRotatedXform()
|
|
*
|
|
* History :
|
|
*
|
|
* 14-Feb-1993 -By- Hideyuki Nagase [HideyukN]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID
|
|
vComputeRotatedXform
|
|
(
|
|
POINTL *pptlScale,
|
|
LONG lXscale ,
|
|
LONG lYscale
|
|
)
|
|
{
|
|
|
|
// If the caling factor is 0 , We have to set it to 1 for avoiding overflow
|
|
|
|
if( lXscale == 0L )
|
|
{
|
|
pptlScale->x = 1L;
|
|
}
|
|
else
|
|
{
|
|
pptlScale->x = lXscale;
|
|
|
|
if( pptlScale->x < 0 )
|
|
pptlScale->x = -(pptlScale->x);
|
|
|
|
if( pptlScale->x > MAX_HORZ_SCALE )
|
|
pptlScale->x = MAX_HORZ_SCALE;
|
|
}
|
|
|
|
if( lYscale == 0L )
|
|
{
|
|
pptlScale->y = 1L;
|
|
}
|
|
else
|
|
{
|
|
pptlScale->y = lYscale;
|
|
|
|
if( pptlScale->y < 0 )
|
|
pptlScale->y = -(pptlScale->y);
|
|
|
|
if( pptlScale->y > MAX_VERT_SCALE )
|
|
pptlScale->y = MAX_VERT_SCALE;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* ULONG ulGetRotate()
|
|
*
|
|
* Effects:
|
|
*
|
|
* Warnings:
|
|
*
|
|
* History:
|
|
*
|
|
* 8-Feb-1993 -by- Hideyuki Nagase [HideyukN]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
ULONG ulGetRotate( POINTL *pptlScale , XFORMOBJ *pxo )
|
|
{
|
|
EFLOAT efXX , efXY , efYX , efYY;
|
|
LONG lXX , lXY , lYX , lYY;
|
|
XFORML xform;
|
|
|
|
// Get the transform elements.
|
|
|
|
XFORMOBJ_iGetXform(pxo,&xform);
|
|
|
|
// Convert elements of the matrix from IEEE float to our EFLOAT.
|
|
|
|
vEToEF(xform.eM11 , &efXX );
|
|
vEToEF(xform.eM12 , &efXY );
|
|
vEToEF(xform.eM21 , &efYX );
|
|
vEToEF(xform.eM22 , &efYY );
|
|
|
|
// Convert these from EFLOAT to LONG
|
|
|
|
if( !bEFtoL( &efXX , &lXX ) ||
|
|
!bEFtoL( &efXY , &lXY ) ||
|
|
!bEFtoL( &efYX , &lYX ) ||
|
|
!bEFtoL( &efYY , &lYY )
|
|
)
|
|
{
|
|
WARNING("BMFD!bEToEF() fail\n");
|
|
vComputeRotatedXform( pptlScale , MAX_HORZ_SCALE , MAX_VERT_SCALE );
|
|
return( 0L );
|
|
}
|
|
|
|
// Check transform.
|
|
|
|
//
|
|
// 0 ' 180 '
|
|
//
|
|
// ( 1 0 )(X) = ( X) ( -1 0 )(X) = (-X) ( XX XY )(X)
|
|
// ( 0 1 )(Y) ( Y) ( 0 -1 )(Y) (-Y) ( YX YY )(Y)
|
|
//
|
|
// 90 ' 270 '
|
|
//
|
|
// ( 0 -1 )(X) = (-Y) ( 0 1 )(X) = ( Y)
|
|
// ( 1 0 )(Y) ( X) ( -1 0 )(Y) (-X)
|
|
//
|
|
|
|
#ifdef FIREWALLS_MORE
|
|
DbgPrint(" XX = %ld , XY = %ld\n" , lXX , lXY );
|
|
DbgPrint(" YX = %ld , YY = %ld\n" , lYX , lYY );
|
|
#endif // FIREWALLS_MORE
|
|
|
|
if ( ( lXX > 0 && lXY == 0 ) &&
|
|
( lYX == 0 && lYY > 0 ) )
|
|
{
|
|
|
|
// We have to Rotate bitmap image to 0 degree
|
|
|
|
// Compute X Y scaling factor
|
|
|
|
vComputeRotatedXform( pptlScale , lXX , lYY );
|
|
return( 0L );
|
|
}
|
|
else if ( ( lXX == 0 && lXY < 0 ) &&
|
|
( lYX > 0 && lYY == 0 ) )
|
|
{
|
|
vComputeRotatedXform( pptlScale , lXY , lYX );
|
|
return( 900L );
|
|
}
|
|
else if ( ( lXX < 0 && lXY == 0 ) &&
|
|
( lYX == 0 && lYY < 0 ) )
|
|
{
|
|
vComputeRotatedXform( pptlScale , lXX , lYY );
|
|
return( 1800L );
|
|
}
|
|
else if ( ( lXX == 0 && lXY > 0 ) &&
|
|
( lYX < 0 && lYY == 0 ) )
|
|
{
|
|
vComputeRotatedXform( pptlScale , lXY , lYX );
|
|
return( 2700L );
|
|
}
|
|
|
|
//
|
|
// we are here because:
|
|
// 1) we are asked to handle arbitrary rotation. ( this should not happen )
|
|
// 2) lXX == lXY == lYX == lYY == 0
|
|
//
|
|
// we choose default transformation
|
|
//
|
|
|
|
vComputeRotatedXform( pptlScale , 1L , 1L );
|
|
|
|
#ifdef FIREWALLS_MORE
|
|
WARNING("Bmfd:ulGetRatate():Use default transform ( ulRotate = 0 )\n");
|
|
#endif // FIREWALLS_MORE
|
|
|
|
return( 0L );
|
|
}
|
|
|
|
#endif // FE_SB
|
|
|
|
|
|
#ifndef FE_SB // We use vComputeRotatedXform() instead of vInitXform()
|
|
|
|
/******************************Private*Routine*****************************\
|
|
* VOID vInitXform
|
|
*
|
|
* Initialize the coefficients of the transforms for the given font context.
|
|
* It also transforms and saves various measurements of the font in the
|
|
* context.
|
|
*
|
|
* Mon 01-Feb-1993 -by- Bodin Dresevic [BodinD]
|
|
* update: changed it to return data into pptlScale
|
|
*
|
|
\**************************************************************************/
|
|
|
|
|
|
|
|
VOID vInitXform(POINTL * pptlScale , XFORMOBJ *pxo)
|
|
{
|
|
EFLOAT efloat;
|
|
XFORM xfm;
|
|
|
|
// Get the transform elements.
|
|
|
|
XFORMOBJ_iGetXform(pxo, &xfm);
|
|
|
|
// Convert elements of the matrix from IEEE float to our EFLOAT.
|
|
|
|
vEToEF(xfm.eM11, &efloat);
|
|
|
|
// If we overflow set to the maximum scaling factor
|
|
|
|
if( !bEFtoL( &efloat, &pptlScale->x ) )
|
|
pptlScale->x = MAX_HORZ_SCALE;
|
|
else
|
|
{
|
|
// Ignore the sign of the scale
|
|
|
|
if( pptlScale->x == 0 )
|
|
{
|
|
pptlScale->x = 1;
|
|
}
|
|
else
|
|
{
|
|
if( pptlScale->x < 0 )
|
|
pptlScale->x = -pptlScale->x;
|
|
|
|
|
|
if( pptlScale->x > MAX_HORZ_SCALE )
|
|
pptlScale->x = MAX_HORZ_SCALE;
|
|
}
|
|
}
|
|
|
|
vEToEF(xfm.eM22, &efloat);
|
|
|
|
if( !bEFtoL( &efloat, &pptlScale->y ) )
|
|
pptlScale->y = MAX_VERT_SCALE;
|
|
else
|
|
{
|
|
// Ignore the sign of the scale
|
|
|
|
if( pptlScale->y == 0 )
|
|
{
|
|
pptlScale->y = 1;
|
|
}
|
|
else
|
|
{
|
|
if( pptlScale->y < 0 )
|
|
pptlScale->y = -pptlScale->y;
|
|
|
|
if( pptlScale->y > MAX_VERT_SCALE )
|
|
pptlScale->y = MAX_VERT_SCALE;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BmfdOpenFontContext
|
|
*
|
|
* History:
|
|
* 19-Nov-1990 -by- Bodin Dresevic [BodinD]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
HFC
|
|
BmfdOpenFontContext (
|
|
FONTOBJ *pfo
|
|
)
|
|
{
|
|
PFONTFILE pff;
|
|
FACEINFO *pfai;
|
|
FONTCONTEXT *pfc = (FONTCONTEXT *)NULL;
|
|
PCVTFILEHDR pcvtfh;
|
|
ULONG cxMax;
|
|
ULONG cjGlyphMax;
|
|
POINTL ptlScale;
|
|
PVOID pvView;
|
|
COUNT cjView;
|
|
ULONG cjfc = offsetof(FONTCONTEXT,ajStretchBuffer);
|
|
FLONG flStretch;
|
|
#ifdef FE_SB
|
|
ULONG cxMaxNoRotate;
|
|
ULONG cjGlyphMaxNoRotate;
|
|
ULONG cyMax;
|
|
ULONG ulRotate;
|
|
#endif // FE_SB
|
|
|
|
#ifdef DUMPCALL
|
|
DbgPrint("\nBmfdOpenFontContext(");
|
|
DbgPrint("\n FONTOBJ *pfo = %-#8lx", pfo);
|
|
DbgPrint("\n )\n");
|
|
#endif
|
|
|
|
if ( ((HFF) pfo->iFile) == HFF_INVALID)
|
|
return(HFC_INVALID);
|
|
|
|
pff = PFF((HFF) pfo->iFile);
|
|
|
|
if ((pfo->iFace < 1L) || (pfo->iFace > pff->cFntRes)) // pfo->iFace values are 1 based
|
|
return(HFC_INVALID);
|
|
|
|
pfai = &pff->afai[pfo->iFace - 1];
|
|
pcvtfh = &(pfai->cvtfh);
|
|
|
|
if ((pfo->flFontType & FO_SIM_BOLD) && (pfai->pifi->fsSelection & FM_SEL_BOLD))
|
|
return HFC_INVALID;
|
|
if ((pfo->flFontType & FO_SIM_ITALIC) && (pfai->pifi->fsSelection & FM_SEL_ITALIC))
|
|
return HFC_INVALID;
|
|
|
|
#ifdef FE_SB // BmfdOpenFontContext():Get Rotate and compute XY scaling
|
|
|
|
// get rotation ( 0 , 900 , 1800 or 2700 )
|
|
// And we compute horizontal and vertical scaling factors
|
|
|
|
ulRotate = ulGetRotate( &ptlScale , FONTOBJ_pxoGetXform(pfo));
|
|
|
|
#else // We compute horizontal and vertical scaling facter in above function.
|
|
|
|
// compute the horizontal and vertical scaling factors
|
|
|
|
vInitXform(&ptlScale, FONTOBJ_pxoGetXform(pfo));
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef FE_SB // BmfdOpenFontConText(): Compute cjGlyphMax
|
|
|
|
// Compute cjGlyphMax of Rotated font
|
|
|
|
cjGlyphMaxNoRotate =
|
|
cjGlyphDataSimulated(
|
|
pfo,
|
|
(ULONG)pcvtfh->usMaxWidth * ptlScale.x,
|
|
(ULONG)pcvtfh->cy * ptlScale.y,
|
|
&cxMaxNoRotate,
|
|
0L);
|
|
|
|
// In Y axis, We do not have to consider font simulation.
|
|
|
|
cyMax = (ULONG)pcvtfh->cy * ptlScale.y;
|
|
|
|
if( ( ulRotate == 0L ) || ( ulRotate == 1800L ) )
|
|
{
|
|
|
|
// In the case of 0 or 180 degree.
|
|
|
|
cjGlyphMax = cjGlyphMaxNoRotate;
|
|
cxMax = cxMaxNoRotate;
|
|
}
|
|
else
|
|
{
|
|
|
|
// In the case of 90 or 270 degree.
|
|
// Compute simulated and rotated cjGlyphMax.
|
|
|
|
cjGlyphMax =
|
|
cjGlyphDataSimulated(
|
|
pfo,
|
|
(ULONG)pcvtfh->usMaxWidth * ptlScale.x,
|
|
(ULONG)pcvtfh->cy * ptlScale.y,
|
|
NULL,
|
|
ulRotate);
|
|
|
|
cxMax = cyMax;
|
|
}
|
|
|
|
#ifdef DBG_MORE
|
|
DbgPrint("clGlyphMax - 0x%x\n",cjGlyphMax);
|
|
#endif
|
|
|
|
#else
|
|
cjGlyphMax =
|
|
cjGlyphDataSimulated(
|
|
pfo,
|
|
(ULONG)pcvtfh->usMaxWidth * ptlScale.x,
|
|
(ULONG)pcvtfh->cy * ptlScale.y,
|
|
&cxMax);
|
|
#endif
|
|
|
|
// init stretch flags
|
|
|
|
flStretch = 0;
|
|
if ((ptlScale.x != 1) || (ptlScale.y != 1))
|
|
{
|
|
#ifdef FE_SB // BmfdOpenFontContext() Adjust stretch buffer
|
|
ULONG cjScan = CJ_SCAN(cxMaxNoRotate);
|
|
#else
|
|
ULONG cjScan = CJ_SCAN(cxMax); // cj of the stretch buffer
|
|
#endif
|
|
|
|
flStretch |= FC_DO_STRETCH;
|
|
|
|
if (cjScan > CJ_STRETCH) // will use the one at the bottom of FC
|
|
{
|
|
cjfc += cjScan;
|
|
flStretch |= FC_STRETCH_WIDE;
|
|
}
|
|
}
|
|
|
|
// allocate memory for the font context and get the pointer to font context
|
|
// NOTE THAT WE ARE NOT TOUCHING THE MEMORY MAPPED FILE AFTER WE ALLOCATE MEMORY
|
|
// IN THIS ROUTINE. GOOD CONSEQUENCE OF THIS IS THAT NO SPECIAL CLEAN UP
|
|
// CODE IS NECESSARY TO FREE THAT MEMORY, IT WILL GET CLEANED WHEN
|
|
// CloseFontContext is called [bodind]
|
|
|
|
if (!(pfc = PFC(hfcAlloc(cjfc))))
|
|
{
|
|
SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY);
|
|
return(HFC_INVALID);
|
|
}
|
|
|
|
pfc->ident = ID_FONTCONTEXT;
|
|
|
|
// state that the hff passed to this function is the FF selected in
|
|
// this font context
|
|
|
|
pfc->hff = (HFF) pfo->iFile;
|
|
pfc->pfai = pfai;
|
|
pfc->flFontType = pfo->flFontType;
|
|
pfc->ptlScale = ptlScale;
|
|
pfc->flStretch = flStretch;
|
|
pfc->cxMax = cxMax;
|
|
pfc->cjGlyphMax = cjGlyphMax;
|
|
#ifdef FE_SB // BmfdOpenFontContext() keep rotation degree in FONTCONTEXT
|
|
pfc->ulRotate = ulRotate;
|
|
#endif // FE_SB
|
|
|
|
// increase the reference count of the font file
|
|
// ONLY AFTER WE ARE SURE THAT WE CAN NOT FAIL ANY MORE
|
|
// make sure that another thread is not doing it at the same time
|
|
// opening another context off of the same fontfile pff
|
|
|
|
EngAcquireSemaphore(ghsemBMFD);
|
|
|
|
// if this is the first font context corresponding to this font file
|
|
// and then we have to remap file to memory and make sure the pointers
|
|
// to FNT resources are updated accordingly
|
|
|
|
if (pff->cRef == 0)
|
|
{
|
|
INT i;
|
|
|
|
if (!EngMapFontFileFD(pff->iFile, (PULONG *) &pvView, &cjView))
|
|
{
|
|
WARNING("BMFD!somebody removed that bm font file!!!\n");
|
|
|
|
EngReleaseSemaphore(ghsemBMFD);
|
|
VFREEMEM(pfc);
|
|
return HFC_INVALID;
|
|
}
|
|
|
|
for (i = 0; i < (INT)pff->cFntRes; i++)
|
|
{
|
|
pff->afai[i].re.pvResData = (PVOID) (
|
|
(BYTE*)pvView + pff->afai[i].re.dpResData
|
|
);
|
|
}
|
|
}
|
|
|
|
// now can not fail, update cRef
|
|
|
|
(pff->cRef)++;
|
|
EngReleaseSemaphore(ghsemBMFD);
|
|
|
|
return((HFC)pfc);
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BmfdDestroyFont
|
|
*
|
|
* Driver can release all resources associated with this font realization
|
|
* (embodied in the FONTOBJ).
|
|
*
|
|
* History:
|
|
* 30-Aug-1992 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID
|
|
BmfdDestroyFont (
|
|
FONTOBJ *pfo
|
|
)
|
|
{
|
|
//
|
|
// For the bitmap font driver, this is simply closing the font context.
|
|
// We cleverly store the font context handle in the FONTOBJ pvProducer
|
|
// field.
|
|
//
|
|
|
|
// This pvProducer could be null if exception occured while
|
|
// trying to create fc
|
|
|
|
if (pfo->pvProducer)
|
|
{
|
|
BmfdCloseFontContext((HFC) pfo->pvProducer);
|
|
pfo->pvProducer = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BmfdCloseFontContext
|
|
*
|
|
* History:
|
|
* 19-Nov-1990 -by- Bodin Dresevic [BodinD]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL
|
|
BmfdCloseFontContext (
|
|
HFC hfc
|
|
)
|
|
{
|
|
PFONTFILE pff;
|
|
BOOL bRet;
|
|
|
|
if (hfc != HFC_INVALID)
|
|
{
|
|
//
|
|
// get the handle of the font file that is selected into this FONTCONTEXT
|
|
// get the pointer to the FONTFILE
|
|
//
|
|
|
|
pff = PFF(PFC(hfc)->hff);
|
|
|
|
// decrement the reference count for the corresponding FONTFILE
|
|
// make sure that another thread is not doing it at the same time
|
|
// closing another context off of the same fontfile pff
|
|
|
|
EngAcquireSemaphore(ghsemBMFD);
|
|
|
|
if (pff->cRef > 0L)
|
|
{
|
|
(pff->cRef)--;
|
|
|
|
//
|
|
// if this file is temporarily going out of use, unmap it
|
|
//
|
|
|
|
if (pff->cRef == 0)
|
|
{
|
|
if (!(pff->fl & FF_EXCEPTION_IN_PAGE_ERROR))
|
|
{
|
|
// if FF_EXCEPTION_IN_PAGE_ERROR is set
|
|
// the file should have been unmapped
|
|
// in vBmfdMarkFontGone function
|
|
|
|
EngUnmapFontFileFD(pff->iFile);
|
|
}
|
|
pff->fl &= ~FF_EXCEPTION_IN_PAGE_ERROR;
|
|
}
|
|
|
|
|
|
// free the memory associated with hfc
|
|
|
|
VFREEMEM(hfc);
|
|
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
WARNING("BmfdCloseFontContext: cRef <= 0\n");
|
|
bRet = FALSE;
|
|
}
|
|
|
|
EngReleaseSemaphore(ghsemBMFD);
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|