|
|
1.1 root 1: /******************************Module*Header*******************************\
2: * Module Name: TextOut.c
3: *
4: * S3 Text accelerations
5: *
6: * Copyright (c) 1992 Microsoft Corporation
7: *
8: \**************************************************************************/
9:
10: #include "driver.h"
11: #include "memory.h"
12:
13: // Part of the fix to limit the amount of resources allocated for fonts
14:
15: #define MAX_GLYPHS_TO_ALLOC 256
16:
17: // number of bytes in the glyph bitmap scanline
18:
19: #define CJ_SCAN(cx) (((cx) + 7) >> 3)
20:
21: #define TRIVIAL_ACCEPT 0x00000001
22: #define MONO_SPACED_FONT 0x00000002
23: #define MONO_SIZE_VALID 0x00000004
24: #define MONO_FIRST_TIME 0x00000008
25:
26: PCACHEDFONT pCachedFontsRoot; // Cached Fonts list root.
27:
28: WORD iPlaneBits[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
29:
30: BOOL bOpaqueRect(
31: PPDEV ppdev,
32: RECTL *prclOpaque,
33: RECTL *prclBounds,
34: BRUSHOBJ *pboOpaque);
35:
36: BOOL bSetS3TextColorAndMix(
37: PPDEV ppdev,
38: MIX mix,
39: BRUSHOBJ *pboFore,
40: BRUSHOBJ *pboOpaque);
41:
42: VOID vBlowCache(PPDEV ppdev);
43:
44: VOID vInitGlyphAlloc(PPDEV ppdev);
45:
46: BOOL bAllocGlyphMemory(PPDEV ppdev,
47: PSIZEL psizlGlyph,
48: PXYZPOINTL pxyzGlyph);
49:
50: PCACHEDGLYPH pCacheFont(PPDEV ppdev,
51: STROBJ *pstro,
52: FONTOBJ *pfo,
53: PCACHEDFONT *ppCachedFont);
54:
55: BOOL bAllocateGlyph(PPDEV ppdev,
56: HGLYPH hg,
57: GLYPHBITS *pgb,
58: PCACHEDGLYPH pcg);
59:
60: BOOL bHandleNonCachedFonts(SURFOBJ *pso,
61: STROBJ *pstro,
62: FONTOBJ *pfo,
63: RECTL *prclClip,
64: RECTL *prclExtra,
65: RECTL *prclOpaque,
66: BRUSHOBJ *pboFore,
67: BRUSHOBJ *pboOpaque,
68: POINTL *pptlOrg,
69: MIX mix);
70:
71: BOOL bHandleCachedFonts(SURFOBJ *pso,
72: STROBJ *pstro,
73: RECTL *prclClip,
74: FONTOBJ *pfo,
75: RECTL *prclOpaque,
76: BRUSHOBJ *pboFore,
77: BRUSHOBJ *pboOpaque,
78: POINTL *pptlOrg,
79: MIX mix);
80:
81: #if DBG
82:
83: ULONG nGlyphs, nOverlaps;
84:
85: #define TFIFOWAIT(level) nGlyphs++; \
86: if (INPW(GP_STAT) & level) { \
87: nOverlaps++; \
88: while (INPW(GP_STAT) & level); \
89: }
90: #else
91:
92: #define TFIFOWAIT(level) FIFOWAIT(level)
93:
94: #endif
95:
96:
97: /****************************************************************************
98: * DrvDestroyFont
99: ***************************************************************************/
100: VOID DrvDestroyFont(FONTOBJ *pfo)
101: {
102: PCACHEDFONT pCachedFont, pcfLast;
103: PCACHEDGLYPH pcg, pcgNext;
104: INT nGlyphs, i;
105:
106: DISPDBG((1, "S3.DLL!DrvDestroyFont - Entry\n"));
107:
108: if (((pCachedFont = ((PCACHEDFONT) pfo->pvConsumer)) != NULL))
109: {
110: if (pfo->iUniq == pCachedFont->iUniq)
111: {
112: // We have found our font.
113:
114: DISPDBG((1, "S3.DLL: Destroying font: pfo->iUniq: %x\n",
115: pfo->iUniq));
116:
117: // First free any nodes in the collision list.
118:
119: nGlyphs = pCachedFont->cGlyphs+1;
120: for (i = 0; i < nGlyphs; i++)
121: {
122: // get a pointer to this glyph node.
123:
124: pcg = &(pCachedFont->pCachedGlyphs[i]);
125:
126: // get a pointer to this glyphs collision list
127:
128: pcg = pcg->pcgCollisionLink;
129: for (; pcg != NULL; pcg = pcgNext)
130: {
131: pcgNext = pcg->pcgCollisionLink;
132: LocalFree(pcg);
133: }
134: }
135:
136: // Now free the cached glyph array
137:
138: LocalFree(pCachedFont->pCachedGlyphs);
139:
140: // Now remove the font node from the list of fonts
141: // and free it.
142:
143: pcfLast = (PCACHEDFONT) &pCachedFontsRoot;
144: for (pCachedFont = pCachedFontsRoot;
145: pCachedFont != NULL;
146: pCachedFont = pCachedFont->pcfNext)
147: {
148: if (pCachedFont->iUniq == pfo->iUniq)
149: {
150: pcfLast->pcfNext = pCachedFont->pcfNext;
151: LocalFree(pCachedFont);
152: break;
153: }
154: pcfLast = pCachedFont;
155: }
156:
157: if (pCachedFont == NULL)
158: {
159: RIP("S3.DLL!DrvDestroyFont - pCachedFont not found\n");
160: }
161: }
162: else
163: {
164: RIP("S3.DLL!DrvDestroyFont - pfo->pvConsumer error\n");
165: }
166: }
167:
168: // In all cases we want to zero out the pvConsumer field.
169:
170: pfo->pvConsumer = NULL;
171:
172: }
173:
174:
175: /****************************************************************************
176: * DrvTextOut
177: ***************************************************************************/
178: BOOL DrvTextOut(
179: SURFOBJ *pso,
180: STROBJ *pstro,
181: FONTOBJ *pfo,
182: CLIPOBJ *pco,
183: RECTL *prclExtra,
184: RECTL *prclOpaque,
185: BRUSHOBJ *pboFore,
186: BRUSHOBJ *pboOpaque,
187: POINTL *pptlOrg,
188: MIX mix)
189: {
190: BOOL b, bMore;
191: UINT i;
192: ENUMRECTS8 EnumRects8;
193: PPDEV ppdev;
194:
195: DISPDBG((3, "S3.DLL: DrvTextOut - Entry\n"));
196:
197: // Pickup the ppdev.
198:
199: ppdev = (PPDEV) pso->dhpdev;
200:
201: // Protect the code path from a potentially NULL clip object
202: // This also gives a maximum rclBounds which we use later:
203:
204: if (pco == NULL || pco->iDComplexity == DC_TRIVIAL)
205: {
206: pco = ppdev->pcoDefault;
207: }
208:
209: // Determine if we can cache this string.
210: // This is done by checking the size of glyph.
211:
212: b = TRUE;
213:
214: if ((pfo->cxMax > GLYPH_CACHE_CX) ||
215: ((pstro->rclBkGround.bottom - pstro->rclBkGround.top) > GLYPH_CACHE_CY))
216: {
217: b = FALSE;
218: }
219:
220: // If the glyphs in this string will fit in the font cache
221: // then try to render it as a cached font.
222:
223: if (b == TRUE)
224: {
225: // Take care of the clipping.
226:
227: if (pco->iDComplexity != DC_COMPLEX)
228: {
229: b = bHandleCachedFonts(pso, pstro, &(pco->rclBounds), pfo,
230: prclOpaque, pboFore,
231: pboOpaque, pptlOrg, mix);
232:
233: }
234: else
235: {
236: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
237:
238: do
239: {
240: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8),
241: (PULONG)&EnumRects8);
242:
243: for (i = 0; i < EnumRects8.c; i++)
244: {
245: b = bHandleCachedFonts(pso, pstro, &(EnumRects8.arcl[i]),
246: pfo, prclOpaque, pboFore, pboOpaque, pptlOrg, mix);
247: if (!b)
248: {
249: // If we failed, stop immediately, so we can fall back
250: // to bHandleNonCachedFonts. Otherwise, if we just blew
251: // the cache, the next call in this loop will succeed,
252: // and we'll never redo this rectangle properly. Note
253: // that this is very inefficient, forcing the whole
254: // rest of the call to go through
255: // bHandleNonCachedFonts
256: break;
257: }
258: }
259:
260: } while (bMore & b);
261: }
262: }
263:
264: // If something went wrong with rendering the string as a cached
265: // font then render it as a large font.
266:
267: if (b == FALSE)
268: {
269: if (pco->iDComplexity != DC_COMPLEX)
270: {
271: b = bHandleNonCachedFonts(pso, pstro, pfo, &(pco->rclBounds),
272: prclExtra, prclOpaque, pboFore, pboOpaque, pptlOrg, mix);
273:
274: }
275: else
276: {
277: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
278:
279: do
280: {
281: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8),
282: (PULONG)&EnumRects8);
283:
284: for (i = 0; i < EnumRects8.c; i++)
285: {
286: b = bHandleNonCachedFonts(pso, pstro, pfo,
287: &(EnumRects8.arcl[i]), prclExtra, prclOpaque,
288: pboFore, pboOpaque, pptlOrg, mix);
289: }
290:
291: } while (bMore);
292: }
293:
294: vResetS3Clipping(ppdev);
295: }
296:
297: return (b);
298: }
299:
300:
301: /****************************************************************************
302: * bHandleCachedFonts
303: ***************************************************************************/
304: BOOL bHandleCachedFonts(
305: SURFOBJ *pso,
306: STROBJ *pstro,
307: RECTL *prclClip,
308: FONTOBJ *pfo,
309: RECTL *prclOpaque,
310: BRUSHOBJ *pboFore,
311: BRUSHOBJ *pboOpaque,
312: POINTL *pptlOrg,
313: MIX mix)
314: {
315: BOOL b, bMoreGlyphs, bFound;
316: ULONG iGlyph, cGlyphs;
317: POINTL ptl;
318: GLYPHPOS *pgp;
319: INT ihGlyph, cxGlyph, cyGlyph;
320: PCACHEDGLYPH pCachedGlyphs, pcg, pcgNew;
321: WORD Cmd;
322: XYZPOINTL xyzGlyph;
323: PCACHEDFONT pCachedFont;
324: PPDEV ppdev;
325: INT i, culRcl;
326: ULONG flAccel;
327: RECTL arclTmp[4];
328: ULONG ulCharInc;
329: ULONG yMonoStart, xMonoPosition;
330: POINTL ptlSrc;
331: RECTL rclGlyph;
332: HGLYPH hg;
333: GLYPHBITS *pgb;
334: ULONG fl = 0;
335: BYTE jBackgroundRop;
336:
337: DISPDBG((4, "S3.DLL:bHandleCachedFonts - Entry\n"));
338:
339: ppdev = (PPDEV) pso->dhpdev;
340:
341: //
342: // If we have seen this font before then pvConsumer will be non-NULL.
343: //
344:
345: if (((pCachedFont = ((PCACHEDFONT) pfo->pvConsumer)) != NULL))
346: {
347: pCachedGlyphs = pCachedFont->pCachedGlyphs;
348:
349: if (pfo->iUniq != pCachedFont->iUniq)
350: {
351: DISPDBG((1, "S3.DLL: pfo->iUniq: %x, pCachedFont->iUniq: %x\n",
352: pfo->iUniq, pCachedFont->iUniq));
353: return (FALSE);
354: }
355: }
356:
357: else
358: {
359: DISPDBG((2, "S3.DLL!bHandleCachedFonts - Caching Font: %d\n", pfo->iUniq));
360:
361: pCachedGlyphs = pCacheFont(ppdev, pstro, pfo, &pCachedFont);
362:
363: if (pCachedGlyphs == NULL)
364: {
365: DISPDBG((1, "S3.DLL!bHandleCachedFonts - pCacheFont failed once\n"));
366:
367: vBlowCache(ppdev);
368:
369: pCachedGlyphs = pCacheFont(ppdev, pstro, pfo, &pCachedFont);
370: if (pCachedGlyphs == NULL)
371: {
372: DISPDBG((1, "S3.DLL!bHandleCachedFonts - pCacheFont failed twice\n"));
373: return(FALSE);
374: }
375: }
376:
377: (PCACHEDFONT)(pfo->pvConsumer) = pCachedFont;
378: }
379:
380: // If this string has a Zero Bearing and the string object's
381: // opaque rectangle is the same size as the opaque rectangle then
382: // and opaque mode is requested, then lay down the glyphs in
383: // opaque mode.
384:
385: if (((flAccel = pstro->flAccel) & SO_ZERO_BEARINGS) &&
386: ((flAccel & (SO_HORIZONTAL | SO_VERTICAL | SO_REVERSED)) == SO_HORIZONTAL) &&
387: (flAccel & SO_CHAR_INC_EQUAL_BM_BASE) &&
388: (prclOpaque != NULL))
389: {
390: // If the Opaque rect and the string rect match then
391: // were done. If not then we have to fill in the strips
392: // (top, bottom, left, and right) around the text.
393:
394: culRcl = 0;
395:
396: // Top fragment
397:
398: if (pstro->rclBkGround.top > prclOpaque->top)
399: {
400: arclTmp[culRcl].top = prclOpaque->top;
401: arclTmp[culRcl].left = prclOpaque->left;
402: arclTmp[culRcl].right = prclOpaque->right;
403: arclTmp[culRcl++].bottom = pstro->rclBkGround.top;
404: }
405:
406: // Left fragment
407:
408: if (pstro->rclBkGround.left > prclOpaque->left)
409: {
410: arclTmp[culRcl].top = pstro->rclBkGround.top;
411: arclTmp[culRcl].left = prclOpaque->left;
412: arclTmp[culRcl].right = pstro->rclBkGround.left;
413: arclTmp[culRcl++].bottom = pstro->rclBkGround.bottom;
414: }
415:
416: // Right fragment
417:
418: if (pstro->rclBkGround.right < prclOpaque->right)
419: {
420: arclTmp[culRcl].top = pstro->rclBkGround.top;
421: arclTmp[culRcl].right = prclOpaque->right;
422: arclTmp[culRcl].left = pstro->rclBkGround.right;
423: arclTmp[culRcl++].bottom = pstro->rclBkGround.bottom;
424: }
425:
426: // Bottom fragment
427:
428: if (pstro->rclBkGround.bottom < prclOpaque->bottom)
429: {
430: arclTmp[culRcl].bottom = prclOpaque->bottom;
431: arclTmp[culRcl].left = prclOpaque->left;
432: arclTmp[culRcl].right = prclOpaque->right;
433: arclTmp[culRcl++].top = pstro->rclBkGround.bottom;
434: }
435:
436: // Fill any fringe rectangles we found
437:
438: for (i = 0; i < culRcl; i++)
439: {
440: bOpaqueRect(ppdev, &(arclTmp[i]), prclClip, pboOpaque);
441: }
442:
443: // Set the mix mode for opaque text.
444:
445: mix = (mix & 0x0F) | (R2_COPYPEN << 8);
446: b = bSetS3TextColorAndMix(ppdev, mix, pboFore, pboOpaque);
447: if (b == FALSE)
448: return (b);
449:
450: }
451: else
452: {
453: // Take care of any opaque rectangles.
454:
455: if (prclOpaque != NULL)
456: {
457: bOpaqueRect(ppdev, prclOpaque, prclClip, pboOpaque);
458: }
459:
460: jBackgroundRop = R2_NOP;
461:
462: // Take care of the glyph attributes, color and mix.
463:
464: mix = (mix & 0x0F) | (jBackgroundRop << 8);
465: b = bSetS3TextColorAndMix(ppdev, mix, pboFore, pboOpaque);
466: if (b == FALSE)
467: return (b);
468: }
469:
470: // Test for a trivial accept of the string rect.
471:
472: if (bTrivialAcceptTest(&(pstro->rclBkGround), prclClip))
473: fl |= TRIVIAL_ACCEPT;
474:
475: // Test and setup for a mono-spaced font.
476:
477: if ((ulCharInc = pstro->ulCharInc) != 0)
478: fl |= MONO_SPACED_FONT;
479:
480: // Set the S3 command.
481:
482: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE |
483: MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM;
484:
485: // This does not change in the inner loop so it is now out of it.
486:
487: FIFOWAIT(FIFO_1_EMPTY);
488: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY));
489:
490: // Get the Glyph Handles.
491:
492: if ((pstro->pgp) == NULL)
493: STROBJ_vEnumStart(pstro);
494:
495: do
496: {
497: if (pstro->pgp == NULL)
498: {
499: bMoreGlyphs = STROBJ_bEnum(pstro, &cGlyphs, &pgp);
500:
501: }
502: else
503: {
504: pgp = pstro->pgp;
505: cGlyphs = pstro->cGlyphs;
506: bMoreGlyphs = FALSE;
507: }
508:
509: // For mono space fonts this is non-zero.
510:
511: if (fl & MONO_SPACED_FONT)
512: {
513: xMonoPosition = pgp[0].ptl.x;
514: yMonoStart = pgp[0].ptl.y;
515: }
516:
517: for (iGlyph = 0; iGlyph < cGlyphs; iGlyph++)
518: {
519: // Get the Glyph Handle.
520: // If there was a hash table hit for the glygph
521: // then were "golden", if not then we have to search
522: // the collision list.
523:
524: ihGlyph = pgp[iGlyph].hg & pCachedFont->cGlyphs;
525:
526: pcg = &(pCachedGlyphs[ihGlyph]);
527:
528: if ((hg = pgp[iGlyph].hg) != pcg->hg)
529: {
530: if (!(pcg->fl & VALID_GLYPH))
531: {
532: // Allocate a place in the cache.
533:
534: pgb = pgp[iGlyph].pgdf->pgb;
535: b = bAllocateGlyph(ppdev, hg, pgb, pcg);
536: if (b == FALSE)
537: {
538: vBlowCache(ppdev);
539: return (FALSE);
540: }
541:
542: b = bSetS3TextColorAndMix(ppdev, mix, pboFore, pboOpaque);
543: if (b == FALSE)
544: return (FALSE);
545:
546: FIFOWAIT(FIFO_1_EMPTY);
547: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY));
548:
549: }
550: else
551: {
552: // Search the collision list.
553:
554: DISPDBG((1, "S3.DLL!bHandleCachedFonts - searching collision list\n"));
555:
556: bFound = FALSE;
557: while (pcg->pcgCollisionLink != END_COLLISIONS)
558: {
559: pcg = pcg->pcgCollisionLink;
560:
561: if (pcg->hg == pgp[iGlyph].hg)
562: {
563: bFound = TRUE;
564: break;
565: }
566: }
567:
568: if (!bFound)
569: {
570: // Allocate a new font glyph node.
571:
572: pcgNew = (PCACHEDGLYPH) LocalAlloc(LPTR, sizeof(CACHEDGLYPH));
573: if (pcgNew == NULL)
574: {
575: DISPDBG((1, "S3.DLL!bHandleCachedFont - Local Alloc (pcgNew) failed\n"));
576: return (FALSE);
577: }
578:
579: // Connect the end of the collision list to the new
580: // glyph node.
581:
582: pcg->pcgCollisionLink = pcgNew;
583:
584: // Set up the pointer to the node where going to init.
585:
586: pcg = pcgNew;
587:
588: pgb = pgp[iGlyph].pgdf->pgb;
589: b = bAllocateGlyph(ppdev, hg, pgb, pcg);
590: if (b == FALSE)
591: {
592: vBlowCache(ppdev);
593: return (FALSE);
594: }
595:
596: b = bSetS3TextColorAndMix(ppdev, mix, pboFore, pboOpaque);
597: if (b == FALSE)
598: return (FALSE);
599:
600: FIFOWAIT(FIFO_1_EMPTY);
601: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY));
602:
603: }
604: }
605: }
606:
607: // Adjust the placement of the glyph.
608: // And if this is a mono-spaced font set the blt height & width.
609:
610: if (fl & MONO_SPACED_FONT)
611: {
612: ptl.x = xMonoPosition + pcg->ptlOrigin.x;
613: ptl.y = yMonoStart + pcg->ptlOrigin.y;
614: xMonoPosition += ulCharInc;
615:
616: if ((!(fl & MONO_SIZE_VALID) && (fl & TRIVIAL_ACCEPT)) ||
617: (!(fl & MONO_FIRST_TIME)))
618: {
619: fl |= MONO_SIZE_VALID;
620:
621: TFIFOWAIT(FIFO_2_EMPTY);
622: OUTPW(RECT_WIDTH, pcg->sizlBitmap.cx - 1);
623: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (pcg->sizlBitmap.cy - 1)));
624: }
625:
626: }
627: else
628: {
629: ptl.x = pgp[iGlyph].ptl.x + pcg->ptlOrigin.x;
630: ptl.y = pgp[iGlyph].ptl.y + pcg->ptlOrigin.y;
631: }
632:
633: if (fl & TRIVIAL_ACCEPT)
634: {
635: // Blit the glyph
636:
637: if (!(fl & MONO_SPACED_FONT))
638: {
639: TFIFOWAIT(FIFO_2_EMPTY);
640: OUTPW(RECT_WIDTH, pcg->sizlBitmap.cx - 1);
641: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (pcg->sizlBitmap.cy - 1)));
642: }
643:
644: TFIFOWAIT(FIFO_6_EMPTY);
645: TEST_AND_SET_RD_MASK(LOWORD(pcg->xyzGlyph.z));
646:
647: OUTPW(CUR_X, pcg->xyzGlyph.x);
648: OUTPW(CUR_Y, pcg->xyzGlyph.y);
649: OUTPW(DEST_X, ptl.x);
650: OUTPW(DEST_Y, ptl.y);
651: OUTPW(CMD, Cmd);
652:
653: }
654: else
655: {
656: xyzGlyph = pcg->xyzGlyph;
657:
658: // Clip each character,
659:
660: rclGlyph.left = ptl.x;
661: rclGlyph.top = ptl.y;
662: rclGlyph.right = ptl.x + pcg->sizlBitmap.cx;
663: rclGlyph.bottom = ptl.y + pcg->sizlBitmap.cy;
664:
665: if (bIntersectTest(&rclGlyph, prclClip))
666: {
667: rclGlyph.left = max (rclGlyph.left, prclClip->left);
668: rclGlyph.top = max (rclGlyph.top, prclClip->top);
669: rclGlyph.right = min (rclGlyph.right, prclClip->right);
670: rclGlyph.bottom = min (rclGlyph.bottom, prclClip->bottom);
671:
672: cxGlyph = (rclGlyph.right - rclGlyph.left) - 1;
673: cyGlyph = (rclGlyph.bottom - rclGlyph.top) - 1;
674:
675: if (cxGlyph < 0 || cyGlyph < 0)
676: continue;
677:
678: ptlSrc.x = xyzGlyph.x + (rclGlyph.left - ptl.x);
679: ptlSrc.y = xyzGlyph.y + (rclGlyph.top - ptl.y);
680:
681: // Blit the glyph
682:
683: TFIFOWAIT(FIFO_8_EMPTY);
684: TEST_AND_SET_RD_MASK(LOWORD(pcg->xyzGlyph.z));
685:
686: OUTPW(RECT_WIDTH, cxGlyph);
687: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyGlyph));
688: OUTPW(CUR_X, ptlSrc.x);
689: OUTPW(CUR_Y, ptlSrc.y);
690: OUTPW(DEST_X, rclGlyph.left);
691: OUTPW(DEST_Y, rclGlyph.top);
692: OUTPW(CMD, Cmd);
693:
694: }
695: else
696: {
697: continue;
698: }
699: }
700: }
701:
702: } while(bMoreGlyphs);
703:
704: return (TRUE);
705:
706: }
707:
708:
709: /****************************************************************************
710: * bHandleNonCachedFonts
711: ***************************************************************************/
712: BOOL bHandleNonCachedFonts(
713: SURFOBJ *pso,
714: STROBJ *pstro,
715: FONTOBJ *pfo,
716: RECTL *prclClip,
717: RECTL *prclExtra,
718: RECTL *prclOpaque,
719: BRUSHOBJ *pboFore,
720: BRUSHOBJ *pboOpaque,
721: POINTL *pptlOrg,
722: MIX mix)
723: {
724: BOOL b,
725: bMoreGlyphs;
726: ULONG iGlyph,
727: cGlyphs;
728: GLYPHBITS *pgb;
729: POINTL ptl;
730: GLYPHPOS *pgp;
731: LONG cyGlyph,
732: cjGlyph,
733: GlyphBmPitchInBytes;
734: WORD S3Cmd;
735: INT i, culRcl;
736: ULONG flAccel;
737: RECTL arclTmp[4];
738:
739: ULONG ulCharInc;
740: ULONG yMonoStart, xMonoPosition;
741: PPDEV ppdev;
742: BYTE jBackgroundRop;
743: RECTL rclClip;
744:
745: ULONG fl = 0;
746:
747: DISPDBG((4, "S3.DLL!bHandleNonCachedFonts\n"));
748:
749: ppdev = (PPDEV) pso->dhpdev;
750:
751: // We need to reset the clipping so any opaque rectangles are
752: // rendered correctly.
753:
754: vResetS3Clipping(ppdev);
755:
756: // If this string has a Zero Bearing and the string object's
757: // opaque rectangle is the same size as the opaque rectangle then
758: // and opaque mode is requested, then lay down the glyphs in
759: // opaque mode.
760:
761: if (((flAccel = pstro->flAccel) & SO_ZERO_BEARINGS) &&
762: ((flAccel & (SO_HORIZONTAL | SO_VERTICAL | SO_REVERSED)) == SO_HORIZONTAL) &&
763: (flAccel & SO_CHAR_INC_EQUAL_BM_BASE) &&
764: (prclOpaque != NULL))
765: {
766: // If the Opaque rect and the string rect match then
767: // were done. If not then we have to fill in the strips
768: // (top, bottom, left, and right) around the text.
769:
770: culRcl = 0;
771:
772: // Top fragment
773:
774: if (pstro->rclBkGround.top > prclOpaque->top)
775: {
776: arclTmp[culRcl].top = prclOpaque->top;
777: arclTmp[culRcl].left = prclOpaque->left;
778: arclTmp[culRcl].right = prclOpaque->right;
779: arclTmp[culRcl++].bottom = pstro->rclBkGround.top;
780: }
781:
782: // Left fragment
783:
784: if (pstro->rclBkGround.left > prclOpaque->left)
785: {
786: arclTmp[culRcl].top = pstro->rclBkGround.top;
787: arclTmp[culRcl].left = prclOpaque->left;
788: arclTmp[culRcl].right = pstro->rclBkGround.left;
789: arclTmp[culRcl++].bottom = pstro->rclBkGround.bottom;
790: }
791:
792: // Right fragment
793:
794: if (pstro->rclBkGround.right < prclOpaque->right)
795: {
796: arclTmp[culRcl].top = pstro->rclBkGround.top;
797: arclTmp[culRcl].right = prclOpaque->right;
798: arclTmp[culRcl].left = pstro->rclBkGround.right;
799: arclTmp[culRcl++].bottom = pstro->rclBkGround.bottom;
800: }
801:
802: // Bottom fragment
803:
804: if (pstro->rclBkGround.bottom < prclOpaque->bottom)
805: {
806: arclTmp[culRcl].bottom = prclOpaque->bottom;
807: arclTmp[culRcl].left = prclOpaque->left;
808: arclTmp[culRcl].right = prclOpaque->right;
809: arclTmp[culRcl++].top = pstro->rclBkGround.bottom;
810: }
811:
812: // Fill any fringe rectangles we found
813:
814: for (i = 0; i < culRcl; i++)
815: {
816: bOpaqueRect(ppdev, &(arclTmp[i]), prclClip, pboOpaque);
817: }
818:
819: // Set the mix mode for opaque text.
820:
821: mix = (mix & 0x0F) | (R2_COPYPEN << 8);
822: b = bSetS3TextColorAndMix(ppdev, mix, pboFore, pboOpaque);
823: if (b == FALSE)
824: return (b);
825: }
826: else
827: {
828: // Take care of any opaque rectangles.
829:
830: if (prclOpaque != NULL)
831: {
832: bOpaqueRect(ppdev, prclOpaque, prclClip, pboOpaque);
833: }
834:
835: jBackgroundRop = R2_NOP;
836:
837: // Take care of the glyph attributes, color and mix.
838:
839: mix = (mix & 0x0F) | (jBackgroundRop << 8);
840: b = bSetS3TextColorAndMix(ppdev, mix, pboFore, pboOpaque);
841: if (b == FALSE)
842: return (b);
843: }
844:
845: rclClip = *prclClip;
846: rclClip.bottom;
847: rclClip.right;
848: vSetS3ClipRect(ppdev, &rclClip);
849:
850: // Test and setup for a mono-spaced font.
851:
852: if ((ulCharInc = pstro->ulCharInc) != 0)
853: fl |= MONO_SPACED_FONT;
854:
855: // Setup the Command Word for the S3.
856:
857: S3Cmd = RECTANGLE_FILL | BUS_SIZE_8 |
858: WAIT | DRAWING_DIR_TBLRXM | DRAW |
859: LAST_PIXEL_ON | MULTIPLE_PIXELS | WRITE;
860:
861: FIFOWAIT(FIFO_2_EMPTY)
862:
863: // Enable the write mask for all planes.
864: // and set the S3 for CPU Data.
865:
866: TEST_AND_SET_WRT_MASK(0xFF);
867: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA));
868:
869: // Get the Glyph Handles.
870:
871: if ((pstro->pgp) == NULL)
872: STROBJ_vEnumStart(pstro);
873:
874: do
875: {
876: if (pstro->pgp == NULL)
877: {
878: bMoreGlyphs = STROBJ_bEnum(pstro, &cGlyphs, &pgp);
879: }
880: else
881: {
882: pgp = pstro->pgp;
883: cGlyphs = pstro->cGlyphs;
884: bMoreGlyphs = FALSE;
885: }
886:
887: // For mono space fonts this is non-zero.
888:
889: if (fl & MONO_SPACED_FONT)
890: {
891: xMonoPosition = pgp[0].ptl.x;
892: yMonoStart = pgp[0].ptl.y;
893: }
894:
895: for (iGlyph = 0; iGlyph < cGlyphs; iGlyph++)
896: {
897: // Get a pointer to the GlyphBits.
898:
899: pgb = pgp[iGlyph].pgdf->pgb;
900:
901: // Adjust the placement of the glyph.
902: // If this is a mono-spaced font set the blt height & width only
903: // once for the string.
904:
905: if (fl & MONO_SPACED_FONT)
906: {
907: ptl.x = xMonoPosition + pgb->ptlOrigin.x;
908: ptl.y = yMonoStart + pgb->ptlOrigin.y;
909: xMonoPosition += ulCharInc;
910:
911: if (!(fl & MONO_SIZE_VALID))
912: {
913: fl |= MONO_SIZE_VALID;
914:
915: // Calculate the number of bytes in this glyph.
916:
917: cyGlyph = pgb->sizlBitmap.cy;
918:
919: GlyphBmPitchInBytes = CJ_SCAN(pgb->sizlBitmap.cx);
920: cjGlyph = GlyphBmPitchInBytes * cyGlyph;
921:
922: TFIFOWAIT(FIFO_2_EMPTY);
923: OUTPW(RECT_WIDTH, pgb->sizlBitmap.cx - 1);
924: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyGlyph - 1));
925: }
926:
927: FIFOWAIT(FIFO_3_EMPTY)
928: }
929: else
930: {
931: ptl.x = pgp[iGlyph].ptl.x + pgb->ptlOrigin.x;
932: ptl.y = pgp[iGlyph].ptl.y + pgb->ptlOrigin.y;
933:
934: // Calculate the number of bytes in this glyph.
935:
936: cyGlyph = pgb->sizlBitmap.cy;
937:
938: GlyphBmPitchInBytes = CJ_SCAN(pgb->sizlBitmap.cx);
939: cjGlyph = GlyphBmPitchInBytes * cyGlyph;
940:
941: FIFOWAIT(FIFO_5_EMPTY)
942:
943: // Set up for the image transfer.
944:
945: OUTPW(RECT_WIDTH, pgb->sizlBitmap.cx - 1);
946: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyGlyph - 1));
947: }
948:
949: // If a character is way off to the left then continue
950:
951: if ((ptl.x < 0) && ((ptl.x + pgb->sizlBitmap.cx) < 0))
952: continue;
953:
954: // Yes, believe it or not we have to check for chipping on the right also.
955:
956: if ((ptl.x > (LONG) ppdev->cxScreen) && ((ptl.x + pgb->sizlBitmap.cx) > (LONG) ppdev->cxScreen))
957: continue;
958:
959: // Set up for the image transfer.
960:
961: OUTPW(CUR_X, LOWORD(ptl.x));
962: OUTPW(CUR_Y, LOWORD(ptl.y));
963:
964: GPWAIT();
965:
966: OUTPW(CMD, S3Cmd);
967:
968: CHECK_DATA_READY;
969:
970: vDataPortOutB(ppdev, pgb->aj, cjGlyph);
971:
972: CHECK_DATA_COMPLETE;
973:
974: }
975:
976: } while(bMoreGlyphs);
977:
978: return (TRUE);
979:
980: }
981:
982:
983: /*****************************************************************************
984: * S3 Solid Opaque Rect.
985: *
986: * Returns TRUE if the Opaque Rect was handled.
987: ****************************************************************************/
988: BOOL bOpaqueRect(
989: PPDEV ppdev,
990: RECTL *prclOpaque,
991: RECTL *prclBounds,
992: BRUSHOBJ *pboOpaque)
993: {
994: INT width, height;
995: WORD S3Cmd;
996: ULONG iSolidColor;
997: RECTL rclClipped;
998: BOOL bClipRequired;
999:
1000: DISPDBG((4, "S3.DLL!bOpaqueRect - Entry\n"));
1001:
1002: rclClipped = *prclOpaque;
1003:
1004: // First handle the trivial rejection.
1005:
1006: bClipRequired = bIntersectTest(&rclClipped, prclBounds);
1007:
1008: // define the clipped target rectangle.
1009:
1010: if (bClipRequired)
1011: {
1012: rclClipped.left = max (rclClipped.left, prclBounds->left);
1013: rclClipped.top = max (rclClipped.top, prclBounds->top);
1014: rclClipped.right = min (rclClipped.right, prclBounds->right);
1015: rclClipped.bottom = min (rclClipped.bottom, prclBounds->bottom);
1016: }
1017: else
1018: return (TRUE);
1019:
1020: // Set the color
1021:
1022: iSolidColor = pboOpaque->iSolidColor;
1023: if (iSolidColor == -1)
1024: return(FALSE);
1025:
1026: width = (rclClipped.right - rclClipped.left) - 1;
1027: height = (rclClipped.bottom - rclClipped.top) - 1;
1028:
1029: if (width >= 0 && height >= 0)
1030: {
1031:
1032: FIFOWAIT(FIFO_8_EMPTY)
1033:
1034: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | OVERPAINT);
1035: TEST_AND_SET_FRGD_COLOR(LOWORD(iSolidColor));
1036: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
1037: OUTPW(CUR_X, LOWORD(rclClipped.left));
1038: OUTPW(CUR_Y, LOWORD(rclClipped.top));
1039: OUTPW(RECT_WIDTH, width);
1040: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | height));
1041:
1042: S3Cmd = RECTANGLE_FILL | DRAWING_DIR_TBLRXM | DRAW |
1043: DIR_TYPE_XY | LAST_PIXEL_ON |
1044: MULTIPLE_PIXELS | WRITE;
1045:
1046: OUTPW(CMD, S3Cmd);
1047: }
1048:
1049: return (TRUE);
1050: }
1051:
1052:
1053:
1054: /******************************************************************************
1055: * bSetS3TextColorAndMix - Setup the S3's Text Colors and mix modes
1056: *
1057: * Note: We will always set the mode to transparent. We will assume the
1058: * opaque rectangle will take care of any opaqueing we may need.
1059: *****************************************************************************/
1060: BOOL bSetS3TextColorAndMix(
1061: PPDEV ppdev,
1062: MIX mix,
1063: BRUSHOBJ *pboFore,
1064: BRUSHOBJ *pboOpaque)
1065: {
1066: ULONG ulForeSolidColor, ulBackSolidColor;
1067: BYTE jS3ForeMix, jS3BackMix;
1068:
1069: // Pickup all the glyph attributes.
1070:
1071: jS3ForeMix = Rop2ToS3Rop[(mix & 0xF) - R2_BLACK];
1072: ulForeSolidColor = pboFore->iSolidColor;
1073:
1074: jS3BackMix = Rop2ToS3Rop[((mix >> 8) & 0xF) - R2_BLACK];
1075: ulBackSolidColor = pboOpaque->iSolidColor;
1076:
1077: // For now let the engine handle the non-solid brush cases. !!!
1078: // We should use S3 when we get some more time !!!
1079:
1080: if (ulForeSolidColor == -1 || ulBackSolidColor == -1)
1081: return(FALSE);
1082:
1083: FIFOWAIT(FIFO_4_EMPTY)
1084:
1085: // Set the S3 Attributes.
1086:
1087: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | jS3ForeMix);
1088: TEST_AND_SET_FRGD_COLOR(LOWORD(ulForeSolidColor));
1089:
1090: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | jS3BackMix);
1091: TEST_AND_SET_BKGD_COLOR(LOWORD(ulBackSolidColor));
1092:
1093: return (TRUE);
1094:
1095: }
1096:
1097: /*****************************************************************************
1098: * pCacheFont - Make sure the glyphs we need in this font are cached.
1099: * Return a pointer to the array of glyph caches.
1100: *
1101: * if there is an error, return NULL.
1102: ****************************************************************************/
1103: PCACHEDGLYPH pCacheFont(
1104: PPDEV ppdev,
1105: STROBJ *pstro,
1106: FONTOBJ *pfo,
1107: PCACHEDFONT *ppCachedFont)
1108: {
1109: FONTINFO fi;
1110: PCACHEDFONT pCachedFont;
1111: ULONG cFntGlyphs;
1112: UINT nSize;
1113:
1114: BOOL bFoundBit, bEven;
1115: ULONG mask, mask1;
1116: INT i, j;
1117:
1118: DISPDBG((3, "S3.DLL!pCacheFont - Entry\n"));
1119:
1120: // Allocate a Font Cache node.
1121:
1122: pCachedFont = (PCACHEDFONT) LocalAlloc(LPTR, sizeof(CACHEDFONT));
1123: if (pCachedFont == NULL)
1124: {
1125: DISPDBG((1, "S3.DLL!pCacheFont - LocalAlloc of pCachedFont failed\n"));
1126: return(NULL);
1127: }
1128:
1129: // Add this font to the beginning of the font list.
1130:
1131: pCachedFont->pcfNext = pCachedFontsRoot;
1132: pCachedFontsRoot = pCachedFont;
1133:
1134: // Set the font ID for the font.
1135:
1136: pCachedFont->iUniq = pfo->iUniq;
1137:
1138: // Allocate the glyph cache.
1139:
1140: FONTOBJ_vGetInfo(pfo, sizeof(FONTINFO), &fi);
1141: cFntGlyphs = fi.cGlyphsSupported;
1142:
1143: // This is where we clamp the size of the Font structures we are allocating.
1144:
1145: if (cFntGlyphs > MAX_GLYPHS_TO_ALLOC)
1146: cFntGlyphs = MAX_GLYPHS_TO_ALLOC;
1147:
1148: // Round up to the next power of 2.
1149:
1150: bFoundBit = FALSE;
1151: mask = 0x80000000;
1152: for (i = 32; i != 0 && !bFoundBit; i--)
1153: {
1154: if (cFntGlyphs & mask)
1155: {
1156: bFoundBit = TRUE;
1157: mask1 = mask >> 1;
1158: bEven = TRUE;
1159: for (j = i - 1; j != 0; j--)
1160: {
1161: if (cFntGlyphs & mask1 )
1162: {
1163: bEven = FALSE;
1164: break;
1165: }
1166: mask1 >>= 1;
1167: }
1168: }
1169: else
1170: mask >>= 1;
1171: }
1172:
1173: if (bEven)
1174: cFntGlyphs = mask;
1175: else
1176: cFntGlyphs = mask << 1;
1177:
1178: // Get the font info.
1179:
1180: pCachedFont->cGlyphs = cFntGlyphs - 1;
1181:
1182: // Allocate memory for the CachedGlyphs of this font.
1183:
1184: nSize = cFntGlyphs * sizeof(CACHEDGLYPH);
1185:
1186: pCachedFont->pCachedGlyphs = (PCACHEDGLYPH) LocalAlloc(LPTR, nSize);
1187: if (pCachedFont->pCachedGlyphs == NULL)
1188: {
1189: DISPDBG((1, "S3.DLL!pCacheFont - LocalAlloc of pCachedGlyphs failed\n"));
1190: pCachedFont->cGlyphs = 0;
1191: return(NULL);
1192: }
1193:
1194: pCachedFont->pCachedGlyphs[0].hg = (HGLYPH)-1;
1195:
1196: // Return the pointer to the cached font. This is required
1197: // by the collision handling code.
1198:
1199: *ppCachedFont = pCachedFont;
1200:
1201: return(pCachedFont->pCachedGlyphs);
1202:
1203: }
1204:
1205:
1206: /*****************************************************************************
1207: * bAllocateGlyph - Allocate and initialize the cached glyph
1208: ****************************************************************************/
1209: BOOL bAllocateGlyph(
1210: PPDEV ppdev,
1211: HGLYPH hg,
1212: GLYPHBITS *pgb,
1213: PCACHEDGLYPH pcg)
1214: {
1215: BOOL b;
1216: ULONG cyGlyph, GlyphBmPitchInPels, GlyphBmPitchInBytes;
1217: XYZPOINTL xyzGlyph;
1218: WORD Cmd;
1219:
1220: DISPDBG((3, "S3.DLL!bAllocateGlyph - Entry\n"));
1221:
1222: cyGlyph = pgb->sizlBitmap.cy;
1223:
1224: GlyphBmPitchInBytes = CJ_SCAN(pgb->sizlBitmap.cx);
1225: GlyphBmPitchInPels = GlyphBmPitchInBytes * 8;
1226:
1227: // Allocate memory for the glyph data on the S3.
1228:
1229: b = bAllocGlyphMemory(ppdev, &(pgb->sizlBitmap), &xyzGlyph);
1230: if (b == FALSE)
1231: {
1232: DISPDBG((1, "S3.DLL!bAllocateGlyph - hCpAlloc failed\n"));
1233: return(FALSE);
1234: }
1235:
1236: // Initialize the Glyph Cache node.
1237:
1238: pcg->fl |= VALID_GLYPH;
1239: pcg->hg = hg;
1240: pcg->pcgCollisionLink = END_COLLISIONS;
1241: pcg->ptlOrigin = pgb->ptlOrigin;
1242: pcg->sizlBitmap = pgb->sizlBitmap;
1243: pcg->BmPitchInPels = GlyphBmPitchInPels;
1244: pcg->BmPitchInBytes = GlyphBmPitchInBytes;
1245: pcg->xyzGlyph = xyzGlyph;
1246:
1247: // Initialize the Glyph Cache data in S3 memory.
1248:
1249: Cmd = RECTANGLE_FILL | BUS_SIZE_8 | WAIT |
1250: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY |
1251: LAST_PIXEL_ON | MULTIPLE_PIXELS | WRITE;
1252:
1253: // Setup the S3 chip.
1254:
1255: FIFOWAIT(FIFO_5_EMPTY);
1256:
1257: TEST_AND_SET_FRGD_MIX(LOGICAL_1);
1258: TEST_AND_SET_BKGD_MIX(LOGICAL_0);
1259: TEST_AND_SET_WRT_MASK(LOWORD(xyzGlyph.z));
1260: OUTPW(CUR_X, xyzGlyph.x);
1261: OUTPW(CUR_Y, xyzGlyph.y);
1262:
1263: FIFOWAIT(FIFO_4_EMPTY);
1264:
1265: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA));
1266: OUTPW(RECT_WIDTH, GlyphBmPitchInPels - 1);
1267: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyGlyph - 1));
1268: GPWAIT();
1269: OUTPW(CMD, Cmd);
1270:
1271: CHECK_DATA_READY;
1272:
1273: // Now transfer the data.
1274:
1275: vDataPortOutB(ppdev, pgb->aj, GlyphBmPitchInBytes * cyGlyph);
1276:
1277: CHECK_DATA_COMPLETE;
1278:
1279: // Need to reset the write mask.
1280:
1281: FIFOWAIT(FIFO_1_EMPTY);
1282:
1283: TEST_AND_SET_WRT_MASK(0xFF);
1284:
1285: return (TRUE);
1286: }
1287:
1288:
1289: /****************************************************************************
1290: * vBlowCache - Blow Away the Cache
1291: ***************************************************************************/
1292: VOID vBlowCache(PPDEV ppdev)
1293: {
1294: PCACHEDFONT pcf;
1295: PCACHEDGLYPH pcg, pcgNext;
1296: INT nGlyphs, i;
1297:
1298: DISPDBG((2, "S3.DLL!vBlowCache - Entry\n"));
1299:
1300: // Traverse the CachedFonts list.
1301: // Free the collision nodes, and invalidate the cached glyphs
1302:
1303: for (pcf = pCachedFontsRoot; pcf != NULL; pcf = pcf->pcfNext)
1304: {
1305: // If there are any collision nodes for this glyph
1306: // free them.
1307:
1308: nGlyphs = pcf->cGlyphs+1;
1309:
1310: for (i = 0; i < nGlyphs; i++)
1311: {
1312: pcg = &(pcf->pCachedGlyphs[i]);
1313: pcg = pcg->pcgCollisionLink;
1314: for (; pcg != NULL; pcg = pcgNext)
1315: {
1316: pcgNext = pcg->pcgCollisionLink;
1317: LocalFree(pcg);
1318: }
1319: pcf->pCachedGlyphs[i].pcgCollisionLink = NULL;
1320:
1321: }
1322:
1323: // Invalidate all the glyphs in the glyph array.
1324:
1325: pcg = pcf->pCachedGlyphs;
1326: for (i = 0; i < nGlyphs; i++)
1327: {
1328: pcg[i].hg = (HGLYPH) -1;
1329: pcg[i].fl &= ~VALID_GLYPH;
1330: }
1331: }
1332:
1333: // Now ReInitialize the S3 Heap.
1334:
1335: memset((PVOID)ppdev->ajGlyphAllocBitVector,
1336: 0, CACHED_GLYPHS_ROWS * GLYPHS_PER_ROW);
1337:
1338: return;
1339: }
1340:
1341: /******************************************************************************
1342: * bAllocGlyphMemory -
1343: *
1344: * Allocate the some memory for the glyph.
1345: *
1346: *
1347: * return: TRUE - if memory was allocated.
1348: * FALSE - if there was no more memory.
1349: *
1350: *****************************************************************************/
1351: BOOL bAllocGlyphMemory(
1352: PPDEV ppdev,
1353: PSIZEL psizlGlyph,
1354: PXYZPOINTL pxyzGlyph)
1355: {
1356: BOOL bFound;
1357: INT iPlane, iRow, iGlyph;
1358: BYTE jPlaneBitVector;
1359:
1360:
1361: // Search the bit vector
1362:
1363: bFound = FALSE;
1364: for (iPlane = 0; iPlane < 8; iPlane++)
1365: {
1366: jPlaneBitVector = (BYTE) iPlaneBits[iPlane];
1367:
1368: for (iRow = 0; iRow < CACHED_GLYPHS_ROWS; iRow++)
1369: {
1370: for (iGlyph = 0; iGlyph < GLYPHS_PER_ROW; iGlyph++)
1371: {
1372: if (!(ppdev->ajGlyphAllocBitVector[iRow][iGlyph] & jPlaneBitVector))
1373: {
1374: bFound = TRUE;
1375: ppdev->ajGlyphAllocBitVector[iRow][iGlyph] |=
1376: jPlaneBitVector;
1377:
1378: pxyzGlyph->z = jPlaneBitVector;
1379: pxyzGlyph->x = iGlyph * GLYPH_CACHE_CX;
1380: pxyzGlyph->y = (iRow * GLYPH_CACHE_CY) + GLYPH_CACHE_Y;
1381:
1382: DISPDBG((5, "S3.DLL!bAllocGlyphMemory\n"));
1383: DISPDBG((5, "\t pxyzGlyph->z: %0x\n", pxyzGlyph->z));
1384: DISPDBG((5, "\t pxyzGlyph->x: %d\n", pxyzGlyph->x));
1385: DISPDBG((5, "\t pxyzGlyph->y: %d\n", pxyzGlyph->y));
1386:
1387: return (bFound);
1388: }
1389: }
1390: }
1391: }
1392:
1393: return (bFound);
1394: }
1395:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.