mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
789 lines
20 KiB
789 lines
20 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: fontfile.c *
|
|
* *
|
|
* "Methods" for operating on FONTCONTEXT and FONTFILE objects *
|
|
* *
|
|
* Created: 18-Nov-1990 15:23:10 *
|
|
* Author: Bodin Dresevic [BodinD] *
|
|
* *
|
|
* Copyright (c) 1993 Microsoft Corporation *
|
|
\**************************************************************************/
|
|
|
|
#include "fd.h"
|
|
#include "fdsem.h"
|
|
|
|
|
|
|
|
// these are truly globaly defined structures
|
|
|
|
GLYPHSET_MAC_ROMAN gumcr;
|
|
|
|
STATIC VOID vInitGlyphset
|
|
(
|
|
PFD_GLYPHSET pgset,
|
|
PWCRANGE pwcrg,
|
|
ULONG cwcrg
|
|
);
|
|
|
|
PFD_GLYPHSET gpgsetCurrentCP = NULL; // current code page
|
|
PFD_GLYPHSET gpgsetSymbolCP = NULL; // current code page + symbol area
|
|
|
|
#define C_ANSI_CHAR_MAX 256
|
|
|
|
HSEMAPHORE ghsemTTFD;
|
|
|
|
// The driver function table with all function index/address pairs
|
|
|
|
DRVFN gadrvfnTTFD[] =
|
|
{
|
|
{ INDEX_DrvEnablePDEV, (PFN) ttfdEnablePDEV, },
|
|
{ INDEX_DrvDisablePDEV, (PFN) ttfdDisablePDEV, },
|
|
{ INDEX_DrvCompletePDEV, (PFN) ttfdCompletePDEV, },
|
|
{ INDEX_DrvQueryFont, (PFN) ttfdQueryFont },
|
|
{ INDEX_DrvQueryFontTree, (PFN) ttfdQueryFontTree },
|
|
{ INDEX_DrvQueryFontData, (PFN) ttfdSemQueryFontData },
|
|
{ INDEX_DrvDestroyFont, (PFN) ttfdSemDestroyFont },
|
|
{ INDEX_DrvQueryFontCaps, (PFN) ttfdQueryFontCaps },
|
|
{ INDEX_DrvLoadFontFile, (PFN) ttfdSemLoadFontFile },
|
|
{ INDEX_DrvUnloadFontFile, (PFN) ttfdSemUnloadFontFile },
|
|
{ INDEX_DrvQueryFontFile, (PFN) ttfdQueryFontFile },
|
|
{ INDEX_DrvQueryAdvanceWidths, (PFN) ttfdSemQueryAdvanceWidths },
|
|
{ INDEX_DrvFree, (PFN) ttfdSemFree },
|
|
{ INDEX_DrvQueryTrueTypeTable, (PFN) ttfdSemQueryTrueTypeTable },
|
|
{ INDEX_DrvQueryTrueTypeOutline, (PFN) ttfdSemQueryTrueTypeOutline},
|
|
{ INDEX_DrvGetTrueTypeFile, (PFN) ttfdGetTrueTypeFile }
|
|
};
|
|
|
|
/******************************Public*Routine******************************\
|
|
* ttfdEnableDriver
|
|
*
|
|
* Enables the driver by retrieving the drivers function table and version.
|
|
*
|
|
* Sun 25-Apr-1993 -by- Patrick Haluptzok [patrickh]
|
|
* Change to be same as DDI Enable.
|
|
*
|
|
* History:
|
|
* 12-Dec-1990 -by- Bodin Dresevic [BodinD]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL ttfdEnableDriver(
|
|
ULONG iEngineVersion,
|
|
ULONG cj,
|
|
PDRVENABLEDATA pded)
|
|
{
|
|
WCHAR awc[C_ANSI_CHAR_MAX];
|
|
BYTE aj[C_ANSI_CHAR_MAX];
|
|
INT cRuns;
|
|
ULONG cjCurrentCP, cjSymbolCP;
|
|
|
|
// Engine Version is passed down so future drivers can support previous
|
|
// engine versions. A next generation driver can support both the old
|
|
// and new engine conventions if told what version of engine it is
|
|
// working with. For the first version the driver does nothing with it.
|
|
|
|
iEngineVersion;
|
|
|
|
if ((ghsemTTFD = EngCreateSemaphore()) == (HSEMAPHORE) 0)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
pded->pdrvfn = gadrvfnTTFD;
|
|
pded->c = sizeof(gadrvfnTTFD) / sizeof(DRVFN);
|
|
pded->iDriverVersion = DDI_DRIVER_VERSION;
|
|
|
|
// gpgsetCurrentCP contains the unicode runs for the current ansi code page
|
|
// It is going to be used for fonts with PlatformID for Mac, but for which
|
|
// we have determined that we are going to cheat and pretend that the code
|
|
// page is NOT mac but windows code page. Those are the fonts identified
|
|
// by bCvtUnToMac = FALSE
|
|
|
|
cRuns = cUnicodeRangesSupported(
|
|
0, // cp, not supported yet, uses current code page
|
|
0, // iFirst,
|
|
C_ANSI_CHAR_MAX, // cChar, <--> iLast == 255
|
|
awc, // out buffer with sorted array of unicode glyphs
|
|
aj // coressponding ansi values
|
|
);
|
|
|
|
// allocate memory for the glyphset corresponding to this code page
|
|
|
|
cjCurrentCP = SZ_GLYPHSET(cRuns,C_ANSI_CHAR_MAX);
|
|
|
|
// for symbol fonts we report both the current code page plus
|
|
// the range 0xf000-0xf0ff.
|
|
|
|
cjSymbolCP = SZ_GLYPHSET(cRuns + 1, 2 * C_ANSI_CHAR_MAX);
|
|
|
|
gpgsetCurrentCP = (FD_GLYPHSET *)PV_ALLOC(cjCurrentCP + cjSymbolCP);
|
|
|
|
if (gpgsetCurrentCP == NULL)
|
|
{
|
|
EngDeleteSemaphore(ghsemTTFD);
|
|
RETURN("TTFD!_out of mem at init time\n", FD_ERROR);
|
|
}
|
|
|
|
cComputeGlyphSet (
|
|
awc, // input buffer with a sorted array of cChar supported WCHAR's
|
|
aj,
|
|
C_ANSI_CHAR_MAX, // cChar
|
|
cRuns, // if nonzero, the same as return value
|
|
gpgsetCurrentCP // output buffer to be filled with cRanges runs
|
|
);
|
|
|
|
//!!! add one more char to wcrun[0] for the default glyph!!!
|
|
|
|
#ifdef DBG_GLYPHSET
|
|
|
|
{
|
|
int i,j;
|
|
for (i = 0; i < C_ANSI_CHAR_MAX; i += 16)
|
|
{
|
|
for (j = 0; j < 16; j++)
|
|
TtfdDbgPrint("0x%x,", awc[i+j]);
|
|
TtfdDbgPrint("\n");
|
|
|
|
}
|
|
}
|
|
|
|
vDbgGlyphset(gpgsetCurrentCP);
|
|
#endif // DBG_GLYPHSET
|
|
|
|
// symbol cp is allocated from the same chunck
|
|
// of memory as the gpgsetCurrentCP.
|
|
|
|
gpgsetSymbolCP = (PFD_GLYPHSET)((BYTE*)gpgsetCurrentCP + cjCurrentCP);
|
|
|
|
// now use gpgsetCurrentCP to manufacture symbol character set:
|
|
|
|
gpgsetSymbolCP->cjThis = cjSymbolCP;
|
|
gpgsetSymbolCP->flAccel = gpgsetCurrentCP->flAccel;
|
|
|
|
gpgsetSymbolCP->cGlyphsSupported = 2 * C_ANSI_CHAR_MAX;
|
|
gpgsetSymbolCP->cRuns = cRuns + 1;
|
|
|
|
{
|
|
INT iRun, ihg;
|
|
HGLYPH *phgS, *phgD;
|
|
|
|
phgD = (HGLYPH *)&gpgsetSymbolCP->awcrun[cRuns+1];
|
|
for
|
|
(
|
|
iRun = 0;
|
|
(iRun < cRuns) && (gpgsetCurrentCP->awcrun[iRun].wcLow < 0xf000);
|
|
iRun++
|
|
)
|
|
{
|
|
gpgsetSymbolCP->awcrun[iRun].wcLow =
|
|
gpgsetCurrentCP->awcrun[iRun].wcLow;
|
|
gpgsetSymbolCP->awcrun[iRun].cGlyphs =
|
|
gpgsetCurrentCP->awcrun[iRun].cGlyphs;
|
|
gpgsetSymbolCP->awcrun[iRun].phg = phgD;
|
|
RtlCopyMemory(
|
|
phgD,
|
|
gpgsetCurrentCP->awcrun[iRun].phg,
|
|
sizeof(HGLYPH) * gpgsetCurrentCP->awcrun[iRun].cGlyphs
|
|
);
|
|
phgD += gpgsetCurrentCP->awcrun[iRun].cGlyphs;
|
|
}
|
|
|
|
// now insert the user defined area:
|
|
|
|
gpgsetSymbolCP->awcrun[iRun].wcLow = 0xf000;
|
|
gpgsetSymbolCP->awcrun[iRun].cGlyphs = C_ANSI_CHAR_MAX;
|
|
gpgsetSymbolCP->awcrun[iRun].phg = phgD;
|
|
for (ihg = 0; ihg < C_ANSI_CHAR_MAX; ihg++)
|
|
*phgD++ = ihg;
|
|
|
|
// and now add the remaining ranges if any from the current code page:
|
|
|
|
for ( ; iRun < cRuns; iRun++)
|
|
{
|
|
gpgsetSymbolCP->awcrun[iRun+1].wcLow =
|
|
gpgsetCurrentCP->awcrun[iRun].wcLow;
|
|
gpgsetSymbolCP->awcrun[iRun+1].cGlyphs =
|
|
gpgsetCurrentCP->awcrun[iRun].cGlyphs;
|
|
gpgsetSymbolCP->awcrun[iRun+1].phg = phgD;
|
|
|
|
RtlCopyMemory(
|
|
phgD,
|
|
gpgsetCurrentCP->awcrun[iRun].phg,
|
|
sizeof(HGLYPH) * gpgsetCurrentCP->awcrun[iRun].cGlyphs
|
|
);
|
|
phgD += gpgsetCurrentCP->awcrun[iRun].cGlyphs;
|
|
}
|
|
}
|
|
|
|
// make sure that we have correctly defined C_RUNS_XXXX
|
|
// which is necessary in order to be able to define GLYPHSET unions
|
|
// correctly
|
|
|
|
ASSERTDD(sizeof(gawcrgMacRoman)/sizeof(gawcrgMacRoman[0]) == C_RUNS_MAC_ROMAN,
|
|
"C_RUNS_MAC_ROMAN\n");
|
|
|
|
// init global glyphset structures:
|
|
|
|
vInitGlyphset(& gumcr.gset, gawcrgMacRoman, C_RUNS_MAC_ROMAN);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* DHPDEV DrvEnablePDEV
|
|
*
|
|
* Initializes a bunch of fields for GDI
|
|
*
|
|
\**************************************************************************/
|
|
|
|
DHPDEV
|
|
ttfdEnablePDEV(
|
|
DEVMODEW* pdm,
|
|
PWSTR pwszLogAddr,
|
|
ULONG cPat,
|
|
HSURF* phsurfPatterns,
|
|
ULONG cjCaps,
|
|
ULONG* pdevcaps,
|
|
ULONG cjDevInfo,
|
|
DEVINFO* pdi,
|
|
HDEV hdev,
|
|
PWSTR pwszDeviceName,
|
|
HANDLE hDriver)
|
|
{
|
|
|
|
PVOID* ppdev;
|
|
|
|
//
|
|
// Allocate a four byte PDEV for now
|
|
// We can grow it if we ever need to put information in it.
|
|
//
|
|
|
|
ppdev = (PVOID*) EngAllocMem(0, sizeof(PVOID), 'dftT');
|
|
|
|
return ((DHPDEV) ppdev);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* DrvDisablePDEV
|
|
*
|
|
* Release the resources allocated in DrvEnablePDEV. If a surface has been
|
|
* enabled DrvDisableSurface will have already been called.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID
|
|
ttfdDisablePDEV(
|
|
DHPDEV dhpdev)
|
|
{
|
|
EngFreeMem(dhpdev);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID DrvCompletePDEV
|
|
*
|
|
* Store the HPDEV, the engines handle for this PDEV, in the DHPDEV.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID
|
|
ttfdCompletePDEV(
|
|
DHPDEV dhpdev,
|
|
HDEV hdev)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* VOID vInitGlyphState(PGLYPHSTAT pgstat)
|
|
*
|
|
* Effects: resets the state of the new glyph
|
|
*
|
|
* History:
|
|
* 22-Nov-1991 -by- Bodin Dresevic [BodinD]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vInitGlyphState(PGLYPHSTATUS pgstat)
|
|
{
|
|
pgstat->hgLast = HGLYPH_INVALID;
|
|
pgstat->igLast = 0xffffffff;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* STATIC VOID vInitGlyphset
|
|
*
|
|
*
|
|
* init global glyphset strucutes, given the set of supported ranges
|
|
*
|
|
* Warnings:
|
|
*
|
|
* History:
|
|
* 24-Jan-1992 -by- Bodin Dresevic [BodinD]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
STATIC VOID vInitGlyphset
|
|
(
|
|
PFD_GLYPHSET pgset,
|
|
PWCRANGE pwcrg,
|
|
ULONG cwcrg
|
|
)
|
|
{
|
|
ULONG i;
|
|
|
|
pgset->cjThis = offsetof(FD_GLYPHSET,awcrun) + cwcrg * sizeof(WCRUN);
|
|
pgset->flAccel = GS_UNICODE_HANDLES | GS_16BIT_HANDLES;
|
|
pgset->cRuns = cwcrg;
|
|
|
|
pgset->cGlyphsSupported = 0;
|
|
|
|
for (i = 0; i < cwcrg; i++)
|
|
{
|
|
pgset->awcrun[i].wcLow = pwcrg[i].wcLo;
|
|
pgset->awcrun[i].cGlyphs = (USHORT)(pwcrg[i].wcHi - pwcrg[i].wcLo + 1);
|
|
pgset->awcrun[i].phg = (HGLYPH *)NULL;
|
|
pgset->cGlyphsSupported += pgset->awcrun[i].cGlyphs;
|
|
}
|
|
|
|
// will add an extra glyph to awcrun[0] which will be used as default glyph:
|
|
|
|
pgset->awcrun[0].cGlyphs += 1;
|
|
pgset->cGlyphsSupported += 1;
|
|
}
|
|
|
|
|
|
#ifdef FE_SB
|
|
VOID vMarkFontGone(TTC_FONTFILE *pff, DWORD iExceptionCode)
|
|
{
|
|
ULONG i;
|
|
|
|
ASSERTDD(pff, "ttfd!vMarkFontGone, pff\n");
|
|
|
|
// this font has disappeared, probably net failure or somebody pulled the
|
|
// floppy with ttf file out of the floppy drive
|
|
|
|
if (iExceptionCode == STATUS_IN_PAGE_ERROR) // file disappeared
|
|
{
|
|
// prevent any further queries about this font:
|
|
|
|
pff->fl |= FF_EXCEPTION_IN_PAGE_ERROR;
|
|
|
|
for( i = 0; i < pff->ulNumEntry ; i++ )
|
|
{
|
|
PFONTFILE pffReal;
|
|
|
|
// get real pff.
|
|
|
|
pffReal = PFF(pff->ahffEntry[i].hff);
|
|
|
|
// if memoryBases 0,3,4 were allocated free the memory,
|
|
// for they are not going to be used any more
|
|
|
|
if (pffReal->pj034)
|
|
{
|
|
V_FREE(pffReal->pj034);
|
|
pffReal->pj034 = NULL;
|
|
}
|
|
|
|
// if memory for font context was allocated and exception occured
|
|
// after allocation but before completion of ttfdOpenFontContext,
|
|
// we have to free it:
|
|
|
|
if (pffReal->pfcToBeFreed)
|
|
{
|
|
V_FREE(pffReal->pfcToBeFreed);
|
|
pffReal->pfcToBeFreed = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (iExceptionCode == STATUS_ACCESS_VIOLATION)
|
|
{
|
|
RIP("TTFD!this is probably a buggy ttf file\n");
|
|
}
|
|
}
|
|
#else
|
|
VOID vMarkFontGone(FONTFILE *pff, DWORD iExceptionCode)
|
|
{
|
|
|
|
ASSERTDD(pff, "vMarkFontGone, pff\n");
|
|
|
|
// this font has disappeared, probably net failure or somebody pulled the
|
|
// floppy with ttf file out of the floppy drive
|
|
|
|
if (iExceptionCode == STATUS_IN_PAGE_ERROR) // file disappeared
|
|
{
|
|
// prevent any further queries about this font:
|
|
|
|
pff->fl |= FF_EXCEPTION_IN_PAGE_ERROR;
|
|
|
|
// if memoryBases 0,3,4 were allocated free the memory,
|
|
// for they are not going to be used any more
|
|
|
|
if (pff->pj034)
|
|
{
|
|
V_FREE(pff->pj034);
|
|
pff->pj034 = NULL;
|
|
}
|
|
|
|
// if memory for font context was allocated and exception occured
|
|
// after allocation but before completion of ttfdOpenFontContext,
|
|
// we have to free it:
|
|
|
|
if (pff->pfcToBeFreed)
|
|
{
|
|
V_FREE(pff->pfcToBeFreed);
|
|
pff->pfcToBeFreed = NULL;
|
|
}
|
|
}
|
|
|
|
if (iExceptionCode == STATUS_ACCESS_VIOLATION)
|
|
{
|
|
WARNING("TTFD!this is probably a buggy ttf file\n");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/**************************************************************************\
|
|
*
|
|
* These are semaphore grabbing wrapper functions for TT driver entry
|
|
* points that need protection.
|
|
*
|
|
* Mon 29-Mar-1993 -by- Bodin Dresevic [BodinD]
|
|
* update: added try/except wrappers
|
|
*
|
|
* !!! should we also do some unmap file clean up in case of exception?
|
|
* !!! what are the resources to be freed in this case?
|
|
* !!! I would think,if av files should be unmapped, if in_page exception
|
|
* !!! nothing should be done
|
|
*
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HFF
|
|
ttfdSemLoadFontFile (
|
|
ULONG cFiles,
|
|
ULONG *piFile,
|
|
PVOID *ppvView,
|
|
ULONG *pcjView,
|
|
ULONG ulLangId
|
|
)
|
|
{
|
|
HFF hff = (HFF)NULL;
|
|
ULONG iFile;
|
|
PVOID pvView;
|
|
ULONG cjView;
|
|
|
|
if (cFiles != 1)
|
|
return hff;
|
|
|
|
iFile = *piFile;
|
|
pvView = *ppvView;
|
|
cjView = *pcjView;
|
|
|
|
EngAcquireSemaphore(ghsemTTFD);
|
|
|
|
try
|
|
{
|
|
// BUGBUG The client side has to tell us if it is embedded !
|
|
BOOL bRet = FALSE;
|
|
|
|
//BUGBUG
|
|
|
|
|
|
#ifdef FE_SB
|
|
bRet = bLoadFontFile(iFile,
|
|
pvView,
|
|
cjView,
|
|
ulLangId,
|
|
&hff
|
|
);
|
|
#else
|
|
bRet = bLoadTTF(iFile,
|
|
pvView,
|
|
cjView,
|
|
0, // just set to 0 actually ignored in non FE_SB build
|
|
ulLangId,
|
|
&hff
|
|
);
|
|
#endif
|
|
|
|
|
|
if (!bRet)
|
|
{
|
|
ASSERTDD(hff == (HFF)NULL, "LoadFontFile, hff not null\n");
|
|
}
|
|
}
|
|
except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
WARNING("TTFD!_ exception in ttfdLoadFontFile\n");
|
|
|
|
ASSERTDD(GetExceptionCode() == STATUS_IN_PAGE_ERROR,
|
|
"ttfdSemLoadFontFile, strange exception code\n");
|
|
|
|
if (hff)
|
|
{
|
|
vFreeFF(hff);
|
|
hff = (HFF)NULL;
|
|
}
|
|
}
|
|
|
|
EngReleaseSemaphore(ghsemTTFD);
|
|
return hff;
|
|
}
|
|
|
|
BOOL
|
|
ttfdSemUnloadFontFile (
|
|
HFF hff
|
|
)
|
|
{
|
|
BOOL bRet;
|
|
EngAcquireSemaphore(ghsemTTFD);
|
|
|
|
try
|
|
{
|
|
#ifdef FE_SB
|
|
bRet = ttfdUnloadFontFileTTC(hff);
|
|
#else
|
|
bRet = ttfdUnloadFontFile(hff);
|
|
#endif
|
|
}
|
|
except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
WARNING("TTFD!_ exception in ttfdUnloadFontFile\n");
|
|
bRet = FALSE;
|
|
}
|
|
|
|
EngReleaseSemaphore(ghsemTTFD);
|
|
return bRet;
|
|
}
|
|
|
|
|
|
LONG
|
|
ttfdSemQueryFontData (
|
|
DHPDEV dhpdev,
|
|
FONTOBJ *pfo,
|
|
ULONG iMode,
|
|
HGLYPH hg,
|
|
GLYPHDATA *pgd,
|
|
PVOID pv,
|
|
ULONG cjSize
|
|
)
|
|
{
|
|
LONG lRet;
|
|
|
|
dhpdev;
|
|
|
|
EngAcquireSemaphore(ghsemTTFD);
|
|
|
|
try
|
|
{
|
|
lRet = ttfdQueryFontData (
|
|
pfo,
|
|
iMode,
|
|
hg,
|
|
pgd,
|
|
pv,
|
|
cjSize
|
|
);
|
|
}
|
|
except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
WARNING("TTFD!_ exception in ttfdQueryFontData\n");
|
|
|
|
#ifdef FE_SB
|
|
vMarkFontGone((TTC_FONTFILE *)pfo->iFile, GetExceptionCode());
|
|
#else
|
|
vMarkFontGone((FONTFILE *)pfo->iFile, GetExceptionCode());
|
|
#endif
|
|
|
|
lRet = FD_ERROR;
|
|
}
|
|
|
|
EngReleaseSemaphore(ghsemTTFD);
|
|
return lRet;
|
|
}
|
|
|
|
|
|
VOID
|
|
ttfdSemFree (
|
|
PVOID pv,
|
|
ULONG id
|
|
)
|
|
{
|
|
EngAcquireSemaphore(ghsemTTFD);
|
|
|
|
ttfdFree (
|
|
pv,
|
|
id
|
|
);
|
|
|
|
EngReleaseSemaphore(ghsemTTFD);
|
|
}
|
|
|
|
|
|
VOID
|
|
ttfdSemDestroyFont (
|
|
FONTOBJ *pfo
|
|
)
|
|
{
|
|
EngAcquireSemaphore(ghsemTTFD);
|
|
|
|
ttfdDestroyFont (
|
|
pfo
|
|
);
|
|
|
|
EngReleaseSemaphore(ghsemTTFD);
|
|
}
|
|
|
|
|
|
LONG
|
|
ttfdSemQueryTrueTypeOutline (
|
|
DHPDEV dhpdev,
|
|
FONTOBJ *pfo,
|
|
HGLYPH hglyph,
|
|
BOOL bMetricsOnly,
|
|
GLYPHDATA *pgldt,
|
|
ULONG cjBuf,
|
|
TTPOLYGONHEADER *ppoly
|
|
)
|
|
{
|
|
LONG lRet;
|
|
|
|
dhpdev;
|
|
|
|
EngAcquireSemaphore(ghsemTTFD);
|
|
|
|
try
|
|
{
|
|
lRet = ttfdQueryTrueTypeOutline (
|
|
pfo,
|
|
hglyph,
|
|
bMetricsOnly,
|
|
pgldt,
|
|
cjBuf,
|
|
ppoly
|
|
);
|
|
|
|
}
|
|
except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
WARNING("TTFD!_ exception in ttfdQueryTrueTypeOutline\n");
|
|
|
|
#ifdef FE_SB
|
|
vMarkFontGone((TTC_FONTFILE *)pfo->iFile, GetExceptionCode());
|
|
#else
|
|
vMarkFontGone((FONTFILE *)pfo->iFile, GetExceptionCode());
|
|
#endif
|
|
|
|
lRet = FD_ERROR;
|
|
}
|
|
|
|
EngReleaseSemaphore(ghsemTTFD);
|
|
return lRet;
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BOOL ttfdQueryAdvanceWidths
|
|
*
|
|
* History:
|
|
* 29-Jan-1993 -by- Bodin Dresevic [BodinD]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
|
|
|
|
BOOL ttfdSemQueryAdvanceWidths
|
|
(
|
|
DHPDEV dhpdev,
|
|
FONTOBJ *pfo,
|
|
ULONG iMode,
|
|
HGLYPH *phg,
|
|
LONG *plWidths,
|
|
ULONG cGlyphs
|
|
)
|
|
{
|
|
BOOL bRet;
|
|
|
|
dhpdev;
|
|
|
|
EngAcquireSemaphore(ghsemTTFD);
|
|
|
|
try
|
|
{
|
|
bRet = bQueryAdvanceWidths (
|
|
pfo,
|
|
iMode,
|
|
phg,
|
|
plWidths,
|
|
cGlyphs
|
|
);
|
|
}
|
|
except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
WARNING("TTFD!_ exception in bQueryAdvanceWidths\n");
|
|
|
|
#ifdef FE_SB
|
|
vMarkFontGone((TTC_FONTFILE *)pfo->iFile, GetExceptionCode());
|
|
#else
|
|
vMarkFontGone((FONTFILE *)pfo->iFile, GetExceptionCode());
|
|
#endif
|
|
|
|
bRet = FD_ERROR; // TRI-BOOL according to chuckwh
|
|
}
|
|
|
|
EngReleaseSemaphore(ghsemTTFD);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
|
|
LONG
|
|
ttfdSemQueryTrueTypeTable (
|
|
HFF hff,
|
|
ULONG ulFont, // always 1 for version 1.0 of tt
|
|
ULONG ulTag, // tag identifying the tt table
|
|
PTRDIFF dpStart, // offset into the table
|
|
ULONG cjBuf, // size of the buffer to retrieve the table into
|
|
PBYTE pjBuf // ptr to buffer into which to return the data
|
|
)
|
|
{
|
|
LONG lRet;
|
|
|
|
EngAcquireSemaphore(ghsemTTFD);
|
|
|
|
try
|
|
{
|
|
lRet = ttfdQueryTrueTypeTable (
|
|
hff,
|
|
ulFont, // always 1 for version 1.0 of tt
|
|
ulTag, // tag identifying the tt table
|
|
dpStart, // offset into the table
|
|
cjBuf, // size of the buffer to retrieve the table into
|
|
pjBuf // ptr to buffer into which to return the data
|
|
);
|
|
}
|
|
except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
WARNING("TTFD!_ exception in ttfdQueryTrueTypeTable\n");
|
|
|
|
#ifdef FE_SB
|
|
vMarkFontGone((TTC_FONTFILE *)hff, GetExceptionCode());
|
|
#else
|
|
vMarkFontGone((FONTFILE *)hff, GetExceptionCode());
|
|
#endif
|
|
|
|
lRet = FD_ERROR;
|
|
}
|
|
|
|
EngReleaseSemaphore(ghsemTTFD);
|
|
return lRet;
|
|
}
|