Leaked source code of windows server 2003
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

  1. /******************************Module*Header*******************************\
  2. * Module Name: rfntxlat.cxx
  3. *
  4. * Methods for translating wchars to hglyphs or pgd's
  5. *
  6. * Created: March 5, 1992
  7. * Author: Paul Butzi
  8. *
  9. * Copyright (c) 1992-1999 Microsoft Corporation
  10. *
  11. \**************************************************************************/
  12. #include "precomp.hxx"
  13. void RFONTOBJ::pfdg(FD_GLYPHSET *pfdg)
  14. {
  15. prfnt->pfdg = pfdg;
  16. }
  17. /******************************Public*Routine******************************\
  18. * void chglyGetAllGlyphHandles
  19. *
  20. * Get all the glyph handles for an RFONTOBJ
  21. * return the number of handles
  22. *
  23. *
  24. * History:
  25. * 06-Mar-92 -by- Paul Butzi
  26. * Wrote it.
  27. \**************************************************************************/
  28. COUNT RFONTOBJ::chglyGetAllHandles
  29. (
  30. HGLYPH *pgh
  31. )
  32. {
  33. // first check if this is one of the tt fonts which supports
  34. // possibly more glyphs than can be accessed via fd_glyphset directly.
  35. // In this case handles are the same as glyph indicies
  36. IFIMETRICS * pifi = prfnt->ppfe->pifi;
  37. ULONG cig = 0;
  38. if (pifi->cjIfiExtra > offsetof(IFIEXTRA, cig))
  39. {
  40. cig = ((IFIEXTRA *)(pifi + 1))->cig;
  41. }
  42. if (cig)
  43. {
  44. if (pgh)
  45. {
  46. for (ULONG hg = 0; hg < cig; hg++, pgh++)
  47. *pgh = hg;
  48. }
  49. return cig;
  50. }
  51. FD_GLYPHSET *pfdg = prfnt->pfdg;
  52. if ( pgh == NULL )
  53. return pfdg->cGlyphsSupported;
  54. for ( COUNT i = 0; i < pfdg->cRuns; i += 1 )
  55. {
  56. WCRUN *pwcr = &pfdg->awcrun[i];
  57. if ( pwcr->phg != NULL )
  58. {
  59. for ( COUNT j = 0; j < pwcr->cGlyphs; j += 1 )
  60. {
  61. *pgh = pwcr->phg[j];
  62. pgh += 1;
  63. }
  64. }
  65. else
  66. {
  67. for ( COUNT j = 0; j < pwcr->cGlyphs; j += 1 )
  68. {
  69. *pgh = pwcr->wcLow + j;
  70. pgh += 1;
  71. }
  72. }
  73. }
  74. return pfdg->cGlyphsSupported;
  75. }
  76. extern const BYTE acBits[16] = {0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4};
  77. extern const INT aiStart[17] = {0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
  78. VOID RFONTOBJ::vXlatGlyphArray(WCHAR *pwc,UINT cwc,HGLYPH *phg, DWORD iMode, BOOL bSubset)
  79. {
  80. FD_GLYPHSET *pgs = prfnt->pfdg;
  81. BOOL bHorizGS = FALSE;
  82. ULONG iFont;
  83. PFE *ppfeHoriz;
  84. iFont = prfnt->ppfe->iFont;
  85. // if this is used on @face font by font subsetting
  86. // we return the "base" glyph indices
  87. if (bSubset && iFont && !(iFont & 1))
  88. {
  89. PFEOBJ pfeObj(ppfeHoriz = ((PFE**)(prfnt->pPFF->aulData))[(iFont - 1) & 0xFFFFFFFE]);
  90. FD_GLYPHSET *pgsTmp;
  91. if (pfeObj.bValid() && (pgsTmp = pfeObj.pfdg()))
  92. {
  93. bHorizGS = TRUE;
  94. pgs = pgsTmp;
  95. }
  96. }
  97. if (pgs->cRuns == 0)
  98. {
  99. WARNING("vXlatGlyphArray - empty glyphset\n");
  100. for (; cwc != 0; --cwc, ++phg)
  101. {
  102. *phg = prfnt->hgDefault;
  103. }
  104. return;
  105. }
  106. WCRUN *pwcRunBase = pgs->awcrun;
  107. int iMax = (int) pgs->cRuns - 1;
  108. WCRUN *pwcRun;
  109. int nwc;
  110. int iThis;
  111. int iFirst;
  112. int cBits;
  113. HGLYPH hgReplace = (iMode == GGI_MARK_NONEXISTING_GLYPHS) ?
  114. 0xffffffff : prfnt->hgDefault;
  115. // We should precompute this stuff.
  116. // Count the bits.
  117. if (iMax > 0xFFFF)
  118. iMax = 0xFFFF; // 65000 runs
  119. if ( iMax & 0xF000 )
  120. cBits = acBits[(iMax >> 12) & 0x00FF] + 12;
  121. else if (iMax & 0x0F00 )
  122. cBits = acBits[(iMax >> 8) & 0x00FF] + 8;
  123. else if (iMax & 0x00F0)
  124. cBits = acBits[(iMax >> 4) & 0x00FF] + 4;
  125. else
  126. cBits = acBits[iMax];
  127. // Set the starting point.
  128. iFirst = aiStart[cBits];
  129. while (cwc)
  130. {
  131. // Handle a common case which otherwise causes us to do a lot of
  132. // useless searching. It also guarantees that we never have to look
  133. // below run 0.
  134. if (*pwc < pwcRunBase->wcLow)
  135. {
  136. do { *phg++ = hgReplace; pwc++; cwc--; }
  137. while (cwc && (*pwc < pwcRunBase->wcLow));
  138. continue;
  139. }
  140. // Binary search to find a run for the first character.
  141. iThis = iFirst;
  142. switch (cBits)
  143. {
  144. case 16:
  145. iThis += (*pwc >= pwcRunBase[iThis].wcLow) ? 32768 : 0;
  146. iThis -= 16384;
  147. case 15:
  148. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 16384 : 0;
  149. iThis -= 8192;
  150. case 14:
  151. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 8192 : 0;
  152. iThis -= 4096;
  153. case 13:
  154. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 4096 : 0;
  155. iThis -= 2048;
  156. case 12:
  157. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 2048 : 0;
  158. iThis -= 1024;
  159. case 11:
  160. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 1024 : 0;
  161. iThis -= 512;
  162. case 10:
  163. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 512 : 0;
  164. iThis -= 256;
  165. case 9:
  166. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 256 : 0;
  167. iThis -= 128;
  168. case 8:
  169. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 128 : 0;
  170. iThis -= 64;
  171. case 7:
  172. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 64 : 0;
  173. iThis -= 32;
  174. case 6:
  175. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 32 : 0;
  176. iThis -= 16;
  177. case 5:
  178. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 16 : 0;
  179. iThis -= 8;
  180. case 4:
  181. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 8 : 0;
  182. iThis -= 4;
  183. case 3:
  184. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 4 : 0;
  185. iThis -= 2;
  186. case 2:
  187. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 2 : 0;
  188. iThis -= 1;
  189. case 1:
  190. iThis += ((iThis <= iMax) && (*pwc >= pwcRunBase[iThis].wcLow)) ? 1 : 0;
  191. iThis -= 1;
  192. case 0:
  193. break;
  194. }
  195. pwcRun = &pwcRunBase[iThis]; // This is our candidate.
  196. nwc = *pwc - pwcRun->wcLow;
  197. if (nwc >= pwcRun->cGlyphs)
  198. {
  199. // Oops, there is no such character. Store the default.
  200. #ifdef FE_SB
  201. if(bIsLinkedGlyph(*pwc) || bIsSystemTTGlyph(*pwc))
  202. {
  203. prfnt->flEUDCState |= EUDC_WIDTH_REQUESTED;
  204. }
  205. #endif
  206. *phg++ = hgReplace; pwc++; cwc--;
  207. continue;
  208. }
  209. // Here's the better case, we found a run. Let's try to use it a lot.
  210. if (pwcRun->phg != NULL)
  211. {
  212. do { *phg++ = pwcRun->phg[nwc]; pwc++; cwc--; }
  213. while
  214. (
  215. cwc
  216. && ((nwc = *pwc - pwcRun->wcLow) >= 0)
  217. && (nwc < (int) pwcRun->cGlyphs)
  218. );
  219. }
  220. else
  221. {
  222. do { *phg++ = *pwc++; cwc--; }
  223. while
  224. (
  225. cwc
  226. && ((nwc = *pwc - pwcRun->wcLow) >= 0)
  227. && (nwc < (int) pwcRun->cGlyphs)
  228. );
  229. }
  230. }
  231. if (bHorizGS)
  232. {
  233. PFEOBJ pfeObj(ppfeHoriz);
  234. pfeObj.vFreepfdg();
  235. }
  236. }