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.
 
 
 
 
 
 

850 lines
25 KiB

/******************************Module*Header*******************************\
* Module Name: fdcvt.c
*
* Font file loading and unloadking. Adapted from BodinD's bitmap font driver.
*
* Created: 26-Feb-1992 20:23:54
* Author: Wendy Wu [wendywu]
*
* Copyright (c) 1990 Microsoft Corporation
\**************************************************************************/
#include "fd.h"
// points to the linked list of glyphset strucs
CP_GLYPHSET *gpcpVTFD = NULL;
ULONG cjVTFDIFIMETRICS(PBYTE ajHdr);
// !!! put prototype in common area for all font drivers so change
// !!! in 1 is reflected in all.
FSHORT fsSelectionFlags(PBYTE ajHdr); // in bmfd
extern BOOL bDbgPrintAndFail(PSZ psz);
#if DBG
extern BOOL bDbgPrintAndFail(PSZ psz);
#else
#define bDbgPrintAndFail(psz) FALSE
#endif
ULONG iDefaultFace(PBYTE ajHdr) // similar to vDefFace, should not be duplicated
{
ULONG iDefFace;
if (READ_WORD(&ajHdr[OFF_Weight]) <= FW_NORMAL)
{
if (ajHdr[OFF_Italic])
{
iDefFace = FF_FACE_ITALIC;
}
else
{
iDefFace = FF_FACE_NORMAL;
}
}
else
{
if (ajHdr[OFF_Italic])
{
iDefFace = FF_FACE_BOLDITALIC;
}
else
{
iDefFace = FF_FACE_BOLD;
}
}
return iDefFace;
}
/******************************Private*Routine*****************************\
* BOOL bVerifyVTFD
*
* CHECK whether header contains file info which corresponds to
* the raster font requirements, go into the file and check
* the consistency of the header data
*
* History:
* 26-Feb-1992 -by- Wendy Wu [wendywu]
* Adapted from bmfd.
\**************************************************************************/
BOOL bVerifyVTFD(PRES_ELEM pre)
{
PBYTE ajHdr = (PBYTE)pre->pvResData;
if (pre->cjResData < OFF_OffTable20)
return(bDbgPrintAndFail("VTFD! resource size too small for OFF_OffTable20\n")); // supported.
if (!(READ_WORD(&ajHdr[OFF_Type]) & TYPE_VECTOR)) // Vector bit has to
return(bDbgPrintAndFail("VTFD!fsType \n")); // be on.
if ((READ_WORD(&ajHdr[OFF_Version]) != 0x0100) && // The only version
(READ_WORD(&ajHdr[OFF_Version]) != 0x0200) ) // The only version
return(bDbgPrintAndFail("VTFD!iVersion\n")); // supported.
if ((ajHdr[OFF_BitsOffset] & 1) != 0) // Must be an even
return(bDbgPrintAndFail("VTFD!dpBits odd \n")); // offset.
// file size must be <= than the size of the view
if (READ_DWORD(&ajHdr[OFF_Size]) > pre->cjResData)
return(bDbgPrintAndFail("VTFD!cjSize \n"));
// make sure that the reserved bits are all zero
if ((READ_WORD(&ajHdr[OFF_Type]) & BITS_RESERVED) != 0)
return(bDbgPrintAndFail("VTFD!fsType, reserved bits \n"));
if (abs(READ_WORD(&ajHdr[OFF_Ascent])) > READ_WORD(&ajHdr[OFF_PixHeight]))
return(bDbgPrintAndFail("VTFD!sAscent \n")); // Ascent Too Big
if (READ_WORD(&ajHdr[OFF_IntLeading]) > READ_WORD(&ajHdr[OFF_Ascent]))
return(bDbgPrintAndFail("VTFD! IntLeading too big\n")); // Int Lead Too Big;
// check consistency of character ranges
if (ajHdr[OFF_FirstChar] > ajHdr[OFF_LastChar])
return(bDbgPrintAndFail("VTFD! FirstChar\n")); // this can't be
// default and break character are given relative to the FirstChar,
// so that the actual default (break) character is given as
// chFirst + chDefault(Break)
if ((BYTE)(ajHdr[OFF_DefaultChar] + ajHdr[OFF_FirstChar]) > ajHdr[OFF_LastChar])
return(bDbgPrintAndFail("VTFD! DefaultChar\n"));
if ((BYTE)(ajHdr[OFF_BreakChar] + ajHdr[OFF_FirstChar]) > ajHdr[OFF_LastChar])
return(bDbgPrintAndFail("VTFD! BreakChar\n"));
// finally verify that all the offsets to glyph data point to locations
// within the file and that what they point to is valid glyph data: [BodinD]
{
INT iIndex, dIndex, iIndexEnd;
PBYTE pjCharTable, pjGlyphData,pjFirstChar, pjEndFile;
iIndexEnd = (INT)ajHdr[OFF_LastChar] - (INT)ajHdr[OFF_FirstChar] + 1;
// init out of the loop:
if (READ_WORD(&ajHdr[OFF_PixWidth]) != 0) // fixed pitch
{
iIndexEnd <<= 1; // each entry is 2-byte long
dIndex = 2;
}
else
{
iIndexEnd <<= 2; // each entry is 4-byte long
dIndex = 4;
}
pjFirstChar = ajHdr + READ_DWORD(ajHdr + OFF_BitsOffset);
// Vector font file doesn't have the byte filler. Win31 bug?
pjCharTable = ajHdr + OFF_jUnused20;
pjEndFile = ajHdr + READ_DWORD(ajHdr + OFF_Size);
if (OFF_jUnused20 + (ULONG)(iIndexEnd * dIndex) > pre->cjResData)
return(bDbgPrintAndFail("VTFD! OffsetTable out of file \n"));
for (iIndex = 0; iIndex < iIndexEnd; iIndex += dIndex)
{
pjGlyphData = pjFirstChar + READ_WORD(&pjCharTable[iIndex]);
if ((pjGlyphData >= pjEndFile) || (*pjGlyphData != (BYTE)PEN_UP))
return(bDbgPrintAndFail("VTFD!bogus vector font \n"));
}
}
{
PSZ pszFaceName = ajHdr + READ_DWORD(&ajHdr[OFF_Face]);
SIZE_T pszFaceNameLength;
if (!bMappedViewStrlen(pre->pvResData, pre->cjResData, pszFaceName, &pszFaceNameLength))
return(bDbgPrintAndFail("VTFD!bogus FaceName \n"));
}
return(TRUE);
}
/******************************Private*Routine*****************************\
* ULONG cVtfdResFaces
*
* Compute the number of faces that the given .FNT file can support.
*
* History:
* 04-Mar-1992 -by- Wendy Wu [wendywu]
* Wrote it.
\**************************************************************************/
ULONG cVtfdResFaces(PBYTE ajHdr)
{
// We set the FM_SEL_BOLD flag iff weight is > FW_NORMAL (400).
// We will not allow emboldening simulation on the font that has this
// flag set.
if (READ_WORD(&ajHdr[OFF_Weight]) <= FW_NORMAL)
{
if (ajHdr[OFF_Italic])
return(2);
else
return(4);
}
else
{
if (ajHdr[OFF_Italic])
return(1);
else
return(2);
}
}
/******************************Private*Routine*****************************\
* VOID vVtfdFill_IFIMetrics
*
* Looks into the .FNT file and fills the IFIMETRICS structure accordingly.
*
* History:
* Wed 04-Nov-1992 -by- Bodin Dresevic [BodinD]
* update: new ifimetrics
* 26-Feb-1992 -by- Wendy Wu [wendywu]
* Adapted from bmfd.
\**************************************************************************/
VOID vVtfdFill_IFIMetrics(PBYTE ajHdr, FD_GLYPHSET * pgset, PIFIMETRICS pifi)
{
FWORD fwdHeight;
FONTSIM *pFontSim;
FONTDIFF *pfdiffBold = 0, *pfdiffItalic = 0, *pfdiffBoldItalic = 0;
PANOSE *ppanose;
ULONG iDefFace;
ULONG cjIFI = ALIGN4(sizeof(IFIMETRICS));
ULONG cch;
FWORD cy;
// compute pointers to the various sections of the converted file
// face name lives in the original file, this is the only place pvView is used
PSZ pszFaceName = (PSZ)(ajHdr + READ_DWORD(&ajHdr[OFF_Face]));
pifi->cjIfiExtra = 0;
pifi->cjThis = cjVTFDIFIMETRICS(ajHdr);
// the string begins on a DWORD aligned address.
pifi->dpwszFaceName = cjIFI;
// face name == family name for vector fonts [Win3.0 compatibility]
pifi->dpwszFamilyName = pifi->dpwszFaceName;
// these names don't exist, so point to the NULL char [Win3.1 compatibility]
// Note: lstrlen() does not count the terminating NULL.
cch = (ULONG)strlen(pszFaceName);
pifi->dpwszStyleName = pifi->dpwszFaceName + sizeof(WCHAR) * cch;
pifi->dpwszUniqueName = pifi->dpwszStyleName;
cjIFI += ALIGN4((cch + 1) * sizeof(WCHAR));
// copy the strings to their new location. Here we assume that the sufficient
// memory has been allocated
vToUNICODEN((LPWSTR)((PBYTE)pifi + pifi->dpwszFaceName), cch+1, pszFaceName, cch+1);
// Check to see if simulations are necessary and if they are, fill
// in the offsets to the various simulation fields and update cjThis
// field of the IFIMETRICS structure
iDefFace = iDefaultFace(ajHdr);
if (iDefFace == FF_FACE_BOLDITALIC)
{
pifi->dpFontSim = 0;
}
else
{
pifi->dpFontSim = cjIFI;
pFontSim = (FONTSIM*) ((BYTE*)pifi + pifi->dpFontSim);
cjIFI += ALIGN4(sizeof(FONTSIM));
switch (iDefFace)
{
case FF_FACE_NORMAL:
//
// simulations are needed for bold, italic, and bold-italic
//
pFontSim->dpBold = ALIGN4(sizeof(FONTSIM));
pFontSim->dpItalic = pFontSim->dpBold + ALIGN4(sizeof(FONTDIFF));
pFontSim->dpBoldItalic = pFontSim->dpItalic + ALIGN4(sizeof(FONTDIFF));
pfdiffBold =
(FONTDIFF*) ((BYTE*) pFontSim + pFontSim->dpBold);
pfdiffItalic =
(FONTDIFF*) ((BYTE*) pFontSim + pFontSim->dpItalic);
pfdiffBoldItalic =
(FONTDIFF*) ((BYTE*) pFontSim + pFontSim->dpBoldItalic);
cjIFI += (3 * ALIGN4(sizeof(FONTDIFF)));
break;
case FF_FACE_BOLD:
case FF_FACE_ITALIC:
//
// a simulation is needed for bold-italic only
//
pFontSim->dpBold = 0;
pFontSim->dpItalic = 0;
pFontSim->dpBoldItalic = ALIGN4(sizeof(FONTSIM));
pfdiffBoldItalic =
(FONTDIFF*) ((BYTE*) pFontSim + pFontSim->dpBoldItalic);
cjIFI += ALIGN4(sizeof(FONTDIFF));
break;
default:
RIP("VTFD -- bad iDefFace\n");
break;
}
}
ASSERTDD(cjIFI == pifi->cjThis, "cjIFI is wrong\n");
pifi->jWinCharSet = ajHdr[OFF_CharSet];
pifi->jWinPitchAndFamily = ajHdr[OFF_Family];
//
// !!![kirko] The next line of code is very scary but it seems to work.
// This will call a font with FIXED_PITCH set, a varible pitch font.
// Or should this be decided upon whether cx == 0 or not? [bodind]
//
// this is the excert from wendy's code:
// if ((ajHdr[OFF_Family] & 1) == 0)
// pifi->flInfo |= FM_INFO_CONSTANT_WIDTH;
if (pifi->jWinPitchAndFamily & 0x0f)
{
pifi->jWinPitchAndFamily = ((pifi->jWinPitchAndFamily & 0xf0) | VARIABLE_PITCH);
}
else
{
pifi->jWinPitchAndFamily = ((pifi->jWinPitchAndFamily & 0xf0) | FIXED_PITCH);
}
pifi->usWinWeight = READ_WORD(&ajHdr[OFF_Weight]);
// weight, may have to fix it up if the font contains a garbage value [bodind]
if ((pifi->usWinWeight > MAX_WEIGHT) || (pifi->usWinWeight < MIN_WEIGHT))
pifi->usWinWeight = 400;
pifi->flInfo = ( FM_INFO_TECH_STROKE
| FM_INFO_ARB_XFORMS
| FM_INFO_RETURNS_STROKES
| FM_INFO_RIGHT_HANDED
);
if ((pifi->jWinPitchAndFamily & 0xf) == FIXED_PITCH)
{
pifi->flInfo |= (FM_INFO_CONSTANT_WIDTH | FM_INFO_OPTICALLY_FIXED_PITCH);
}
pifi->lEmbedId = 0;
pifi->fsSelection = fsSelectionFlags(ajHdr);
//
// The choices for fsType are FM_TYPE_LICENSED and FM_READONLY_EMBED
// These are TrueType things and do not apply to old fashioned bitmap and vector
// fonts.
//
pifi->fsType = 0;
cy = (FWORD)READ_WORD(&ajHdr[OFF_PixHeight]);
pifi->fwdUnitsPerEm = ((FWORD)READ_WORD(&ajHdr[OFF_IntLeading]) > 0) ?
cy - (FWORD)READ_WORD(&ajHdr[OFF_IntLeading]) : cy;
pifi->fwdLowestPPEm = 0;
pifi->fwdWinAscender = (FWORD)READ_WORD(&ajHdr[OFF_Ascent]);
pifi->fwdWinDescender = cy - pifi->fwdWinAscender;
pifi->fwdMacAscender = pifi->fwdWinAscender ;
pifi->fwdMacDescender = -pifi->fwdWinDescender;
pifi->fwdMacLineGap = (FWORD)READ_WORD(&ajHdr[OFF_ExtLeading]);
pifi->fwdTypoAscender = pifi->fwdMacAscender;
pifi->fwdTypoDescender = pifi->fwdMacDescender;
pifi->fwdTypoLineGap = pifi->fwdMacLineGap;
pifi->fwdAveCharWidth = (FWORD)READ_WORD(&ajHdr[OFF_AvgWidth]);
pifi->fwdMaxCharInc = (FWORD)READ_WORD(&ajHdr[OFF_MaxWidth]);
//
// don't know much about SuperScripts
//
pifi->fwdSubscriptXSize = 0;
pifi->fwdSubscriptYSize = 0;
pifi->fwdSubscriptXOffset = 0;
pifi->fwdSubscriptYOffset = 0;
//
// don't know much about SubScripts
//
pifi->fwdSuperscriptXSize = 0;
pifi->fwdSuperscriptYSize = 0;
pifi->fwdSuperscriptXOffset = 0;
pifi->fwdSuperscriptYOffset = 0;
//
// win 30 magic. see the code in textsims.c in the Win 3.1 sources
//
fwdHeight = pifi->fwdWinAscender + pifi->fwdWinDescender;
pifi->fwdUnderscoreSize = (fwdHeight > 12) ? (fwdHeight / 12) : 1;
pifi->fwdUnderscorePosition = -(FWORD)(pifi->fwdUnderscoreSize / 2 + 1);
pifi->fwdStrikeoutSize = pifi->fwdUnderscoreSize;
{
// We are further adjusting underscore position if underline
// hangs below char stems.
// The only font where this effect is noticed to
// be important is an ex pm font sys08cga.fnt, presently used in console
FWORD yUnderlineBottom = -pifi->fwdUnderscorePosition
+ ((pifi->fwdUnderscoreSize + (FWORD)1) >> 1);
FWORD dy = yUnderlineBottom - pifi->fwdWinDescender;
if (dy > 0)
{
#ifdef CHECK_CRAZY_DESC
DbgPrint("bmfd: Crazy descender: old = %ld, adjusted = %ld\n\n",
(ULONG)pifi->fwdMaxDescender,
(ULONG)yUnderlineBottom);
#endif // CHECK_CRAZY_DESC
pifi->fwdUnderscorePosition += dy;
}
}
//
// Win 3.1 method
//
// LineOffset = ((((Ascent-IntLeading)*2)/3) + IntLeading)
//
// [remember that they measure the offset from the top of the cell,
// where as NT measures offsets from the baseline]
//
pifi->fwdStrikeoutPosition =
(FWORD) (((FWORD)READ_WORD(&ajHdr[OFF_Ascent]) - (FWORD)READ_WORD(&ajHdr[OFF_IntLeading]) + 2)/3);
pifi->chFirstChar = ajHdr[OFF_FirstChar];
pifi->chLastChar = ajHdr[OFF_LastChar];;
// wcDefaultChar
// wcBreakChar
{
UCHAR chDefault = ajHdr[OFF_FirstChar] + ajHdr[OFF_DefaultChar];
UCHAR chBreak = ajHdr[OFF_FirstChar] + ajHdr[OFF_BreakChar];
// Default and Break chars are given relative to the first char
pifi->chDefaultChar = chDefault;
pifi->chBreakChar = chBreak;
EngMultiByteToUnicodeN(&pifi->wcDefaultChar, sizeof(WCHAR), NULL, &chDefault, 1);
EngMultiByteToUnicodeN(&pifi->wcBreakChar , sizeof(WCHAR), NULL, &chBreak, 1);
}
// These have to be taken from the glyph set [bodind]
{
WCRUN *pwcrunLast = &(pgset->awcrun[pgset->cRuns - 1]);
pifi->wcFirstChar = pgset->awcrun[0].wcLow;
pifi->wcLastChar = pwcrunLast->wcLow + pwcrunLast->cGlyphs - 1;
}
pifi->fwdCapHeight = 0;
pifi->fwdXHeight = 0;
pifi->dpCharSets = 0; // no multiple charsets in vector fonts
// All the fonts that this font driver will see are to be rendered left
// to right
pifi->ptlBaseline.x = 1;
pifi->ptlBaseline.y = 0;
pifi->ptlAspect.y = (LONG) READ_WORD(&ajHdr[OFF_VertRes ]);
pifi->ptlAspect.x = (LONG) READ_WORD(&ajHdr[OFF_HorizRes]);
if (pifi->ptlAspect.y == 0)
{
pifi->ptlAspect.y = 1;
WARNING("VTFD!vVtfdFill_IFIMetrics():ptlAspect.y == 0\n");
}
if (pifi->ptlAspect.x == 0)
{
pifi->ptlAspect.x = 1;
WARNING("VTFD!vVtfdFill_IFIMetrics():ptlAspect.x == 0\n");
}
if (!(pifi->fsSelection & FM_SEL_ITALIC))
{
// The base class of font is not italicized,
pifi->ptlCaret.x = 0;
pifi->ptlCaret.y = 1;
}
else
{
// somewhat arbitrary
pifi->ptlCaret.x = 1;
pifi->ptlCaret.y = 2;
}
//
// The font box reflects the fact that a-spacing and c-spacing are zero
//
pifi->rclFontBox.left = 0;
pifi->rclFontBox.top = (LONG) pifi->fwdTypoAscender;
pifi->rclFontBox.right = (LONG) pifi->fwdMaxCharInc;
pifi->rclFontBox.bottom = (LONG) pifi->fwdTypoDescender;
//
// achVendorId, do not bother figuring it out
//
pifi->achVendId[0] = 'U';
pifi->achVendId[1] = 'n';
pifi->achVendId[2] = 'k';
pifi->achVendId[3] = 'n';
pifi->cKerningPairs = 0;
//
// Panose
//
pifi->ulPanoseCulture = FM_PANOSE_CULTURE_LATIN;
ppanose = &(pifi->panose);
ppanose->bFamilyType = PAN_NO_FIT;
ppanose->bSerifStyle =
((pifi->jWinPitchAndFamily & 0xf0) == FF_SWISS) ?
PAN_SERIF_NORMAL_SANS : PAN_ANY;
ppanose->bWeight = (BYTE) WINWT_TO_PANWT(READ_WORD(&ajHdr[OFF_Weight]));
ppanose->bProportion = (READ_WORD(&ajHdr[OFF_PixWidth]) == 0) ? PAN_ANY : PAN_PROP_MONOSPACED;
ppanose->bContrast = PAN_ANY;
ppanose->bStrokeVariation = PAN_ANY;
ppanose->bArmStyle = PAN_ANY;
ppanose->bLetterform = PAN_ANY;
ppanose->bMidline = PAN_ANY;
ppanose->bXHeight = PAN_ANY;
//
// Now fill in the fields for the simulated fonts
//
if (pifi->dpFontSim)
{
//
// Create a FONTDIFF template reflecting the base font
//
FONTDIFF FontDiff;
FontDiff.jReserved1 = 0;
FontDiff.jReserved2 = 0;
FontDiff.jReserved3 = 0;
FontDiff.bWeight = pifi->panose.bWeight;
FontDiff.usWinWeight = pifi->usWinWeight;
FontDiff.fsSelection = pifi->fsSelection;
FontDiff.fwdAveCharWidth = pifi->fwdAveCharWidth;
FontDiff.fwdMaxCharInc = pifi->fwdMaxCharInc;
FontDiff.ptlCaret = pifi->ptlCaret;
if (pfdiffBold)
{
*pfdiffBold = FontDiff;
pfdiffBoldItalic->bWeight = PAN_WEIGHT_BOLD;
pfdiffBold->fsSelection |= FM_SEL_BOLD;
pfdiffBold->usWinWeight = FW_BOLD;
// in vtfd case this is only true in the notional space
pfdiffBold->fwdAveCharWidth += 1;
pfdiffBold->fwdMaxCharInc += 1;
}
if (pfdiffItalic)
{
*pfdiffItalic = FontDiff;
pfdiffItalic->fsSelection |= FM_SEL_ITALIC;
pfdiffItalic->ptlCaret.x = 1;
pfdiffItalic->ptlCaret.y = 2;
}
if (pfdiffBoldItalic)
{
*pfdiffBoldItalic = FontDiff;
pfdiffBoldItalic->bWeight = PAN_WEIGHT_BOLD;
pfdiffBoldItalic->fsSelection |= (FM_SEL_BOLD | FM_SEL_ITALIC);
pfdiffBoldItalic->usWinWeight = FW_BOLD;
pfdiffBoldItalic->ptlCaret.x = 1;
pfdiffBoldItalic->ptlCaret.y = 2;
// in vtfd case this is only true in the notional space
pfdiffBoldItalic->fwdAveCharWidth += 1;
pfdiffBoldItalic->fwdMaxCharInc += 1;
}
}
}
ULONG cjVTFDIFIMETRICS(PBYTE ajHdr)
{
ULONG cjIFI = ALIGN4(sizeof(IFIMETRICS));
PSZ pszFaceName = ajHdr + READ_DWORD(&ajHdr[OFF_Face]);
ULONG cSims;
cjIFI += ALIGN4((strlen(pszFaceName) + 1) * sizeof(WCHAR));
// add simulations:
if (cSims = (cVtfdResFaces(ajHdr) - 1))
cjIFI += (ALIGN4(sizeof(FONTSIM)) + cSims * ALIGN4(sizeof(FONTDIFF)));
return cjIFI;
}
/******************************Private*Routine*****************************\
* HFF hffVtfdLoadFont
*
* Loads an *.fon or an *.fnt file, returns handle to a fonfile object
* if successfull.
*
* History:
* Wed 04-Nov-1992 -by- Bodin Dresevic [BodinD]
* update: rewrote it to reflect the new ifimetrics organization;
* 26-Feb-1992 -by- Wendy Wu [wendywu]
* Adapted from bmfd.
\**************************************************************************/
BOOL bVtfdLoadFont(PVOID pvView, ULONG cjView, ULONG_PTR iFile, ULONG iType, HFF *phff)
{
WINRESDATA wrd;
RES_ELEM re;
ULONG dpIFI, cjFF;
ULONG ifnt;
PIFIMETRICS pifi;
BOOL bResult;
BOOL bCleanupOnError;
bResult = FALSE;
bCleanupOnError = FALSE;
*phff = (HFF)NULL;
if (iType == TYPE_DLL16)
{
if (!bInitWinResData(pvView,cjView, &wrd))
{
goto Exit;
}
}
else // TYPE_FNT or TYPE_EXE
{
ASSERTDD((iType == TYPE_FNT) || (iType == TYPE_EXE),
"hffVtfdLoadFont: wrong iType\n");
re.pvResData = pvView;
re.dpResData = 0;
re.cjResData = cjView;
re.pjFaceName = NULL;
wrd.cFntRes = 1;
}
cjFF = dpIFI = offsetof(FONTFILE,afd) + wrd.cFntRes * sizeof(FACEDATA);
for (ifnt = 0; ifnt < wrd.cFntRes; ifnt++)
{
if (iType == TYPE_DLL16)
{
if (!bGetFntResource(&wrd, ifnt, &re))
{
goto Exit;
}
}
// verify that this is a no nonsense resource:
if (!bVerifyVTFD(&re))
{
goto Exit;
}
cjFF += cjVTFDIFIMETRICS(re.pvResData);
}
// now at the bottom of the structure we will store File name
// Let's allocate the FONTFILE struct.
if ((*phff = (HFF)pffAlloc(cjFF)) == (HFF)NULL)
{
WARNING("hffVtfdLoadFont: memory allocation error\n");
goto Exit;
}
bCleanupOnError = TRUE;
// Initialize fields of FONTFILE struct.
PFF(*phff)->iType = iType;
PFF(*phff)->fl = 0;
PFF(*phff)->cRef = 0L;
PFF(*phff)->iFile = iFile;
PFF(*phff)->pvView = pvView;
PFF(*phff)->cjView = cjView;
PFF(*phff)->cFace = wrd.cFntRes;
pifi = (PIFIMETRICS)((PBYTE)PFF(*phff) + dpIFI);
for (ifnt = 0; ifnt < wrd.cFntRes; ifnt++)
{
if (iType == TYPE_DLL16)
{
if (!bGetFntResource(&wrd, ifnt, &re))
{
goto Exit;
}
}
PFF(*phff)->afd[ifnt].re = re;
PFF(*phff)->afd[ifnt].iDefFace = iDefaultFace(re.pvResData);
PFF(*phff)->afd[ifnt].pifi = pifi;
PFF(*phff)->afd[ifnt].pcp = pcpComputeGlyphset(
&gpcpVTFD,
(UINT)((BYTE *)re.pvResData)[OFF_FirstChar],
(UINT)((BYTE *)re.pvResData)[OFF_LastChar],
((BYTE*)(re.pvResData))[OFF_CharSet]
);
if (PFF(*phff)->afd[ifnt].pcp == NULL)
{
WARNING("pgsetCompute failed\n");
goto Exit;
}
vVtfdFill_IFIMetrics(re.pvResData, &(PFF(*phff)->afd[ifnt].pcp->gset),pifi);
pifi = (PIFIMETRICS)((PBYTE)pifi + pifi->cjThis);
}
bResult = TRUE;
Exit:
if (!bResult)
{
#if DBG
NotifyBadFont("%s failing\n", __FUNCTION__);
#endif
if (bCleanupOnError)
{
vFree(*phff); // clean up
*phff = (HFF)NULL; // do not clean up again in exception code path
}
}
return bResult;
}
/******************************Public*Routine******************************\
* vtfdLoadFontFile
*
* Load the given font file into memory and prepare the file for use.
*
* History:
* 26-Feb-1992 -by- Wendy Wu [wendywu]
* Adapted from bmfd.
\**************************************************************************/
BOOL vtfdLoadFontFile(ULONG_PTR iFile, PVOID pvView, ULONG cjView, HFF *phff)
{
BOOL bRet = FALSE;
*phff = (HFF)NULL;
// Try loading it as a fon file, if it does not work, try as an fnt file.
if (!(bRet = bVtfdLoadFont(pvView, cjView, iFile, TYPE_DLL16,phff)))
bRet = bVtfdLoadFont(pvView, cjView, iFile, TYPE_FNT, phff); // try as an *.fnt file
return bRet;
}
/******************************Public*Routine******************************\
* BOOL vtfdUnloadFontFile
*
* Unload a font file and free all the structures created.
*
* History:
* 26-Feb-1992 -by- Wendy Wu [wendywu]
* Adapted from bmfd.
\**************************************************************************/
BOOL vtfdUnloadFontFile(HFF hff)
{
ULONG iFace;
if (hff == HFF_INVALID)
return(FALSE);
// check the reference count, if not 0 (font file is still
// selected into a font context) we have a problem
ASSERTDD(PFF(hff)->cRef == 0L, "cRef: links are broken\n");
// unload all glyphsets:
for (iFace = 0; iFace < PFF(hff)->cFace; iFace++)
{
vUnloadGlyphset(&gpcpVTFD,
PFF(hff)->afd[iFace].pcp);
}
// the file has been umapped as cRef went back to zero
vFree(PFF(hff));
return(TRUE);
}