|
|
/******************************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); }
|