Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1945 lines
67 KiB

/* @(#)CM_VerSion xcf_cff.c atm09 1.3 16499.eco sum= 57954 atm09.002 */
/* @(#)CM_VerSion xcf_cff.c atm08 1.7 16343.eco sum= 21676 atm08.005 */
/***********************************************************************/
/* */
/* Copyright 1995-1996 Adobe Systems Incorporated. */
/* All rights reserved. */
/* */
/* Patents Pending */
/* */
/* NOTICE: All information contained herein is the property of Adobe */
/* Systems Incorporated. Many of the intellectual and technical */
/* concepts contained herein are proprietary to Adobe, are protected */
/* as trade secrets, and are made available only to Adobe licensees */
/* for their internal use. Any reproduction or dissemination of this */
/* software is strictly forbidden unless prior written permission is */
/* obtained from Adobe. */
/* */
/* PostScript and Display PostScript are trademarks of Adobe Systems */
/* Incorporated or its subsidiaries and may be registered in certain */
/* jurisdictions. */
/* */
/***********************************************************************/
/***********************************************************************
Original version: John Felton, Dec 12 1995
************************************************************************/
/* -------------------------------------------------------------------------
Header Includes
--------------------------------------------------------------------- */
#ifdef __cplusplus
extern "C" {
#endif
#include "xcf_pub.h"
#include "xcf_priv.h"
#ifdef T13
#include "xcf_t13.h"
#endif
char PTR_PREFIX *stdStrIndex[] = {
#include "xcf_sstr.h"
};
static StringID isoAdobeCharset[] = {
#include "xcf_isoc.h"
};
static StringID expertCharset[] = {
#include "xcf_expc.h"
};
static StringID expertSubsetCharset[] = {
#include "xcf_exsc.h"
};
static StringID stdEncoding[] = {
#include "xcf_stde.h"
};
static StringID expertEncoding[] = {
#include "xcf_expe.h"
};
void XCF_ReadBlock(XCF_Handle h, Offset pos, Card32 length)
{
if (!h->callbacks.getBytes(&h->inBuffer.start, pos, (short int) length, h->callbacks.getBytesHook))
XCF_FATAL_ERROR(h, XCF_GetBytesCallbackFailure, "Read block error.", 0);
h->inBuffer.pos = h->inBuffer.start;
h->inBuffer.end = (unsigned char PTR_PREFIX *)h->inBuffer.start + length;
h->inBuffer.blockOffset = pos;
h->inBuffer.blockLength = length;
}
void XCF_LookUpTableEntry(XCF_Handle h, IndexDesc PTR_PREFIX *pIndex, CardX index)
{
Card32 offset, nextOffset;
Card16 length;
offset = pIndex->offsetArrayOffset + (pIndex->offsetSize*index);
XCF_ReadBlock(h, offset, pIndex->offsetSize*2);
offset = XCF_Read(h, pIndex->offsetSize);
nextOffset = XCF_Read(h, pIndex->offsetSize);
length = (Card16) (nextOffset - offset);
XCF_ReadBlock(h, pIndex->dataOffset + offset, length);
}
static Offset ReadTableInfo(XCF_Handle h, Offset pos, IndexDesc PTR_PREFIX *pIndex)
{
XCF_ReadBlock(h, pos, 2);
pIndex->count = XCF_Read2(h);
if (pIndex->count == 0)
{
pIndex->offsetSize = 1;
pIndex->offsetArrayOffset = 0;
pIndex->dataOffset = 0;
return pos + 2;
}
XCF_ReadBlock(h, pos + 2, 1);
pIndex->offsetSize = XCF_Read1(h);
if ((pIndex->offsetSize == 0) || (pIndex->offsetSize > 4))
XCF_FATAL_ERROR(h, XCF_InvalidOffsetSize, "Invalid offset size in table.", pIndex->offsetSize);
pIndex->offsetArrayOffset = pos + 3;
pIndex->dataOffset = pIndex->offsetArrayOffset + ((pIndex->count+1)*pIndex->offsetSize) - 1;;
XCF_LookUpTableEntry(h, pIndex, pIndex->count-1);
return h->inBuffer.blockOffset + h->inBuffer.blockLength;
}
void XCF_LookUpString(XCF_Handle h, StringID sid, char PTR_PREFIX * PTR_PREFIX *str, Card16 PTR_PREFIX *length)
{
if (sid < ARRAY_LEN(stdStrIndex))
{
*str = stdStrIndex[sid];
*length = h->callbacks.strlen(*str);
}
else
{
sid -= ARRAY_LEN(stdStrIndex);
XCF_LookUpTableEntry(h, &h->fontSet.strings, sid);
*length = (Card16) h->inBuffer.blockLength;
*str = (char *) h->inBuffer.start;
}
}
Card16 XCF_CalculateSubrBias(CardX subrCount)
{
if (subrCount < 1240)
return(107);
else if (subrCount < 33900)
return(1131);
return(32768);
}
/* Returns 1 if this is a font with transitional designs, 0 otherwise. */
int XCF_TransDesignFont(XCF_Handle h)
{
char fontName[512];
XCF_FontName(h, (unsigned short int)h->fontSet.fontIndex, fontName,
(unsigned short int)512);
if (h->callbacks.strcmp(fontName, "ITCGaramondMM") == 0 ||
h->callbacks.strcmp(fontName, "ITCGaramondMM-It") == 0 ||
h->callbacks.strcmp(fontName, "JimboMM") == 0)
return 1;
return 0;
}
void ProcessOneCharString(XCF_Handle h, CardX i)
{
#if HAS_COOLTYPE_UFL == 1
/* Characters that have transitional designs are handled separately
because there isn't a general mechanism that can deal with these
special characters. The charstrings are hardcoded (yech!) and
written out directly by the TransDesignChar procedure.
*/
if (!CIDFONT && XC_TransDesignChar(h, i))
return;
#endif
XCF_LookUpTableEntry(h, &h->fontSet.charStrings, i);
if (CIDFONT)
{
Card8 fd = XCF_GetFDIndex(h, i);
h->cstr.languageGroup = h->type1.cid.languageGroup[fd];
h->dict.nominalWidthX = h->type1.cid.nominalWidthX[fd];
h->dict.defaultWidthX = h->type1.cid.defaultWidthX[fd];
h->dict.localSubrs = h->type1.cid.localSubrs[fd];
h->dict.localSubrBias = h->type1.cid.localSubrBias[fd];
if ((h->options.outputCharstrType != 2) && (h->dict.fontType == 1))
h->type1.charStrs.cnt = i;
}
else
h->cstr.languageGroup = (CardX) h->dict.languageGroup;
XC_ProcessCharstr(h);
}
static void ProcessCharStrings(XCF_Handle h)
{
CardX i;
if ((CIDFONT) || ((h->options.outputCharstrType != 2) && (h->dict.fontType != 1)))
{
if (CIDFONT || !h->options.subrFlatten)
{
for (i=0; i<h->fontSet.charStrings.count; ++i)
{
ProcessOneCharString(h, i);
if (CIDFONT)
XT1_CIDWriteCharString(h);
}
XC_CleanUp(h);
}
}
}
static void SaveArgs(
XCF_Handle h,
IntX PTR_PREFIX *countDest,
Fixed PTR_PREFIX *pArgArray,
Card8 PTR_PREFIX *argList,
Card16 opCode,
IntX argCount,
IntX min,
IntX max,
boolean type2)
{
IntX i;
boolean fracType =
(opCode == cff_BlueScale) || (opCode == cff_ExpansionFactor);
if (*countDest) /* Only save if entry has not already been saved */
return;
if (argCount < min)
XCF_FATAL_ERROR(h, XCF_InvalidDictArgumentCount, "Too few arguments for operator", opCode);
if (argCount > max)
XCF_FATAL_ERROR(h, XCF_InvalidDictArgumentCount, "Too many arguments for operator", opCode);
*countDest = argCount;
if (type2)
{
for (i=0; i<argCount; i++)
*pArgArray++ = fracType ? h->dict.mmDictArg[i] << 14 : h->dict.mmDictArg[i];
h->dict.mmDictArgCount = 0;
}
else
XCF_SaveDictArgumentList(h, pArgArray, argList, argCount, fracType);
}
static void SaveIntArgs(
XCF_Handle h,
IntX PTR_PREFIX *countDest,
Int32 PTR_PREFIX *pArgArray,
Card8 PTR_PREFIX *argList,
Card16 opCode,
IntX argCount,
IntX min,
IntX max,
boolean type2)
{
if (*countDest) /* Only save if entry has not already been saved */
return;
if (argCount < min)
XCF_FATAL_ERROR(h, XCF_InvalidDictArgumentCount, "Too few arguments for operator", opCode);
if (argCount > max)
XCF_FATAL_ERROR(h, XCF_InvalidDictArgumentCount, "Too many arguments for operator", opCode);
*countDest = argCount;
if (type2)
/* Can't have more than 1 value for UniqueID and UIDBase. */
XCF_FATAL_ERROR(h, XCF_InvalidDictArgumentCount, "Too many arguments for operator", opCode);
else
XCF_SaveDictIntArgumentList(h, pArgArray, argList, argCount);
}
static void SaveFontMatrixStr(
XCF_Handle h,
IntX PTR_PREFIX *countDest,
char (PTR_PREFIX *pArgArray)[FONT_MATRIX_ENTRY_SIZE],
Card8 PTR_PREFIX *argList,
Card16 opCode,
IntX argCount,
IntX min,
IntX max)
{
if (*countDest) /* Only save if entry has not already been saved */
return;
if (argCount < min)
XCF_FATAL_ERROR(h, XCF_InvalidDictArgumentCount, "Too few arguments for operator", opCode);
if (argCount > max)
XCF_FATAL_ERROR(h, XCF_InvalidDictArgumentCount, "Too many arguments for operator", opCode);
*countDest = argCount;
XCF_SaveFontMatrixStr(h, pArgArray, argList, argCount);
}
static void SaveStrArgs(
XCF_Handle h,
IntX PTR_PREFIX *countDest,
char PTR_PREFIX *pArgArray,
Card8 PTR_PREFIX *argList,
Card16 opCode,
IntX argCount,
IntX min,
IntX max)
{
if (*countDest) /* Only save if entry has not already been saved */
return;
if (argCount < min)
XCF_FATAL_ERROR(h, XCF_InvalidDictArgumentCount, "Too few arguments for operator", opCode);
if (argCount > max)
XCF_FATAL_ERROR(h, XCF_InvalidDictArgumentCount, "Too many arguments for operator", opCode);
*countDest = argCount;
XCF_SaveStrArgs(h, pArgArray, argList, argCount);
}
static void SaveDictEntry(XCF_Handle h, Card16 opCode, Card8 PTR_PREFIX *argList, IntX argCount, boolean type2)
{
switch (opCode)
{
case cff_BlendAxisTypes :
SaveIntArgs(h, &h->dict.blendAxisTypesCount, (Int32 *)&h->dict.blendAxisTypes[0], argList, opCode, argCount, 1, MAX_MM_AXES, type2);
break;
case cff_MultipleMaster :
{
IntX i;
SaveArgs(h, &h->dict.userDesignVectorCount, &h->dict.userDesignVector[0],
argList, opCode, argCount, 2, MAX_MM_AXES + 4, type2);
h->dict.numberOfMasters = FIXED_TO_INT(h->dict.userDesignVector[0]);
h->dict.userDesignVectorCount = h->dict.normDesignVectorCount = argCount - 4;
for (i=0; i<h->dict.userDesignVectorCount; ++i)
h->dict.userDesignVector[i] = h->dict.userDesignVector[i+1];
i += 1;
h->dict.lenBuildCharArray = FIXED_TO_INT(h->dict.userDesignVector[i++]);
h->dict.lenBuildCharArrayCount = h->dict.lenBuildCharArray == 0 ? 0 : 1;
h->dict.ndv = FIXED_TO_INT(h->dict.userDesignVector[i++]);
h->dict.cdv = FIXED_TO_INT(h->dict.userDesignVector[i++]);
}
break;
case cff_XUID :
SaveIntArgs(h, &h->dict.xUIDCount, (Int32 *)&h->dict.xUID[0], argList, opCode, argCount, 1, MAX_XUID_ENTRIES, type2);
break;
case cff_FontBBox :
SaveArgs(h, &h->dict.fontBBoxCount, &h->dict.fontBBox[0], argList, opCode, argCount, 4, MAX_FONTBBOX_ENTRIES, type2);
break;
case cff_StdHW :
SaveArgs(h, &h->dict.stdHWCount, &h->dict.stdHW[0], argList, opCode, argCount, 1, MAX_STD_HW_ENTRIES, type2);
break;
case cff_StdVW :
SaveArgs(h, &h->dict.stdVWCount, &h->dict.stdVW[0], argList, opCode, argCount, 1, MAX_STD_VW_ENTRIES, type2);
break;
case cff_BlueValues :
SaveArgs(h, &h->dict.blueValuesCount, &h->dict.blueValues[0], argList, opCode, argCount, 1, MAX_BLUE_VALUE_ENTRIES, type2);
break;
case cff_OtherBlues :
SaveArgs(h, &h->dict.otherBluesCount, &h->dict.otherBlues[0], argList, opCode, argCount, 1, MAX_OTHER_BLUES_ENTRIES, type2);
break;
case cff_FamilyBlues :
SaveArgs(h, &h->dict.familyBluesCount, &h->dict.familyBlues[0], argList, opCode, argCount, 1, MAX_FAMILY_BLUES_ENTRIES, type2);
break;
case cff_FamilyOtherBlues :
SaveArgs(h, &h->dict.familyOtherBluesCount, &h->dict.familyOtherBlues[0], argList, opCode, argCount, 1, MAX_FAMILY_OTHER_BLUES_ENTRIES, type2);
break;
case cff_UniqueID :
SaveIntArgs(h, &h->dict.uniqueIDCount, (Int32 *)&h->dict.uniqueID, argList, opCode, argCount, 1, 1, type2);
break;
case cff_version :
SaveIntArgs(h, &h->dict.versionCount, (Int32 *)&h->dict.version, argList, opCode, argCount, 1, 1, type2);
break;
case cff_Encoding :
SaveIntArgs(h, &h->dict.encodingCount, (Int32 *)&h->dict.encoding, argList, opCode, argCount, 1, 1, type2);
break;
case cff_Subrs :
SaveIntArgs(h, &h->dict.subrsCount, (Int32 *)&h->dict.subrs, argList, opCode, argCount, 1, 1, type2);
break;
case cff_FullName :
SaveIntArgs(h, &h->dict.fullNameCount, (Int32 *)&h->dict.fullName, argList, opCode, argCount, 1, 1, type2);
break;
case cff_FamilyName :
SaveIntArgs(h, &h->dict.familyNameCount, (Int32 *)&h->dict.familyName, argList, opCode, argCount, 1, 1, type2);
break;
case cff_BaseFontName :
SaveIntArgs(h, &h->dict.baseFontNameCount, (Int32 *)&h->dict.baseFontName, argList, opCode, argCount, 1, 1, type2);
break;
case cff_BaseFontBlend :
SaveArgs(h, &h->dict.baseFontBlendCount, &h->dict.baseFontBlend[0], argList, opCode, argCount, 1, MAX_BASE_FONT_BLEND_ENTRIES, type2);
break;
case cff_Weight :
SaveIntArgs(h, &h->dict.weightCount, (Int32 *)&h->dict.weight, argList, opCode, argCount, 1, 1, type2);
break;
case cff_Private :
SaveIntArgs(h, &h->dict.privateDictCount, (Int32 *)&h->dict.privateDict[0], argList, opCode, argCount, PRIVATE_DICT_ENTRIES, PRIVATE_DICT_ENTRIES, type2);
h->fontSet.fontPrivDictInfo.offset = (Offset) h->dict.privateDict[1];
h->fontSet.fontPrivDictInfo.size = (short int) h->dict.privateDict[0];
break;
case cff_charset :
SaveIntArgs(h, &h->dict.charsetCount, (Int32 *)&h->dict.charset, argList, opCode, argCount, 1, 1, type2);
break;
case cff_CharStrings :
SaveIntArgs(h, &h->dict.charStringsCount, (Int32 *)&h->dict.charStrings, argList, opCode, argCount, 1, 1, type2);
break;
case cff_nominalWidthX :
SaveArgs(h, &h->dict.nominalWidthXCount, &h->dict.nominalWidthX, argList, opCode, argCount, 1, 1, type2);
break;
case cff_defaultWidthX :
SaveArgs(h, &h->dict.defaultWidthXCount, &h->dict.defaultWidthX, argList, opCode, argCount, 1, 1, type2);
break;
case cff_Notice :
SaveIntArgs(h, &h->dict.noticeCount, (Int32 *)&h->dict.notice, argList, opCode, argCount, 1, 1, type2);
break;
case cff_StemSnapH :
SaveArgs(h, &h->dict.stemSnapHCount, &h->dict.stemSnapH[0], argList, opCode, argCount, 1, MAX_STEM_SNAP_H_ENTRIES, type2);
break;
case cff_StemSnapV :
SaveArgs(h, &h->dict.stemSnapVCount, &h->dict.stemSnapV[0], argList, opCode, argCount, 1, MAX_STEM_SNAP_V_ENTRIES, type2);
break;
case cff_BlueScale :
SaveArgs(h, &h->dict.blueScaleCount, &h->dict.blueScale[0], argList, opCode, argCount, 1, MAX_BLUE_SCALE_ENTRIES, type2);
break;
case cff_BlueFuzz :
SaveArgs(h, &h->dict.blueFuzzCount, &h->dict.blueFuzz[0], argList, opCode, argCount, 1, MAX_BLUE_FUZZ_ENTRIES, type2);
break;
case cff_BlueShift :
SaveArgs(h, &h->dict.blueShiftCount, &h->dict.blueShift[0], argList, opCode, argCount, 1, MAX_BLUE_SHIFT_ENTRIES, type2);
break;
case cff_ForceBold :
SaveArgs(h, &h->dict.forceBoldCount, &h->dict.forceBold[0], argList, opCode, argCount, 1, MAX_FORCE_BOLD_ENTRIES, type2);
break;
case cff_FontMatrix :
SaveFontMatrixStr(h, &h->dict.fontMatrixCount, h->dict.fontMatrix, argList, opCode, argCount, FONT_MATRIX_ENTRIES, FONT_MATRIX_ENTRIES);
break;
case cff_StrokeWidth :
SaveArgs(h, &h->dict.strokeWidthCount, &h->dict.strokeWidth[0], argList, opCode, argCount, 1, MAX_MM_DESIGNS, type2);
break;
case cff_ExpansionFactor :
SaveArgs(h, &h->dict.expansionFactorCount, &h->dict.expansionFactor, argList, opCode, argCount, 1, 1, type2);
break;
case cff_ForceBoldThreshold :
SaveArgs(h, &h->dict.forceBoldThresholdCount, &h->dict.forceBoldThreshold, argList, opCode, argCount, 1, 1, type2);
break;
case cff_initialRandomSeed :
SaveArgs(h, &h->dict.initialRandomSeedCount, &h->dict.initialRandomSeed, argList, opCode, argCount, 1, 1, type2);
break;
case cff_lenIV :
SaveIntArgs(h, &h->dict.lenIVCount, &h->dict.lenIV, argList, opCode, argCount, 1, 1, type2);
break;
case cff_PaintType :
SaveArgs(h, &h->dict.paintTypeCount, &h->dict.paintType, argList, opCode, argCount, 1, 1, type2);
break;
case cff_LanguageGroup :
SaveIntArgs(h, &h->dict.languageGroupCount, (Int32 *)&h->dict.languageGroup, argList, opCode, argCount, 1, 1, type2);
break;
case cff_ItalicAngle :
SaveArgs(h, &h->dict.italicAngleCount, &h->dict.italicAngle[0], argList, opCode, argCount, 1, MAX_MM_DESIGNS, type2);
break;
case cff_isFixedPitch :
SaveArgs(h, &h->dict.isFixedPitchCount, &h->dict.isFixedPitch[0], argList, opCode, argCount, 1, MAX_MM_DESIGNS, type2);
break;
case cff_UnderlinePosition :
SaveArgs(h, &h->dict.underlinePositionCount, &h->dict.underlinePosition[0], argList, opCode, argCount, 1, MAX_MM_DESIGNS, type2);
break;
case cff_UnderlineThickness :
SaveArgs(h, &h->dict.underlineThicknessCount, &h->dict.underlineThickness[0], argList, opCode, argCount, 1, MAX_MM_DESIGNS, type2);
break;
case cff_PostScript :
SaveIntArgs(h, &h->dict.embeddedPostscriptCount, (Int32 *)&h->dict.embeddedPostscript, argList, opCode, argCount, 1, 1, type2);
break;
case cff_Copyright :
SaveIntArgs(h, &h->dict.copyrightCount, (Int32 *)&h->dict.copyright, argList, opCode, argCount, 1, 1, type2);
break;
case cff_CharstringType :
SaveIntArgs(h, &h->dict.fontTypeCount, &h->dict.fontType, argList, opCode, argCount, 1, 1, type2);
break;
case cff_FontName :
SaveIntArgs(h, &h->dict.fdFontNameCount, (Int32 *)&h->dict.fdFontName, argList, opCode, argCount, 1, 1, type2);
break;
case cff_CIDFontVersion :
SaveStrArgs(h, &h->dict.cidFontVersionCount, h->dict.cidFontVersion, argList, opCode, argCount, 1, 1);
break;
case cff_CIDFontType :
SaveIntArgs(h, &h->dict.cidFontTypeCount, &h->dict.cidFontType, argList, opCode, argCount, 1, 1, type2);
break;
case cff_ROS :
SaveIntArgs(h, &h->dict.ROSCount, (Int32 *)&h->dict.ROS[0], argList, opCode,
argCount, 3, 3, type2);
break;
case cff_UIDBase :
SaveIntArgs(h, &h->dict.uidBaseCount, (Int32 *)&h->dict.uidBase, argList, opCode, argCount, 1, 1, type2);
break;
case cff_FDArray :
SaveIntArgs(h, &h->dict.cidFDArrayCount, &h->dict.cidFDArray, argList, opCode, argCount, 1, 1, type2);
break;
case cff_FDSelect :
SaveIntArgs(h, &h->dict.cidFDIndexCount, &h->dict.cidFDIndex, argList, opCode, argCount, 1, 1, type2);
break;
case cff_SyntheticBase :
SaveArgs(h, &h->dict.syntheticBaseCount, &h->dict.syntheticBase, argList,
opCode, argCount, 1, 1, type2);
break;
case cff_CIDCount :
SaveIntArgs(h, &h->dict.cidCountCount, &h->dict.cidCount, argList, opCode, argCount, 1, 1, type2);
break;
#ifdef XCF_DEVELOP
default :
XCF_FATAL_ERROR(h, XCF_InternalError, "Development Error, Unknown Dictionary Operator", opCode);
break;
#endif
}
}
static void SaveT2Args(XCF_Handle h, Card8 PTR_PREFIX *argList, IntX argCount)
{
if (argCount == 0)
return;
XCF_SaveDictArgumentList(h, &h->dict.mmDictArg[h->dict.mmDictArgCount],
argList, argCount, false);
h->dict.mmDictArgCount += argCount;
}
static void SaveT2BlendArgs(XCF_Handle h, Card8 PTR_PREFIX *argList, IntX argCount)
{
IntX blendCount;
Fixed argArray[T2_MAX_OP_STACK];
IntX i, j, deltaIndex;
if (argCount == 0)
return;
if (argCount > T2_MAX_OP_STACK)
XCF_FATAL_ERROR(h, XCF_InvalidDictArgumentCount, "Too many arguments", argCount);
XCF_SaveDictArgumentList(h, &argArray[0], argList, argCount, false);
blendCount = FIXED_TO_INT(argArray[argCount-1]);
deltaIndex = blendCount;
for (i=0; i<blendCount; i++)
{
h->dict.mmDictArg[h->dict.mmDictArgCount++] = argArray[i];
for (j=0; j<h->dict.numberOfMasters-1; j++)
{
h->dict.mmDictArg[h->dict.mmDictArgCount++] = argArray[i] + argArray[deltaIndex++];
}
}
}
void XCF_ReadDictionary(XCF_Handle h)
{
Card16 opCode;
Card8 PTR_PREFIX *argList;
IntX argCount;
boolean t2Active = false;
while (h->inBuffer.pos < h->inBuffer.end)
{
argList = h->inBuffer.pos; /* Save Position */
argCount = XCF_FindNextOperator(h, &opCode, true);
if (opCode != cff_T2)
SaveDictEntry(h, opCode, argList, argCount, false);
else
{ /* Process T2 charstring */
h->dict.mmDictArgCount = 0;
while ((t2Active) || (opCode == cff_T2))
{
if (opCode == cff_T2)
{
t2Active = true;
SaveT2Args(h, argList, argCount);
}
else if (opCode == tx_endchar)
{
t2Active = false;
}
else if (opCode == t2_blend)
{
SaveT2BlendArgs(h, argList, argCount);
}
argList = h->inBuffer.pos; /* Save Position */
argCount = XCF_FindNextOperator(h, &opCode, true);
}
SaveDictEntry(h, opCode, (Card8 *)NULL, h->dict.mmDictArgCount, true);
}
}
}
static void SetDefault(XCF_Handle h, IntX *pCount, Fixed *pValue, const Fixed defaultValue)
{
if (!*pCount)
{
*pCount = 1;
*pValue = defaultValue;
}
}
#define BLUE_SCALE_DEFAULT 0x0289374CL /* 0.039625 */
#define EXP_FACTOR_DEFAULT 0x03D70A3EL /* 0.06 */
static void AssignDictionaryDefaults(XCF_Handle h)
{
SetDefault(h, &h->dict.fontTypeCount, (Fixed *)&h->dict.fontType, 2);
SetDefault(h, &h->dict.lenIVCount, (Fixed *)&h->dict.lenIV, -1);
SetDefault(h, &h->dict.isFixedPitchCount, &h->dict.isFixedPitch[0], 0);
SetDefault(h, &h->dict.italicAngleCount, &h->dict.italicAngle[0], 0);
SetDefault(h, &h->dict.underlinePositionCount, &h->dict.underlinePosition[0], INT_TO_FIXED(-100));
SetDefault(h, &h->dict.underlineThicknessCount, &h->dict.underlineThickness[0], INT_TO_FIXED(50));
SetDefault(h, &h->dict.encodingCount, (Fixed *) &h->dict.encoding, 0);
SetDefault(h, &h->dict.paintTypeCount, &h->dict.paintType, 0);
SetDefault(h, &h->dict.strokeWidthCount, &h->dict.strokeWidth[0], 0);
SetDefault(h, &h->dict.blueScaleCount, &h->dict.blueScale[0], BLUE_SCALE_DEFAULT);
SetDefault(h, &h->dict.blueShiftCount, &h->dict.blueShift[0], INT_TO_FIXED(7));
SetDefault(h, &h->dict.blueFuzzCount, &h->dict.blueFuzz[0], FIXEDONE);
SetDefault(h, &h->dict.expansionFactorCount, &h->dict.expansionFactor, EXP_FACTOR_DEFAULT);
SetDefault(h, &h->dict.initialRandomSeedCount, &h->dict.initialRandomSeed, 0);
SetDefault(h, &h->dict.cidFontTypeCount, (Fixed *)&h->dict.cidFontType, 0);
/* xxx Currently the CIDFontType is not written in the cff since it must be zero. */
SetDefault(h, &h->dict.cidCountCount, (Fixed *)&h->dict.cidCount, 8720);
if (!h->dict.fontMatrixCount)
{
h->dict.fontMatrixCount = 6;
h->callbacks.memcpy(h->dict.fontMatrix[0], "0.001", 5);
h->callbacks.memcpy(h->dict.fontMatrix[1], "0", 1);
h->callbacks.memcpy(h->dict.fontMatrix[2], "0", 1);
h->callbacks.memcpy(h->dict.fontMatrix[3], "0.001", 5);
h->callbacks.memcpy(h->dict.fontMatrix[4], "0", 1);
h->callbacks.memcpy(h->dict.fontMatrix[5], "0", 1);
}
}
static void ProcessDictionaryData(XCF_Handle h, boolean setDefaults)
{
if (setDefaults)
AssignDictionaryDefaults(h);
if (h->dict.charStringsCount != 0)
ReadTableInfo(h, (Offset) h->dict.charStrings, &h->fontSet.charStrings);
else
XCF_FATAL_ERROR(h, XCF_NoCharstringsFound, "No charstring offset found in dictionary", 0 );
if (h->dict.subrsCount != 0)
{
/* The local subrs offset is relative to the private dict data. */
ReadTableInfo(h,
(Offset) (h->dict.subrs + h->fontSet.fontPrivDictInfo.offset),
&h->dict.localSubrs);
h->dict.localSubrBias = XCF_CalculateSubrBias(h->dict.localSubrs.count);
}
else
h->dict.localSubrs.count = 0;
}
#if 0
static void InitFontSetValues(XCF_Handle h)
{
}
static void InitClientOptions(XCF_Handle h)
{
h->options.fontIndex = 0;
h->options.uniqueIDMethod = XCF_KEEP_UID;
h->options.subrFlatten = false;
h->options.lenIV = 4;
h->options.hexEncoding = true;
h->options.eexecEncryption = true;
h->options.outputCharstrType = 1;
h->options.maxBlockSize = MAX_OUT_BUFFER;
h->options.dlOptions.useSpecialEncoding = 0;
h->options.dlOptions.encodeName = 0;
h->options.dlOptions.fontName = 0;
}
#endif
static void CopyOptionStrings(XCF_Handle h,
XCF_ClientOptions PTR_PREFIX *options)
{
char PTR_PREFIX *str;
Card32 cb;
if (options->dlOptions.encodeName)
{
cb = h->callbacks.strlen((char *)options->dlOptions.encodeName) + 1;
str = 0;
if (!h->callbacks.allocate((void PTR_PREFIX * PTR_PREFIX *)&str, cb,
h->callbacks.allocateHook))
XCF_FATAL_ERROR(h, XCF_MemoryAllocationError,
"Failure to allocate memory for encode name option", cb);
h->callbacks.xcfSprintf(str, cb / sizeof(char), "%s", options->dlOptions.encodeName);
h->options.dlOptions.encodeName = (unsigned char PTR_PREFIX *) str;
}
if (options->dlOptions.fontName)
{
cb = h->callbacks.strlen((char *)options->dlOptions.fontName) + 1;
str = 0;
if (!h->callbacks.allocate((void PTR_PREFIX * PTR_PREFIX *)&str, cb,
h->callbacks.allocateHook))
XCF_FATAL_ERROR(h, XCF_MemoryAllocationError,
"Failure to allocate memory for font name option", cb);
h->callbacks.xcfSprintf(str, cb / sizeof(char), "%s", options->dlOptions.fontName);
h->options.dlOptions.fontName = (unsigned char PTR_PREFIX *)str;
}
}
static void SetClientOptions(XCF_Handle h,
XCF_ClientOptions PTR_PREFIX *options)
{
if (!options)
return;
h->options.uniqueIDMethod = options->uniqueIDMethod;
h->options.uniqueID = options->uniqueID;
h->options.subrFlatten = options->subrFlatten;
h->options.lenIV = options->lenIV;
h->options.hexEncoding = options->hexEncoding;
h->options.eexecEncryption = options->eexecEncryption;
h->options.outputCharstrType = options->outputCharstrType;
h->options.dlOptions.otherSubrNames = options->dlOptions.otherSubrNames;
h->options.maxBlockSize = MIN(options->maxBlockSize, MAX_OUT_BUFFER);
h->options.dlOptions.useSpecialEncoding =
options->dlOptions.useSpecialEncoding;
h->options.dlOptions.notdefEncoding = options->dlOptions.notdefEncoding;
CopyOptionStrings(h, options);
}
static void InitOutBuffer(XCF_Handle h)
{
h->outBuffer.eexecOn = false;
h->outBuffer.eexecKey = 0;
h->outBuffer.charsOnLine = 0;
h->outBuffer.outBufferCount = 0;
h->outBuffer.lenIVInitialBytes[0] = 'x';
h->outBuffer.lenIVInitialBytes[1] = 'x';
h->outBuffer.lenIVInitialBytes[2] = 'x';
h->outBuffer.lenIVInitialBytes[3] = 'x';
h->outBuffer.eexecInitialBytes[0] = 'y';
h->outBuffer.eexecInitialBytes[1] = 'o';
h->outBuffer.eexecInitialBytes[2] = 'g';
h->outBuffer.eexecInitialBytes[3] = 'i';
}
static void InitInBuffer(XCF_Handle h)
{
h->inBuffer.start = (Card8 *)NULL;
h->inBuffer.end = (Card8 *)NULL;
h->inBuffer.pos = (Card8 *)NULL;
h->inBuffer.blockOffset = 0;
h->inBuffer.blockLength = 0;
}
static void InitDownloadRecord(XCF_Handle h)
{
h->dl.glyphs = (Card8 *)NULL;
h->dl.cSeacs = 0;
h->dl.state = XCF_DL_CREATE;
}
static void ClearDictionaryData(XCF_Handle h)
{
h->callbacks.memset(&h->dict, 0, sizeof(DictEntriesStruct));
}
static unsigned long int DA_Allocate(void PTR_PREFIX * PTR_PREFIX *pBlock, unsigned long int size, void PTR_PREFIX *clientHook )
{
XCF_Handle h = (XCF_Handle) clientHook;
if (!h->callbacks.allocate(pBlock, size, h->callbacks.allocateHook))
XCF_FATAL_ERROR(h, XCF_MemoryAllocationError, "Dynamic Array Allocation Failure.", size);
return true;
}
static void InitType1(XCF_Handle h)
{
/* Only allocate enough space for the best scenario which will flatten
* both subrs and charstrings */
da_INIT(h->type1.charStrs, 2000, 20000,DA_Allocate, h);
da_INIT(h->type1.charStrOffsets, 10, 500,DA_Allocate, h);
da_INIT(h->type1.subrs, 300, 8000,DA_Allocate, h);
da_INIT(h->type1.subrOffsets, 10, 500,DA_Allocate, h);
da_INIT(h->type1.charset, 400, 400,DA_Allocate, h);
}
static int InRAMGetBytes( unsigned char PTR_PREFIX * PTR_PREFIX *ppData, long int position, unsigned short int length, void PTR_PREFIX *clientHook )
{
XCF_Handle h = (XCF_Handle) clientHook;
if ((Card32)(position + length) > h->callbacks.fontLength)
return false;
*ppData = (Card8 PTR_PREFIX *) h->callbacks.pFont + position;
return true;
}
static void InitHandle(
XCF_Handle h, /* Out */
XCF_CallbackStruct PTR_PREFIX *pCallbacks) /* In */
{
pCallbacks->memset(h, 0, sizeof(*h));
h->callbacks = *pCallbacks;
if (h->callbacks.getBytes == (XCF_GetBytesFromPosFunc)NULL)
{
h->callbacks.getBytes = InRAMGetBytes;
h->callbacks.getBytesHook = h;
}
/* InitFontSetValues(h); */
/* InitClientOptions(h); */
InitOutBuffer(h);
InitInBuffer(h);
InitType1(h);
InitDownloadRecord(h);
}
static void ProcessCharset(XCF_Handle h)
{
CardX i;
CardX formatType;
if ((!h->dict.charsetCount) || (h->dict.charset == cff_ISOAdobeCharset))
{
h->type1.pCharset = isoAdobeCharset;
h->type1.charsetSize = ARRAY_LEN(isoAdobeCharset);
}
else if (h->dict.charset == cff_ExpertCharset)
{
h->type1.pCharset = expertCharset;
h->type1.charsetSize = ARRAY_LEN(expertCharset);
}
else if (h->dict.charset == cff_ExpertSubsetCharset)
{
h->type1.pCharset = expertSubsetCharset;
h->type1.charsetSize = ARRAY_LEN(expertSubsetCharset);
}
else
{
h->type1.charset.cnt = 0; /* clear charset */
XCF_ReadBlock(h, (Offset) h->dict.charset, 1);
formatType = XCF_Read1(h);
if (formatType == 0)
{
XCF_ReadBlock(h, (Offset) h->dict.charset + 1, (h->fontSet.charStrings.count-1)*2);
for (i=0; i<h->fontSet.charStrings.count-1; ++i)
*da_NEXT(h->type1.charset) = XCF_Read2(h);
}
else /* (formatType is 1 or 2 ) */
{
Offset charsetDataOffset = (Offset) h->dict.charset + 1;
CardX glyphCount = 0;
CardX nLeftSize = (formatType == 1) ? 1 : 2;
while (glyphCount < h->fontSet.charStrings.count - 1)
{
StringID firstSID;
CardX numberOfSIDsInRange;
XCF_ReadBlock(h, charsetDataOffset, 2 + nLeftSize);
charsetDataOffset += 2 + nLeftSize;
firstSID = XCF_Read2(h);
numberOfSIDsInRange = (CardX) XCF_Read(h, nLeftSize) + 1;
for (i=0; i<numberOfSIDsInRange; ++i)
{
*da_NEXT(h->type1.charset) = firstSID + i;
glyphCount++;
}
} /* end for */
}
h->type1.pCharset = h->type1.charset.array;
h->type1.charsetSize = h->fontSet.charStrings.count-1;
}
}
static enum XCF_Result ProcessFDIndex(XCF_Handle h)
{
Card16 i = 0;
CardX formatType;
if (!h->callbacks.allocate((void PTR_PREFIX * PTR_PREFIX *)&h->type1.cid.pFDIndex,
h->type1.charsetSize + 1, h->callbacks.allocateHook))
return XCF_MemoryAllocationError;
XCF_ReadBlock(h, (Offset) h->dict.cidFDIndex, 1);
formatType = XCF_Read1(h);
switch (formatType)
{
case 0:
XCF_ReadBlock(h, (Offset) h->dict.cidFDIndex + 1, h->type1.charsetSize + 1);
for (i = 0 ; i < h->type1.charsetSize + 1 ; ++i)
h->type1.cid.pFDIndex[i] = XCF_Read1(h);
break;
case 2:
{
FDIndex fd;
Card16 count;
Offset dataOffset = (Offset) h->dict.cidFDIndex + 1;
while (i < h->type1.charsetSize + 1)
{
XCF_ReadBlock(h, dataOffset, 3);
dataOffset += 3;
fd = XCF_Read1(h);
count = XCF_Read2(h) + 1;
while (count-- != 0)
h->type1.cid.pFDIndex[i++] = fd;
}
}
break;
case 3:
{
Offset dataOffset = (Offset) h->dict.cidFDIndex + 1;
Card16 nRanges; /* number of ranges defined */
Card16 first, last; /* first and last glyph index in range */
FDIndex fd;
Card16 j;
XCF_ReadBlock(h, dataOffset, 4);
dataOffset += 4;
nRanges = XCF_Read2(h);
first = XCF_Read2(h);
for (i = 0; i < nRanges; i++)
{
XCF_ReadBlock(h, dataOffset, 3);
dataOffset += 3;
fd = XCF_Read1(h);
last = XCF_Read2(h);
for (j = first; j < last; j++)
h->type1.cid.pFDIndex[j] = fd;
first = last;
}
}
break;
default:
return XCF_IndexOutOfRange;
}
return XCF_Ok;
}
Card8 XCF_GetFDIndex(XCF_Handle h, Int32 code)
{
if (!h->type1.cid.pFDIndex)
XCF_FATAL_ERROR(h, XCF_EarlyEndOfData, "no FDIndex", code);
if (code > (IntX) h->type1.charsetSize)
XCF_FATAL_ERROR(h, XCF_EarlyEndOfData, "FDIndex error", code);
return h->type1.cid.pFDIndex[code];
}
static void ProcessEncoding(XCF_Handle h)
{
CardX i, j;
CardX formatType;
CardX numberOfElements;
Card8 characterCode;
CardX glyphCount;
Card8 firstCode;
CardX numberOfCodesInRange;
Offset extraEntries;
if ((!h->dict.encodingCount) || (h->dict.encoding == cff_StandardEncoding))
h->type1.pEncoding = stdEncoding;
else if (h->dict.encoding == cff_ExpertEncoding)
h->type1.pEncoding = expertEncoding;
else
{
XCF_ReadBlock(h, (Offset) h->dict.encoding, 2);
formatType = XCF_Read1(h);
numberOfElements = XCF_Read1(h);
if ((formatType == 0) || (formatType == 128))
{
XCF_ReadBlock(h, (Offset) h->dict.encoding + 2, numberOfElements);
for (i=0; i<numberOfElements; ++i)
{
characterCode = XCF_Read1(h);
h->type1.encoding[characterCode] = h->type1.pCharset[i];
}
extraEntries = (Offset) h->dict.encoding + 2 + numberOfElements;
}
else /* ((formatType == 1) || (formatType == 129)) */
{
XCF_ReadBlock(h, (Offset) h->dict.encoding + 2, numberOfElements * 2);
glyphCount = 0;
for (i=0; i<numberOfElements; ++i)
{
firstCode = XCF_Read1(h);
numberOfCodesInRange = XCF_Read1(h) + 1;
for (j=0;j<numberOfCodesInRange;++j)
h->type1.encoding[firstCode + j] = h->type1.pCharset[glyphCount++];
} /* end for */
extraEntries = (Offset) h->dict.encoding + 2 + (numberOfElements * 2);
}
if (formatType > 127) /* Additional entries */
{
XCF_ReadBlock(h, (Offset) extraEntries, 1);
numberOfElements = XCF_Read1(h);
XCF_ReadBlock(h, (Offset) extraEntries + 1, numberOfElements * 3);
for (i=0; i<numberOfElements; ++i)
{
characterCode = XCF_Read1(h);
h->type1.encoding[characterCode] = XCF_Read2(h);
}
}
h->type1.pEncoding = h->type1.encoding;
}
}
static void ReadFontSetHeader(XCF_Handle h) /* Read all values which are not specific to a given font. */
{
Offset offset;
/* Read Header */
XCF_ReadBlock(h, 0, 4);
h->fontSet.majorVersion = XCF_Read1(h);
h->fontSet.minorVersion = XCF_Read1(h);
h->fontSet.headerSize = XCF_Read1(h);
h->fontSet.offsetSize = XCF_Read1(h);
if (h->fontSet.majorVersion != 1)
XCF_FATAL_ERROR(h, XCF_UnsupportedVersion, "Unsupported Major Version", h->fontSet.majorVersion);
if ((h->fontSet.offsetSize == 0) || (h->fontSet.offsetSize > 4))
XCF_FATAL_ERROR(h, XCF_InvalidOffsetSize, "Invalid Global Offset Size", h->fontSet.offsetSize);
offset = h->fontSet.headerSize;
offset = ReadTableInfo(h, offset, &h->fontSet.fontNames);
offset = ReadTableInfo(h, offset, &h->fontSet.fontDicts);
offset = ReadTableInfo(h, offset, &h->fontSet.strings);
offset = ReadTableInfo(h, offset, &h->fontSet.globalSubrs);
h->fontSet.globalSubrBias = XCF_CalculateSubrBias(h->fontSet.globalSubrs.count);
}
static void FreeDAStorage(XCF_Handle h)
{
da_FREE(h->type1.charStrs);
da_FREE(h->type1.charStrOffsets);
da_FREE(h->type1.subrs);
da_FREE(h->type1.subrOffsets);
da_FREE(h->type1.charset);
}
static void FreeDownloadData(XCF_Handle h)
{
/* Free download record */
if (h->dl.glyphs)
{
h->callbacks.allocate((void PTR_PREFIX * PTR_PREFIX *)&h->dl.glyphs,
0, h->callbacks.allocateHook);
h->dl.glyphs = 0;
}
if (h->options.dlOptions.encodeName)
h->callbacks.allocate((void PTR_PREFIX * PTR_PREFIX *)&h->options.dlOptions.encodeName, 0, h->callbacks.allocateHook);
if (h->options.dlOptions.fontName)
h->callbacks.allocate((void PTR_PREFIX * PTR_PREFIX *)&h->options.dlOptions.fontName, 0, h->callbacks.allocateHook);
}
static void FreeCounterValues(XCF_Handle h, void PTR_PREFIX* PTR_PREFIX *p)
{
if (*p)
{
h->callbacks.allocate(p, 0, h->callbacks.allocateHook);
*p = 0;
}
}
static void FreeStackValues(XCF_Handle h, void PTR_PREFIX* PTR_PREFIX *p)
{
if (*p)
{
h->callbacks.allocate(p, 0, h->callbacks.allocateHook);
*p = 0;
}
}
enum XCF_Result XCF_Init(
XFhandle PTR_PREFIX *pHandle, /* Out */
XCF_CallbackStruct PTR_PREFIX *pCallbacks, /* In */
XCF_ClientOptions PTR_PREFIX *options) /* In */
{
XCF_Handle h = (XCF_Handle)NULL;
enum XCF_Result status;
jmp_buf old_env;
DEFINE_ALIGN_SETJMP_VAR;
if (!pCallbacks->allocate((void PTR_PREFIX * PTR_PREFIX *)&h, sizeof(*h), pCallbacks->allocateHook))
return XCF_MemoryAllocationError;
InitHandle(h, pCallbacks);
h->callbacks.memcpy(old_env, &h->jumpData, sizeof(h->jumpData));
status = (enum XCF_Result)SETJMP(h->jumpData); /* Set up error handler */
if (status)
{
h->callbacks.memcpy(&h->jumpData, old_env, sizeof(h->jumpData));
return status;
}
ReadFontSetHeader(h);
*pHandle = h;
SetClientOptions(h, options);
h->fontSet.fontIndex = options->fontIndex;
h->fontSet.stringIDBias = ARRAY_LEN(stdStrIndex);
h->callbacks.memcpy(&h->jumpData, old_env, sizeof(h->jumpData));
return XCF_Ok;
}
enum XCF_Result XCF_CleanUp(
XFhandle PTR_PREFIX *pHandle) /* In/Out */
{
XCF_Handle h = (XCF_Handle) *pHandle;
FreeDAStorage(h);
FreeDownloadData(h);
FreeCounterValues(h, (void PTR_PREFIX* PTR_PREFIX *)&h->cstr.pCounterVal);
FreeStackValues(h, (void PTR_PREFIX* PTR_PREFIX *)&h->cstr.pstackVal);
if (CIDFONT && h->type1.cid.pFDIndex)
{
h->callbacks.allocate((void PTR_PREFIX* PTR_PREFIX *)&h->type1.cid.pFDIndex, 0,
h->callbacks.allocateHook);
h->type1.cid.pFDIndex = 0;
}
h->callbacks.allocate((void PTR_PREFIX * PTR_PREFIX *)&h,
0, h->callbacks.allocateHook);
*pHandle = NULL;
return XCF_Ok;
}
enum XCF_Result XCF_FontCount(
XFhandle handle, /* In */
unsigned int PTR_PREFIX *count) /* Out */
{
XCF_Handle h = (XCF_Handle) handle;
*count = h->fontSet.fontNames.count;
return XCF_Ok;
}
enum XCF_Result XCF_FontName(XFhandle handle, /* In */
unsigned short int fontIndex, /* In */
char PTR_PREFIX *fontName, /* Out */
unsigned short int maxFontNameLength) /* In */
{
XCF_Handle h = (XCF_Handle) handle;
enum XCF_Result status;
jmp_buf old_env;
DEFINE_ALIGN_SETJMP_VAR;
h->callbacks.memcpy(old_env, &h->jumpData, sizeof(h->jumpData));
status = (enum XCF_Result)SETJMP(h->jumpData); /* Set up error handler */
if (status)
{
h->callbacks.memcpy(&h->jumpData, old_env, sizeof(h->jumpData));
return status;
}
*fontName = '\0';
if (fontIndex >= h->fontSet.fontNames.count)
XCF_FATAL_ERROR(h, XCF_InvalidFontIndex, "Invalid Font index", fontIndex);
XCF_LookUpTableEntry(h, &h->fontSet.fontNames, fontIndex);
if (maxFontNameLength < h->inBuffer.blockLength + 1)
{
h->callbacks.memcpy(fontName, h->inBuffer.start, (unsigned short int) (maxFontNameLength - 1));
fontName += maxFontNameLength-1;
*fontName = 0; /* Null terminate string */
XCF_FATAL_ERROR(h, XCF_FontNameTooLong, "Font name too long to fit in available space", h->inBuffer.blockLength);
}
h->callbacks.memcpy(fontName, h->inBuffer.start, (short int) h->inBuffer.blockLength);
fontName += h->inBuffer.blockLength;
*fontName = 0; /* Null terminate string */
h->callbacks.memcpy(&h->jumpData, old_env, sizeof(h->jumpData));
return XCF_Ok;
}
/* Given a handle to a font returns in identifier whether it is a synthetic,
multiple master, single master, cid, or chameleon font. */
enum XCF_Result XCF_FontIdentification(
XFhandle handle,
unsigned short int PTR_PREFIX *identifier)
{
XCF_Handle h = (XCF_Handle) handle;
Card16 opCode;
if (handle == 0)
return XCF_InvalidFontSetHandle;
XCF_LookUpTableEntry(h, &h->fontSet.fontDicts, h->options.fontIndex);
XCF_FindNextOperator(h, &opCode, true);
switch(opCode)
{
case cff_Chameleon:
*identifier = XCF_Chameleon;
break;
case cff_MultipleMaster:
*identifier = XCF_MultipleMaster;
break;
case cff_ROS:
*identifier = XCF_CID;
break;
case cff_SyntheticBase:
*identifier = XCF_SyntheticBase;
break;
default:
*identifier = XCF_SingleMaster;
break;
}
return XCF_Ok;
}
static enum XCF_Result ReadCIDTopDictInfo(XCF_Handle h)
{
Card8 offSize;
if (h->dict.charStringsCount != 0)
ReadTableInfo(h, (Offset) h->dict.charStrings, &h->fontSet.charStrings);
else
XCF_FATAL_ERROR(h, XCF_NoCharstringsFound, "No charstring offset found in dictionary", 0);
/* must have 1 offset to FontDict */
if (h->dict.cidFDArrayCount != 1)
return XCF_InvalidCIDFont;
XCF_ReadBlock(h, (Offset) h->dict.cidFDArray, 3);
h->type1.cid.fdCount = XCF_Read2(h);
offSize = XCF_Read1(h);
if (h->type1.cid.fdCount > MAX_FD)
XCF_FATAL_ERROR(h, XCF_InvalidCIDFont, "too many FDs", h->type1.cid.fdCount);
ProcessCharset(h); /* Also counts CharStrings */
ProcessFDIndex(h);
/* We already read the top-level dict data in XCF_ProcessCFF. */
AssignDictionaryDefaults(h);
XC_SetUpStandardSubrs(h);
return XCF_Ok;
}
static void ReadandWriteCIDDict(XCF_Handle h, Card32 subrMapStart)
{
Offset index;
Offset dataStart;
Card8 offSize;
Card32 dictOffset;
Card32 nextdictOffset;
CardX dictLength;
Card16 fd;
Card32 subrMapOffset = subrMapStart;
Card16 subrCount;
Int32 saveFontType;
char defStr[10];
/* Always use the fontType from the top-level dictionary. */
saveFontType = h->dict.fontType;
XCF_ReadBlock(h, (Offset) h->dict.cidFDArray + 2, 1);
offSize = XCF_Read1(h);
/* We can avoid reading the first offset, which is 1. */
index = (Offset) h->dict.cidFDArray + 3 + offSize;
dataStart = index + (offSize * h->type1.cid.fdCount) - 1;
dictOffset = 1;
for (fd = 0; fd < h->type1.cid.fdCount ; ++fd)
{
/* Clear dictionary data before filling. */
h->callbacks.memset(&h->dict, 0, sizeof(DictEntriesStruct));
/* Read next Offset */
XCF_ReadBlock(h, index, offSize);
nextdictOffset = XCF_Read(h, offSize);
index += offSize;
/* Read dict */
dictLength = (CardX) (nextdictOffset - dictOffset);
XCF_ReadBlock(h, dataStart + dictOffset, dictLength);
/* Process font dict */
XCF_ReadDictionary(h);
/* Process Private dict */
XCF_ReadBlock(h, h->fontSet.fontPrivDictInfo.offset,
h->fontSet.fontPrivDictInfo.size);
XCF_ReadDictionary(h);
/* Advance to next index element */
dictOffset = nextdictOffset;
/* Both FontDict and Private have been processed for this value of fd, now write them. */
if (h->dict.subrsCount)
{
/* The local subrs offset is relative to the private dict data. */
ReadTableInfo(h,
(Offset) (h->dict.subrs + h->fontSet.fontPrivDictInfo.offset),
&h->type1.cid.localSubrs[fd]);
h->type1.cid.localSubrBias[fd] =
XCF_CalculateSubrBias(h->type1.cid.localSubrs[fd].count);
}
subrCount = h->options.outputCharstrType == 1 ? 5 : h->type1.cid.localSubrs[fd].count;
AssignDictionaryDefaults(h);
h->dict.fontType = saveFontType;
#ifdef T13
XT13_SetLenIV(h);
#endif
h->type1.cid.languageGroup[fd] = (Card8) ((h->dict.languageGroupCount == 1) ? h->dict.languageGroup : 0);
h->type1.cid.nominalWidthX[fd] = (Fixed) ((h->dict.nominalWidthXCount == 1) ? h->dict.nominalWidthX : 0);
h->type1.cid.defaultWidthX[fd] = (Fixed) ((h->dict.defaultWidthXCount == 1) ?
h->dict.defaultWidthX : 0);
XT1_WriteCIDDict(h, fd, subrMapOffset, subrCount);
subrMapOffset += (subrCount + 1) * 4; /* xxx if SDBytes is not 4 this changes! */
/* The +1 is for the final interval for the last subr in each group. */
}
h->callbacks.xcfSprintf(defStr, CCHOF(defStr), "def%s", XCF_NEW_LINE);
XCF_PutData(h, (Card8 PTR_PREFIX *)defStr, h->callbacks.strlen(defStr));
h->type1.cid.subrDataStart = subrMapOffset;
h->type1.cid.charMapStart = 0;
}
static enum XCF_Result Process_CIDFont(XCF_Handle h)
{
Card16 fd;
Card16 fdBytes = (h->type1.cid.fdCount > 1 ? 1 : 0);
XT1_WriteCIDTop(h); /* Write top-level dict, up to FDArray */
/* xxx If FDBytes or GDBytes is variable, then the 2nd argument,
subrMapStart will change. */
ReadandWriteCIDDict(h, ((Offset)h->dict.cidCount + 1) * (fdBytes + 4));
XT1_CIDBeginBinarySection(h);
h->type1.cid.flags |= WRITE_SUBR_FLAG;
/* xxx This will become more complicated when we have real subrs. */
for (fd = 0; fd < h->type1.cid.fdCount ; ++fd)
XT1_CIDWriteSubrMap(h, fd);
/* xxx now we should be in the same place */
h->type1.cid.subrDataStart = XCF_OutputPos(h);
for (fd = 0; fd < h->type1.cid.fdCount ; ++fd)
XT1_CIDWriteSubrs(h, fd);
h->type1.cid.charDataStart = XCF_OutputPos(h);
h->type1.cid.flags &= 0xFFFD; /* Reset WriteSubr flag */
ProcessCharStrings(h);
h->type1.cid.charDataEnd = XCF_OutputPos(h);
XT1_CIDWriteCharMap(h);
XT1_CIDEndBinarySection(h);
XCF_FlushOutputBuffer(h);
return XCF_Ok;
}
static void DLGlyphs_Allocate(XCF_Handle h)
{
/* Allocate space to keep track of the downloaded glyphs */
h->dl.glyphs = (Card8 *)NULL;
h->dl.glyphsSize = (h->fontSet.charStrings.count + 7) / 8;
/* Allocate memory for incremental download bookkeeping */
if (!h->callbacks.allocate(
(void PTR_PREFIX * PTR_PREFIX *)&h->dl.glyphs,
h->dl.glyphsSize, h->callbacks.allocateHook))
XCF_FATAL_ERROR(h, XCF_MemoryAllocationError,
"Failure to allocate memory for incremental download bookkeeping",
h->dl.glyphsSize);
/* Initialize the list */
h->callbacks.memset(h->dl.glyphs, 0, (unsigned short int)h->dl.glyphsSize);
h->dl.state = XCF_DL_INIT;
}
/* Modifies the XUID if one exists and creates an XUID if one doesn't
exist in order to prevent any possible conflicts that can occur
between a subsetted font that has been downloaded and the fully
"released" Type 1 font as a result of font caching. The problem
occurs if both fonts have the same UniqueID or XUID. For example,
if the subsetted font has flattened subroutines and is downloaded
first then the full font which includes subroutines is downloaded
the second font will not work if it tries to show a glyph that
depends on a subroutine because the font cache has not been updated.
*/
static void SetXUID(XCF_Handle h)
{
if (h->dict.xUIDCount != 0)
/* 5 means that the rest of the XUID is an XUID for a font which is
basically the same as this except that "flattening" of subroutines
has been done in this font. */
h->dict.xUID[0] = 5;
else if ((h->dict.uniqueIDCount != 0)
|| (h->options.uniqueIDMethod == XCF_USER_UID))
{ /* Create an XUID of the form: [6 <UniqueID>] */
h->dict.xUIDCount = 2;
h->dict.xUID[0] = 6;
h->dict.xUID[1] = h->options.uniqueIDMethod == XCF_USER_UID ?
h->options.uniqueID : h->dict.uniqueID;
}
}
enum XCF_Result XCF_ProcessCFF(XFhandle handle)
{
XCF_Handle h = (XCF_Handle) handle;
enum XCF_Result status;
jmp_buf old_env;
DEFINE_ALIGN_SETJMP_VAR;
h->callbacks.memcpy(old_env, &h->jumpData, sizeof(h->jumpData));
status = (enum XCF_Result)SETJMP(h->jumpData); /* Set up error handler */
if (status)
{
h->callbacks.memcpy(&h->jumpData, old_env, sizeof(h->jumpData));
return status;
}
h->type1.cid.flags = 0;
/* Initialize XCF */
ClearDictionaryData(h);
XCF_LookUpTableEntry(h, &h->fontSet.fontDicts, h->options.fontIndex);
XCF_ReadDictionary(h); /* Font Dict */
XC_Init(h); /* This call has to be after the top dict is read because
* it uses the numberOfMasters field to allocate space.
*/
if (h->dict.numberOfMasters)
{ /* Convert user design vector to a weight vector. */
char PTR_PREFIX *str;
Card16 length;
XCF_LookUpString(h, h->dict.ndv, &str, &length);
XC_ParseCharStr(h, (unsigned char PTR_PREFIX *)str, 2);
XCF_LookUpString(h, h->dict.cdv, &str, &length);
XC_ParseCharStr(h, (unsigned char PTR_PREFIX *)str, 2);
}
if (h->dict.ROSCount == 3)
h->type1.cid.flags |= CID_FLAG;
SetXUID(h);
/* This version of xcf does not support global subroutines or
outputting Type 2 charstrings in CIDFonts. */
if ((h->options.outputCharstrType == 2) && (CIDFONT ||
h->fontSet.globalSubrs.count))
{
h->callbacks.memcpy(&h->jumpData, old_env, sizeof(h->jumpData));
return XCF_Unimplemented;
}
if (!CIDFONT)
{
XCF_ReadBlock(h, h->fontSet.fontPrivDictInfo.offset,
h->fontSet.fontPrivDictInfo.size);
XCF_ReadDictionary(h); /* Private Dict */
ProcessDictionaryData(h, true);
if (h->dl.state == XCF_DL_CREATE)
DLGlyphs_Allocate(h);
ProcessCharset(h);
/* Don't need to process the encoding array if the client specifies
its own encoding array name */
if (!h->options.dlOptions.encodeName && h->dl.state == XCF_DL_INIT)
ProcessEncoding(h);
XC_SetUpStandardSubrs(h);
#if HAS_COOLTYPE_UFL == 1
if (h->options.outputCharstrType != 2 && XCF_TransDesignFont(h))
XC_ProcessTransDesignSubrs(h);
#endif
ProcessCharStrings(h);
}
else
{
/* CID font indicated by presence of ROS in top level dict */
if ((status = ReadCIDTopDictInfo(h)) == XCF_Ok)
if (h->dl.state == XCF_DL_CREATE)
DLGlyphs_Allocate(h);
}
h->callbacks.memcpy(&h->jumpData, old_env, sizeof(h->jumpData));
return status;
}
enum XCF_Result XCF_ConvertToPostScript(XFhandle handle)
{
XCF_Handle h = (XCF_Handle) handle;
enum XCF_Result status;
status = XCF_ProcessCFF(handle);
if (status == XCF_Ok)
{
if (!CIDFONT)
{
XT1_WriteT1Font(h);
XCF_FlushOutputBuffer(h);
}
else
Process_CIDFont(h);
}
return status;
}
#ifdef XCF_DUMP_CFF
enum XCF_Result XCF_DumpCff(
XFhandle handle, /* In */
unsigned int fontIndex, /* In */
int dumpCompleteFontSet, /* In */
char PTR_PREFIX *fileName, /* In */
char PTR_PREFIX *commandLine) /* In */
{
XCF_Handle h = (XCF_Handle) handle;
enum XCF_Result status;
Card16 lastFontIndex;
Card16 i;
jmp_buf old_env;
DEFINE_ALIGN_SETJMP_VAR;
h->callbacks.memcpy(&old_env, &h->jumpData, sizeof(h->jumpData));
status = (enum XCF_Result)SETJMP(h->jumpData); /* Set up error handler */
if (status)
{
h->callbacks.memcpy(&h->jumpData, &old_env, sizeof(h->jumpData));
return status;
}
h->options.eexecEncryption = 0;
h->options.maxBlockSize = MAX_OUT_BUFFER;
h->fontSet.stringIDBias = ARRAY_LEN(stdStrIndex);
if (dumpCompleteFontSet)
{
fontIndex = 0;
lastFontIndex = h->fontSet.fontNames.count - 1;
}
else
{
lastFontIndex = fontIndex;
h->fontSet.fontIndex = fontIndex;
}
h->outBuffer.eexecOn = false;
/*
XCF_PutString(h, "// CFF To ASCII conversion" XCF_NEW_LINE);
XCF_PutString(h, "// Generated by XCF VER " XCF_Version XCF_NEW_LINE);
XCF_PutString(h, "// Input File = \"");
XCF_PutString(h, fileName);
XCF_PutString(h, "\"" XCF_NEW_LINE);
XCF_PutString(h, "// Command Line = \"");
XCF_PutString(h, commandLine);
XCF_PutString(h, "\"" XCF_NEW_LINE);
*/
XCF_PutString(h, "CFF Dump Version 0.2" XCF_NEW_LINE);
XCF_DumpGlobalCFFSections(h, dumpCompleteFontSet);
for (i = fontIndex; i <= lastFontIndex; ++i)
{
ClearDictionaryData(h);
h->fontSet.fontIndex = i;
XCF_LookUpTableEntry(h, &h->fontSet.fontDicts, i);
XCF_ReadDictionary(h); /* Font Dict */
if (h->dict.syntheticBaseCount) /* If synthetic then read base font dict */
{
XCF_LookUpTableEntry(h, &h->fontSet.fontDicts, (CardX) h->dict.syntheticBase);
XCF_ReadDictionary(h);
}
if (h->dict.ROSCount == 3)
h->type1.cid.flags |= CID_FLAG;
XCF_ReadBlock(h, h->fontSet.fontPrivDictInfo.offset, h->fontSet.fontPrivDictInfo.size);
XCF_ReadDictionary(h); /* Private Dict */
ProcessDictionaryData(h, false);
ProcessCharset(h);
ProcessEncoding(h);
if (CIDFONT)
ProcessFDIndex(h);
XCF_DumpFontSpecificCFFSections(h);
}
XCF_PutString(h, XCF_NEW_LINE "[END]" XCF_NEW_LINE);
XCF_FlushOutputBuffer(h);
h->callbacks.memcpy(&h->jumpData, &old_env, sizeof(h->jumpData));
return XCF_Ok;
}
#endif
static void DownloadFont(XCF_Handle h, short cGlyphs,
XCFGlyphID PTR_PREFIX *pGlyphID,
unsigned char PTR_PREFIX **pGlyphName,
unsigned long PTR_PREFIX *pCharStrLength)
{
if (h->dl.state == XCF_DL_INIT)
{ /* A new font */
if (!CIDFONT)
XT1_WriteFontSubset(h, cGlyphs, pGlyphID, pGlyphName, pCharStrLength);
else
{
XT1_WriteCIDTop(h); /* Write top-level dict, up to FDArray */
ReadandWriteCIDDict(h, 0);
XT1_WriteGlyphDictEntries(h, cGlyphs, pGlyphID, pCharStrLength);
XT1_WriteCIDVMBinarySection(h);
}
h->dl.state = XCF_DL_BASE;
}
else
{ /* A font that has been downloaded */
if (!CIDFONT)
XT1_WriteAdditionalFontSubset(h, cGlyphs, pGlyphID, pGlyphName,
pCharStrLength);
else
{
XT1_WriteAdditionalGlyphDictEntries(h, cGlyphs, pGlyphID, pCharStrLength);
}
h->dl.state = XCF_DL_SUBSET;
}
XCF_FlushOutputBuffer(h);
}
enum XCF_Result XCF_DownloadFontIncr(
XFhandle hfontset,
short cGlyphs, /* In */
XCFGlyphID PTR_PREFIX *pGlyphID, /* In */
unsigned char PTR_PREFIX **pGlyphName, /* In */
unsigned long PTR_PREFIX *pCharStrLength /* Out */
)
{
enum XCF_Result retVal;
XCF_Handle h = (XCF_Handle)hfontset;
short i, glyphID;
short numGlyphs = cGlyphs;
CardX totalGlyphs = h->fontSet.charStrings.count;
boolean completeFont = false;
boolean glyphsToDld = false;
XCFGlyphID PTR_PREFIX *pID = pGlyphID;
DEFINE_ALIGN_SETJMP_VAR;
/* Set up error handler */
retVal = (enum XCF_Result)SETJMP(((XCF_Handle)h)->jumpData);
if (retVal != 0)
return retVal;
if (h->dl.state == XCF_DL_INIT)
glyphsToDld = true;
else /* Check if there are any glyphs to download. */
{
if (cGlyphs == -1)
{
numGlyphs = (short)totalGlyphs;
completeFont = true;
}
for (i = 0; i < numGlyphs; i++, pID++)
{
glyphID = (short)((completeFont) ? i : *pID);
if (glyphID > (XCFGlyphID)totalGlyphs)
XCF_FATAL_ERROR(h, XCF_InvalidGID, "bad Glyph ID", glyphID);
if (!IS_GLYPH_SENT(h->dl.glyphs, glyphID))
{
glyphsToDld = true;
break;
}
}
}
if (glyphsToDld)
DownloadFont(h, cGlyphs, pGlyphID, pGlyphName, pCharStrLength);
return retVal;
}
/* Clears (reset to 0) the list of glyphs that have been downloaded. */
enum XCF_Result XCF_ClearIncrGlyphList(XFhandle hfontset)
{
XCF_Handle h;
if (hfontset == 0)
return XCF_InvalidFontSetHandle;
h = (XCF_Handle)hfontset;
if (h->dl.glyphs != NULL)
{
h->callbacks.memset(h->dl.glyphs, 0, (unsigned short int)h->dl.glyphsSize);
h->callbacks.memset(&h->dl.seacs, 0, (unsigned short int)32);
h->dl.cSeacs = 0;
}
return XCF_Ok;
}
/* For each glyphID in pGlyphIDs gidToCharName is called with the associated
character name and string length. */
enum XCF_Result XCF_GlyphIDsToCharNames(
XFhandle handle,
short cGlyphs,
XCFGlyphID PTR_PREFIX *pGlyphIDs, /* list of glyphIDs */
void PTR_PREFIX *client, /* client data passed to callback, can be NULL */
unsigned short clientSize /* size of client data buffer */)
{
short i;
char PTR_PREFIX *str;
char cidStr[10];
Card16 len = 0, lenUsed;
XCF_Handle h;
Card32 index;
if (handle == 0)
return XCF_InvalidFontSetHandle;
h = (XCF_Handle)handle;
if (h->callbacks.gidToCharName == 0)
return XCF_InvalidCallbackFunction;
for (i = 0; i < cGlyphs; i++)
{
index = *pGlyphIDs;
/* The charset table does not include the 0th entry for .notdef. */
if (index)
index--;
else
{
if (CIDFONT)
h->callbacks.gidToCharName(handle, client, *pGlyphIDs++, "0", 1);
else
h->callbacks.gidToCharName(handle, client, *pGlyphIDs++, ".notdef", 7);
continue;
}
if (CIDFONT)
{
h->callbacks.xcfSprintf(cidStr, CCHOF(cidStr), "%d", h->type1.pCharset[index]);
len = h->callbacks.strlen(cidStr);
str = cidStr;
}
else
XCF_LookUpString(h, h->type1.pCharset[index], &str, &len);
lenUsed = (len < (Card16)clientSize)? len : (Card16)(clientSize-1);
h->callbacks.gidToCharName(handle, client, *pGlyphIDs++, str, lenUsed);
}
return XCF_Ok;
}
/* For each glyphID in pGlyphIDs gidToCID is called with the associated cid. */
enum XCF_Result XCF_GlyphIDsToCIDs(XFhandle handle,
short cGlyphs, /* number of glyphs in glyphID list */
XCFGlyphID PTR_PREFIX *pGlyphIDs, /* list of glyphIDs */
void PTR_PREFIX *client /* client data, can be NULL */)
{
short i;
XCF_Handle h = (XCF_Handle)handle;
Card32 gid;
Card16 cid;
CardX totalGlyphs = h->fontSet.charStrings.count;
if (handle == 0)
return XCF_InvalidFontSetHandle;
if (h->callbacks.gidToCID == 0)
return XCF_InvalidCallbackFunction;
for (i = 0; i < cGlyphs; i++, pGlyphIDs++)
{
gid = *pGlyphIDs;
/* The charset table does not include the 0th entry for .notdef. */
cid = (gid == 0 || gid > (Card32)totalGlyphs) ? 0 : (Card16)(h->type1.pCharset[gid - 1]);
h->callbacks.gidToCID(handle, client, gid, cid);
}
return XCF_Ok;
}
enum XCF_Result XCF_CharNamesToGIDs(XFhandle handle,
short cGlyphs,
char PTR_PREFIX **charNames,
void PTR_PREFIX *client)
{
Card16 i,j;
char PTR_PREFIX *str;
Card16 len, inputLen;
XCF_Handle h = (XCF_Handle)handle;
if (h->callbacks.gnameToGid == 0)
return XCF_InvalidCallbackFunction;
/* for now, this doesnt work for cid fonts */
if (CIDFONT)
return XCF_Unimplemented;
for (i = 0; i < (Card16)cGlyphs; i++)
{
/* The charset array does not include an entry for ".notdef" */
if (h->callbacks.strcmp(charNames[i], NOTDEF_STR) == 0) {
h->callbacks.gnameToGid(handle, client, i, charNames[i], NOTDEF_GID);
continue;
}
inputLen = h->callbacks.strlen(charNames[i]);
/* there is no good way to do this...just loop through
* looking for a match
*/
for (j = 0; j < h->type1.charsetSize; j++) {
XCF_LookUpString(h, h->type1.pCharset[j], &str, &len);
if (inputLen == len && !h->callbacks.strncmp(charNames[i], str, len)){
h->callbacks.gnameToGid(handle, client, i, charNames[i], j+1);
break;
}
}
}
return XCF_Ok;
}
enum XCF_Result XCF_CountDownloadGlyphs(
XFhandle hfontset, /* In */
short cGlyphs, /* In */
XCFGlyphID PTR_PREFIX *pGlyphID, /* In */
unsigned short PTR_PREFIX *pcNewGlyphs /* Out */
)
{
enum XCF_Result status;
boolean flCompleteFont;
short i, glyphID;
Card8 PTR_PREFIX *tempGlyphList = 0;
XCF_Handle h = (XCF_Handle)hfontset;
CardX totalGlyphs;
jmp_buf old_env;
DEFINE_ALIGN_SETJMP_VAR;
*pcNewGlyphs = 0;
h->callbacks.memcpy(old_env, &h->jumpData, sizeof(h->jumpData));
if (!(status = (enum XCF_Result)SETJMP(h->jumpData))) /* Set up error handler */
{
totalGlyphs = h->fontSet.charStrings.count;
if ( cGlyphs == -1 )
{
cGlyphs = (short)totalGlyphs;
flCompleteFont = true;
}
else
flCompleteFont = false;
/* Allocate memory for the temporary list. */
if (!h->callbacks.allocate(
(void PTR_PREFIX * PTR_PREFIX *)&tempGlyphList,
h->dl.glyphsSize, h->callbacks.allocateHook))
XCF_FATAL_ERROR(h, XCF_MemoryAllocationError,
"Failure to allocate memory for incremental download bookkeeping",
h->dl.glyphsSize);
/* Copy this current downloaded glyphs */
h->callbacks.memcpy(tempGlyphList, h->dl.glyphs, (Card16)h->dl.glyphsSize);
for (i=0; i < cGlyphs; i++, pGlyphID++)
{
glyphID = (short)((flCompleteFont) ? i : *pGlyphID);
if (glyphID < 0 || glyphID > (XCFGlyphID)totalGlyphs)
XCF_FATAL_ERROR(h, XCF_InvalidGID, "bad Glyph ID", glyphID);
/* Check to see if we have downloaded this glyph. If this is a normal
character, then we simply check it against the glyphs
list. */
if (!IS_GLYPH_SENT(tempGlyphList, glyphID))
{
SET_GLYPH_SENT_STATUS(tempGlyphList, glyphID);
*pcNewGlyphs += 1;
}
}
}
/* Deallocate temporary glyph list */
if (tempGlyphList)
h->callbacks.allocate((void PTR_PREFIX * PTR_PREFIX *)&tempGlyphList, 0, h->callbacks.allocateHook);
h->callbacks.memcpy(&h->jumpData, old_env, sizeof(h->jumpData));
return status;
}
CardX GetStdEncodeSID(CardX gid)
{
return stdEncoding[gid];
}
char PTR_PREFIX *GetStdEncodingName(CardX gid)
{
if (gid < 256)
return (char PTR_PREFIX *)(stdStrIndex[stdEncoding[gid]]);
else
return (char PTR_PREFIX *)NULL;
}
#if HAS_COOLTYPE_UFL == 1
/* Initializes, creates, and returns an XFhandle in pHandle.
This is essentially the same function as XCF_Init except
that it does not read a fontset to initialize certain
fields in its internal fontSet data structure.
*/
enum XCF_Result XCF_InitHandle(
XFhandle PTR_PREFIX *pHandle, /* Out */
XCF_CallbackStruct PTR_PREFIX *pCallbacks, /* In */
XCF_ClientOptions PTR_PREFIX *options, /* In */
unsigned long charStrCt) /* In */
{
XCF_Handle h = (XCF_Handle)NULL;
enum XCF_Result status;
jmp_buf old_env;
if (!pCallbacks->allocate((void PTR_PREFIX * PTR_PREFIX *)&h, sizeof(*h), pCallbacks->allocateHook))
return XCF_MemoryAllocationError;
InitHandle(h, pCallbacks);
/* Allocate download glyph data structure. */
h->fontSet.charStrings.count = charStrCt;
DLGlyphs_Allocate(h);
DEFINE_ALIGN_SETJMP_VAR;
h->callbacks.memcpy(&old_env, &h->jumpData, sizeof(h->jumpData));
status = (enum XCF_Result)SETJMP(h->jumpData); /* Set up error handler */
if (status)
{
h->callbacks.memcpy(&h->jumpData, &old_env, sizeof(h->jumpData));
return status;
}
*pHandle = h;
SetClientOptions(h, options);
h->fontSet.fontIndex = options->fontIndex;
h->fontSet.stringIDBias = ARRAY_LEN(stdStrIndex);
h->callbacks.memcpy(&h->jumpData, &old_env, sizeof(h->jumpData));
return XCF_Ok;
}
#endif
#ifdef XCF_DEVELOP
enum XCF_Result XCF_ShowHexString(XFhandle fontsetHandle,
unsigned char PTR_PREFIX *hexString, unsigned char showCtrlD)
{
enum XCF_Result status;
DEFINE_ALIGN_SETJMP_VAR;
/* Set up error handler */
status = (enum XCF_Result)SETJMP(((XCF_Handle)fontsetHandle)->jumpData);
if (status)
return status;
XT1_ShowHexString((XCF_Handle)fontsetHandle, hexString, showCtrlD);
XCF_FlushOutputBuffer((XCF_Handle)fontsetHandle);
}
#endif
#ifdef __cplusplus
}
#endif