Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

441 lines
12 KiB

/******************************Module*Header*******************************\
* Module Name: tt.cxx
*
* tt stuff, mostly stolen from ttfd
*
* Created: 24-Nov-1993 11:17:35
* Author: Bodin Dresevic [BodinD]
*
\**************************************************************************/
extern "C" {
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "windows.h"
// tt stuff
#include "FSERROR.H"
#include "FSCDEFS.H" // inlcudes fsconfig.h
#include "FONTMATH.H"
#include "SFNT.H" // includes sfnt_en.h
#include "FNT.H"
#include "INTERP.H"
#include "FNTERR.H"
#include "SFNTACCS.H"
#include "FSGLUE.H"
#include "SCENTRY.H"
#include "SBIT.H"
#include "FSCALER.H"
#include "SCGLOBAL.H"
};
#include "sbit.hxx"
/******************************Public*Routine******************************\
* PBYTE pjTable(ULONG ulTag, FILEVIEW *pfvw, ULONG *pcjTable)
*
* stolen from ttfd, find a table given a tag
*
* History:
* 24-Nov-1993 -by- Bodin Dresevic [BodinD]
* Wrote it.
\**************************************************************************/
PBYTE pjTable(ULONG ulTag, FILEVIEW *pfvw, ULONG *pcjTable)
{
INT cTables;
sfnt_OffsetTable *pofft;
register sfnt_DirectoryEntry *pdire, *pdireEnd;
// offset table is at the very top of the file,
pofft = (sfnt_OffsetTable *) pfvw->pjView;
cTables = (INT) SWAPW(pofft->numOffsets);
//!!! here we do linear search, but perhaps we could optimize and do binary
//!!! search since tags are ordered in ascending order
pdireEnd = &pofft->table[cTables];
ulTag = SWAPL(ulTag);
for
(
pdire = &pofft->table[0];
pdire < pdireEnd;
pdire++
)
{
if (ulTag == pdire->tag)
{
ULONG ulOffset = (ULONG)SWAPL(pdire->offset);
ULONG ulLength = (ULONG)SWAPL(pdire->length);
// check if the ends of all tables are within the scope of the
// tt file. If this is is not the case trying to access the field in the
// table may result in an access violation, as is the case with the
// spurious FONT.TTF that had the beginning of the cmap table below the
// end of file, which was resulting in the system crash reported by beta
// testers. [bodind]
if
(
!ulLength ||
((ulOffset + ulLength) > pfvw->cjView)
)
{
return NULL;
}
else // we found it
{
*pcjTable = ulLength;
return ((PBYTE)pfvw->pjView + ulOffset);
}
}
}
// if we are here, we did not find it.
return NULL;
}
#define SIZEOF_CMAPTABLE (3 * sizeof(uint16))
#define OFF_segCountX2 6
#define OFF_endCount 14
/******************************Public*Routine******************************\
*
* bWcharToIndex
*
* stolen and modified from ttfd
*
* History:
* 24-Nov-1993 -by- Bodin Dresevic [BodinD]
* Wrote it.
\**************************************************************************/
BOOL bWcharToIndex (PBYTE pmap, uint16 wc, uint16 * pgi)
{
uint16 *pstartCount, *pendCount, // Arrays that define the
*pidDelta, *pidRangeOffset; // Unicode runs supported
// by the CMAP table.
uint16 *pendCountStart; // Beginning of arrays.
uint16 cRuns; // Number of Unicode runs.
uint16 usLo, usHi, idDelta, idRangeOffset; // Current Unicode run.
*pgi = 0; // ZERO init
cRuns = SWAPW(pmap[OFF_segCountX2]) >> 1;
// Get the pointer to the beginning of the array of endCount code points
pendCountStart = (uint16 *)(pmap + OFF_endCount);
// The final endCode has to be 0xffff; if this is not the case, there
// is a bug in the TT file or in our code:
ASSERT(pendCountStart[cRuns - 1] == 0xFFFF,
"TTFD!_bIndexToWchar pendCount[cRuns - 1] != 0xFFFF\n");
// Loop through the four paralel arrays (startCount, endCount, idDelta, and
// idRangeOffset) and find wc that usIndex corresponds to. Each iteration
// scans a continuous range of Unicode characters supported by the TT font.
//
// To be Win3.1 compatible, we are looking for the LAST Unicode character
// that corresponds to usIndex. So we scan all the arrays backwards,
// starting at the end of each of the arrays.
//
// Please note the following:
// For resons known only to the TT designers, startCount array does not
// begin immediately after the end of endCount array, i.e. at
// &pendCount[cRuns]. Instead, they insert an uint16 padding which has to
// set to zero and the startCount array begins after the padding. This
// padding in no way helps alignment of the structure.
//
// Here is the format of the arrays:
// ________________________________________________________________________________________
// | endCount[cRuns] | skip 1 | startCount[cRuns] | idDelta[cRuns] | idRangeOffset[cRuns] |
// |_________________|________|___________________|________________|______________________|
pendCount = &pendCountStart[cRuns - 1];
pstartCount = &pendCount[cRuns + 1]; // add 1 because of padding
pidDelta = &pstartCount[cRuns];
pidRangeOffset = &pidDelta[cRuns];
for ( ;
pendCount >= pendCountStart;
pstartCount--, pendCount--,pidDelta--,pidRangeOffset--
)
{
usLo = SWAPW(pstartCount[0]); // current Unicode run
usHi = SWAPW(pendCount[0]); // [usLo, usHi], inclusive
idDelta = SWAPW(pidDelta[0]);
idRangeOffset = SWAPW(pidRangeOffset[0]);
ASSERT(usLo <= usHi, "bWcharToIndex: usLo > usHi\n");
if ((wc < usLo) || (wc > usHi))
continue;
// Depending on idRangeOffset for the run, indexes are computed
// differently.
//
// If idRangeOffset is zero, then index is the Unicode codepoint
// plus the delta value.
//
// Otherwise, idRangeOffset specifies the BYTE offset of an array of
// glyph indices (elements of which correspond to the Unicode range
// [usLo, usHi], inclusive). Actually, each element of the array is
// the glyph index minus idDelta, so idDelta must be added in order
// to derive the actual glyph indices from the array values.
//
// Notice that the delta arithmetic is always mod 65536.
if (idRangeOffset == 0)
{
// Glyph index == Unicode codepoint + delta.
//
// If (usIndex-idDelta) is within the range [usLo, usHi], inclusive,
// we have found the glyph index. We'll overload usIndexBE
// to be usIndex-idDelta == Unicode codepoint.
*pgi = ((uint32)wc + idDelta) & 0xffff;
return TRUE;
}
else
{
/*
fprintf(stdout,
"usLo = 0x%x, usHi = 0x%x, idDelta = 0x%x, idRangeOffset = 0x%x\n",
usLo,usHi,idDelta,idRangeOffset);
*/
// this line is a black magic prescription of the tt spec:
uint16 usIndex = *(pidRangeOffset + ((wc - usLo) + idRangeOffset/2));
uint32 ulIndex = (uint32)SWAPW(usIndex);
*pgi = (uint16)((ulIndex + idDelta) & 0xffff); // modulo 65536
return (TRUE);
}
}
fprintf(stderr, "bWcharToIndex: wchar 0x%x not found in cmap table\n",wc);
return FALSE;
}
BYTE * pjMapTable(FILEVIEW *pfvw)
{
ULONG cjTable;
sfnt_char2IndexDirectory * pcmap =
(sfnt_char2IndexDirectory *)pjTable(tag_CharToIndexMap, pfvw, &cjTable);
if (!pcmap)
return NULL;
sfnt_platformEntry * pplat = &pcmap->platform[0];
sfnt_platformEntry * pplatEnd = pplat + SWAPW(pcmap->numTables);
BYTE *pjMap = NULL;
if (pcmap->version != 0) // no need to swap bytes, 0 == be 0
{
fprintf(stderr,"TTFD!_bComputeIDs: version number\n");
return NULL;
}
// find the first sfnt_platformEntry with platformID == PLAT_ID_MS,
// if there was no MS mapping table, go for the mac one
for (; pplat < pplatEnd; pplat++)
{
if ((pplat->platformID == 0x300) && (pplat->specificID == 0x100))
{
pjMap = ((PBYTE)pcmap + SWAPL(pplat->offset));
break;
}
}
return pjMap;
}
BOOL bCheckGlyphIndex1(BYTE *pjMap, UINT wcIn, UINT giIn)
{
uint16 gi;
if (!bWcharToIndex(pjMap, (uint16)wcIn, &gi))
return FALSE;
BOOL bRet = (gi == (uint16)giIn);
if (!bRet)
fprintf(stderr,
"wc = 0x%lx, giTTF = %ld, giBDF = %ld\n",
(ULONG)wcIn, (ULONG)gi, giIn
);
return bRet;
}
/*****************************************************************************\
*
* FOR THIS STUFF TO WORK FSCALER.LIB HAS TO BE ADDED TO UMLIB LINE IN SOURCES
*
\*****************************************************************************/
#ifdef LINK_IN_FSCALER
// in the debug version of the rasterizer STAMPEXTRA shoud be added to the
// sizes. strictly speaking this is illegal, but nevertheless very useful.
// it assumes the knowlege of rasterizer internalls [bodind],
// see fscaler.c
#define STAMPEXTRA 4
#define CJ_0 NATURAL_ALIGN(sizeof(fs_SplineKey) + STAMPEXTRA)
#define DONTUSE(X) (X) = (X)
voidPtr FS_CALLBACK_PROTO
pvGetPointerCallback(
long clientID,
long dp,
long cjData
)
{
DONTUSE(cjData);
// clientID is just the pointer to the top of the font file
return (voidPtr)((PBYTE)clientID + dp);
}
void FS_CALLBACK_PROTO
vReleasePointerCallback(
voidPtr pv
)
{
DONTUSE(pv);
}
/******************************Public*Routine******************************\
* bCheckGlyphIndex
*
* // make sure that the glyph index gi indeed corresponds
* // to the unicode code point wc according to the cmap table of the
* // font file pointed to by pjTTF
*
* History:
* 23-Nov-1993 -by- Bodin Dresevic [BodinD]
* Wrote it.
\**************************************************************************/
#define DWORD_ALIGN(x) (((x) + 3L) & ~3L)
#define QWORD_ALIGN(x) (((x) + 7L) & ~7L)
#if defined(i386)
// natural alignment for x86 is on 32 bit boundary
#define NATURAL DWORD
#define NATURAL_ALIGN(x) DWORD_ALIGN(x)
#else
// for mips and alpha we want 64 bit alignment
#define NATURAL ULONGLONG
#define NATURAL_ALIGN(x) QWORD_ALIGN(x)
#endif
BOOL bCheckGlyphIndex(BYTE *pjTTF, UINT wc, UINT gi)
{
FS_ENTRY iRet;
fs_GlyphInputType gin;
fs_GlyphInfoType gout;
NATURAL anat0[CJ_0 / sizeof(NATURAL)];
// Notice that this information is totaly independent
// of the font file in question, seems to be right according to fsglue.h
// and compfont code
if ((iRet = fs_OpenFonts(&gin, &gout)) != NO_ERR)
{
return (FALSE);
}
ASSERT(NATURAL_ALIGN(gout.memorySizes[0]) == CJ_0, "TTFD!_mem size 0\n");
ASSERT(gout.memorySizes[1] == 0, "TTFD!_mem size 1\n");
#if DBG
if (gout.memorySizes[2] != 0)
fprintf(stderr,"TTFD!_mem size 2 = 0x%lx \n", gout.memorySizes[2]);
#endif
gin.memoryBases[0] = (char *)anat0;
gin.memoryBases[1] = NULL;
gin.memoryBases[2] = NULL;
// initialize the font scaler, notice no fields of gin are initialized [BodinD]
if ((iRet = fs_Initialize(&gin, &gout)) != NO_ERR)
{
return (FALSE);
}
// initialize info needed by NewSfnt function
gin.sfntDirectory = (int32 *)pjTTF; // pointer to the top of the view of the ttf file
gin.clientID = (int32)pjTTF; // pointer to the top of the view of the ttf file
gin.GetSfntFragmentPtr = pvGetPointerCallback;
gin.ReleaseSfntFrag = vReleasePointerCallback;
gin.param.newsfnt.platformID = 0x03; // MSFT
gin.param.newsfnt.specificID = 0x01; // UGL
if ((iRet = fs_NewSfnt(&gin, &gout)) != NO_ERR)
{
return (FALSE);
}
gin.param.newglyph.characterCode = (uint16)wc;
gin.param.newglyph.glyphIndex = 0;
// compute the glyph index from the character code:
if ((iRet = fs_NewGlyph(&gin, &gout)) != NO_ERR)
{
return FALSE;
}
// return the glyph index corresponding to this hglyph:
return (gout.glyphIndex == (uint16)gi);
}
#endif // LINK_IN_FSCALER