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.
961 lines
27 KiB
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);
|
|
}
|