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.

719 lines
25 KiB

  1. /******************************Module*Header***********************************\
  2. * Module Name: text.c
  3. *
  4. * Non-cached glyph rendering functions.
  5. *
  6. * Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
  7. * Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
  8. *
  9. \******************************************************************************/
  10. #include "precomp.h"
  11. #include "gdi.h"
  12. // The shift equations are a nuisance. We want x<<32 to be
  13. // zero but some processors only use the bottom 5 bits
  14. // of the shift value. So if we want to shift by n bits
  15. // where we know that n may be 32, we do it in two parts.
  16. // It turns out that in the algorithms below we get either
  17. // (32 <= n < 0) or (32 < n <= 0). We use the macro for
  18. // the first one and a normal shift for the second.
  19. //
  20. #define SHIFT_LEFT(src, n) (((src) << ((n)-1)) << 1)
  21. //------------------------------------------------------------------------------
  22. // FUNC: bClippedText
  23. //
  24. // Renders an array of proportional or monospaced glyphs within a non-trivial
  25. // clip region
  26. //
  27. // ppdev------pointer to physical device object
  28. // pgp--------array of glyphs to render (all members of the pcf font)
  29. // cGlyph-----number of glyphs to render
  30. // ulCharInc--fixed character spacing increment (0 if proportional font)
  31. // pco--------pointer to the clip region object
  32. //
  33. // Returns TRUE if string object rendered
  34. //------------------------------------------------------------------------------
  35. BOOL
  36. bClippedText(PDev* ppdev,
  37. GLYPHPOS* pgp,
  38. LONG cGlyph,
  39. ULONG ulCharInc,
  40. CLIPOBJ* pco)
  41. {
  42. LONG cGlyphOriginal;
  43. GLYPHPOS *pgpOriginal;
  44. GLYPHBITS* pgb;
  45. POINTL ptlOrigin;
  46. BOOL bMore;
  47. ClipEnum ce;
  48. RECTL* prclClip;
  49. LONG cxGlyph;
  50. LONG cyGlyph;
  51. BYTE* pjGlyph;
  52. LONG x;
  53. DWORD renderBits;
  54. LONG unused;
  55. LONG rShift;
  56. ULONG bits;
  57. ULONG bitWord;
  58. ULONG* pBuffer;
  59. ULONG* pBufferEnd;
  60. ULONG* pReservationEnd;
  61. PERMEDIA_DECL;
  62. DBG_GDI((7, "bClippedText: entered for %d glyphs", cGlyph));
  63. ASSERTDD(pco != NULL, "Don't expect NULL clip objects here");
  64. //we'll go through the glyph list for each of the clipping rectangles
  65. cGlyphOriginal = cGlyph;
  66. pgpOriginal = pgp;
  67. renderBits = __RENDER_TRAPEZOID_PRIMITIVE | __RENDER_SYNC_ON_BIT_MASK;
  68. // since we are clipping, assume that we will need the scissor clip. So
  69. // enable user level scissoring here. We disable it just before returning.
  70. //
  71. InputBufferReserve(ppdev, 2, &pBuffer);
  72. pBuffer[0] = __Permedia2TagScissorMode;
  73. pBuffer[1] = USER_SCISSOR_ENABLE | SCREEN_SCISSOR_DEFAULT;
  74. pBuffer += 2;
  75. InputBufferCommit(ppdev, pBuffer);
  76. if (pco->iDComplexity != DC_COMPLEX)
  77. {
  78. // We could call 'cEnumStart' and 'bEnum' when the clipping is
  79. // DC_RECT, but the last time I checked, those two calls took
  80. // more than 150 instructions to go through GDI. Since
  81. // 'rclBounds' already contains the DC_RECT clip rectangle,
  82. // and since it's such a common case, we'll special case it:
  83. DBG_GDI((7, "bClippedText: Enumerating rectangular clip region"));
  84. bMore = FALSE;
  85. prclClip = &pco->rclBounds;
  86. ce.c = 1;
  87. goto SingleRectangle;
  88. }
  89. DBG_GDI((7, "bClippedText: Enumerating complex clip region"));
  90. CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
  91. do
  92. {
  93. bMore = CLIPOBJ_bEnum(pco, sizeof(ce), (ULONG*) &ce);
  94. for (prclClip = &ce.arcl[0]; ce.c != 0; ce.c--, prclClip++)
  95. {
  96. cGlyph = cGlyphOriginal;
  97. pgp = pgpOriginal;
  98. SingleRectangle:
  99. pgb = pgp->pgdf->pgb;
  100. ptlOrigin.x = pgb->ptlOrigin.x + pgp->ptl.x;
  101. ptlOrigin.y = pgb->ptlOrigin.y + pgp->ptl.y;
  102. // load Permedia2 scissor clip to trap partially clipped glyphs. We still
  103. // check whether a glyph is completely clipped out as an optimisation.
  104. // I suppose that since we construct the bits to download to Permedia2, with
  105. // a bit more work I could do the clipping while downloading the bits.
  106. // But, in the future we will probably cache the packed bits anyway so
  107. // use the scissor. Wait for the first 5 FIFO entries here as well.
  108. //
  109. DBG_GDI((7, "bClippedText: loading scissor clip (%d,%d):(%d,%d)",
  110. prclClip->left, prclClip->top,
  111. prclClip->right, prclClip->bottom));
  112. InputBufferReserve(ppdev, 4, &pBuffer);
  113. pBuffer[0] = __Permedia2TagScissorMinXY;
  114. pBuffer[1] = (prclClip->top << 16) | (prclClip->left);
  115. pBuffer[2] = __Permedia2TagScissorMaxXY;
  116. pBuffer[3] = (prclClip->bottom << 16) | (prclClip->right);
  117. pBuffer += 4;
  118. InputBufferCommit(ppdev, pBuffer);
  119. // Loop through all the glyphs for this rectangle:
  120. for(;;)
  121. {
  122. cxGlyph = pgb->sizlBitmap.cx;
  123. cyGlyph = pgb->sizlBitmap.cy;
  124. // reject completely clipped out glyphs
  125. if ((prclClip->right <= ptlOrigin.x) ||
  126. (prclClip->bottom <= ptlOrigin.y) ||
  127. (prclClip->left >= ptlOrigin.x + cxGlyph) ||
  128. (prclClip->top >= ptlOrigin.y + cyGlyph))
  129. {
  130. DBG_GDI((7, "bClippedText: glyph clipped at (%d,%d):(%d,%d)",
  131. ptlOrigin.x, ptlOrigin.y,
  132. ptlOrigin.x + cxGlyph, ptlOrigin.y + cyGlyph));
  133. goto ContinueGlyphs;
  134. }
  135. pjGlyph = pgb->aj;
  136. cyGlyph = pgb->sizlBitmap.cy;
  137. x = ptlOrigin.x;
  138. unused = 32;
  139. bitWord = 0;
  140. DBG_GDI((7, "bClippedText: glyph clipped at (%d,%d):(%d,%d)",
  141. x, ptlOrigin.y, x + cxGlyph, ptlOrigin.y + cyGlyph));
  142. InputBufferReserve(ppdev, 10, &pBuffer);
  143. pBuffer[0] = __Permedia2TagStartXDom;
  144. pBuffer[1] = INTtoFIXED(x);
  145. pBuffer[2] = __Permedia2TagStartXSub;
  146. pBuffer[3] = INTtoFIXED(x + cxGlyph);
  147. pBuffer[4] = __Permedia2TagStartY;
  148. pBuffer[5] = INTtoFIXED(ptlOrigin.y);
  149. pBuffer[6] = __Permedia2TagCount;
  150. pBuffer[7] = cyGlyph;
  151. pBuffer[8] = __Permedia2TagRender;
  152. pBuffer[9] = renderBits;
  153. pBuffer += 10;
  154. InputBufferCommit(ppdev, pBuffer);
  155. DBG_GDI((7, "bClippedText: downloading %d pel wide glyph",
  156. cxGlyph));
  157. InputBufferStart(ppdev, 100, &pBuffer, &pBufferEnd, &pReservationEnd);
  158. if (cxGlyph <= 8)
  159. {
  160. //-----------------------------------------------------
  161. // 1 to 8 pels in width
  162. BYTE *pSrcB;
  163. pSrcB = pjGlyph;
  164. rShift = 8 - cxGlyph;
  165. for(;;)
  166. {
  167. bits = *pSrcB >> rShift;
  168. unused -= cxGlyph;
  169. if (unused > 0)
  170. bitWord |= bits << unused;
  171. else
  172. {
  173. bitWord |= bits >> -unused;
  174. InputBufferContinue(ppdev, 2, &pBuffer, &pBufferEnd,
  175. &pReservationEnd);
  176. pBuffer[0] = __Permedia2TagBitMaskPattern;
  177. pBuffer[1] = bitWord;
  178. pBuffer += 2;
  179. unused += 32;
  180. bitWord = SHIFT_LEFT(bits, unused);
  181. }
  182. if (--cyGlyph == 0)
  183. break;
  184. ++pSrcB;
  185. }
  186. }
  187. else if (cxGlyph <= 16)
  188. {
  189. //-----------------------------------------------------
  190. // 9 to 16 pels in width
  191. USHORT *pSrcW;
  192. pSrcW = (USHORT *)pjGlyph;
  193. rShift = 32 - cxGlyph;
  194. for(;;)
  195. {
  196. bits = *pSrcW;
  197. bits = ((bits << 24) | (bits << 8)) >> rShift;
  198. unused -= cxGlyph;
  199. if (unused > 0)
  200. bitWord |= bits << unused;
  201. else
  202. {
  203. bitWord |= bits >> -unused;
  204. InputBufferContinue(ppdev, 2, &pBuffer, &pBufferEnd,
  205. &pReservationEnd);
  206. pBuffer[0] = __Permedia2TagBitMaskPattern;
  207. pBuffer[1] = bitWord;
  208. pBuffer += 2;
  209. unused += 32;
  210. bitWord = SHIFT_LEFT(bits, unused);
  211. }
  212. if (--cyGlyph == 0)
  213. break;
  214. ++pSrcW;
  215. }
  216. }
  217. else
  218. {
  219. //-----------------------------------------------------
  220. // More than 16 pels in width
  221. ULONG *pSrcL;
  222. LONG nRight;
  223. LONG nRemainder;
  224. LONG lDelta;
  225. lDelta = (cxGlyph + 7) >> 3;
  226. for(;;)
  227. {
  228. pSrcL = (ULONG*)((INT_PTR)pjGlyph & ~3);
  229. nRight=(LONG)(32-(((INT_PTR)pjGlyph-(INT_PTR)pSrcL) << 3));
  230. LSWAP_BYTES(bits, pSrcL);
  231. bits &= SHIFT_LEFT(1, nRight) - 1;
  232. nRemainder = cxGlyph - nRight;
  233. if (nRemainder < 0)
  234. {
  235. bits >>= -nRemainder;
  236. nRight = cxGlyph;
  237. nRemainder = 0;
  238. }
  239. unused -= nRight;
  240. if (unused > 0)
  241. bitWord |= bits << unused;
  242. else
  243. {
  244. bitWord |= bits >> -unused;
  245. InputBufferContinue(ppdev, 2, &pBuffer, &pBufferEnd,
  246. &pReservationEnd);
  247. pBuffer[0] = __Permedia2TagBitMaskPattern;
  248. pBuffer[1] = bitWord;
  249. pBuffer += 2;
  250. unused += 32;
  251. bitWord = SHIFT_LEFT(bits, unused);
  252. }
  253. while (nRemainder >= 32)
  254. {
  255. ++pSrcL;
  256. LSWAP_BYTES(bits, pSrcL);
  257. bitWord |= bits >> (32 - unused);
  258. InputBufferContinue(ppdev, 2, &pBuffer, &pBufferEnd,
  259. &pReservationEnd);
  260. pBuffer[0] = __Permedia2TagBitMaskPattern;
  261. pBuffer[1] = bitWord;
  262. pBuffer += 2;
  263. bitWord = SHIFT_LEFT(bits, unused);
  264. nRemainder -= 32;
  265. }
  266. if (nRemainder > 0)
  267. {
  268. ++pSrcL;
  269. LSWAP_BYTES(bits, pSrcL);
  270. bits >>= (32 - nRemainder);
  271. unused -= nRemainder;
  272. if (unused > 0)
  273. bitWord |= bits << unused;
  274. else
  275. {
  276. bitWord |= bits >> -unused;
  277. InputBufferContinue(ppdev, 2, &pBuffer, &pBufferEnd,
  278. &pReservationEnd);
  279. pBuffer[0] = __Permedia2TagBitMaskPattern;
  280. pBuffer[1] = bitWord;
  281. pBuffer += 2;
  282. unused += 32;
  283. bitWord = SHIFT_LEFT(bits, unused);
  284. }
  285. }
  286. if (--cyGlyph == 0)
  287. break;
  288. /* go onto next scanline */
  289. pjGlyph += lDelta;
  290. }
  291. }
  292. // complete the bit download
  293. if (unused < 32)
  294. {
  295. InputBufferContinue(ppdev, 2, &pBuffer, &pBufferEnd,
  296. &pReservationEnd);
  297. pBuffer[0] = __Permedia2TagBitMaskPattern;
  298. pBuffer[1] = bitWord;
  299. pBuffer += 2;
  300. }
  301. InputBufferCommit(ppdev, pBuffer);
  302. DBG_GDI((7, "bClippedText: download completed"));
  303. ContinueGlyphs:
  304. if (--cGlyph == 0)
  305. break;
  306. DBG_GDI((7, "bClippedText: %d still to render", cGlyph));
  307. // Get ready for next glyph:
  308. pgp++;
  309. pgb = pgp->pgdf->pgb;
  310. if (ulCharInc == 0)
  311. {
  312. ptlOrigin.x = pgp->ptl.x + pgb->ptlOrigin.x;
  313. ptlOrigin.y = pgp->ptl.y + pgb->ptlOrigin.y;
  314. }
  315. else
  316. {
  317. ptlOrigin.x += ulCharInc;
  318. }
  319. }
  320. }
  321. } while (bMore);
  322. // reset the scissor. default is the whole of VRAM.
  323. DBG_GDI((20, "bClippedText: resetting scissor clip"));
  324. InputBufferReserve(ppdev, 2, &pBuffer);
  325. pBuffer[0] = __Permedia2TagScissorMode;
  326. pBuffer[1] = SCREEN_SCISSOR_DEFAULT;
  327. pBuffer += 2;
  328. InputBufferCommit(ppdev, pBuffer);
  329. DBG_GDI((7, "bClippedText: exited"));
  330. return(TRUE);
  331. }
  332. //------------------------------------------------------------------------------
  333. // FUNC: bClippedAAText
  334. //
  335. // Renders an array of proportional or monospaced anti-aliassed glyphs within
  336. // a non-trivial clip region
  337. //
  338. // ppdev------pointer to physical device object
  339. // pgp--------array of glyphs to render (all members of the pcf font)
  340. // cGlyph-----number of glyphs to render
  341. // ulCharInc--fixed character spacing increment (0 if proportional font)
  342. // pco--------pointer to the clip region object
  343. //
  344. // Returns TRUE if string object rendered
  345. //------------------------------------------------------------------------------
  346. BOOL
  347. bClippedAAText(PDev* ppdev,
  348. GLYPHPOS* pgp,
  349. LONG cGlyph,
  350. ULONG ulCharInc,
  351. CLIPOBJ* pco)
  352. {
  353. LONG cGlyphOriginal;
  354. GLYPHPOS *pgpOriginal;
  355. GLYPHBITS* pgb;
  356. POINTL ptlOrigin;
  357. BOOL bMore;
  358. ClipEnum ce;
  359. RECTL* prclClip;
  360. LONG cxGlyph;
  361. LONG cyGlyph;
  362. BYTE* pjGlyph;
  363. LONG x;
  364. DWORD renderBits;
  365. LONG unused;
  366. LONG rShift;
  367. ULONG bits;
  368. ULONG bitWord;
  369. ULONG* pBuffer;
  370. ULONG* pBufferEnd;
  371. ULONG* pReservationEnd;
  372. PERMEDIA_DECL;
  373. DBG_GDI((7, "bClippedAAText: entered for %d glyphs", cGlyph));
  374. ASSERTDD(pco != NULL, "Don't expect NULL clip objects here");
  375. //we'll go through the glyph list for each of the clipping rectangles
  376. cGlyphOriginal = cGlyph;
  377. pgpOriginal = pgp;
  378. renderBits = __RENDER_TRAPEZOID_PRIMITIVE |
  379. __RENDER_TEXTURED_PRIMITIVE |
  380. __RENDER_SYNC_ON_HOST_DATA;
  381. // since we are clipping, assume that we will need the scissor clip. So
  382. // enable user level scissoring here. We disable it just before returning.
  383. //
  384. InputBufferReserve(ppdev, 14, &pBuffer);
  385. pBuffer[0] = __Permedia2TagScissorMode;
  386. pBuffer[1] = USER_SCISSOR_ENABLE | SCREEN_SCISSOR_DEFAULT;
  387. pBuffer[2] = __Permedia2TagDitherMode;
  388. pBuffer[3] = (COLOR_MODE << PM_DITHERMODE_COLORORDER) |
  389. (ppdev->ulPermFormat << PM_DITHERMODE_COLORFORMAT) |
  390. (ppdev->ulPermFormatEx << PM_DITHERMODE_COLORFORMATEXTENSION) |
  391. (1 << PM_DITHERMODE_ENABLE);
  392. pBuffer[4] = __Permedia2TagAlphaBlendMode;
  393. pBuffer[5] = (0 << PM_ALPHABLENDMODE_BLENDTYPE) | // RGB
  394. (1 << PM_ALPHABLENDMODE_COLORORDER) | // RGB
  395. (1 << PM_ALPHABLENDMODE_ENABLE) |
  396. (1 << PM_ALPHABLENDMODE_ENABLE) |
  397. (84 << PM_ALPHABLENDMODE_OPERATION) | // PreMult
  398. (ppdev->ulPermFormat << PM_ALPHABLENDMODE_COLORFORMAT) |
  399. (ppdev->ulPermFormatEx << PM_ALPHABLENDMODE_COLORFORMATEXTENSION);
  400. pBuffer[6] = __Permedia2TagLogicalOpMode;
  401. pBuffer[7] = __PERMEDIA_DISABLE;
  402. pBuffer[8] = __Permedia2TagTextureColorMode;
  403. pBuffer[9] = (1 << PM_TEXCOLORMODE_ENABLE) |
  404. (0 << 4) | // RGB
  405. (0 << 1); // Modulate
  406. pBuffer[10] = __Permedia2TagTextureDataFormat;
  407. pBuffer[11] = (ppdev->ulPermFormat << PM_TEXDATAFORMAT_FORMAT) |
  408. (ppdev->ulPermFormatEx << PM_TEXDATAFORMAT_FORMATEXTENSION) |
  409. (COLOR_MODE << PM_TEXDATAFORMAT_COLORORDER);
  410. pBuffer[12] = __Permedia2TagColorDDAMode;
  411. pBuffer[13] = 1;
  412. pBuffer += 14;
  413. InputBufferCommit(ppdev, pBuffer);
  414. if (pco->iDComplexity != DC_COMPLEX)
  415. {
  416. // We could call 'cEnumStart' and 'bEnum' when the clipping is
  417. // DC_RECT, but the last time I checked, those two calls took
  418. // more than 150 instructions to go through GDI. Since
  419. // 'rclBounds' already contains the DC_RECT clip rectangle,
  420. // and since it's such a common case, we'll special case it:
  421. DBG_GDI((7, "bClippedText: Enumerating rectangular clip region"));
  422. bMore = FALSE;
  423. prclClip = &pco->rclBounds;
  424. ce.c = 1;
  425. goto SingleRectangle;
  426. }
  427. DBG_GDI((7, "bClippedAAText: Enumerating complex clip region"));
  428. CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
  429. do
  430. {
  431. bMore = CLIPOBJ_bEnum(pco, sizeof(ce), (ULONG*) &ce);
  432. for (prclClip = &ce.arcl[0]; ce.c != 0; ce.c--, prclClip++)
  433. {
  434. cGlyph = cGlyphOriginal;
  435. pgp = pgpOriginal;
  436. SingleRectangle:
  437. pgb = pgp->pgdf->pgb;
  438. ptlOrigin.x = pgb->ptlOrigin.x + pgp->ptl.x;
  439. ptlOrigin.y = pgb->ptlOrigin.y + pgp->ptl.y;
  440. // load Permedia2 scissor clip to trap partially clipped glyphs. We still
  441. // check whether a glyph is completely clipped out as an optimisation.
  442. // I suppose that since we construct the bits to download to Permedia2, with
  443. // a bit more work I could do the clipping while downloading the bits.
  444. // But, in the future we will probably cache the packed bits anyway so
  445. // use the scissor. Wait for the first 5 FIFO entries here as well.
  446. //
  447. DBG_GDI((7, "bClippedAAText: loading scissor clip (%d,%d):(%d,%d)",
  448. prclClip->left, prclClip->top,
  449. prclClip->right, prclClip->bottom));
  450. InputBufferReserve(ppdev, 4, &pBuffer);
  451. pBuffer[0] = __Permedia2TagScissorMinXY;
  452. pBuffer[1] = (prclClip->top << 16) | (prclClip->left);
  453. pBuffer[2] = __Permedia2TagScissorMaxXY;
  454. pBuffer[3] = (prclClip->bottom << 16) | (prclClip->right);
  455. pBuffer += 4;
  456. InputBufferCommit(ppdev, pBuffer);
  457. // Loop through all the glyphs for this rectangle:
  458. for(;;)
  459. {
  460. cxGlyph = pgb->sizlBitmap.cx;
  461. cyGlyph = pgb->sizlBitmap.cy;
  462. // reject completely clipped out glyphs
  463. if ((prclClip->right <= ptlOrigin.x) ||
  464. (prclClip->bottom <= ptlOrigin.y) ||
  465. (prclClip->left >= ptlOrigin.x + cxGlyph) ||
  466. (prclClip->top >= ptlOrigin.y + cyGlyph))
  467. {
  468. DBG_GDI((7, "bClippedAAText: glyph clipped at (%d,%d):(%d,%d)",
  469. ptlOrigin.x, ptlOrigin.y,
  470. ptlOrigin.x + cxGlyph, ptlOrigin.y + cyGlyph));
  471. goto ContinueGlyphs;
  472. }
  473. pjGlyph = pgb->aj;
  474. cyGlyph = pgb->sizlBitmap.cy;
  475. x = ptlOrigin.x;
  476. unused = 32;
  477. bitWord = 0;
  478. DBG_GDI((7, "bClippedAAText: glyph clipped at (%d,%d):(%d,%d)",
  479. x, ptlOrigin.y, x + cxGlyph, ptlOrigin.y + cyGlyph));
  480. InputBufferReserve(ppdev, 12, &pBuffer);
  481. pBuffer[0] = __Permedia2TagStartXDom;
  482. pBuffer[1] = INTtoFIXED(x);
  483. pBuffer[2] = __Permedia2TagStartXSub;
  484. pBuffer[3] = INTtoFIXED(x + cxGlyph);
  485. pBuffer[4] = __Permedia2TagStartY;
  486. pBuffer[5] = INTtoFIXED(ptlOrigin.y);
  487. pBuffer[6] = __Permedia2TagdY;
  488. pBuffer[7] = 1 << 16;
  489. pBuffer[8] = __Permedia2TagCount;
  490. pBuffer[9] = cyGlyph;
  491. pBuffer[10] = __Permedia2TagRender;
  492. pBuffer[11] = renderBits;
  493. pBuffer += 12;
  494. InputBufferCommit(ppdev, pBuffer);
  495. DBG_GDI((7, "bClippedAAText: downloading %d pel wide glyph",
  496. cxGlyph));
  497. while(cyGlyph--)
  498. {
  499. InputBufferReserve(ppdev, cxGlyph + 1, &pBuffer);
  500. *pBuffer++ = ((cxGlyph - 1) << 16) | __Permedia2TagTexel0;
  501. x = 0;
  502. while (x++ < cxGlyph)
  503. {
  504. ULONG pixels = *pjGlyph++;
  505. ULONG alpha = pixels & 0xf0;
  506. alpha |= alpha >> 4;
  507. ULONG pixel;
  508. pixel = (alpha << 24) | 0xffffff;
  509. *pBuffer++ = pixel;
  510. if(x++ < cxGlyph)
  511. {
  512. alpha = pixels & 0xf;
  513. alpha |= alpha << 4;
  514. pixel = (alpha << 24) | 0xffffff;
  515. *pBuffer++ = pixel;
  516. }
  517. }
  518. InputBufferCommit(ppdev, pBuffer);
  519. }
  520. DBG_GDI((7, "bClippedAAText: download completed"));
  521. ContinueGlyphs:
  522. if (--cGlyph == 0)
  523. break;
  524. DBG_GDI((7, "bClippedAAText: %d still to render", cGlyph));
  525. // Get ready for next glyph:
  526. pgp++;
  527. pgb = pgp->pgdf->pgb;
  528. if (ulCharInc == 0)
  529. {
  530. ptlOrigin.x = pgp->ptl.x + pgb->ptlOrigin.x;
  531. ptlOrigin.y = pgp->ptl.y + pgb->ptlOrigin.y;
  532. }
  533. else
  534. {
  535. ptlOrigin.x += ulCharInc;
  536. }
  537. }
  538. }
  539. } while (bMore);
  540. // reset the scissor. default is the whole of VRAM.
  541. DBG_GDI((20, "bClippedAAText: resetting scissor clip"));
  542. InputBufferReserve(ppdev, 10, &pBuffer);
  543. pBuffer[0] = __Permedia2TagScissorMode;
  544. pBuffer[1] = SCREEN_SCISSOR_DEFAULT;
  545. pBuffer[2] = __Permedia2TagDitherMode;
  546. pBuffer[3] = __PERMEDIA_DISABLE;
  547. pBuffer[4] = __Permedia2TagAlphaBlendMode;
  548. pBuffer[5] = __PERMEDIA_DISABLE;
  549. pBuffer[6] = __Permedia2TagTextureColorMode;
  550. pBuffer[7] = __PERMEDIA_DISABLE;
  551. pBuffer[8] = __Permedia2TagColorDDAMode;
  552. pBuffer[9] = __PERMEDIA_DISABLE;
  553. pBuffer += 10;
  554. InputBufferCommit(ppdev, pBuffer);
  555. DBG_GDI((7, "bClippedText: exited"));
  556. return(TRUE);
  557. }