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