Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

961 lines
27 KiB

/****************************** Module Header ******************************\
* Module Name: Scale.c
*
* Created: 16-Oct-1992
*
* Copyright: (c) 1987-1990, 1992 by Apple Computer, Inc., all rights reserved.
* (c) 1989-1993. Microsoft Corporation.
*
* All Rights Reserved
*
* History:
* Tue 16-Oct-1992 09:53:51 -by- Greg Hitchcock [gregh]
* Created.
\***************************************************************************/
// added by bodind, speed optimization
#include "nt.h"
#include "ntrtl.h"
/* INCLUDES */
#include "fserror.h"
#include "fscdefs.h"
#include "fontmath.h"
#include "fnt.h"
#include "scale.h"
#include "stat.h"
/* Constants */
/* use the lower ones for public phantom points */
/* public phantom points start here */
#define LEFTSIDEBEARING 0
#define RIGHTSIDEBEARING 1
/* private phantom points start here */
#define ORIGINPOINT 2
#define LEFTEDGEPOINT 3
#define CANTAKESHIFT 0x02000000
/* MACROS */
/* d is half of the denumerator */
#define FROUND( x, n, d, s ) \
((SHORTMUL (x, n) + (d)) >> s)
#define SROUND( x, n, d, halfd ) \
(x < 0 ? -((SHORTMUL (-(x), (n)) + (halfd)) / (d)) : ((SHORTMUL ((x), (n)) + (halfd)) / (d)))
#define NUMBEROFCHARPOINTS(pElement) (uint16)(pElement->ep[pElement->nc - 1] + 1)
#define NUMBEROFTOTALPOINTS(pElement) (uint16)(pElement->ep[pElement->nc - 1] + 1 + PHANTOMCOUNT)
#define LSBPOINTNUM(pElement) (uint16)(pElement->ep[pElement->nc - 1] + 1 + LEFTSIDEBEARING)
#define RSBPOINTNUM(pElement) (uint16)(pElement->ep[pElement->nc - 1] + 1 + RIGHTSIDEBEARING)
#define ORIGINPOINTNUM(pElement) (uint16)(pElement->ep[pElement->nc - 1] + 1 + ORIGINPOINT)
#define LEFTEDGEPOINTNUM(pElement) (uint16)(pElement->ep[pElement->nc - 1] + 1 + LEFTEDGEPOINT)
/* PROTOTYPES */
FS_PRIVATE GlobalGSScaleFunc scl_ComputeScaling(fnt_ScaleRecord* rec, Fixed N, Fixed D);
FS_PRIVATE F26Dot6 scl_FRound (fnt_ScaleRecord* rec, F26Dot6 value);
FS_PRIVATE F26Dot6 scl_SRound (fnt_ScaleRecord* rec, F26Dot6 value);
FS_PRIVATE F26Dot6 scl_FixRound (fnt_ScaleRecord* rec, F26Dot6 value);
FS_PRIVATE void scl_ShiftOldPoints (
fnt_ElementType * pElement,
F26Dot6 fxXShift,
F26Dot6 fxYShift,
uint16 usFirstPoint,
uint16 usNumPoints);
FS_PRIVATE void scl_Scale (
fnt_ScaleRecord * sr,
GlobalGSScaleFunc ScaleFunc,
F26Dot6 * oop,
F26Dot6 * p,
int32 numPts);
/* FUNCTIONS */
FS_PUBLIC ErrorCode scl_InitializeScaling(
void * pvGlobalGS, /* GlobalGS */
boolean bIntegerScaling, /* Integer Scaling Flag */
transMatrix * trans, /* Current Transformation */
uint16 usUpem, /* Current units per Em */
Fixed fxPointSize, /* Current point size */
int16 sXResolution, /* Current X Resolution */
int16 sYResolution, /* Current Y Resolution */
uint32 * pulPixelsPerEm) /* OUT: Pixels Per Em */
{
Fixed maxScale;
Fixed fxUpem;
fnt_GlobalGraphicStateType * globalGS;
globalGS = (fnt_GlobalGraphicStateType *)pvGlobalGS;
mth_FoldPointSizeResolution(fxPointSize, sXResolution, sYResolution, trans);
mth_ReduceMatrix (trans);
fxUpem = INTTOFIX(usUpem);
/*
* First set up the scalars...
*/
globalGS->interpScalarX = mth_max_abs (trans->transform[0][0], trans->transform[0][1]);
globalGS->interpScalarY = mth_max_abs (trans->transform[1][0], trans->transform[1][1]);
globalGS->fxMetricScalarX = globalGS->interpScalarX;
globalGS->fxMetricScalarY = globalGS->interpScalarY;
if (bIntegerScaling)
{
globalGS->interpScalarX = (Fixed)ROUNDFIXED(globalGS->interpScalarX);
globalGS->interpScalarY = (Fixed)ROUNDFIXED(globalGS->interpScalarY);
}
globalGS->ScaleFuncX = scl_ComputeScaling(&globalGS->scaleX, globalGS->interpScalarX, fxUpem);
globalGS->ScaleFuncY = scl_ComputeScaling(&globalGS->scaleY, globalGS->interpScalarY, fxUpem);
if (globalGS->interpScalarX >= globalGS->interpScalarY)
{
globalGS->ScaleFuncCVT = globalGS->ScaleFuncX;
globalGS->scaleCVT = globalGS->scaleX;
globalGS->cvtStretchX = ONEFIX;
globalGS->cvtStretchY = FixDiv(globalGS->interpScalarY, globalGS->interpScalarX);;
maxScale = globalGS->interpScalarX;
}
else
{
globalGS->ScaleFuncCVT = globalGS->ScaleFuncY;
globalGS->scaleCVT = globalGS->scaleY;
globalGS->cvtStretchX = FixDiv(globalGS->interpScalarX, globalGS->interpScalarY);
globalGS->cvtStretchY = ONEFIX;
maxScale = globalGS->interpScalarY;
}
*pulPixelsPerEm = (uint32)ROUNDFIXTOINT (globalGS->interpScalarY);
globalGS->bSameStretch = (uint8)mth_SameStretch( globalGS->interpScalarX, globalGS->interpScalarY );
globalGS->pixelsPerEm = (uint16)ROUNDFIXTOINT(maxScale);
globalGS->pointSize = (uint16)ROUNDFIXTOINT( fxPointSize );
globalGS->fpem = maxScale;
globalGS->identityTransformation = (int8)mth_PositiveSquare( trans );
/* Use bit 1 of non90degreeTransformation to signify stretching. stretch = 2 */
globalGS->non90DegreeTransformation = (int8)(mth_GeneralRotation( trans ) & NON90DEGTRANS_ROTATED);
if( !mth_PositiveSquare( trans ))
{
globalGS->non90DegreeTransformation |= NON90DEGTRANS_STRETCH;
}
return NO_ERR;
}
/******************** These three scale 26.6 to 26.6 ********************/
/*
* Fast (scaling)
*/
FS_PRIVATE F26Dot6 scl_FRound(fnt_ScaleRecord* rec, F26Dot6 value)
{
return (F26Dot6) FROUND (value, rec->numer, rec->denom >> 1, rec->shift);
}
/*
* Medium (scaling)
*/
FS_PRIVATE F26Dot6 scl_SRound(fnt_ScaleRecord* rec, F26Dot6 value)
{
int32 D;
D = rec->denom;
return (F26Dot6) SROUND (value, rec->numer, D, D >> 1);
}
/*
* Fixed Rounding (scaling), really slow
*/
FS_PRIVATE F26Dot6 scl_FixRound(fnt_ScaleRecord* rec, F26Dot6 value)
{
return (F26Dot6) FixMul ((Fixed)value, rec->fixedScale);
}
/********************************* End scaling utilities ************************/
FS_PRIVATE GlobalGSScaleFunc scl_ComputeScaling(fnt_ScaleRecord* rec, Fixed N, Fixed D)
{
int32 lShift;
lShift = mth_CountLowZeros((uint32)(N | D) ) - 1;
if (lShift > 0)
{
N >>= lShift;
D >>= lShift;
}
if ( N < CANTAKESHIFT )
{
N <<= FNT_PIXELSHIFT;
}
else
{
D >>= FNT_PIXELSHIFT;
}
if (N <= SHRT_MAX) /* Check to see if N fits in a short */
{
lShift = mth_GetShift ((uint32) D);
rec->numer = (int32)N;
rec->denom = (int32)D;
if ( lShift >= 0 ) /* FAST SCALE */
{
rec->shift = (int32)lShift;
return scl_FRound;
}
else /* MEDIUM SCALE */
{
return scl_SRound;
}
}
else /* SLOW SCALE */
{
rec->fixedScale = FixDiv(N, D);
return scl_FixRound;
}
}
FS_PRIVATE void scl_Scale (
fnt_ScaleRecord * sr,
GlobalGSScaleFunc ScaleFunc,
F26Dot6 * oop,
F26Dot6 * p,
int32 numPts)
{
int32 Index;
if (ScaleFunc == scl_FRound)
{
for(Index = 0; Index < numPts; Index++)
{
p[Index] = (F26Dot6) FROUND (oop[Index], sr->numer, sr->denom >> 1, sr->shift);
}
}
else
{
if (ScaleFunc == scl_SRound)
{
for(Index = 0; Index < numPts; Index++)
{
p[Index] = (F26Dot6) SROUND (oop[Index], sr->numer, sr->denom, sr->denom >> 1);
}
}
else
{
for(Index = 0; Index < numPts; Index++)
{
p[Index] = (F26Dot6) FixMul ((Fixed)oop[Index], sr->fixedScale);
}
}
}
}
/*
* scl_ScaleChar <3>
*
* Scales a character
*/
FS_PUBLIC void scl_ScaleOldCharPoints (
fnt_ElementType * pElement, /* Element */
void * pvGlobalGS) /* GlobalGS */
{
fnt_GlobalGraphicStateType * globalGS;
globalGS = (fnt_GlobalGraphicStateType *)pvGlobalGS;
scl_Scale (&globalGS->scaleX,
globalGS->ScaleFuncX,
pElement->oox,
pElement->ox,
(int32)NUMBEROFCHARPOINTS(pElement));
scl_Scale (&globalGS->scaleY,
globalGS->ScaleFuncY,
pElement->ooy,
pElement->oy,
(int32)NUMBEROFCHARPOINTS(pElement));
}
FS_PUBLIC void scl_ScaleOldPhantomPoints (
fnt_ElementType * pElement, /* Element */
void * pvGlobalGS) /* GlobalGS */
{
uint16 usFirstPhantomPoint;
fnt_GlobalGraphicStateType * globalGS;
globalGS = (fnt_GlobalGraphicStateType *)pvGlobalGS;
usFirstPhantomPoint = LSBPOINTNUM(pElement);
scl_Scale (&globalGS->scaleX,
globalGS->ScaleFuncX,
&(pElement->oox[usFirstPhantomPoint]),
&(pElement->ox[usFirstPhantomPoint]),
(int32)PHANTOMCOUNT);
scl_Scale (&globalGS->scaleY,
globalGS->ScaleFuncY,
&(pElement->ooy[usFirstPhantomPoint]),
&(pElement->oy[usFirstPhantomPoint]),
(int32)PHANTOMCOUNT);
}
/*
* scl_ScaleCVT
*/
FS_PUBLIC void scl_ScaleCVT(
void * pvGlobalGS,
F26Dot6 * pfxCVT)
{
fnt_GlobalGraphicStateType * globalGS;
globalGS = (fnt_GlobalGraphicStateType *)pvGlobalGS;
if(globalGS->cvtCount > 0)
{
scl_Scale (
&globalGS->scaleCVT,
globalGS->ScaleFuncCVT,
pfxCVT,
globalGS->controlValueTable,
(int32)globalGS->cvtCount);
}
}
FS_PUBLIC void scl_GetCVTPtr(
void * pvGlobalGS,
F26Dot6 ** pfxCVT)
{
fnt_GlobalGraphicStateType * globalGS;
globalGS = (fnt_GlobalGraphicStateType *)pvGlobalGS;
*pfxCVT = globalGS->controlValueTable;
}
FS_PUBLIC void scl_CalcOrigPhantomPoints(
fnt_ElementType * pElement, /* Element */
BBOX * bbox, /* Bounding Box */
int16 sNonScaledLSB, /* Non-scaled Left Side Bearing */
uint16 usNonScaledAW) /* Non-scaled Advance Width */
{
F26Dot6 fxXMinMinusLSB;
MEMSET (&(pElement->ooy[LSBPOINTNUM(pElement)]),
'\0',
PHANTOMCOUNT * sizeof (pElement->ooy[0]));
fxXMinMinusLSB = ((F26Dot6)bbox->xMin - (F26Dot6)sNonScaledLSB);
pElement->oox[LSBPOINTNUM(pElement)] = fxXMinMinusLSB;
pElement->oox[RSBPOINTNUM(pElement)] = fxXMinMinusLSB + (F26Dot6)usNonScaledAW;
pElement->oox[ORIGINPOINTNUM(pElement)] = fxXMinMinusLSB;
pElement->oox[LEFTEDGEPOINTNUM(pElement)] = (F26Dot6)bbox->xMin;
}
FS_PUBLIC void scl_AdjustOldCharSideBearing(
fnt_ElementType * pElement) /* Element */
{
F26Dot6 fxOldLeftOrigin;
F26Dot6 fxNewLeftOrigin;
uint16 cNumCharPoints;
cNumCharPoints = NUMBEROFCHARPOINTS(pElement);
fxOldLeftOrigin = pElement->ox[LSBPOINTNUM(pElement)];
fxNewLeftOrigin = fxOldLeftOrigin;
fxNewLeftOrigin += FNT_PIXELSIZE/2; /* round to a pixel boundary */
fxNewLeftOrigin &= ~(FNT_PIXELSIZE - 1);
scl_ShiftOldPoints (
pElement,
fxNewLeftOrigin - fxOldLeftOrigin,
0L,
0,
cNumCharPoints);
}
FS_PUBLIC void scl_AdjustOldPhantmSideBearing(
fnt_ElementType * pElement) /* Element */
{
F26Dot6 fxOldLeftOrigin;
F26Dot6 fxNewLeftOrigin;
fxOldLeftOrigin = pElement->ox[LSBPOINTNUM(pElement)];
fxNewLeftOrigin = fxOldLeftOrigin;
fxNewLeftOrigin += FNT_PIXELSIZE/2; /* round to a pixel boundary */
fxNewLeftOrigin &= ~(FNT_PIXELSIZE - 1);
scl_ShiftOldPoints (
pElement,
fxNewLeftOrigin - fxOldLeftOrigin,
0L,
LSBPOINTNUM(pElement),
PHANTOMCOUNT);
}
FS_PUBLIC void scl_AdjustOldSideBearingPoints(
fnt_ElementType * pElement) /* Element */
{
F26Dot6 fxOldLeftOrigin;
F26Dot6 fxNewLeftOrigin;
fxOldLeftOrigin = pElement->ox[LSBPOINTNUM(pElement)];
fxNewLeftOrigin = fxOldLeftOrigin;
fxNewLeftOrigin += FNT_PIXELSIZE/2; /* round to a pixel boundary */
fxNewLeftOrigin &= ~(FNT_PIXELSIZE - 1);
pElement->ox[LSBPOINTNUM(pElement)] = fxNewLeftOrigin;
pElement->ox[RSBPOINTNUM(pElement)] += fxNewLeftOrigin - fxOldLeftOrigin;
}
FS_PUBLIC void scl_CopyOldCharPoints(
fnt_ElementType * pElement) /* Element */
{
MEMCPY(pElement->ox, pElement->x, (size_t)NUMBEROFCHARPOINTS(pElement) * sizeof(F26Dot6));
MEMCPY(pElement->oy, pElement->y, (size_t)NUMBEROFCHARPOINTS(pElement) * sizeof(F26Dot6));
}
FS_PUBLIC void scl_CopyCurrentCharPoints(
fnt_ElementType * pElement) /* Element */
{
MEMCPY(pElement->x, pElement->ox, (size_t)NUMBEROFCHARPOINTS(pElement) * sizeof(F26Dot6));
MEMCPY(pElement->y, pElement->oy, (size_t)NUMBEROFCHARPOINTS(pElement) * sizeof(F26Dot6));
}
FS_PUBLIC void scl_CopyCurrentPhantomPoints(
fnt_ElementType * pElement) /* Element */
{
uint16 usFirstPhantomPoint;
usFirstPhantomPoint = LSBPOINTNUM(pElement);
MEMCPY(&pElement->x[usFirstPhantomPoint],
&pElement->ox[usFirstPhantomPoint],
PHANTOMCOUNT * sizeof(F26Dot6));
MEMCPY(&pElement->y[usFirstPhantomPoint],
&pElement->oy[usFirstPhantomPoint],
PHANTOMCOUNT * sizeof(F26Dot6));
}
FS_PUBLIC void scl_RoundCurrentSideBearingPnt(
fnt_ElementType * pElement, /* Element */
void * pvGlobalGS, /* GlobalGS */
uint16 usEmResolution)
{
F26Dot6 fxWidth;
fnt_GlobalGraphicStateType * globalGS;
globalGS = (fnt_GlobalGraphicStateType *)pvGlobalGS;
/* autoround the right side bearing */
fxWidth = FIXEDTODOT6 (ShortMulDiv( (int32)globalGS->interpScalarX,
(int16)(pElement->oox[RSBPOINTNUM(pElement)] - pElement->oox[LSBPOINTNUM(pElement)]),
(int16)usEmResolution ));
/*
fxWidth = globalGS->ScaleFuncX(&globalGS->scaleX,
(pElement->oox[RSBPOINTNUM(pElement)] - pElement->oox[LSBPOINTNUM(pElement)]));
*/
pElement->x[RSBPOINTNUM(pElement)] =
pElement->x[LSBPOINTNUM(pElement)] + (fxWidth + DOT6ONEHALF) & ~(LOWSIXBITS);
}
/*
* scl_ShiftChar
*
* Shifts a character <3>
*/
FS_PUBLIC void scl_ShiftCurrentCharPoints (
fnt_ElementType * pElement,
F26Dot6 fxXShift,
F26Dot6 fxYShift)
{
uint32 ulCharIndex;
if (fxXShift != 0)
{
for(ulCharIndex = 0; ulCharIndex < (uint32)NUMBEROFCHARPOINTS(pElement); ulCharIndex++)
{
pElement->x[ulCharIndex] += fxXShift;
}
}
if (fxYShift != 0)
{
for(ulCharIndex = 0; ulCharIndex < (uint32)NUMBEROFCHARPOINTS(pElement); ulCharIndex++)
{
pElement->y[ulCharIndex] += fxYShift;
}
}
}
FS_PRIVATE void scl_ShiftOldPoints (
fnt_ElementType * pElement,
F26Dot6 fxXShift,
F26Dot6 fxYShift,
uint16 usFirstPoint,
uint16 usNumPoints)
{
uint32 ulCharIndex;
if (fxXShift != 0)
{
for(ulCharIndex = (uint32)usFirstPoint; ulCharIndex < ((uint32)usFirstPoint + (uint32)usNumPoints); ulCharIndex++)
{
pElement->ox[ulCharIndex] += fxXShift;
}
}
if (fxYShift != 0)
{
for(ulCharIndex = (uint32)usFirstPoint; ulCharIndex < ((uint32)usFirstPoint + (uint32)usNumPoints); ulCharIndex++)
{
pElement->oy[ulCharIndex] += fxYShift;
}
}
}
FS_PUBLIC void scl_CalcComponentOffset(
void * pvGlobalGS, /* GlobalGS */
int16 sXOffset, /* IN: X Offset */
int16 sYOffset, /* Y Offset */
boolean bRounding, /* Rounding Indicator */
F26Dot6 * pfxXOffset, /* OUT: X Offset */
F26Dot6 * pfxYOffset) /* Y Offset */
{
fnt_GlobalGraphicStateType * globalGS;
globalGS = (fnt_GlobalGraphicStateType *)pvGlobalGS;
*pfxXOffset = globalGS->ScaleFuncX(&globalGS->scaleX,(F26Dot6)sXOffset);
*pfxYOffset = globalGS->ScaleFuncY(&globalGS->scaleY,(F26Dot6)sYOffset);
if (bRounding)
{
*pfxXOffset += FNT_PIXELSIZE / 2;
*pfxXOffset &= ~(FNT_PIXELSIZE - 1);
*pfxYOffset += FNT_PIXELSIZE / 2;
*pfxYOffset &= ~(FNT_PIXELSIZE - 1);
}
}
FS_PUBLIC void scl_CalcComponentAnchorOffset(
fnt_ElementType * pParentElement, /* Parent Element */
uint16 usAnchorPoint1, /* Parent Anchor Point */
fnt_ElementType * pChildElement, /* Child Element */
uint16 usAnchorPoint2, /* Child Anchor Point */
F26Dot6 * pfxXOffset, /* OUT: X Offset */
F26Dot6 * pfxYOffset) /* Y Offset */
{
*pfxXOffset = pParentElement->x[usAnchorPoint1] - pChildElement->x[usAnchorPoint2];
*pfxYOffset = pParentElement->y[usAnchorPoint1] - pChildElement->y[usAnchorPoint2];
}
FS_PUBLIC void scl_SetSideBearingPoints(
fnt_ElementType * pElement, /* Element */
point * pptLSB, /* Left Side Bearing point */
point * pptRSB) /* Right Side Bearing point */
{
uint16 usPhantomPointNumber;
usPhantomPointNumber = LSBPOINTNUM(pElement);
pElement->x[usPhantomPointNumber] = pptLSB->x;
pElement->y[usPhantomPointNumber] = pptLSB->y;
usPhantomPointNumber++;
pElement->x[usPhantomPointNumber] = pptRSB->x;
pElement->y[usPhantomPointNumber] = pptRSB->y;
}
FS_PUBLIC void scl_SaveSideBearingPoints(
fnt_ElementType * pElement, /* Element */
point * pptLSB, /* Left Side Bearing point */
point * pptRSB) /* Right Side Bearing point */
{
uint16 usPhantomPointNumber;
usPhantomPointNumber = LSBPOINTNUM(pElement);
pptLSB->x = pElement->x[usPhantomPointNumber];
pptLSB->y = pElement->y[usPhantomPointNumber];
usPhantomPointNumber++;
pptRSB->x = pElement->x[usPhantomPointNumber];
pptRSB->y = pElement->y[usPhantomPointNumber];
}
FS_PUBLIC void scl_InitializeTwilightContours(
fnt_ElementType * pElement, /* Element */
int16 sMaxPoints,
int16 sMaxContours)
{
pElement->sp[0] = 0;
pElement->ep[0] = sMaxPoints - 1;
pElement->nc = sMaxContours;
}
FS_PUBLIC void scl_ZeroOutlineData(
fnt_ElementType * pElement, /* Element pointer */
uint16 usNumberOfPoints,
uint16 usNumberOfContours)
{
MEMSET (&pElement->x[0], 0, (size_t)usNumberOfPoints * sizeof(F26Dot6));
MEMSET (&pElement->ox[0], 0, (size_t)usNumberOfPoints * sizeof(F26Dot6));
MEMSET (&pElement->oox[0], 0, (size_t)usNumberOfPoints * sizeof(F26Dot6));
MEMSET (&pElement->y[0], 0, (size_t)usNumberOfPoints * sizeof(F26Dot6));
MEMSET (&pElement->oy[0], 0, (size_t)usNumberOfPoints * sizeof(F26Dot6));
MEMSET (&pElement->ooy[0], 0, (size_t)usNumberOfPoints * sizeof(F26Dot6));
MEMSET (&pElement->onCurve[0], 0, (size_t)usNumberOfPoints * sizeof(uint8));
MEMSET (&pElement->f[0], 0, (size_t)usNumberOfPoints * sizeof(uint8));
MEMSET (&pElement->sp[0], 0, (size_t)usNumberOfContours * sizeof(int16));
MEMSET (&pElement->ep[0], 0, (size_t)usNumberOfContours * sizeof(int16));
}
FS_PUBLIC void scl_ZeroOutlineFlags(
fnt_ElementType * pElement) /* Element pointer */
{
MEMSET (&pElement->f[0], 0, (size_t)NUMBEROFTOTALPOINTS(pElement) * sizeof(uint8));
}
FS_PUBLIC void scl_IncrementChildElement(
fnt_ElementType * pChildElement, /* Child Element pointer */
fnt_ElementType * pParentElement) /* Parent Element pointer */
{
uint16 usParentNewStartPoint;
if(pParentElement->nc != 0)
{
usParentNewStartPoint = LSBPOINTNUM(pParentElement);
pChildElement->x = &pParentElement->x[usParentNewStartPoint];
pChildElement->y = &pParentElement->y[usParentNewStartPoint];
pChildElement->ox = &pParentElement->ox[usParentNewStartPoint];
pChildElement->oy = &pParentElement->oy[usParentNewStartPoint];
pChildElement->oox = &pParentElement->oox[usParentNewStartPoint];
pChildElement->ooy = &pParentElement->ooy[usParentNewStartPoint];
pChildElement->onCurve = &pParentElement->onCurve[usParentNewStartPoint];
pChildElement->f = &pParentElement->f[usParentNewStartPoint];
pChildElement->sp = &pParentElement->sp[pParentElement->nc];
pChildElement->ep = &pParentElement->ep[pParentElement->nc];
pChildElement->nc = 0;
}
else
{
MEMCPY(pChildElement, pParentElement, sizeof(fnt_ElementType));
}
}
FS_PUBLIC void scl_UpdateParentElement(
fnt_ElementType * pChildElement, /* Child Element pointer */
fnt_ElementType * pParentElement) /* Parent Element pointer */
{
uint16 usNumberOfParentPoints;
uint32 ulPointIndex;
if(pParentElement->nc != 0)
{
usNumberOfParentPoints = NUMBEROFCHARPOINTS(pParentElement);
for(ulPointIndex = (uint32)(uint16)pParentElement->nc;
ulPointIndex < (uint32)(uint16)pParentElement->nc + (uint32)(uint16)pChildElement->nc;
ulPointIndex++)
{
pParentElement->sp[ulPointIndex] += (int16)usNumberOfParentPoints;
pParentElement->ep[ulPointIndex] += (int16)usNumberOfParentPoints;
}
}
pParentElement->nc += pChildElement->nc;
}
FS_PUBLIC uint32 scl_GetContourDataSize (
fnt_ElementType * pElement)
{
uint16 usNumberOfPoints;
uint32 ulSize;
usNumberOfPoints = NUMBEROFCHARPOINTS(pElement);
ulSize = sizeof( pElement->nc );
ulSize += sizeof( *pElement->sp ) * (size_t)pElement->nc;
ulSize += sizeof( *pElement->ep ) * (size_t)pElement->nc;
ulSize += sizeof( *pElement->x ) * (size_t)usNumberOfPoints;
ulSize += sizeof( *pElement->y ) * (size_t)usNumberOfPoints;
ulSize += sizeof( *pElement->onCurve ) * (size_t)usNumberOfPoints;
return( ulSize );
}
FS_PUBLIC void scl_DumpContourData(
fnt_ElementType * pElement,
uint8 ** ppbyOutline)
{
uint16 usNumberOfPoints;
usNumberOfPoints = NUMBEROFCHARPOINTS(pElement);
*((int16 *)*ppbyOutline) = pElement->nc;
*ppbyOutline += sizeof( pElement->nc );
MEMCPY(*ppbyOutline, pElement->sp, (size_t)pElement->nc * sizeof( *pElement->sp ));
*ppbyOutline += (size_t)pElement->nc * sizeof( *pElement->sp );
MEMCPY(*ppbyOutline, pElement->ep, (size_t)pElement->nc * sizeof( *pElement->ep ));
*ppbyOutline += (size_t)pElement->nc * sizeof( *pElement->sp );
MEMCPY(*ppbyOutline, pElement->x, (size_t)usNumberOfPoints * sizeof(*pElement->x));
*ppbyOutline += (size_t)usNumberOfPoints * sizeof( *pElement->x );
MEMCPY(*ppbyOutline, pElement->y, (size_t)usNumberOfPoints * sizeof(*pElement->y));
*ppbyOutline += (size_t)usNumberOfPoints * sizeof( *pElement->y );
MEMCPY(*ppbyOutline, pElement->onCurve, (size_t)usNumberOfPoints * sizeof(*pElement->onCurve));
*ppbyOutline += (size_t)usNumberOfPoints * sizeof( *pElement->onCurve );
}
FS_PUBLIC void scl_RestoreContourData(
fnt_ElementType * pElement,
uint8 ** ppbyOutline)
{
uint16 usNumberOfPoints;
pElement->nc = *((int16 *)(*ppbyOutline));
*ppbyOutline += sizeof( int16 );
pElement->sp = (int16 *)(*ppbyOutline);
*ppbyOutline += (size_t)pElement->nc * sizeof( int16 );
pElement->ep = (int16 *)(*ppbyOutline);
*ppbyOutline += (size_t)pElement->nc * sizeof( int16 );
usNumberOfPoints = NUMBEROFCHARPOINTS(pElement);
pElement->x = (F26Dot6 *)(*ppbyOutline);
*ppbyOutline += (size_t)usNumberOfPoints * sizeof( F26Dot6 );
pElement->y = (F26Dot6 *)(*ppbyOutline);
*ppbyOutline += (size_t)usNumberOfPoints * sizeof( F26Dot6 );
pElement->onCurve = (uint8 *)(*ppbyOutline);
*ppbyOutline += (size_t)usNumberOfPoints * sizeof( uint8 );
}
FS_PUBLIC void scl_ScaleAdvanceWidth (
void * pvGlobalGS, /* GlobalGS */
vectorType * AdvanceWidth,
uint16 usNonScaledAW,
boolean bPositiveSquare,
uint16 usEmResolution,
transMatrix * trans)
{
fnt_GlobalGraphicStateType * globalGS;
globalGS = (fnt_GlobalGraphicStateType *)pvGlobalGS;
if ( bPositiveSquare )
{
AdvanceWidth->x = (Fixed)ShortMulDiv( (int32)globalGS->fxMetricScalarX, (int16)usNonScaledAW, (int16)usEmResolution );
}
else
{
AdvanceWidth->x = FixRatio( (int16)usNonScaledAW, (int16)usEmResolution );
mth_FixXYMul( &AdvanceWidth->x, &AdvanceWidth->y, trans );
}
}
FS_PUBLIC void scl_ScaleVerticalMetrics (
void * pvGlobalGS,
uint16 usNonScaledAH,
int16 sNonScaledTSB,
boolean bPositiveSquare,
uint16 usEmResolution,
transMatrix * trans,
vectorType * pvecAdvanceHeight,
vectorType * pvecTopSideBearing
)
{
fnt_GlobalGraphicStateType * globalGS;
if ( bPositiveSquare )
{
globalGS = (fnt_GlobalGraphicStateType *)pvGlobalGS;
pvecAdvanceHeight->y = (Fixed)ShortMulDiv(
(int32)globalGS->fxMetricScalarY,
(int16)usNonScaledAH,
(int16)usEmResolution );
pvecTopSideBearing->y = (Fixed)ShortMulDiv(
(int32)globalGS->fxMetricScalarY,
sNonScaledTSB,
(int16)usEmResolution );
}
else
{
pvecAdvanceHeight->y = FixRatio( (int16)usNonScaledAH, (int16)usEmResolution );
mth_FixXYMul( &pvecAdvanceHeight->x, &pvecAdvanceHeight->y, trans );
pvecTopSideBearing->y = FixRatio( sNonScaledTSB, (int16)usEmResolution );
mth_FixXYMul( &pvecTopSideBearing->x, &pvecTopSideBearing->y, trans );
}
}
FS_PUBLIC void scl_CalcLSBsAndAdvanceWidths(
fnt_ElementType * pElement,
F26Dot6 f26XMin,
F26Dot6 f26YMax,
point * devAdvanceWidth,
point * devLeftSideBearing,
point * LeftSideBearing,
point * devLeftSideBearingLine,
point * LeftSideBearingLine)
{
scl_CalcDevAdvanceWidth(pElement, devAdvanceWidth);
devLeftSideBearing->x = f26XMin - pElement->x[LSBPOINTNUM(pElement)];
devLeftSideBearing->y = f26YMax - pElement->y[LSBPOINTNUM(pElement)];
LeftSideBearing->x = pElement->x[LEFTEDGEPOINTNUM(pElement)];
LeftSideBearing->x -= pElement->x[ORIGINPOINTNUM(pElement)];
LeftSideBearing->y = f26YMax - pElement->y[LEFTEDGEPOINTNUM(pElement)];
LeftSideBearing->y -= pElement->y[ORIGINPOINTNUM(pElement)];
*devLeftSideBearingLine = *devLeftSideBearing;
*LeftSideBearingLine = *LeftSideBearing;
}
FS_PUBLIC void scl_CalcDevAdvanceWidth(
fnt_ElementType * pElement,
point * devAdvanceWidth)
{
devAdvanceWidth->x = pElement->x[RSBPOINTNUM(pElement)];
devAdvanceWidth->x -= pElement->x[LSBPOINTNUM(pElement)];
devAdvanceWidth->y = pElement->y[RSBPOINTNUM(pElement)];
devAdvanceWidth->y -= pElement->y[LSBPOINTNUM(pElement)];
}
FS_PUBLIC void scl_QueryPPEM(
void * pvGlobalGS,
uint16 * pusPPEM)
{
fnt_GlobalGraphicStateType * globalGS;
globalGS = (fnt_GlobalGraphicStateType *)pvGlobalGS;
*pusPPEM = globalGS->pixelsPerEm;
}
/* Return ppem in X and Y directions for sbits */
FS_PUBLIC void scl_QueryPPEMXY(
void * pvGlobalGS,
uint16 * pusPPEMX,
uint16 * pusPPEMY)
{
fnt_GlobalGraphicStateType * globalGS;
globalGS = (fnt_GlobalGraphicStateType *)pvGlobalGS;
*pusPPEMX = (uint16)ROUNDFIXTOINT(globalGS->interpScalarX);
*pusPPEMY = (uint16)ROUNDFIXTOINT(globalGS->interpScalarY);
}
FS_PUBLIC void scl_45DegreePhaseShift (
fnt_ElementType * pElement)
{
F26Dot6 * x;
int16 count;
x = pElement->x;
count = (int16)NUMBEROFCHARPOINTS(pElement) - 1;
for (; count >= 0; --count)
{
(*x)++;
++x;
}
}
/*
* scl_PostTransformGlyph <3>
*/
FS_PUBLIC void scl_PostTransformGlyph (
void * pvGlobalGS, /* GlobalGS */
fnt_ElementType * pElement,
transMatrix * trans)
{
fnt_GlobalGraphicStateType * globalGS;
globalGS = (fnt_GlobalGraphicStateType *)pvGlobalGS;
mth_IntelMul (
(int32)NUMBEROFTOTALPOINTS (pElement),
pElement->x,
pElement->y,
trans,
/* globalGS->interpScalarX,
globalGS->interpScalarY); */
globalGS->fxMetricScalarX,
globalGS->fxMetricScalarY);
}
/*
* scl_LocalPostTransformGlyph <3>
*
* (1) Inverts the stretch from the CTM
* (2) Applies the local transformation passed in in the trans parameter
* (3) Applies the global stretch from the root CTM
* (4) Restores oox, ooy, oy, ox, and f.
*/
FS_PUBLIC void scl_LocalPostTransformGlyph(fnt_ElementType * pElement, transMatrix *trans)
{
int32 lCount;
lCount = (int32)NUMBEROFTOTALPOINTS(pElement);
mth_IntelMul (lCount, pElement->x, pElement->y, trans, ONEFIX, ONEFIX);
}