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.
282 lines
7.5 KiB
282 lines
7.5 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: rfntxlat.cxx
|
|
*
|
|
* Methods for translating wchars to hglyphs or pgd's
|
|
*
|
|
* Created: March 5, 1992
|
|
* Author: Paul Butzi
|
|
*
|
|
* Copyright (c) 1992-1999 Microsoft Corporation
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
void RFONTOBJ::pfdg(FD_GLYPHSET *pfdg)
|
|
{
|
|
prfnt->pfdg = pfdg;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* void chglyGetAllGlyphHandles
|
|
*
|
|
* Get all the glyph handles for an RFONTOBJ
|
|
* return the number of handles
|
|
*
|
|
*
|
|
* History:
|
|
* 06-Mar-92 -by- Paul Butzi
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
COUNT RFONTOBJ::chglyGetAllHandles
|
|
(
|
|
HGLYPH *pgh
|
|
)
|
|
{
|
|
// first check if this is one of the tt fonts which supports
|
|
// possibly more glyphs than can be accessed via fd_glyphset directly.
|
|
// In this case handles are the same as glyph indicies
|
|
|
|
IFIMETRICS * pifi = prfnt->ppfe->pifi;
|
|
|
|
ULONG cig = 0;
|
|
|
|
if (pifi->cjIfiExtra > offsetof(IFIEXTRA, cig))
|
|
{
|
|
cig = ((IFIEXTRA *)(pifi + 1))->cig;
|
|
}
|
|
|
|
if (cig)
|
|
{
|
|
if (pgh)
|
|
{
|
|
for (ULONG hg = 0; hg < cig; hg++, pgh++)
|
|
*pgh = hg;
|
|
}
|
|
|
|
return cig;
|
|
}
|
|
|
|
FD_GLYPHSET *pfdg = prfnt->pfdg;
|
|
|
|
if ( pgh == NULL )
|
|
return pfdg->cGlyphsSupported;
|
|
|
|
for ( COUNT i = 0; i < pfdg->cRuns; i += 1 )
|
|
{
|
|
WCRUN *pwcr = &pfdg->awcrun[i];
|
|
|
|
if ( pwcr->phg != NULL )
|
|
{
|
|
for ( COUNT j = 0; j < pwcr->cGlyphs; j += 1 )
|
|
{
|
|
*pgh = pwcr->phg[j];
|
|
pgh += 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for ( COUNT j = 0; j < pwcr->cGlyphs; j += 1 )
|
|
{
|
|
*pgh = pwcr->wcLow + j;
|
|
pgh += 1;
|
|
}
|
|
}
|
|
}
|
|
return pfdg->cGlyphsSupported;
|
|
}
|
|
|
|
|
|
extern const BYTE acBits[16] = {0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4};
|
|
|
|
extern const INT aiStart[17] = {0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
|
|
|
|
|
|
VOID RFONTOBJ::vXlatGlyphArray(WCHAR *pwc,UINT cwc,HGLYPH *phg, DWORD iMode, BOOL bSubset)
|
|
{
|
|
FD_GLYPHSET *pgs = prfnt->pfdg;
|
|
|
|
BOOL bHorizGS = FALSE;
|
|
ULONG iFont;
|
|
PFE *ppfeHoriz;
|
|
|
|
iFont = prfnt->ppfe->iFont;
|
|
|
|
// if this is used on @face font by font subsetting
|
|
// we return the "base" glyph indices
|
|
|
|
if (bSubset && iFont && !(iFont & 1))
|
|
{
|
|
PFEOBJ pfeObj(ppfeHoriz = ((PFE**)(prfnt->pPFF->aulData))[(iFont - 1) & 0xFFFFFFFE]);
|
|
FD_GLYPHSET *pgsTmp;
|
|
|
|
if (pfeObj.bValid() && (pgsTmp = pfeObj.pfdg()))
|
|
{
|
|
bHorizGS = TRUE;
|
|
pgs = pgsTmp;
|
|
}
|
|
}
|
|
|
|
if (pgs->cRuns == 0)
|
|
{
|
|
WARNING("vXlatGlyphArray - empty glyphset\n");
|
|
|
|
for (; cwc != 0; --cwc, ++phg)
|
|
{
|
|
*phg = prfnt->hgDefault;
|
|
}
|
|
return;
|
|
}
|
|
|
|
WCRUN *pwcRunBase = pgs->awcrun;
|
|
int iMax = (int) pgs->cRuns - 1;
|
|
WCRUN *pwcRun;
|
|
int nwc;
|
|
int iThis;
|
|
int iFirst;
|
|
int cBits;
|
|
HGLYPH hgReplace = (iMode == GGI_MARK_NONEXISTING_GLYPHS) ?
|
|
0xffffffff : prfnt->hgDefault;
|
|
|
|
// We should precompute this stuff.
|
|
|
|
// Count the bits.
|
|
|
|
|
|
if (iMax > 0xFFFF)
|
|
iMax = 0xFFFF; // 65000 runs
|
|
|
|
if ( iMax & 0xF000 )
|
|
cBits = acBits[(iMax >> 12) & 0x00FF] + 12;
|
|
else if (iMax & 0x0F00 )
|
|
cBits = acBits[(iMax >> 8) & 0x00FF] + 8;
|
|
else if (iMax & 0x00F0)
|
|
cBits = acBits[(iMax >> 4) & 0x00FF] + 4;
|
|
else
|
|
cBits = acBits[iMax];
|
|
|
|
// Set the starting point.
|
|
|
|
iFirst = aiStart[cBits];
|
|
|
|
while (cwc)
|
|
{
|
|
// Handle a common case which otherwise causes us to do a lot of
|
|
// useless searching. It also guarantees that we never have to look
|
|
// below run 0.
|
|
|
|
if (*pwc < pwcRunBase->wcLow)
|
|
{
|
|
|
|
do { *phg++ = hgReplace; pwc++; cwc--; }
|
|
while (cwc && (*pwc < pwcRunBase->wcLow));
|
|
continue;
|
|
}
|
|
|
|
// Binary search to find a run for the first character.
|
|
|
|
iThis = iFirst;
|
|
|
|
switch (cBits)
|
|
{
|
|
case 16:
|
|
iThis += (*pwc >= pwcRunBase[iThis].wcLow) ? 32768 : 0;
|
|
iThis -= 16384;
|
|
case 15:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 16384 : 0;
|
|
iThis -= 8192;
|
|
case 14:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 8192 : 0;
|
|
iThis -= 4096;
|
|
case 13:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 4096 : 0;
|
|
iThis -= 2048;
|
|
case 12:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 2048 : 0;
|
|
iThis -= 1024;
|
|
case 11:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 1024 : 0;
|
|
iThis -= 512;
|
|
case 10:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 512 : 0;
|
|
iThis -= 256;
|
|
case 9:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 256 : 0;
|
|
iThis -= 128;
|
|
case 8:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 128 : 0;
|
|
iThis -= 64;
|
|
case 7:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 64 : 0;
|
|
iThis -= 32;
|
|
case 6:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 32 : 0;
|
|
iThis -= 16;
|
|
case 5:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 16 : 0;
|
|
iThis -= 8;
|
|
case 4:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 8 : 0;
|
|
iThis -= 4;
|
|
case 3:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 4 : 0;
|
|
iThis -= 2;
|
|
case 2:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 2 : 0;
|
|
iThis -= 1;
|
|
case 1:
|
|
iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 1 : 0;
|
|
iThis -= 1;
|
|
case 0:
|
|
break;
|
|
}
|
|
pwcRun = &pwcRunBase[iThis]; // This is our candidate.
|
|
nwc = *pwc - pwcRun->wcLow;
|
|
|
|
if (nwc >= pwcRun->cGlyphs)
|
|
{
|
|
// Oops, there is no such character. Store the default.
|
|
|
|
#ifdef FE_SB
|
|
if(bIsLinkedGlyph(*pwc) || bIsSystemTTGlyph(*pwc))
|
|
{
|
|
prfnt->flEUDCState |= EUDC_WIDTH_REQUESTED;
|
|
}
|
|
#endif
|
|
*phg++ = hgReplace; pwc++; cwc--;
|
|
|
|
continue;
|
|
}
|
|
|
|
// Here's the better case, we found a run. Let's try to use it a lot.
|
|
|
|
if (pwcRun->phg != NULL)
|
|
{
|
|
do { *phg++ = pwcRun->phg[nwc]; pwc++; cwc--; }
|
|
while
|
|
(
|
|
cwc
|
|
&& ((nwc = *pwc - pwcRun->wcLow) >= 0)
|
|
&& (nwc < (int) pwcRun->cGlyphs)
|
|
);
|
|
}
|
|
else
|
|
{
|
|
do { *phg++ = *pwc++; cwc--; }
|
|
while
|
|
(
|
|
cwc
|
|
&& ((nwc = *pwc - pwcRun->wcLow) >= 0)
|
|
&& (nwc < (int) pwcRun->cGlyphs)
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
if (bHorizGS)
|
|
{
|
|
PFEOBJ pfeObj(ppfeHoriz);
|
|
|
|
pfeObj.vFreepfdg();
|
|
}
|
|
}
|