|
|
/******************************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; }
|