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.
 
 
 
 
 
 

2156 lines
68 KiB

/*
File: FSglue.c
Contains: xxx put contents here (or delete the whole line) xxx
Written by: xxx put name of writer here (or delete the whole line) xxx
Copyright: (c) 1987-1990, 1992 by Apple Computer, Inc., all rights reserved.
(c) 1989-1993. Microsoft Corporation, all rights reserved.
Change History (most recent first):
<7> 11/27/90 MR Need two scalars: one for (possibly rounded) outlines and cvt,
and one (always fractional) metrics. [rb]
<6> 11/16/90 MR Add SnapShotOutline to make instructions after components work
[rb]
<5> 11/9/90 MR Unrename fsg_ReleaseProgramPtrs to RELEASESFNTFRAG. [rb]
<4> 11/5/90 MR Change globalGS.ppemDot6 to globalGS.fpem, change all instrPtr
and curve flags to uint8. [rb]
<3> 10/31/90 MR Add bit-field option for integer or fractional scaling [rb]
<2> 10/20/90 MR Change matrix[2][2] back to a fract (in response to change in
skia). However, ReduceMatrix converts it to a fixed after it has
been used to "regularize" the matrix. Changed scaling routines
for outline and CVT to use integer pixelsPerEm. Removed
scaleFunc from the splineKey. Change some routines that were
calling FracDiv and FixDiv to use LongMulDiv and ShortMulDiv for
greater speed and precision. Removed fsg_InitScaling. [rb]
<20> 8/22/90 MR Only call fixmul when needed in finalComponentPass loop
<19> 8/1/90 MR Add line to set non90DegreeTransformation
<18> 7/26/90 MR remove references to metricInfo junk, don't include ToolUtils.h
<17> 7/18/90 MR Change error return type to int, split WorkSpace routine into
two calls, added SWAPW macros
<16> 7/14/90 MR Fixed reference to const SQRT2 to FIXEDSQRT2
<15> 7/13/90 MR Ansi-C stuff, tried to use correct sizes for variables to avoid
coercion (sp?)
<12> 6/21/90 MR Add calls to ReleaseSfntFrag
<11> 6/4/90 MR Remove MVT, change matrix to have bottom right element be a
fixed.
<10> 6/1/90 MR Thou shalt not pay no more attention to the MVT!
<8+> 5/29/90 MR look for problem in Max45Trick
<8> 5/21/90 RB bugfix in fsg_InitInterpreterTrans setting key->imageState
<7> 5/9/90 MR Fix bug in MoreThanXYStretch
<6> 5/4/90 RB support for new scan converter and decryption mrr - add
fsg_ReverseContours and key->reverseContour to account
for glyphs that are flipped. This keeps the
winding-number correct for the scan converter. Mike
fixed fsg_Identity
<5> 5/3/90 RB support for new scan converter and decryption mrr - add
fsg_ReverseContours and key->reverseContour to account for
glyphs that are flipped. This keeps the winding-number correct
for the scan converter.
<4> 4/10/90 CL Fixed infinite loop counter - changed uint16 to int16 (Mikey).
<3> 3/20/90 CL Added HasPerspective for finding fast case
Removed #ifdef SLOW, OLD
Changed NormalizeTransformation to use fpem (16.16) and to use max instead of length
and to loop instead of recurse.
Removed compensation for int ppem in fsg_InitInterpreterTrans (not needed with fpem)
Greased loops in PreTransformGlyph, PostTransformGlyph, LocalPostTransformGlyph,
ShiftChar, ZeroOutTwilightZone, InitLocalT
Changed GetPreMultipliers to special case unit vector * 2x2 matrix
Added support for ppemDot6 and pointSizeDot6
Changed fsg_MxMul to treat the perspective elements as Fracts
arrays to pointers in ScaleChar
Fixed bugs in loops in posttransformglyph, convert loops to --numPts >= 0
<2> 2/27/90 CL It reconfigures itself during runtime ! New lsb and rsb
calculation. Shift bug in instructed components: New error
code for missing but needed table. (0x1409) Optimization which
has to do with shifting and copying ox/x and oy/y. Fixed new
format bug. Changed transformed width calculation. Fixed
device metrics for transformed uninstructed sidebearing
characters. Dropoutcontrol scanconverter and SCANCTRL[]
instruction. Fixed transformed component bug.
<3.3> 11/14/89 CEL Left Side Bearing should work right for any transformation. The
phantom points are in, even for components in a composite glyph.
They should also work for transformations. Device metric are
passed out in the output data structure. This should also work
with transformations. Another leftsidebearing along the advance
width vector is also passed out. whatever the metrics are for
the component at it's level. Instructions are legal in
components. The old perspective bug has been fixed. The
transformation is internally automatically normalized. This
should also solve the overflow problem we had. Changed
sidebearing point calculations to use 16.16 precision. For zero
or negative numbers in my tricky/fast square root computation it
would go instable and loop forever. It was not able to handle
large transformations correctly. This has been fixed and the
normalization may call it self recursively to gain extra
precision! It used to normalize an identity transformation
unecessarily.
<3.2> 10/6/89 CEL Phantom points were removed causing a rounding of last 2 points
bug. Characters would become distorted.
<3.1> 9/27/89 CEL Fixed transformation anchor point bug.
<3.0> 8/28/89 sjk Cleanup and one transformation bugfix
<2.2> 8/14/89 sjk 1 point contours now OK
<2.1> 8/8/89 sjk Improved encryption handling
<2.0> 8/2/89 sjk Just fixed EASE comment
<1.5> 8/1/89 sjk Added composites and encryption. Plus some
enhanclocalpostements.
<1.4> 6/13/89 SJK Comment
<1.3> 6/2/89 CEL 16.16 scaling of metrics, minimum recommended ppem, point size 0
bug, correct transformed integralized ppem behavior, pretty much
so
<1.2> 5/26/89 CEL EASE messed up on "c" comments
<y1.1> 5/26/89 CEL Integrated the new Font Scaler 1.0 into Spline Fonts
<1.0> 5/25/89 CEL Integrated 1.0 Font scaler into Bass code for the first time.
To Do:
*/
/* rwb r/24/90 - Add support for scanControlIn and scanControlOut variables in global graphiscs
* state
*/
/** System Includes **/
/** FontScaler's Includes **/
#include "fserror.h"
#include "fscdefs.h"
#include "fontmath.h"
#include "fnt.h"
#include "interp.h"
#include "sfntaccs.h"
#include "fsglue.h"
#include "scale.h"
/* CONSTANTS */
/* These constants are used for interpreting the scan control and scan type
fields returned by the interpreter. They are documented in the TrueType
specification under the SCANCTRL and SCANTYPE instructions.
*/
#define SCANINFO_SIZE_MASK 0x000000FF
#define SCANINFO_FLAGS_MASK 0x00003F00
#define SCANINFO_TYPE_MASK 0xFFFF0000
#define SCANINFO_SIZE_CLEAR ~SCANINFO_SIZE_MASK
#define SCANINFO_FLAGS_CLEAR ~SCANINFO_FLAGS_MASK
#define SCANINFO_TYPE_CLEAR ~SCANINFO_TYPE_MASK
#define SCANINFO_FLAGS_DONT 0x00003800
#define SCANINFO_FLAGS_DO 0x00000700
#define SCANCTRL_SIZE_MASK 0x000000FF
#define SCANCTRL_DROPOUT_ALL_SIZES 0xFF
#define SCANCTRL_DROPOUT_IF_LESS 0x0100
#define SCANCTRL_DROPOUT_IF_ROTATED 0x0200
#define SCANCTRL_DROPOUT_IF_STRETCHED 0x0400
#define SCANCTRL_NODROP_UNLESS_LESS 0x0800
#define SCANCTRL_NODROP_UNLESS_ROTATED 0x1000
#define SCANCTRL_NODROP_UNLESS_STRETCH 0x2000
#define SCANTYPE_UNINITIALIZED 0xFFFF
/* fo the key->imageState field */
#define IMAGESTATE_ROTATED 0x0400
#define IMAGESTATE_STRETCHED 0x1000
#define IMAGESTATE_NON_POS_RECT 0x2000
#define IMAGESTATE_SIZE_MASK 0x00FF
#define IMAGESTATE_MAX_PPEM_SIZE 0x000000FF
#define COMPOSITE_ROOT 0
#define MAX_TWILIGHT_CONTOURS 1
#define DEFAULT_COMPONENT_ELEMENTS 3UL
#define DEFAULT_COMPONENT_DEPTH 1UL
static const transMatrix IdentTransform =
{{{ONEFIX, 0, 0},
{ 0, ONEFIX, 0},
{ 0, 0, ONEFIX}}};
/*********** macros ************/
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define CHECK_GLYPHDATA(pglyphdata) RAST_ASSERT(((pglyphdata->acIdent[0] == 'G') && \
(pglyphdata->acIdent[1] == 'D')),"Illegal GlyphData pointer");
#define MAX_COMPONENT_DEPTH(pMaxProfile) (uint32)MAX (pMaxProfile->maxComponentDepth, DEFAULT_COMPONENT_DEPTH)
#define MAX_COMPONENT_ELEMENTS(pMaxProfile) (uint32)MAX (pMaxProfile->maxComponentElements, DEFAULT_COMPONENT_ELEMENTS)
#define MAX_NESTED_GLYPHS(pMaxProfile) (uint32)((MAX_COMPONENT_DEPTH(pMaxProfile) + 1) + MAX_COMPONENT_ELEMENTS(pMaxProfile));
/**********************************************************************************/
/* TYPEDEFS */
typedef enum {
glyphSimple,
glyphIncompleteComposite,
glyphComposite,
glyphUndefined
} GlyphTypes;
/* Glyph Data */
typedef struct GlyphData GlyphData;
struct GlyphData{
char acIdent[2]; /* Identifier for GlyphData */
GlyphData * pSibling; /* Pointer to siblings */
GlyphData * pChild; /* Pointer to children */
GlyphData * pParent; /* Pointer to parent */
sfac_GHandle hGlyph; /* Handle for font access */
GlyphTypes GlyphType; /* Type of glyph */
uint16 usGlyphIndex; /* Glyph Index */
BBOX bbox; /* Bounding box for glyph */
uint16 usNonScaledAW; /* Nonscaled Advance Width */
int16 sNonScaledLSB; /* Nonscaled Left Side Bearing */
uint16 usDepth; /* Depth of Glyph in composite tree */
sfac_ComponentTypes MultiplexingIndicator;/* Flag for arguments of composites */
boolean bRoundXYToGrid; /* Round composite offsets to grid */
int16 sXOffset; /* X offset for composite (if supplied) */
int16 sYOffset; /* Y offset for composite (if supplied) */
uint16 usAnchorPoint1; /* Anchor Point 1 for composites (if not offsets) */
uint16 usAnchorPoint2; /* Anchor Point 2 for composites (if not offsets) */
transMatrix mulT; /* Transformation matrix for composite */
boolean bUseChildMetrics; /* Should use child metrics? */
boolean bUseMyMetrics; /* Is glyph USE_MY_METRICS? */
point ptDevLSB; /* Left Side Bearing Point */
point ptDevRSB; /* Right Side Bearing Point */
uint16 usScanType; /* ScanType value for this glyph */
uint16 usSizeOfInstructions; /* Size (in bytes) of glyph instructions */
uint8 * pbyInstructions; /* Pointer to glyph instructions */
fnt_ElementType * pGlyphElement; /* Current glyph element pointer */
};
/**********************************************************************************/
/* PRIVATE PROTOTYPES <4> */
FS_PRIVATE void fsg_GetOutlineSizeAndOffsets(
uint16 usMaxPoints,
uint16 usMaxContours,
fsg_OutlineFieldInfo * offsetPtr,
uint32 * pulOutlineSize,
uint32 * pulReusableMarker);
FS_PRIVATE ErrorCode fsg_CreateGlyphData(
sfac_ClientRec * ClientInfo, /* sfnt Client information */
LocalMaxProfile * pMaxProfile, /* Max Profile Table */
fsg_TransformRec * TransformInfo, /* Transformation information */
void * pvGlobalGS, /* GlobalGS */
fsg_WorkSpaceAddr * pWorkSpaceAddr, /* WorkSpace Address */
fnt_ElementType * pTwilightElement, /* Twilight zone element */
FntTraceFunc traceFunc, /* Trace function for interpreter */
boolean bUseHints, /* True if glyph is gridfitted */
uint16 * pusScanType, /* ScanType value */
boolean * pbGlyphHasOutline, /* Outline for glyph */
uint16 * pusNonScaledAW); /* Return NonScaled Advance Width */
FS_PRIVATE ErrorCode fsg_ExecuteGlyph(
sfac_ClientRec * ClientInfo, /* sfnt Client information */
LocalMaxProfile * pMaxProfile, /* Max Profile Table */
fsg_TransformRec * TransformInfo, /* Transformation information */
uint32 ulGlyphDataCount, /* Max nested components */
void * pvGlobalGS, /* GlobalGS */
GlyphData * pGlyphData, /* GlyphData pointer */
fsg_WorkSpaceAddr * pWorkSpaceAddr, /* WorkSpace Address */
fnt_ElementType * pTwilightElement, /* Twilight zone element */
FntTraceFunc traceFunc, /* Trace function for interpreter */
boolean bUseHints, /* True if glyph is gridfitted */
boolean * pbHasOutline); /* True if glyph has outline */
FS_PRIVATE void fsg_ChooseNextGlyph(
fsg_WorkSpaceAddr * pWorkSpaceAddr, /* WorkSpace Address */
GlyphData * pGlyphData, /* GlyphData pointer */
GlyphData ** ppNextGlyphData); /* Next GlyphData pointer */
FS_PRIVATE ErrorCode fsg_SimpleInnerGridFit (
void * pvGlobalGS,
fnt_ElementType * pTwilightElement,
fnt_ElementType * pGlyphElement,
boolean bUseHints,
FntTraceFunc traceFunc,
uint16 usEmResolution,
uint16 usNonScaledAW,
int16 sNonScaledLSB,
BBOX * bbox,
uint16 usSizeOfInstructions,
uint8 * instructionPtr,
uint16 * pusScanType,
uint16 * pusScanControl,
boolean * pbChangeScanControl);
FS_PRIVATE ErrorCode fsg_CompositeInnerGridFit (
void * pvGlobalGS,
fnt_ElementType * pTwilightElement,
fnt_ElementType * pGlyphElement,
boolean bUseHints,
FntTraceFunc traceFunc,
uint16 usEmResolution,
uint16 usNonScaledAW,
int16 sNonScaledLSB,
BBOX * bbox,
uint16 usSizeOfInstructions,
uint8 * instructionPtr,
uint16 * pusScanType,
uint16 * pusScanControl,
boolean * pbChangeScanControl);
FS_PRIVATE void fsg_LinkChild(
GlyphData * pGlyphData, /* GlyphData pointer */
GlyphData * pChildGlyphData); /* Child GlyphData pointer */
FS_PRIVATE void fsg_MergeGlyphData(
void * pvGlobalGS, /* GlobalGS */
GlyphData * pChildGlyphData); /* GlyphData pointer */
FS_PRIVATE void fsg_TransformChild(
GlyphData * pGlyphData); /* GlyphData pointer */
FS_PRIVATE void fsg_MergeScanType(
GlyphData * pGlyphData, /* GlyphData pointer */
GlyphData * pParentGlyphData); /* GlyphData pointer */
FS_PRIVATE boolean fsg_DoScanControl(
uint16 usScanControl,
uint32 ulImageState);
FS_PRIVATE void fsg_InitializeGlyphDataMemory(
uint32 ulGlyphDataCount,
fsg_WorkSpaceAddr * pWorkSpaceAddr);/* WorkSpace Address */
FS_PRIVATE void fsg_AllocateGlyphDataMemory(
uint32 ulGlyphDataCount,
fsg_WorkSpaceAddr * pWorkSpaceAddr, /* WorkSpace Address */
GlyphData ** ppGlyphData); /* GlyphData pointer */
FS_PRIVATE void fsg_DeallocateGlyphDataMemory(
fsg_WorkSpaceAddr * pWorkSpaceAddr, /* WorkSpace Address */
GlyphData * pGlyphData); /* GlyphData pointer */
FS_PRIVATE void fsg_InitializeGlyphData(
GlyphData * pGlyphData, /* GlyphData pointer */
fsg_WorkSpaceAddr * pWorkSpaceAddr, /* WorkSpace Address */
uint16 usGlyphIndex, /* Glyph Index */
uint16 usDepth); /* Glyph depth */
FS_PRIVATE void fsg_CheckFit(
int32 lSize1,
int32 lSize2,
int32 lSize3,
int32 lTotalSize,
uint32 * pfResult);
/* FSGlue Code */
/* ..............MEMORY MANAGEMENT ROUTINES................ */
/*
* fsg_PrivateFontSpaceSize : This data should remain intact for the life of the sfnt
* because function and instruction defs may be defined in the font program
* and/or the preprogram.
*/
/*
PRIVATE SPACE Memory Layout
typedef struct fsg_PrivateSpaceOffsets {
0 +===========+ --------------------- <- PrivateSpaceOffsets.offset_storage;
| |
| | TrueType Storage
| |
+===========+ --------------------- <- PrivateSpaceOffsets.offset_functions;
| |
| | TrueType Function Defs
| |
+===========+ --------------------- <- PrivateSpaceOffsets.offset_instrDefs;
| |
| | TrueType Instruction Defs
| |
+===========+ --------------------- <- PrivateSpaceOffsets.offset_controlValues;
| |
| | TrueType Scaled CVT
| |
+===========+ --------------------- <- PrivateSpaceOffsets.offset_globalGS;
| pStack |
| pStorage |
| pCVT |
| pFDEF | TrueType Global GS
| pIDEF |
| pFPGM |
| pPPGM |
| pGlyphPgm |
+===========+ --------------------- <- PrivateSpaceOffsets.offset_FontProgram;
| |
| | TrueType Font Program
| |
+===========+ --------------------- <- PrivateSpaceOffsets.offset_PreProgram;
| |
| | TrueType Pre Program
| |
+===========+ --------------------- <- PrivateSpaceOffsets.offset_TwilightZone;
| poox |
+-----------+
| pox |
+-----------+
| px | Twilight Element
+-----------+
: ... :
+-----------+
| pep |
+-----------+
| nc |
+===========+ --------------------- <- PrivateSpaceOffsets.offset_TwilightOutline;
|x[maxtzpts]| Twilight Outline
+-----------+
|y[maxtzpts]|
+-----------+
: ... :
+-----------+
|ep[maxtzct]|
+-----------+
|ox[maxtzpt]|
+-----------+
|oox[mxtzpt]|
+-----------+
: ... :
+-----------+
|f[maxtzpts]|
+===========+ ---------------------
*/
FS_PUBLIC uint32 fsg_PrivateFontSpaceSize (
sfac_ClientRec * ClientInfo,
LocalMaxProfile * pMaxProfile, /* Max Profile Table */
fsg_PrivateSpaceOffsets * PrivateSpaceOffsets)
{
uint32 ulOutlineSize;
uint32 ulReusableMarker; /* Unused dummy variable */
PrivateSpaceOffsets->offset_storage = 0L;
PrivateSpaceOffsets->offset_functions = PrivateSpaceOffsets->offset_storage + (uint32)sizeof (F26Dot6) * (uint32)pMaxProfile->maxStorage;
PrivateSpaceOffsets->offset_instrDefs = PrivateSpaceOffsets->offset_functions + (uint32)sizeof (fnt_funcDef) * (uint32)pMaxProfile->maxFunctionDefs;
PrivateSpaceOffsets->offset_controlValues = PrivateSpaceOffsets->offset_instrDefs + (uint32)sizeof (fnt_instrDef) * (uint32)pMaxProfile->maxInstructionDefs; /* <4> */
PrivateSpaceOffsets->offset_globalGS = PrivateSpaceOffsets->offset_controlValues + (uint32)sizeof (F26Dot6) *
((uint32)SFAC_LENGTH (ClientInfo, sfnt_controlValue) / (uint32)sizeof (sfnt_ControlValue));
PrivateSpaceOffsets->offset_FontProgram = PrivateSpaceOffsets->offset_globalGS + (uint32)sizeof (fnt_GlobalGraphicStateType);
PrivateSpaceOffsets->offset_PreProgram = PrivateSpaceOffsets->offset_FontProgram + (uint32)SFAC_LENGTH (ClientInfo, sfnt_fontProgram);
PrivateSpaceOffsets->offset_TwilightZone = PrivateSpaceOffsets->offset_PreProgram + (uint32)SFAC_LENGTH (ClientInfo, sfnt_preProgram);
ALIGN(int32, PrivateSpaceOffsets->offset_TwilightZone);
/*
Setup the twilight zone element data structure. This data structure will
contain all of the address into the twilight zone outline space.
*/
PrivateSpaceOffsets->offset_TwilightOutline = PrivateSpaceOffsets->offset_TwilightZone + (uint32)sizeof (fnt_ElementType);
ALIGN(int32, PrivateSpaceOffsets->offset_TwilightOutline);
/*
Setup Twilight Zone outline space. This space contains all of the components
to describe a Twilight Zone outline. Set the offset to our current position,
and as we calculate the size of this outline space, update the field
offsets e.g. x, ox, oox, &c.
*/
/*** Outline -- TWILIGHT ZONE ***/
fsg_GetOutlineSizeAndOffsets(
pMaxProfile->maxTwilightPoints,
MAX_TWILIGHT_CONTOURS,
&(PrivateSpaceOffsets->TwilightOutlineFieldOffsets),
&ulOutlineSize,
&ulReusableMarker);
return ((PrivateSpaceOffsets->offset_TwilightOutline + ulOutlineSize) - PrivateSpaceOffsets->offset_storage);
}
/*
* fsg_WorkSpaceSetOffsets : This stuff changes with each glyph
*
* Computes the workspace size and sets the offsets into it.
*
*/
/*
WORKSPACE Memory Layout
0 +===========+ --------------------- <- WorkSpaceOffsets.ulGlyphElementOffset
| poox |
+-----------+
| pox |
+-----------+
| px | Glyph Element 1
+-----------+
: ... :
+-----------+
| pep |
+-----------+
| nc |
+===========+ ---------------------
| poox |
+-----------+
| pox |
+-----------+
| px | Glyph Element 2
+-----------+
: ... :
+-----------+
| pep |
+-----------+
| nc |
+===========+ ---------------------
| |
: : :
| |
+===========+ ---------------------
| poox |
+-----------+
| pox |
+-----------+
| px | Glyph Element [MaxComponentDepth + 1]
+-----------+
: ... :
+-----------+
| pep |
+-----------+
| nc |
+===========+ --------------------- <- WorkSpaceOffsets.ulGlyphOutlineOffset
|x[maxpts] | Glyph Outline
+-----------+
|y[maxpts] |
+-----------+
: ... :
+-----------+
|ep[maxctrs]|
+-----------+
|ox[maxpts] | <- WorkSpaceOffsets.ulReusableMemoryOffset
+-----------+
|oox[maxpts]|
+-----------+
: ... :
+-----------+
|f[maxpts] |
+===========+ --------------------- <- WorkSpaceOffsets.ulGlyphDataByteSetBaseOffset
| T| F| T| F|
+-----------+
| F| F| F| F|
+-----------+
| F| F| F| F| Glyph Data Allocation ByteSet
+-----------+ (number of bytes = ulGlyphDataCount)
| F| F| F| F|
+-----------+
| F| F| F| F|
+===========+ --------------------- <- WorkSpaceOffsets.ulGlyphDataBaseOffset
| acIdent |
+-----------+
| pSibling |
+-----------+
| pChild |
+-----------+
| pParent |
+-----------+ GlyphData 1
| hGlyph |
+-----------+
| GlyphType |
+-----------+
: :
+-----------+
|GlyphElemnt|
+===========+ ---------------------
| acIdent |
+-----------+
| pSibling |
+-----------+
| pChild |
+-----------+
| pParent |
+-----------+ GlyphData 2
| hGlyph |
+-----------+
| GlyphType |
+-----------+
: :
+-----------+
|GlyphElemnt|
+===========+ ---------------------
| |
: : :
| |
+===========+ ---------------------
| acIdent |
+-----------+
| pSibling |
+-----------+
| pChild |
+-----------+
| pParent |
+-----------+ GlyphData [ulGlyphDataCount]
| hGlyph |
+-----------+
| GlyphType |
+-----------+
: :
+-----------+
|GlyphElemnt|
+===========+ --------------------- <- WorkSpaceOffsets.ulStackOffset
| |
| |
| | Stack
| |
| |
| |
+===========+ ---------------------
*/
FS_PUBLIC uint32 fsg_WorkSpaceSetOffsets (
LocalMaxProfile * pMaxProfile, /* Max Profile Table */
fsg_WorkSpaceOffsets * WorkSpaceOffsets,
int32 * plExtraWorkSpace)
{
uint32 ulOutlineDataSize;
uint32 ulWorkSpacePos;
uint32 ulGlyphDataCount;
ulWorkSpacePos = 0UL;
/*
Setup the glyph element data array. This data structure contains all of the
addresses into the glyph outline space. There are the same number of glyph
element arrays as there are outline spaces; this allows us to handle the
worstcase composite in the font.
*/
WorkSpaceOffsets->ulGlyphElementOffset = ulWorkSpacePos;
ulWorkSpacePos += (uint32)sizeof (fnt_ElementType) *
(uint32)(MAX_COMPONENT_DEPTH(pMaxProfile) + 1);
/*** Outline -- GLYPH *****/
/*
Setup Glyph outline space. This space contains all of the components
to describe a Glyph outline. Set the offset to our current position,
and as we calculate the size of this outline space, update the elemental
offsets e.g. x, ox, oox, &c.
Once we have calculated the size of one outline space, we will duly note
its size, and then add enough space to handle the outlines for the worst
case composite depth in the font.
*/
ALIGN(int16, ulWorkSpacePos);
WorkSpaceOffsets->ulGlyphOutlineOffset = ulWorkSpacePos; /* Remember start of Glyph Element */
fsg_GetOutlineSizeAndOffsets(
(uint16)(PHANTOMCOUNT + MAX (pMaxProfile->maxPoints, pMaxProfile->maxCompositePoints)),
(uint16)MAX (pMaxProfile->maxContours, pMaxProfile->maxCompositeContours),
&(WorkSpaceOffsets->GlyphOutlineFieldOffsets),
&ulOutlineDataSize,
(uint32 *)&(WorkSpaceOffsets->ulReusableMemoryOffset));
/* Adjust Reusable memory marker to be based from zero, rather than GlyphOutline */
WorkSpaceOffsets->ulReusableMemoryOffset += WorkSpaceOffsets->ulGlyphOutlineOffset;
ulWorkSpacePos += ulOutlineDataSize;
/*
Set the GlyphData ByteSet array. This array is used to track the memory used
in GlyphData. Each entry in this array is a boolean. One needs to also
calculate the number of GlyphData's that will be needed to handle the
worstcase composite in the font.
*/
ALIGN(boolean, ulWorkSpacePos);
WorkSpaceOffsets->ulGlyphDataByteSetOffset = ulWorkSpacePos;
ulGlyphDataCount = MAX_NESTED_GLYPHS(pMaxProfile);
ulWorkSpacePos += ulGlyphDataCount * (uint32)sizeof (boolean);
/*
Set up the GlyphData array. This array contains the information needed
to describe composites and components for a glyph.
*/
ALIGN(int32, ulWorkSpacePos);
WorkSpaceOffsets->ulGlyphDataOffset = ulWorkSpacePos;
ulWorkSpacePos += (uint32)sizeof(GlyphData) * ulGlyphDataCount;
ALIGN(F26Dot6, ulWorkSpacePos);
WorkSpaceOffsets->ulStackOffset = ulWorkSpacePos;
ulWorkSpacePos += (uint32)pMaxProfile->maxStackElements * (uint32)sizeof (F26Dot6);
/* Calculate amount of extra memory */
*plExtraWorkSpace = (int32)ulWorkSpacePos - (int32)WorkSpaceOffsets->ulReusableMemoryOffset;
WorkSpaceOffsets->ulMemoryBase6Offset = 0L;
WorkSpaceOffsets->ulMemoryBase7Offset = 0L;
/* Return the total size of the WorkSpace memory. */
return(ulWorkSpacePos);
}
FS_PRIVATE void fsg_GetOutlineSizeAndOffsets(
uint16 usMaxPoints,
uint16 usMaxContours,
fsg_OutlineFieldInfo * offsetPtr,
uint32 * pulOutlineSize,
uint32 * pulReusableMarker)
{
uint32 ulArraySize;
offsetPtr->onCurve = 0;
*pulOutlineSize = (uint32)usMaxPoints * (uint32)sizeof (uint8);
ALIGN(int16, *pulOutlineSize);
offsetPtr->sp = *pulOutlineSize;
ulArraySize = (uint32)usMaxContours * (uint32)sizeof (int16);
*pulOutlineSize += ulArraySize;
offsetPtr->ep = *pulOutlineSize;
*pulOutlineSize += ulArraySize;
ALIGN(F26Dot6, *pulOutlineSize);
offsetPtr->x = *pulOutlineSize;
ulArraySize = (uint32)usMaxPoints * (uint32)sizeof (F26Dot6);
*pulOutlineSize += ulArraySize;
offsetPtr->y = *pulOutlineSize;
*pulOutlineSize += ulArraySize;
*pulReusableMarker = *pulOutlineSize;
/* Everything below this point can be reused during contour scanning */
offsetPtr->ox = *pulOutlineSize;
*pulOutlineSize += ulArraySize;
offsetPtr->oy = *pulOutlineSize;
*pulOutlineSize += ulArraySize;
offsetPtr->oox = *pulOutlineSize;
*pulOutlineSize += ulArraySize;
offsetPtr->ooy = *pulOutlineSize;
*pulOutlineSize += ulArraySize;
offsetPtr->f = *pulOutlineSize;
*pulOutlineSize += (uint32)usMaxPoints * (uint32)sizeof (uint8);
ALIGN(int32, *pulOutlineSize);
}
FS_PUBLIC void fsg_UpdatePrivateSpaceAddresses(
sfac_ClientRec * ClientInfo, /* Cached sfnt information */
LocalMaxProfile * pMaxProfile, /* Max Profile Table */
char * pPrivateFontSpace,
fsg_PrivateSpaceOffsets * PrivateSpaceOffsets,
void * pvStack, /* pointer to stack */
void ** pvFontProgram, /* pointer to font program */
void ** pvPreProgram) /* pointer to pre program */
{
void * pvGlobalGS;
void * pvCVT; /* pointer to CVT */
void * pvStore;
void * pvFuncDef;
void * pvInstrDef;
uint32 ulLengthFontProgram, ulLengthPreProgram;
pvCVT = pPrivateFontSpace + PrivateSpaceOffsets->offset_controlValues;
pvStore = pPrivateFontSpace + PrivateSpaceOffsets->offset_storage;
pvFuncDef = pPrivateFontSpace + PrivateSpaceOffsets->offset_functions;
pvInstrDef = pPrivateFontSpace + PrivateSpaceOffsets->offset_instrDefs;
pvGlobalGS = pPrivateFontSpace + PrivateSpaceOffsets->offset_globalGS;
*pvFontProgram = pPrivateFontSpace + PrivateSpaceOffsets->offset_FontProgram;
ulLengthFontProgram = SFAC_LENGTH(ClientInfo, sfnt_fontProgram);
*pvPreProgram = pPrivateFontSpace + PrivateSpaceOffsets->offset_PreProgram;
ulLengthPreProgram = SFAC_LENGTH(ClientInfo, sfnt_preProgram);
itrp_UpdateGlobalGS(pvGlobalGS, pvCVT, pvStore, pvFuncDef, pvInstrDef, pvStack,
pMaxProfile, (uint16)((uint32)SFAC_LENGTH (ClientInfo, sfnt_controlValue) / (uint32)sizeof (sfnt_ControlValue)),
ulLengthFontProgram, *pvFontProgram, ulLengthPreProgram, *pvPreProgram);
}
FS_PUBLIC void fsg_UpdateWorkSpaceAddresses(
char * pWorkSpace,
fsg_WorkSpaceOffsets * WorkSpaceOffsets,
fsg_WorkSpaceAddr * pWorkSpaceAddr)
{
pWorkSpaceAddr->pStack = (F26Dot6 *)(WorkSpaceOffsets->ulStackOffset + pWorkSpace);
pWorkSpaceAddr->pGlyphOutlineBase = WorkSpaceOffsets->ulGlyphOutlineOffset + pWorkSpace;
pWorkSpaceAddr->pGlyphElement = (fnt_ElementType *)(WorkSpaceOffsets->ulGlyphElementOffset + pWorkSpace);
pWorkSpaceAddr->pGlyphDataByteSet = (boolean *)(WorkSpaceOffsets->ulGlyphDataByteSetOffset + pWorkSpace);
pWorkSpaceAddr->pvGlyphData = (void *)(WorkSpaceOffsets->ulGlyphDataOffset + pWorkSpace);
pWorkSpaceAddr->pReusableMemoryMarker = WorkSpaceOffsets->ulReusableMemoryOffset + pWorkSpace;
}
FS_PUBLIC void fsg_UpdateWorkSpaceElement(
fsg_WorkSpaceOffsets * WorkSpaceOffsets,
fsg_WorkSpaceAddr * pWorkSpaceAddr)
{
char * pOutlineBase;
fnt_ElementType * pGlyphElement; /* Address of Glyph Element array */
fsg_OutlineFieldInfo * pOffset;
pOutlineBase = pWorkSpaceAddr->pGlyphOutlineBase;
pGlyphElement = pWorkSpaceAddr->pGlyphElement;
/* Note: only the first level glyph element has address updated. Second */
/* levels are updated when referenced. */
pOffset = & (WorkSpaceOffsets->GlyphOutlineFieldOffsets);
pGlyphElement->x = (F26Dot6 *) (pOutlineBase + pOffset->x);
pGlyphElement->y = (F26Dot6 *) (pOutlineBase + pOffset->y);
pGlyphElement->ox = (F26Dot6 *) (pOutlineBase + pOffset->ox);
pGlyphElement->oy = (F26Dot6 *) (pOutlineBase + pOffset->oy);
pGlyphElement->oox = (F26Dot6 *) (pOutlineBase + pOffset->oox);
pGlyphElement->ooy = (F26Dot6 *) (pOutlineBase + pOffset->ooy);
pGlyphElement->sp = (int16 *) (pOutlineBase + pOffset->sp);
pGlyphElement->ep = (int16 *) (pOutlineBase + pOffset->ep);
pGlyphElement->onCurve = (uint8 *) (pOutlineBase + pOffset->onCurve);
pGlyphElement->f = (uint8 *) (pOutlineBase + pOffset->f);
}
FS_PUBLIC void * fsg_QueryGlobalGS(
char * pPrivateFontSpace,
fsg_PrivateSpaceOffsets * PrivateSpaceOffsets)
{
return ((void *)(pPrivateFontSpace + PrivateSpaceOffsets->offset_globalGS));
}
FS_PUBLIC void * fsg_QueryTwilightElement(
char * pPrivateFontSpace,
fsg_PrivateSpaceOffsets * PrivateSpaceOffsets)
{
fnt_ElementType * pTwilightElement; /* Address of Twilight Zone Element */
fsg_OutlineFieldInfo * pOffset;
char * pTemp;
pOffset = &(PrivateSpaceOffsets->TwilightOutlineFieldOffsets);
pTemp = pPrivateFontSpace + PrivateSpaceOffsets->offset_TwilightOutline;
pTwilightElement = (fnt_ElementType *)(pPrivateFontSpace + PrivateSpaceOffsets->offset_TwilightZone);
pTwilightElement->x = (F26Dot6 *) (pTemp + pOffset->x);
pTwilightElement->y = (F26Dot6 *) (pTemp + pOffset->y);
pTwilightElement->ox = (F26Dot6 *) (pTemp + pOffset->ox);
pTwilightElement->oy = (F26Dot6 *) (pTemp + pOffset->oy);
pTwilightElement->oox = (F26Dot6 *) (pTemp + pOffset->oox);
pTwilightElement->ooy = (F26Dot6 *) (pTemp + pOffset->ooy);
pTwilightElement->sp = (int16 *) (pTemp + pOffset->sp);
pTwilightElement->ep = (int16 *) (pTemp + pOffset->ep);
pTwilightElement->onCurve = (uint8 *) (pTemp + pOffset->onCurve);
pTwilightElement->f = (uint8 *) (pTemp + pOffset->f);
return (void *)pTwilightElement;
}
FS_PUBLIC void * fsg_QueryStack(fsg_WorkSpaceAddr * pWorkSpaceAddr)
{
return ((void *)pWorkSpaceAddr->pStack);
}
FS_PUBLIC void * fsg_QueryReusableMemory(
char * pWorkSpace,
fsg_WorkSpaceOffsets * WorkSpaceOffsets)
{
return pWorkSpace + WorkSpaceOffsets->ulReusableMemoryOffset;
}
FS_PUBLIC void fsg_CheckWorkSpaceForFit(
fsg_WorkSpaceOffsets * WorkSpaceOffsets,
int32 lExtraWorkSpace,
int32 lMGWorkSpace,
int32 * plSizeBitmap1,
int32 * plSizeBitmap2)
{
uint32 ulMemoryOffset;
ulMemoryOffset = WorkSpaceOffsets->ulReusableMemoryOffset;
ulMemoryOffset += (uint32)lMGWorkSpace; /* correct for MeasureGlyph Workspace */
lExtraWorkSpace -= lMGWorkSpace;
WorkSpaceOffsets->ulMemoryBase6Offset = 0L;
WorkSpaceOffsets->ulMemoryBase7Offset = 0L;
/* Save original sizes */
WorkSpaceOffsets->ulMemoryBase6Size = *plSizeBitmap1;
WorkSpaceOffsets->ulMemoryBase7Size = *plSizeBitmap2;
if( *plSizeBitmap1 > *plSizeBitmap2)
{
if( *plSizeBitmap1 <= lExtraWorkSpace )
{
WorkSpaceOffsets->ulMemoryBase6Offset = ulMemoryOffset;
ulMemoryOffset += (uint32)*plSizeBitmap1;
if (( *plSizeBitmap2 <= lExtraWorkSpace - *plSizeBitmap1 ) &&
( *plSizeBitmap2 > 0L ))
{
WorkSpaceOffsets->ulMemoryBase7Offset = ulMemoryOffset;
*plSizeBitmap2 = 0L;
}
*plSizeBitmap1 = 0L;
}
else if (( *plSizeBitmap2 <= lExtraWorkSpace ) &&
( *plSizeBitmap2 > 0L))
{
WorkSpaceOffsets->ulMemoryBase7Offset = ulMemoryOffset;
*plSizeBitmap2 = 0L;
}
}
else /* (plSizeBitmap1 <= *plSizeBitmap2) */
{
if(( *plSizeBitmap2 <= lExtraWorkSpace ) &&
( *plSizeBitmap2 > 0L ))
{
WorkSpaceOffsets->ulMemoryBase7Offset = ulMemoryOffset;
ulMemoryOffset += (uint32)*plSizeBitmap2;
if (( *plSizeBitmap1 <= lExtraWorkSpace - *plSizeBitmap2 ) &&
( *plSizeBitmap1 > 0L ))
{
WorkSpaceOffsets->ulMemoryBase6Offset = ulMemoryOffset;
*plSizeBitmap1 = 0L;
}
*plSizeBitmap2 = 0L;
}
else if (( *plSizeBitmap1 <= lExtraWorkSpace ) &&
( *plSizeBitmap1 > 0L ))
{
WorkSpaceOffsets->ulMemoryBase6Offset = ulMemoryOffset;
*plSizeBitmap1 = 0L;
}
}
}
FS_PUBLIC void fsg_GetRealBitmapSizes(
fsg_WorkSpaceOffsets * WorkSpaceOffsets,
int32 * plSizeBitmap1,
int32 * plSizeBitmap2)
{
*plSizeBitmap1 = WorkSpaceOffsets->ulMemoryBase6Size;
*plSizeBitmap2 = WorkSpaceOffsets->ulMemoryBase7Size;
}
FS_PUBLIC void fsg_SetUpWorkSpaceBitmapMemory(
char * pWorkSpace,
fsg_WorkSpaceOffsets * WorkSpaceOffsets,
char * pClientBitmapPtr2,
char * pClientBitmapPtr3,
char ** ppMemoryBase6,
char ** ppMemoryBase7)
{
if(WorkSpaceOffsets->ulMemoryBase6Offset != 0L)
{
*ppMemoryBase6 = WorkSpaceOffsets->ulMemoryBase6Offset + (char *)pWorkSpace;
}
else
{
*ppMemoryBase6 = pClientBitmapPtr2;
}
if(WorkSpaceOffsets->ulMemoryBase7Offset != 0L)
{
*ppMemoryBase7 = WorkSpaceOffsets->ulMemoryBase7Offset + (char *)pWorkSpace;
}
else
{
*ppMemoryBase7 = pClientBitmapPtr3;
}
}
FS_PUBLIC void fsg_GetWorkSpaceExtra(
char * pWorkSpace,
fsg_WorkSpaceOffsets * WorkSpaceOffsets,
char ** ppWorkSpaceExtra)
{
*ppWorkSpaceExtra = (char *)(pWorkSpace + WorkSpaceOffsets->ulReusableMemoryOffset);
}
FS_PUBLIC void fsg_QueryPPEM(
void * pvGlobalGS,
uint16 * pusPPEM)
{
scl_QueryPPEM(pvGlobalGS, pusPPEM);
}
/* Return PPEM in both X and Y and 90 degree rotation factor for sbit matching */
FS_PUBLIC void fsg_QueryPPEMXY(
void * pvGlobalGS,
fsg_TransformRec * TransformInfo,
uint16 * pusPPEMX,
uint16 * pusPPEMY,
uint16 * pusRotation)
{
*pusRotation = mth_90degRotationFactor( &TransformInfo->currentTMatrix );
scl_QueryPPEMXY(pvGlobalGS, pusPPEMX, pusPPEMY);
}
/* FSGlue Access Routines */
FS_PUBLIC void fsg_GetContourData(
fsg_WorkSpaceAddr * pWorkSpaceAddr,
F26Dot6 ** pX,
F26Dot6 ** pY,
int16 ** pSp,
int16 ** pEp,
uint8 ** pOnCurve,
uint16 * pNc)
{
fnt_ElementType * pElement;
pElement = pWorkSpaceAddr->pGlyphElement;
*pX = pElement->x;
*pY = pElement->y;
*pSp = pElement->sp;
*pEp = pElement->ep;
*pOnCurve = pElement->onCurve;
*pNc = (uint16)pElement->nc;
}
FS_PUBLIC uint32 fsg_GetContourDataSize(
fsg_WorkSpaceAddr * pWorkSpaceAddr)
{
fnt_ElementType * pElement;
pElement = pWorkSpaceAddr->pGlyphElement;
return( scl_GetContourDataSize( pElement ) );
}
FS_PUBLIC void fsg_DumpContourData(
fsg_WorkSpaceAddr * pWorkSpaceAddr,
uint8 ** ppbyOutline)
{
fnt_ElementType * pElement;
pElement = pWorkSpaceAddr->pGlyphElement;
scl_DumpContourData(pElement, ppbyOutline);
}
FS_PUBLIC void fsg_RestoreContourData(
uint8 ** ppbyOutline,
F26Dot6 ** ppX,
F26Dot6 ** ppY,
int16 ** ppSp,
int16 ** ppEp,
uint8 ** ppOnCurve,
uint16 * pNc)
{
fnt_ElementType pElement;
scl_RestoreContourData(&pElement, ppbyOutline);
*ppX = pElement.x;
*ppY = pElement.y;
*ppSp = pElement.sp;
*ppEp = pElement.ep;
*ppOnCurve = pElement.onCurve;
*pNc = (uint16)pElement.nc;
}
FS_PUBLIC void fsg_GetDevAdvanceWidth(
fsg_WorkSpaceAddr * pWorkSpaceAddr,
point * pDevAdvanceWidth)
{
fnt_ElementType * pElement;
pElement = pWorkSpaceAddr->pGlyphElement;
scl_CalcDevAdvanceWidth(pElement, pDevAdvanceWidth);
}
FS_PUBLIC void fsg_GetScaledCVT(
char * pPrivateFontSpace,
fsg_PrivateSpaceOffsets * PrivateSpaceOffsets,
F26Dot6 ** ppScaledCVT)
{
*ppScaledCVT = (F26Dot6 *)(pPrivateFontSpace + PrivateSpaceOffsets->offset_controlValues);
}
FS_PUBLIC void fsg_45DegreePhaseShift(
fsg_WorkSpaceAddr * pWorkSpaceAddr)
{
fnt_ElementType * pElement;
pElement = pWorkSpaceAddr->pGlyphElement;
scl_45DegreePhaseShift(pElement);
}
FS_PUBLIC void fsg_UpdateAdvanceWidth (
fsg_TransformRec * TransformInfo,
void * pvGlobalGS,
uint16 usNonScaledAW,
vectorType * AdvanceWidth)
{
AdvanceWidth->y = 0;
scl_ScaleAdvanceWidth(
pvGlobalGS,
AdvanceWidth,
usNonScaledAW,
TransformInfo->bPositiveSquare,
TransformInfo->usEmResolution,
&TransformInfo->currentTMatrix);
}
FS_PUBLIC void fsg_ScaleVerticalMetrics (
fsg_TransformRec * TransformInfo,
void * pvGlobalGS,
uint16 usNonScaledAH,
int16 sNonScaledTSB,
vectorType * pvecAdvanceHeight,
vectorType * pvecTopSideBearing )
{
pvecAdvanceHeight->x = 0; /* start with x values at zero */
pvecTopSideBearing->x = 0; /* since 'vmtx' refers to y values */
scl_ScaleVerticalMetrics (
pvGlobalGS,
usNonScaledAH,
sNonScaledTSB,
TransformInfo->bPositiveSquare,
TransformInfo->usEmResolution,
&TransformInfo->currentTMatrix,
pvecAdvanceHeight,
pvecTopSideBearing);
}
FS_PUBLIC void fsg_CalcLSBsAndAdvanceWidths(
fsg_WorkSpaceAddr * pWorkSpaceAddr,
F26Dot6 fxXMin,
F26Dot6 fxYMax,
point * devAdvanceWidth,
point * devLeftSideBearing,
point * LeftSideBearing,
point * devLeftSideBearingLine,
point * LeftSideBearingLine)
{
fnt_ElementType * pElement;
pElement = pWorkSpaceAddr->pGlyphElement;
scl_CalcLSBsAndAdvanceWidths(
pElement,
fxXMin,
fxYMax,
devAdvanceWidth,
devLeftSideBearing,
LeftSideBearing,
devLeftSideBearingLine,
LeftSideBearingLine);
}
FS_PUBLIC boolean fsg_IsTransformStretched(
fsg_TransformRec * TransformInfo)
{
return (boolean)(( TransformInfo->ulImageState & IMAGESTATE_STRETCHED ) == IMAGESTATE_STRETCHED);
}
FS_PUBLIC boolean fsg_IsTransformRotated(
fsg_TransformRec * TransformInfo)
{
return (boolean)(( TransformInfo->ulImageState & IMAGESTATE_ROTATED ) == IMAGESTATE_ROTATED);
}
/* Control Routines */
FS_PUBLIC ErrorCode fsg_InitInterpreterTrans (
fsg_TransformRec * TransformInfo,
void * pvGlobalGS,
Fixed fxPointSize,
int16 sXResolution,
int16 sYResolution)
{
ErrorCode error;
uint32 ulPixelsPerEm;
transMatrix * trans;
trans = &TransformInfo->currentTMatrix;
error = scl_InitializeScaling(
pvGlobalGS,
TransformInfo->bIntegerScaling,
&TransformInfo->currentTMatrix,
TransformInfo->usEmResolution,
fxPointSize,
sXResolution,
sYResolution,
&ulPixelsPerEm);
if(error)
{
return error;
}
TransformInfo->bPhaseShift = false;
if ( ulPixelsPerEm > IMAGESTATE_MAX_PPEM_SIZE )
{
TransformInfo->ulImageState = (uint32)IMAGESTATE_MAX_PPEM_SIZE;
}
else
{
TransformInfo->ulImageState = ulPixelsPerEm;
}
TransformInfo->bPositiveSquare = mth_PositiveSquare( trans );
if ( !(mth_PositiveRectangle( trans )))
{
TransformInfo->ulImageState |= IMAGESTATE_NON_POS_RECT;
}
if ( !(TransformInfo->bPositiveSquare) )
{
if( mth_GeneralRotation (trans))
{
TransformInfo->ulImageState |= IMAGESTATE_ROTATED;
}
TransformInfo->ulImageState |= IMAGESTATE_STRETCHED;
TransformInfo->bPhaseShift = mth_IsMatrixStretched(trans); /*<8>*/
}
return NO_ERR;
}
/*
* All this guy does is record FDEFs and IDEFs, anything else is ILLEGAL
*/
FS_PUBLIC ErrorCode fsg_RunFontProgram(
void * pvGlobalGS, /* GlobalGS */
fsg_WorkSpaceAddr * pWorkSpaceAddr,
void * pvTwilightElement)
{
return itrp_ExecuteFontPgm (
(fnt_ElementType *)pvTwilightElement,
pWorkSpaceAddr->pGlyphElement,
pvGlobalGS,
0);
}
/*
* fsg_RunPreProgram
*
* Runs the pre-program and scales the control value table
*
*/
FS_PUBLIC ErrorCode fsg_RunPreProgram (
sfac_ClientRec * ClientInfo,
LocalMaxProfile * pMaxProfile, /* Max Profile Table */
fsg_TransformRec * TransformInfo,
void * pvGlobalGS,
fsg_WorkSpaceAddr * pWorkSpaceAddr,
void * pvTwilightElement,
FntTraceFunc traceFunc)
{
ErrorCode result;
F26Dot6 * pfxCVT;
fnt_ElementType * pTwilightElement;
pTwilightElement = (fnt_ElementType *)pvTwilightElement;
result = itrp_SetDefaults (pvGlobalGS, TransformInfo->fxPixelDiameter);
if (result != NO_ERR)
{
return result;
}
scl_GetCVTPtr(pvGlobalGS, &pfxCVT);
result = sfac_CopyCVT(ClientInfo, pfxCVT);
if (result != NO_ERR)
{
return result;
}
scl_ScaleCVT (pvGlobalGS, pfxCVT);
scl_InitializeTwilightContours(
pTwilightElement,
(int16)pMaxProfile->maxTwilightPoints,
MAX_TWILIGHT_CONTOURS);
scl_ZeroOutlineData(
pTwilightElement,
pMaxProfile->maxTwilightPoints,
MAX_TWILIGHT_CONTOURS);
result = itrp_ExecutePrePgm (
pTwilightElement,
pWorkSpaceAddr->pGlyphElement,
pvGlobalGS,
traceFunc);
return result;
}
/*
* fsg_GridFit
*/
FS_PUBLIC ErrorCode fsg_GridFit (
sfac_ClientRec * ClientInfo, /* sfnt Client information */
LocalMaxProfile * pMaxProfile, /* Max Profile Table */
fsg_TransformRec * TransformInfo, /* Transformation information */
void * pvGlobalGS, /* GlobalGS */
fsg_WorkSpaceAddr * pWorkSpaceAddr,
void * pvTwilightElement,
FntTraceFunc traceFunc,
boolean bUseHints,
uint16 * pusScanType,
boolean * pbGlyphHasOutline,
uint16 * pusNonScaledAW)
{
ErrorCode result;
fnt_ElementType * pTwilightElement;
pTwilightElement = (fnt_ElementType *)pvTwilightElement;
scl_InitializeTwilightContours(
pTwilightElement,
(int16)pMaxProfile->maxTwilightPoints,
MAX_TWILIGHT_CONTOURS);
result = fsg_CreateGlyphData (
ClientInfo,
pMaxProfile,
TransformInfo,
pvGlobalGS,
pWorkSpaceAddr,
pTwilightElement,
traceFunc,
bUseHints,
pusScanType,
pbGlyphHasOutline,
pusNonScaledAW);
if(result == NO_ERR)
{
if (TransformInfo->ulImageState & (IMAGESTATE_NON_POS_RECT))
{
scl_PostTransformGlyph (
pvGlobalGS,
pWorkSpaceAddr->pGlyphElement,
&TransformInfo->currentTMatrix);
}
}
return result;
}
FS_PRIVATE ErrorCode fsg_CreateGlyphData(
sfac_ClientRec * ClientInfo, /* sfnt Client information */
LocalMaxProfile * pMaxProfile, /* Max Profile Table */
fsg_TransformRec * TransformInfo, /* Transformation information */
void * pvGlobalGS, /* GlobalGS */
fsg_WorkSpaceAddr * pWorkSpaceAddr, /* WorkSpace Address */
fnt_ElementType * pTwilightElement, /* Twilight zone element */
FntTraceFunc traceFunc, /* Trace function for interpreter */
boolean bUseHints, /* True if glyph is gridfitted */
uint16 * pusScanType, /* ScanType value */
boolean * pbGlyphHasOutline, /* Outline for glyph */
uint16 * pusNonScaledAW) /* Return NonScaled Advance Width */
{
GlyphData * pGlyphData;
GlyphData * pNextGlyphData;
boolean bHasOutline;
uint32 ulGlyphDataCount;
ErrorCode ReturnCode;
*pbGlyphHasOutline = FALSE;
bHasOutline = FALSE;
ulGlyphDataCount = MAX_NESTED_GLYPHS(pMaxProfile);
fsg_InitializeGlyphDataMemory(ulGlyphDataCount, pWorkSpaceAddr);
fsg_AllocateGlyphDataMemory(ulGlyphDataCount, pWorkSpaceAddr, &pGlyphData); /* Allocates GlyphData for topmost */
/* parent */
fsg_InitializeGlyphData(pGlyphData, pWorkSpaceAddr,
ClientInfo->usGlyphIndex, COMPOSITE_ROOT);
while(pGlyphData != NULL)
{
ReturnCode = fsg_ExecuteGlyph(
ClientInfo,
pMaxProfile,
TransformInfo,
ulGlyphDataCount,
pvGlobalGS,
pGlyphData,
pWorkSpaceAddr,
pTwilightElement,
traceFunc,
bUseHints,
&bHasOutline);
if(ReturnCode)
{
return ReturnCode;
}
*pbGlyphHasOutline |= bHasOutline;
*pusScanType = pGlyphData->usScanType;
fsg_ChooseNextGlyph(pWorkSpaceAddr, pGlyphData, &pNextGlyphData);
*pusNonScaledAW = pGlyphData->usNonScaledAW;
pGlyphData = pNextGlyphData;
}
return NO_ERR;
}
FS_PRIVATE ErrorCode fsg_ExecuteGlyph(
sfac_ClientRec * ClientInfo, /* sfnt Client information */
LocalMaxProfile * pMaxProfile, /* Max Profile Table */
fsg_TransformRec * TransformInfo, /* Transformation information */
uint32 ulGlyphDataCount, /* Max Number of nested glyphs */
void * pvGlobalGS, /* GlobalGS */
GlyphData * pGlyphData, /* GlyphData pointer */
fsg_WorkSpaceAddr * pWorkSpaceAddr, /* WorkSpace Address */
fnt_ElementType * pTwilightElement, /* Twilight zone element */
FntTraceFunc traceFunc, /* Trace function for interpreter */
boolean bUseHints, /* True if glyph is gridfitted */
boolean * pbHasOutline) /* True if glyph has outline */
{
ErrorCode ReturnCode;
boolean bCompositeGlyph;
boolean bLastComponent;
boolean bWeHaveInstructions;
boolean bWeHaveCompositeInstructions;
boolean bScanInfoChanged;
uint16 usScanType;
uint16 usScanControl;
GlyphData * pChildGlyphData;
uint16 usComponentElementCount;
*pbHasOutline = FALSE;
if (pGlyphData->GlyphType == glyphUndefined)
{
if(pGlyphData->pParent != NULL)
{
scl_IncrementChildElement(pGlyphData->pGlyphElement, pGlyphData->pParent->pGlyphElement);
}
ReturnCode = sfac_ReadGlyphHeader(ClientInfo, pGlyphData->usGlyphIndex,
&pGlyphData->hGlyph, &bCompositeGlyph, pbHasOutline,
&pGlyphData->pGlyphElement->nc, &pGlyphData->bbox);
if(ReturnCode != NO_ERR)
{
return ReturnCode;
}
/* Get advance width and left side bearing information */
ReturnCode = sfac_ReadGlyphMetrics(
ClientInfo, pGlyphData->usGlyphIndex,
&pGlyphData->usNonScaledAW, &pGlyphData->sNonScaledLSB);
if(ReturnCode != NO_ERR)
{
return ReturnCode;
}
if (bCompositeGlyph)
{
pGlyphData->GlyphType = glyphIncompleteComposite;
}
else
{
pGlyphData->GlyphType = glyphSimple;
}
}
if (pGlyphData->GlyphType == glyphSimple)
{
ReturnCode = sfac_ReadOutlineData(
pGlyphData->pGlyphElement->onCurve,
pGlyphData->pGlyphElement->ooy, pGlyphData->pGlyphElement->oox,
&pGlyphData->hGlyph, pMaxProfile, *pbHasOutline, pGlyphData->pGlyphElement->nc,
pGlyphData->pGlyphElement->sp, pGlyphData->pGlyphElement->ep,
&pGlyphData->usSizeOfInstructions, &pGlyphData->pbyInstructions);
if(ReturnCode != NO_ERR)
{
return ReturnCode;
}
ReturnCode = fsg_SimpleInnerGridFit(
pvGlobalGS,
pTwilightElement,
pGlyphData->pGlyphElement,
bUseHints,
traceFunc,
TransformInfo->usEmResolution,
pGlyphData->usNonScaledAW,
pGlyphData->sNonScaledLSB,
&pGlyphData->bbox,
pGlyphData->usSizeOfInstructions,
pGlyphData->pbyInstructions,
&usScanType,
&usScanControl,
&bScanInfoChanged);
if(ReturnCode != NO_ERR)
{
return ReturnCode;
}
if( ! fsg_DoScanControl(usScanControl, TransformInfo->ulImageState))
{
pGlyphData->usScanType = SK_NODROPOUT;
}
else
{
pGlyphData->usScanType = usScanType;
}
if (pGlyphData->pParent != NULL)
{
fsg_MergeGlyphData(pvGlobalGS, pGlyphData);
}
ReturnCode = sfac_ReleaseGlyph(ClientInfo, &pGlyphData->hGlyph);
if(ReturnCode != NO_ERR)
{
return ReturnCode;
}
pGlyphData->pbyInstructions = 0;
pGlyphData->usSizeOfInstructions = 0;
}
else if (pGlyphData->GlyphType == glyphComposite)
{
ReturnCode = fsg_CompositeInnerGridFit(
pvGlobalGS,
pTwilightElement,
pGlyphData->pGlyphElement,
bUseHints,
traceFunc,
TransformInfo->usEmResolution,
pGlyphData->usNonScaledAW,
pGlyphData->sNonScaledLSB,
&pGlyphData->bbox,
pGlyphData->usSizeOfInstructions,
pGlyphData->pbyInstructions,
&usScanType,
&usScanControl,
&bScanInfoChanged);
if(ReturnCode != NO_ERR)
{
return ReturnCode;
}
if (pGlyphData->bUseChildMetrics)
{
scl_SetSideBearingPoints(
pGlyphData->pGlyphElement,
&pGlyphData->ptDevLSB,
&pGlyphData->ptDevRSB);
}
/* If composite has set SCANCTRL, use that value, otherwise merged children */
if(bScanInfoChanged)
{
if( ! fsg_DoScanControl(usScanControl, TransformInfo->ulImageState))
{
pGlyphData->usScanType = SK_NODROPOUT;
}
else
{
pGlyphData->usScanType = usScanType;
}
}
if (pGlyphData->pParent != NULL)
{
fsg_MergeGlyphData(pvGlobalGS, pGlyphData);
}
ReturnCode = sfac_ReleaseGlyph(ClientInfo, &pGlyphData->hGlyph);
if(ReturnCode != NO_ERR)
{
return ReturnCode;
}
pGlyphData->pbyInstructions = 0;
pGlyphData->usSizeOfInstructions = 0;
}
else if (pGlyphData->GlyphType == glyphIncompleteComposite)
{
bLastComponent = FALSE;
bWeHaveInstructions = FALSE;
bWeHaveCompositeInstructions = FALSE;
pGlyphData->GlyphType = glyphComposite;
usComponentElementCount = 0;
do
{
if(pGlyphData->usDepth + 1UL > MAX_COMPONENT_DEPTH(pMaxProfile))
{
return BAD_MAXP_DATA;
}
usComponentElementCount++;
if(usComponentElementCount > MAX_COMPONENT_ELEMENTS(pMaxProfile))
{
return BAD_MAXP_DATA;
}
fsg_AllocateGlyphDataMemory(ulGlyphDataCount, pWorkSpaceAddr, &pChildGlyphData);
fsg_InitializeGlyphData(
pChildGlyphData,
pWorkSpaceAddr,
NULL_GLYPH,
(uint16)(pGlyphData->usDepth + 1U) );
fsg_LinkChild(pGlyphData, pChildGlyphData);
ReturnCode = sfac_ReadComponentData(
&pGlyphData->hGlyph,
&pChildGlyphData->MultiplexingIndicator,
&pChildGlyphData->bRoundXYToGrid,
&pChildGlyphData->bUseMyMetrics,
&bWeHaveInstructions,
&pChildGlyphData->usGlyphIndex,
&pChildGlyphData->sXOffset,
&pChildGlyphData->sYOffset,
&pChildGlyphData->usAnchorPoint1,
&pChildGlyphData->usAnchorPoint2,
&pChildGlyphData->mulT,
&bLastComponent);
if(ReturnCode != NO_ERR)
{
return ReturnCode;
}
bWeHaveCompositeInstructions |= bWeHaveInstructions;
}
while (!bLastComponent);
if(bWeHaveCompositeInstructions)
{
ReturnCode = sfac_ReadCompositeInstructions(
&pGlyphData->hGlyph,
&pGlyphData->pbyInstructions,
&pGlyphData->usSizeOfInstructions);
if(ReturnCode != NO_ERR)
{
return ReturnCode;
}
}
}
return NO_ERR;
}
/*
* fsg_SimpleInnerGridFit
*/
FS_PRIVATE ErrorCode fsg_SimpleInnerGridFit (
void * pvGlobalGS,
fnt_ElementType * pTwilightElement,
fnt_ElementType * pGlyphElement,
boolean bUseHints,
FntTraceFunc traceFunc,
uint16 usEmResolution,
uint16 usNonScaledAW,
int16 sNonScaledLSB,
BBOX * bbox,
uint16 usSizeOfInstructions,
uint8 * instructionPtr,
uint16 * pusScanType,
uint16 * pusScanControl,
boolean * pbChangeScanControl)
{
ErrorCode result;
/*
On entry to fsg_SimpleInnerGrid fit the element structure should
contain only valid original points (oox, ooy). The original points
will be scaled into the old points (ox, oy) and those will be
copied into the current points (x, y).
*/
itrp_SetCompositeFlag(pvGlobalGS, FALSE);
itrp_QueryScanInfo(pvGlobalGS, pusScanType, pusScanControl);
*pbChangeScanControl = FALSE;
scl_CalcOrigPhantomPoints(pGlyphElement, bbox, sNonScaledLSB, usNonScaledAW);
scl_ScaleOldCharPoints (pGlyphElement, pvGlobalGS);
scl_ScaleOldPhantomPoints (pGlyphElement, pvGlobalGS);
if (itrp_bApplyHints(pvGlobalGS) && bUseHints)
{
scl_AdjustOldCharSideBearing(pGlyphElement);
scl_AdjustOldPhantmSideBearing(pGlyphElement);
scl_CopyCurrentCharPoints(pGlyphElement);
scl_CopyCurrentPhantomPoints(pGlyphElement);
scl_RoundCurrentSideBearingPnt(pGlyphElement, pvGlobalGS, usEmResolution);
if (usSizeOfInstructions > 0)
{
scl_ZeroOutlineFlags(pGlyphElement);
result = itrp_ExecuteGlyphPgm (
pTwilightElement,
pGlyphElement,
instructionPtr,
instructionPtr + usSizeOfInstructions,
pvGlobalGS,
traceFunc,
pusScanType,
pusScanControl,
pbChangeScanControl);
if(result != NO_ERR)
{
return result;
}
}
}
else
{
scl_CopyCurrentCharPoints(pGlyphElement);
scl_CopyCurrentPhantomPoints(pGlyphElement);
}
return NO_ERR;
}
/*
* fsg_CompositeInnerGridFit
*/
FS_PRIVATE ErrorCode fsg_CompositeInnerGridFit (
void * pvGlobalGS,
fnt_ElementType * pTwilightElement,
fnt_ElementType * pGlyphElement,
boolean bUseHints,
FntTraceFunc traceFunc,
uint16 usEmResolution,
uint16 usNonScaledAW,
int16 sNonScaledLSB,
BBOX * bbox,
uint16 usSizeOfInstructions,
uint8 * instructionPtr,
uint16 * pusScanType,
uint16 * pusScanControl,
boolean * pbChangeScanControl)
{
ErrorCode result;
/*
On entry to fsg_CompositeInnerGridFit, the current points (x, y)
are the only valid points in the element. We copy the current points
onto the old points (ox, oy)
*/
itrp_SetCompositeFlag(pvGlobalGS, TRUE);
itrp_QueryScanInfo(pvGlobalGS, pusScanType, pusScanControl);
*pbChangeScanControl = FALSE;
/* Note: The original composite character points are invalid at this point. */
/* The interpreter handles this case correctly for composites. */
scl_CalcOrigPhantomPoints(pGlyphElement, bbox, sNonScaledLSB, usNonScaledAW);
scl_CopyOldCharPoints(pGlyphElement);
scl_ScaleOldPhantomPoints (pGlyphElement, pvGlobalGS);
if (itrp_bApplyHints(pvGlobalGS) && bUseHints)
{
scl_AdjustOldSideBearingPoints(pGlyphElement);
scl_CopyCurrentPhantomPoints(pGlyphElement);
scl_RoundCurrentSideBearingPnt(pGlyphElement, pvGlobalGS, usEmResolution);
if (usSizeOfInstructions > 0)
{
scl_ZeroOutlineFlags(pGlyphElement);
result = itrp_ExecuteGlyphPgm (
pTwilightElement,
pGlyphElement,
instructionPtr,
instructionPtr + usSizeOfInstructions,
pvGlobalGS,
traceFunc,
pusScanType,
pusScanControl,
pbChangeScanControl);
if(result != NO_ERR)
{
return result;
}
}
}
else
{
scl_CopyCurrentPhantomPoints(pGlyphElement);
}
return NO_ERR;
}
FS_PRIVATE void fsg_ChooseNextGlyph(
fsg_WorkSpaceAddr * pWorkSpaceAddr, /* WorkSpace Address */
GlyphData * pGlyphData, /* GlyphData pointer */
GlyphData ** ppNextGlyphData)/* Next GlyphData pointer */
{
if (pGlyphData->pChild != NULL)
{
*ppNextGlyphData = pGlyphData->pChild;
CHECK_GLYPHDATA(*ppNextGlyphData);
pGlyphData->pChild = NULL;
}
else
{
*ppNextGlyphData = pGlyphData->pSibling;
CHECK_GLYPHDATA(*ppNextGlyphData);
fsg_DeallocateGlyphDataMemory(pWorkSpaceAddr, pGlyphData);
}
}
FS_PRIVATE void fsg_MergeGlyphData(
void * pvGlobalGS, /* GlobalGS */
GlyphData * pChildGlyphData)/* GlyphData pointer */
{
fnt_ElementType * pChildElement;
fnt_ElementType * pParentElement;
F26Dot6 fxXOffset, fxYOffset;
GlyphData * pParentGlyphData; /* Parent GlyphData pointer */
CHECK_GLYPHDATA(pChildGlyphData);
pParentGlyphData = pChildGlyphData->pParent;
CHECK_GLYPHDATA(pParentGlyphData);
pChildElement = pChildGlyphData->pGlyphElement;
pParentElement = pParentGlyphData->pGlyphElement;
fsg_TransformChild(pChildGlyphData);
if (pChildGlyphData->MultiplexingIndicator == OffsetPoints)
{
scl_CalcComponentOffset(
pvGlobalGS,
pChildGlyphData->sXOffset,
pChildGlyphData->sYOffset,
pChildGlyphData->bRoundXYToGrid,
&fxXOffset,
&fxYOffset);
}
else /* Values are anchor points */
{
RAST_ASSERT(pChildGlyphData->MultiplexingIndicator == AnchorPoints,
"Bad Multiplexing Indicator");
scl_CalcComponentAnchorOffset(
pParentElement,
pChildGlyphData->usAnchorPoint1,
pChildElement,
pChildGlyphData->usAnchorPoint2,
&fxXOffset,
&fxYOffset);
}
scl_ShiftCurrentCharPoints(pChildElement, fxXOffset, fxYOffset);
/* If USE_MY_METRICS, copy side bearings to parent */
if (pChildGlyphData->bUseMyMetrics)
{
pParentGlyphData->bUseChildMetrics = TRUE;
scl_SaveSideBearingPoints(
pChildElement,
&pParentGlyphData->ptDevLSB,
&pParentGlyphData->ptDevRSB);
}
fsg_MergeScanType(pChildGlyphData, pParentGlyphData);
/* Start the copy */
/* scl_AppendOutlineData(pChildElement, pParentElement); */
scl_UpdateParentElement(pChildElement, pParentElement);
pChildElement->nc = 0;
}
FS_PRIVATE void fsg_LinkChild(
GlyphData * pGlyphData, /* GlyphData pointer */
GlyphData * pChildGlyphData)/* Child GlyphData pointer */
{
GlyphData * pTempGlyphData;
if (pGlyphData->pChild == NULL)
{
pGlyphData->pChild = pChildGlyphData;
}
else
{
pTempGlyphData = pGlyphData->pChild;
CHECK_GLYPHDATA(pTempGlyphData);
while (pTempGlyphData->pSibling != pGlyphData)
{
pTempGlyphData = pTempGlyphData->pSibling;
CHECK_GLYPHDATA(pTempGlyphData);
}
pTempGlyphData->pSibling = pChildGlyphData;
}
pChildGlyphData->pSibling = pGlyphData;
pChildGlyphData->pParent = pGlyphData;
}
FS_PRIVATE void fsg_TransformChild(
GlyphData * pGlyphData) /* GlyphData pointer */
{
/* Apply local transform to glyph */
if (!mth_Identity(&pGlyphData->mulT))
{
scl_LocalPostTransformGlyph (pGlyphData->pGlyphElement, &pGlyphData->mulT);
}
}
FS_PRIVATE void fsg_MergeScanType(
GlyphData * pGlyphData, /* GlyphData pointer */
GlyphData * pParentGlyphData) /* GlyphData pointer */
{
CHECK_GLYPHDATA(pGlyphData);
CHECK_GLYPHDATA(pParentGlyphData);
/* Merge Scan Type of parent and child */
if(pParentGlyphData->usScanType != SCANTYPE_UNINITIALIZED)
{
pParentGlyphData->usScanType =
(uint16)(((pParentGlyphData->usScanType & (SK_NODROPOUT | SK_STUBS)) &
(pGlyphData->usScanType & (SK_NODROPOUT | SK_STUBS))) |
(pParentGlyphData->usScanType & SK_SMART));
}
else
{
pParentGlyphData->usScanType = pGlyphData->usScanType;
}
}
/* Use various spline key values to determine if dropout control is to be activated
* for this glyph, and if so what kind of dropout control.
* The use of dropout control mode in the scan converter is controlled by 3 conditions.
* The conditions are: Is the glyph rotated?, is the glyph stretched?,
* is the current pixels per Em less than a specified threshold?
* These conditions can be OR'd or ANDed together to determine whether the dropout control
* mode ought to be used.
Six bits are used to specify the joint condition. Their meanings are:
BIT Meaning if set
8 Do dropout mode if other conditions don't block it AND
pixels per em is less than or equal to bits 0-7
9 Do dropout mode if other conditions don't block it AND
glyph is rotated
10 Do dropout mode if other conditions don't block it AND
glyph is stretched
11 Do not do dropout mode unless ppem is less than or equal to bits 0-7
A value of FF in 0-7 means all sizes
A value of 0 in 0-7 means no sizes
12 Do not do dropout mode unless glyph is rotated
13 Do not do dropout mode unless glyph is stretched
In other words, we do not do dropout control if:
No bits are set,
Bit 8 is set, but ppem is greater than threshold
Bit 9 is set, but glyph is not rotated
Bit 10 is set, but glyph is not stretched
None of the conditions specified by bits 11-13 are true.
For example, 0xA10 specifies turn dropout control on if the glyph is rotated providing
that it is also less than 0x10 pixels per em. A glyph is considered stretched if
the X and Y resolutions are different either because of the device characteristics
or because of the transformation matrix. If both X and Y are changed by the same factor
the glyph is not considered stretched.
*/
FS_PRIVATE boolean fsg_DoScanControl(
uint16 usScanControl,
uint32 ulImageState)
{
if ((usScanControl & SCANCTRL_DROPOUT_IF_LESS) &&
((uint8)(ulImageState & IMAGESTATE_SIZE_MASK) <= (uint8)(usScanControl & SCANCTRL_SIZE_MASK)))
{
return TRUE;
}
if ((usScanControl & SCANCTRL_DROPOUT_IF_LESS) &&
((usScanControl & SCANCTRL_SIZE_MASK) == SCANCTRL_DROPOUT_ALL_SIZES))
{
return TRUE;
}
if ((usScanControl & SCANCTRL_DROPOUT_IF_ROTATED) &&
(ulImageState & IMAGESTATE_ROTATED))
{
return TRUE;
}
if ((usScanControl & SCANCTRL_DROPOUT_IF_STRETCHED) &&
(ulImageState & IMAGESTATE_STRETCHED))
{
return TRUE;
}
if ((usScanControl & SCANCTRL_NODROP_UNLESS_LESS) &&
((uint8)(ulImageState & IMAGESTATE_SIZE_MASK) > (uint8)(usScanControl & SCANCTRL_SIZE_MASK)))
{
return FALSE;
}
if ((usScanControl & SCANCTRL_NODROP_UNLESS_ROTATED) &&
! (ulImageState & IMAGESTATE_ROTATED))
{
return FALSE;
}
if ((usScanControl & SCANCTRL_NODROP_UNLESS_STRETCH) &&
! (ulImageState & IMAGESTATE_STRETCHED))
{
return FALSE;
}
return FALSE;
}
FS_PRIVATE void fsg_InitializeGlyphDataMemory(
uint32 ulGlyphDataCount,
fsg_WorkSpaceAddr * pWorkSpaceAddr) /* WorkSpace Address */
{
uint32 ulIndex;
boolean * abyGlyphDataFreeBlocks;
abyGlyphDataFreeBlocks = pWorkSpaceAddr->pGlyphDataByteSet;
for(ulIndex = 0; ulIndex < ulGlyphDataCount; ulIndex++)
{
abyGlyphDataFreeBlocks[ulIndex] = TRUE;
}
RAST_ASSERT((&abyGlyphDataFreeBlocks[ulIndex] == (GlyphData *)(pWorkSpaceAddr->pvGlyphData)),
"Glyph Data initialization error.");
}
FS_PRIVATE void fsg_AllocateGlyphDataMemory(
uint32 ulGlyphDataCount,
fsg_WorkSpaceAddr * pWorkSpaceAddr, /* WorkSpace Address */
GlyphData ** ppGlyphData) /* GlyphData pointer */
{
uint32 ulIndex;
boolean * abyGlyphDataFreeBlocks;
abyGlyphDataFreeBlocks = pWorkSpaceAddr->pGlyphDataByteSet;
ulIndex = 0;
while((!abyGlyphDataFreeBlocks[ulIndex]) && ulIndex < ulGlyphDataCount)
{
ulIndex++;
}
RAST_ASSERT((ulIndex != ulGlyphDataCount), "GlyphData Allocation Error");
abyGlyphDataFreeBlocks[ulIndex] = FALSE;
*ppGlyphData = (GlyphData *)&((GlyphData *)pWorkSpaceAddr->pvGlyphData)[ulIndex];
}
FS_PRIVATE void fsg_DeallocateGlyphDataMemory(
fsg_WorkSpaceAddr * pWorkSpaceAddr, /* WorkSpace Address */
GlyphData * pGlyphData) /* GlyphData pointer */
{
ptrdiff_t ptIndex;
boolean * abyGlyphDataFreeBlocks;
pGlyphData->acIdent[0] = '\0';
pGlyphData->acIdent[1] = '\0';
abyGlyphDataFreeBlocks = pWorkSpaceAddr->pGlyphDataByteSet;
ptIndex = (ptrdiff_t)(pGlyphData - (GlyphData *)pWorkSpaceAddr->pvGlyphData);
abyGlyphDataFreeBlocks[ptIndex] = TRUE;
}
FS_PRIVATE void fsg_InitializeGlyphData(
GlyphData * pGlyphData, /* GlyphData pointer */
fsg_WorkSpaceAddr * pWorkSpaceAddr, /* WorkSpace Address */
uint16 usGlyphIndex, /* Glyph Index */
uint16 usDepth) /* Glyph depth */
{
pGlyphData->acIdent[0] = 'G';
pGlyphData->acIdent[1] = 'D';
pGlyphData->pSibling = NULL;
pGlyphData->pChild = NULL;
pGlyphData->pParent = NULL;
pGlyphData->GlyphType = glyphUndefined;
pGlyphData->hGlyph.pvGlyphBaseAddress = NULL;
pGlyphData->hGlyph.pvGlyphNextAddress = NULL;
pGlyphData->usDepth = usDepth;
pGlyphData->bUseMyMetrics = FALSE;
pGlyphData->bUseChildMetrics = FALSE;
pGlyphData->bbox.xMin = SHRT_MAX;
pGlyphData->bbox.yMin = SHRT_MAX;
pGlyphData->bbox.xMax = SHRT_MIN;
pGlyphData->bbox.yMax = SHRT_MIN;
pGlyphData->usSizeOfInstructions = 0;
pGlyphData->pbyInstructions = NULL;
pGlyphData->usNonScaledAW = 0;
pGlyphData->sNonScaledLSB = 0;
pGlyphData->MultiplexingIndicator = Undefined;
pGlyphData->bRoundXYToGrid = FALSE;
pGlyphData->usGlyphIndex = usGlyphIndex;
pGlyphData->sXOffset = 0;
pGlyphData->sYOffset = 0;
pGlyphData->usAnchorPoint1 = 0;
pGlyphData->usAnchorPoint2 = 0;
pGlyphData->mulT = IdentTransform;
pGlyphData->usScanType = SCANTYPE_UNINITIALIZED;
pGlyphData->ptDevLSB.x = 0L;
pGlyphData->ptDevLSB.y = 0L;
pGlyphData->ptDevRSB.x = 0L;
pGlyphData->ptDevRSB.y = 0L;
pGlyphData->pGlyphElement = &pWorkSpaceAddr->pGlyphElement[usDepth];
pGlyphData->pGlyphElement->nc = 0;
}
#ifdef FSCFG_NO_INITIALIZED_DATA
FS_PUBLIC void fsg_InitializeData (void)
{
itrp_InitializeData ();
}
#endif