|
|
1.1 root 1: /******************************Module*Header*******************************\
2: * Module Name: TextOut.c
3: *
4: * XGA Text accelerations
5: *
6: * Copyright (c) 1992 Microsoft Corporation
7: *
8: \**************************************************************************/
9:
10: #include "driver.h"
11:
12: // Part of the fix to limit the amount of resources allocated for fonts
13:
14: #define MAX_GLYPHS_TO_ALLOC 256
15:
16: #define CJ_SCAN(cx) (((cx) + 7) >> 3)
17:
18: BOOL bSetXgaTextColorAndMix(PPDEV ppdev, MIX mix, BRUSHOBJ *pboFore, BRUSHOBJ *pboOpaque);
19: BOOL bOpaqueRect(PPDEV pdev, CLIPOBJ *pco, RECTL *prclOpaque, BRUSHOBJ *pboOpaque);
20:
21: PCACHEDGLYPH pCacheFont(PPDEV ppdev, STROBJ *pstro, FONTOBJ *pfo);
22: BOOL bBlowCache(SURFOBJ *pso);
23:
24: BOOL bHandleCachedFonts(
25: SURFOBJ *pso,
26: STROBJ *pstro,
27: FONTOBJ *pfo,
28: CLIPOBJ *pco,
29: RECTL *prclExtra,
30: RECTL *prclOpaque,
31: BRUSHOBJ *pboFore,
32: BRUSHOBJ *pboOpaque,
33: POINTL *pptlOrg,
34: MIX mix
35: );
36:
37:
38: BOOL bHandleNonCachedFonts(
39: SURFOBJ *pso,
40: STROBJ *pstro,
41: FONTOBJ *pfo,
42: CLIPOBJ *pco,
43: RECTL *prclExtra,
44: RECTL *prclOpaque,
45: BRUSHOBJ *pboFore,
46: BRUSHOBJ *pboOpaque,
47: POINTL *pptlOrg,
48: MIX mix
49: );
50:
51: BYTE Rop2ToXgaRop[] = {
52: XGA_0, /* 0 */
53: XGA_S_OR_NOT_D, /* DPon */
54: XGA_NOT_S_AND_D, /* DPna */
55: XGA_NOT_S, /* Pn */
56: XGA_NOT_S_AND_NOT_D,/* PDna */
57: XGA_NOT_D, /* Dn */
58: XGA_S_XOR_D, /* DPx */
59: XGA_S_AND_NOT_D, /* DPan */
60: XGA_S_AND_D, /* DPa */
61: XGA_S_XOR_NOT_D, /* DPxn */
62: XGA_D, /* D */
63: XGA_NOT_S_OR_D, /* DPno */
64: XGA_S, /* P */
65: XGA_NOT_S_OR_NOT_D, /* PDno */
66: XGA_S_OR_D, /* DPo */
67: XGA_1 /* 1 */
68: };
69:
70: BYTE jNibbleBitSwap[] = {
71: 0x00, // 0 - 0000
72: 0x08, // 1 - 0001
73: 0x04, // 2 - 0010
74: 0x0C, // 3 - 0011
75: 0x02, // 4 - 0100
76: 0x0A, // 5 - 0101
77: 0x06, // 6 - 0110
78: 0x0E, // 7 - 0111
79: 0x01, // 8 - 1000
80: 0x09, // 9 - 1001
81: 0x05, // A - 1010
82: 0x0D, // B - 1011
83: 0x03, // C - 1100
84: 0x0B, // D - 1101
85: 0x07, // E - 1110
86: 0x0F // F - 1111
87: };
88:
89: #define BITSWAP(b) ((jNibbleBitSwap[b & 0xF] << 4) | (jNibbleBitSwap[(b >> 4) & 0xF]))
90:
91:
92: /****************************************************************************
93: * DrvTextOut
94: ***************************************************************************/
95: BOOL DrvTextOut(
96: SURFOBJ *pso,
97: STROBJ *pstro,
98: FONTOBJ *pfo,
99: CLIPOBJ *pco,
100: RECTL *prclExtra,
101: RECTL *prclOpaque,
102: BRUSHOBJ *pboFore,
103: BRUSHOBJ *pboOpaque,
104: POINTL *pptlOrg,
105: MIX mix)
106: {
107: BOOL b;
108:
109: DISPDBG((2, "XGA.DLL!DrvTextOut - Entry\n"));
110:
111: vWaitForCoProcessor((PPDEV)pso->dhpdev, 100);
112:
113: b = FALSE;
114:
115: // For now only handle fonts with the A & B spaceing components
116: // of 0. This limitation will be removed when I get some more time
117: // to work on this driver. !!!
118:
119: if (!(pstro->flAccel & SO_ZERO_BEARINGS))
120: {
121: if ((pso) && (pso->iType == STYPE_DEVICE))
122: pso = ((PPDEV)(pso->dhpdev))->pSurfObj;
123:
124: b = EngTextOut(pso, pstro, pfo, pco,
125: prclExtra, prclOpaque, pboFore,
126: pboOpaque, pptlOrg, mix);
127: return(b);
128: }
129:
130: if (((PPDEV)pso->dhpdev)->ulfAccelerations_debug & CACHED_FONTS)
131: {
132: b = bHandleCachedFonts(pso, pstro, pfo, pco,
133: prclExtra, prclOpaque, pboFore,
134: pboOpaque, pptlOrg, mix);
135:
136: if (b == FALSE)
137: {
138: b = bHandleNonCachedFonts(pso, pstro, pfo, pco,
139: prclExtra, prclOpaque, pboFore,
140: pboOpaque, pptlOrg, mix);
141: }
142: }
143:
144: if (b == FALSE)
145: {
146: if ((pso) && (pso->iType == STYPE_DEVICE))
147: pso = ((PPDEV)(pso->dhpdev))->pSurfObj;
148:
149: b = EngTextOut(pso, pstro, pfo, pco,
150: prclExtra, prclOpaque, pboFore,
151: pboOpaque, pptlOrg, mix);
152: }
153:
154: return (b);
155:
156:
157: }
158:
159: /****************************************************************************
160: * bHandleCachedFonts
161: ***************************************************************************/
162: BOOL bHandleCachedFonts(
163: SURFOBJ *pso,
164: STROBJ *pstro,
165: FONTOBJ *pfo,
166: CLIPOBJ *pco,
167: RECTL *prclExtra,
168: RECTL *prclOpaque,
169: BRUSHOBJ *pboFore,
170: BRUSHOBJ *pboOpaque,
171: POINTL *pptlOrg,
172: MIX mix)
173: {
174: BOOL b,
175: bMoreGlyphs,
176: bFound;
177:
178: ULONG iGlyph,
179: cGlyphs;
180:
181: POINTL ptl;
182:
183: GLYPHPOS *pgp;
184:
185: ULONG ulPhyXgaGlyphBuff;
186:
187: UINT ihGlyph,
188: cxGlyph,
189: cyGlyph,
190: GlyphBmPitchInBytes,
191: GlyphBmPitchInPels;
192:
193: ULONG XGAPixelOp,
194: ulXgaMask;
195:
196: INT yGlyphBias;
197:
198: PCACHEDGLYPH pCachedGlyphs,
199: pcg;
200:
201: FONTINFO fi;
202:
203: ULONG cFntGlyphs;
204:
205: PXGACPREGS pXgaCpRegs = ((PPDEV)pso->dhpdev)->pXgaCpRegs;
206:
207:
208: DISPDBG((3, "XGA.DLL!bHandleCachedFonts\n"));
209:
210: // Take care of any opaque rectangles.
211:
212: if (prclOpaque != NULL)
213: {
214: b = bOpaqueRect((PPDEV)pso->dhpdev, pco, prclOpaque, pboOpaque);
215: if (b == FALSE)
216: {
217: return (b);
218: }
219: }
220:
221: // Take care of the glyph attributes, color and mix.
222:
223: b = bSetXgaTextColorAndMix((PPDEV)pso->dhpdev, mix, pboFore, pboOpaque);
224: if (b == FALSE)
225: return (b);
226:
227: // Take care of setting the clip rectangle for the string.
228:
229: b = bSetXgaClipping((PPDEV)pso->dhpdev, pco, &ulXgaMask);
230: if (b == FALSE)
231: return (b);
232:
233: // Setup the Control Word for the XGA.
234:
235: XGAPixelOp = BS_BACK_COLOR | FS_FORE_COLOR |
236: STEP_PX_BLT |
237: SRC_PEL_MAP_A | DST_PEL_MAP_A |
238: PATT_PEL_MAP_B | MSK_DISABLE |
239: DM_ALL_PELS | OCT_DY ;
240:
241: XGAPixelOp |= ulXgaMask;
242:
243: //
244: // Get the glyphs into the cache. If the cache is full, then blow
245: // away the cache and start caching over. If there is a problem
246: // with blowing away the cache go back and try the A/B buffer
247: // approach. If the cache was blown away with no error start caching
248: // all over again. If there is another problem with caching then go
249: // back and try the A/B buffer approach, and finally, if the A/B
250: // buffer scheme fails go back to the engine.
251: //
252:
253: pCachedGlyphs = pCacheFont((PPDEV)pso->dhpdev, pstro, pfo);
254: if (pCachedGlyphs == NULL)
255: {
256: DISPDBG((1, "XGA.DLL!bHandleCachedFonts - pCacheFont failed once\n"));
257: b = bBlowCache(pso);
258: if (b == FALSE)
259: {
260: DISPDBG((1, "XGA.DLL!bHandleCachedFonts - bBlowCache failed\n"));
261: return (FALSE);
262: }
263:
264: pCachedGlyphs = pCacheFont((PPDEV)pso->dhpdev, pstro, pfo);
265: if (pCachedGlyphs == NULL)
266: {
267: DISPDBG((1, "XGA.DLL!bHandleCachedFonts - pCacheFont failed twice\n"));
268: return(FALSE);
269: }
270: }
271:
272: // Need to get the number of glyphs in the font.
273: // Get the font info.
274:
275: FONTOBJ_vGetInfo(pfo, sizeof(FONTINFO), &fi);
276: cFntGlyphs = fi.cGlyphsSupported;
277:
278: // This is where we clamp the size of the Font structures we are allocating.
279:
280: if (cFntGlyphs > MAX_GLYPHS_TO_ALLOC)
281: cFntGlyphs = MAX_GLYPHS_TO_ALLOC;
282:
283:
284: // Get the Glyph Handles.
285:
286: STROBJ_vEnumStart(pstro);
287:
288: do
289: {
290: bMoreGlyphs = STROBJ_bEnum(pstro, &cGlyphs, &pgp);
291:
292: // If this is a mono-spaced font we need to set the X
293: // for each glyph.
294:
295: if (pstro->ulCharInc != 0)
296: {
297: UINT ii;
298: LONG x,y;
299:
300: x = pgp[0].ptl.x;
301: y = pgp[0].ptl.y;
302: for (ii=1; ii < cGlyphs; ii++)
303: {
304: x += pstro->ulCharInc;
305: pgp[ii].ptl.x = x;
306: pgp[ii].ptl.y = y;
307: }
308: }
309:
310: for (iGlyph = 0; iGlyph < cGlyphs; iGlyph++)
311: {
312:
313:
314: // Get the Glyph Handle.
315: // If there was a hash table hit for the glygph
316: // then were "golden", if not then we have to search
317: // the collision list.
318:
319: ihGlyph = pgp[iGlyph].hg % cFntGlyphs;
320:
321: pcg = &(pCachedGlyphs[ihGlyph]);
322: if (!(pcg->fl & VALID_GLYPH) || (pcg->hg != pgp[iGlyph].hg))
323: {
324: DISPDBG((2, "XGA.DLL!bHandleCachedFonts - searching collision list\n"));
325:
326: bFound = FALSE;
327: pcg = &(pCachedGlyphs[ihGlyph]);
328: while (pcg->pcgCollisionLink != END_COLLISIONS)
329: {
330: pcg = pcg->pcgCollisionLink;
331: if (pcg->hg == pgp[iGlyph].hg)
332: {
333: bFound = TRUE;
334: break;
335: }
336: }
337:
338: // If we do not find the glyph in the cache, then something
339: // went wrong. We emit an error message, then fail, so the
340: // non-cached font code can render the glyph.
341:
342: if (bFound == FALSE)
343: {
344: DISPDBG((1, "XGA.DLL!bHandleCachedFonts - Cached Font not found\n"));
345: return (FALSE);
346:
347: }
348:
349: }
350:
351: ulPhyXgaGlyphBuff = pcg->ulCpPhysicalMemory;
352: cxGlyph = pcg->sizlBitmap.cx;
353: cyGlyph = pcg->sizlBitmap.cy;
354: GlyphBmPitchInPels = pcg->BmPitchInPels;
355: GlyphBmPitchInBytes = pcg->BmPitchInBytes;
356:
357: // Adjust the placement of the glyph.
358:
359: yGlyphBias = (cyGlyph + pcg->ptlOrigin.y) - 1;
360:
361: ptl.x = pgp[iGlyph].ptl.x + pcg->ptlOrigin.x;
362: ptl.y = pgp[iGlyph].ptl.y + yGlyphBias;
363:
364: // Note: We wait here so every thing that can be done
365: // to get ready for the next character is done
366: // before we have to wait for the CoProcessor.
367:
368: vWaitForCoProcessor((PPDEV)pso->dhpdev, 10);
369:
370: // Setup the pattern bitmap Pel interface registers.
371:
372: pXgaCpRegs->XGAPixelMapIndex = PEL_MAP_B;
373: pXgaCpRegs->XGAPixMapBasePtr = ulPhyXgaGlyphBuff;
374: pXgaCpRegs->XGAPixMapWidth = GlyphBmPitchInPels - 1;
375: pXgaCpRegs->XGAPixMapHeight = cyGlyph - 1;
376: pXgaCpRegs->XGAPixMapFormat = PATT_MAP_FORMAT;
377:
378: // Setup the Blit pattern and dest.
379: // Note: There is no source bitmap, Until we get the pattern
380: // brush.
381:
382: pXgaCpRegs->XGAOpDim1 = cxGlyph - 1;
383: pXgaCpRegs->XGAOpDim2 = cyGlyph - 1;
384:
385: pXgaCpRegs->XGAPatternMapX = 0;
386: pXgaCpRegs->XGAPatternMapY = cyGlyph - 1;
387:
388: pXgaCpRegs->XGADestMapX = LOWORD(ptl.x);
389: pXgaCpRegs->XGADestMapY = LOWORD(ptl.y);
390:
391: // Do the blit operation.
392:
393: pXgaCpRegs->XGAPixelOp = XGAPixelOp;
394:
395:
396: }
397:
398: } while(bMoreGlyphs);
399:
400: return (TRUE);
401:
402: }
403:
404: /****************************************************************************
405: * bHandleNonCachedFonts
406: ***************************************************************************/
407: BOOL bHandleNonCachedFonts(
408: SURFOBJ *pso,
409: STROBJ *pstro,
410: FONTOBJ *pfo,
411: CLIPOBJ *pco,
412: RECTL *prclExtra,
413: RECTL *prclOpaque,
414: BRUSHOBJ *pboFore,
415: BRUSHOBJ *pboOpaque,
416: POINTL *pptlOrg,
417: MIX mix)
418: {
419: BOOL b,
420: bMoreGlyphs;
421: ULONG iGlyph,
422: cGlyphs;
423: GLYPHBITS *pgb;
424: POINTL ptl;
425: GLYPHPOS *pgp;
426: PBYTE pLinXgaGlyphBuff,
427: pXgaLinGlyphBuffA,
428: pXgaLinGlyphBuffB;
429: ULONG ulPhyXgaGlyphBuff,
430: ulXgaPhyGlyphBuffA,
431: ulXgaPhyGlyphBuffB,
432: cjGlyphBuff;
433: UINT i,
434: cxGlyph,
435: cyGlyph,
436: nGlyph,
437: GlyphBmPitchInBytes,
438: GlyphBmPitchInPels;
439: ULONG XGAPixelOp,
440: ulXgaMask;
441: FONTINFO FontInfo;
442: PCPALLOCNODE pcpanA,
443: pcpanB;
444: INT yGlyphBias;
445:
446: PXGACPREGS pXgaCpRegs = ((PPDEV)pso->dhpdev)->pXgaCpRegs;
447:
448: DISPDBG((3, "XGA.DLL!bHandleNonCachedFonts\n"));
449:
450: // Take care of any opaque rectangles.
451:
452: if (prclOpaque != NULL)
453: {
454: b = bOpaqueRect((PPDEV)pso->dhpdev, pco, prclOpaque, pboOpaque);
455: if (b == FALSE)
456: {
457: return (b);
458: }
459: }
460:
461: // Take care of the glyph attributes, color and mix.
462:
463: b = bSetXgaTextColorAndMix((PPDEV)pso->dhpdev, mix, pboFore, pboOpaque);
464: if (b == FALSE)
465: return (b);
466:
467: // Take care of the clipping.
468:
469: b = bSetXgaClipping((PPDEV)pso->dhpdev, pco, &ulXgaMask);
470: if (b == FALSE)
471: return (b);
472:
473: // Setup the Control Word for the XGA.
474:
475: XGAPixelOp = BS_BACK_COLOR | FS_FORE_COLOR |
476: STEP_PX_BLT |
477: SRC_PEL_MAP_A | DST_PEL_MAP_A |
478: PATT_PEL_MAP_B | MSK_DISABLE |
479: DM_ALL_PELS | OCT_DY ;
480:
481: XGAPixelOp |= ulXgaMask;
482:
483: // Get the size of the largest glyph in the font.
484:
485: FONTOBJ_vGetInfo(pfo, sizeof(FONTINFO), &FontInfo);
486:
487: cjGlyphBuff = FontInfo.cjMaxGlyph1;
488:
489: // Get the Glyph Data.
490:
491: STROBJ_vEnumStart(pstro);
492:
493: // Get two buffers in XGA off screen memory.
494:
495: pcpanA = (PCPALLOCNODE) hCpAlloc((PPDEV)pso->dhpdev, cjGlyphBuff, XGA_LOCK_MEM);
496: pXgaLinGlyphBuffA = (PBYTE) pcpanA->pCpLinearMemory;
497: ulXgaPhyGlyphBuffA = pcpanA->ulCpPhysicalMemory;
498:
499: pcpanB = (PCPALLOCNODE) hCpAlloc((PPDEV)pso->dhpdev, cjGlyphBuff, XGA_LOCK_MEM);
500: pXgaLinGlyphBuffB = (PBYTE) pcpanB->pCpLinearMemory;
501: ulXgaPhyGlyphBuffB = pcpanB->ulCpPhysicalMemory;
502:
503: do
504: {
505: bMoreGlyphs = STROBJ_bEnum(pstro, &cGlyphs, &pgp);
506:
507: // If this is a mono-spaced font we need to set the X
508: // for each glyph.
509:
510: if (pstro->ulCharInc != 0)
511: {
512: UINT ii;
513: LONG x,y;
514:
515: x = pgp[0].ptl.x;
516: y = pgp[0].ptl.y;
517: for (ii=1; ii < cGlyphs; ii++)
518: {
519: x += pstro->ulCharInc;
520: pgp[ii].ptl.x = x;
521: pgp[ii].ptl.y = y;
522: }
523: }
524:
525: for (iGlyph = 0; iGlyph < cGlyphs; iGlyph++)
526: {
527:
528: // Get a pointer to the GlyphBits.
529:
530: pgb = pgp[iGlyph].pgdf->pgb;
531:
532: // Get the linear address for the XGA Glyph Buffer.
533:
534: if (iGlyph & 0x1)
535: {
536: pLinXgaGlyphBuff = pXgaLinGlyphBuffA;
537: ulPhyXgaGlyphBuff = ulXgaPhyGlyphBuffA;
538: }
539: else
540: {
541: pLinXgaGlyphBuff = pXgaLinGlyphBuffB;
542: ulPhyXgaGlyphBuff = ulXgaPhyGlyphBuffB;
543: }
544:
545: // Copy over the bits.
546:
547: cxGlyph = pgb->sizlBitmap.cx;
548: cyGlyph = pgb->sizlBitmap.cy;
549:
550: GlyphBmPitchInBytes = CJ_SCAN(cxGlyph);
551: GlyphBmPitchInPels = GlyphBmPitchInBytes * 8;
552:
553: nGlyph = GlyphBmPitchInBytes * cyGlyph;
554:
555: // Need to swap the bits with in the byte.
556: // I think there is an easier way.
557:
558: for (i = 0; i < nGlyph; i++)
559: {
560: pLinXgaGlyphBuff[i] = BITSWAP(pgb->aj[i]);
561: }
562:
563: // Adjust the placement of the glyph.
564:
565: yGlyphBias = (cyGlyph + pgb->ptlOrigin.y) - 1;
566:
567: ptl.x = pgp[iGlyph].ptl.x;
568: ptl.y = pgp[iGlyph].ptl.y + yGlyphBias;
569:
570: // Note: We wait here so every thing that can be done
571: // to get ready for the next character is done
572: // before we have to wait for the CoProcessor.
573:
574: vWaitForCoProcessor((PPDEV)pso->dhpdev, 10);
575:
576: // Setup the pattern bitmap Pel interface registers.
577:
578: pXgaCpRegs->XGAPixelMapIndex = PEL_MAP_B;
579: pXgaCpRegs->XGAPixMapBasePtr = ulPhyXgaGlyphBuff;
580: pXgaCpRegs->XGAPixMapWidth = GlyphBmPitchInPels - 1;
581: pXgaCpRegs->XGAPixMapHeight = cyGlyph - 1;
582: pXgaCpRegs->XGAPixMapFormat = PATT_MAP_FORMAT;
583:
584: // Setup the Blit pattern and dest.
585: // Note: There is no source bitmap, Until we get the pattern
586: // brush.
587:
588: pXgaCpRegs->XGAOpDim1 = cxGlyph - 1;
589: pXgaCpRegs->XGAOpDim2 = cyGlyph - 1;
590:
591: pXgaCpRegs->XGAPatternMapX = 0;
592: pXgaCpRegs->XGAPatternMapY = cyGlyph - 1;
593:
594: pXgaCpRegs->XGADestMapX = LOWORD(ptl.x);
595: pXgaCpRegs->XGADestMapY = LOWORD(ptl.y);
596:
597: // Do the blit operation.
598:
599: pXgaCpRegs->XGAPixelOp = XGAPixelOp;
600:
601:
602: }
603:
604:
605: } while(bMoreGlyphs);
606:
607: hCpFree((PPDEV)(pso->dhpdev), (HANDLE) pcpanA);
608: hCpFree((PPDEV)(pso->dhpdev), (HANDLE) pcpanB);
609:
610: return (TRUE);
611:
612: }
613:
614:
615: /*****************************************************************************
616: * XGA Solid Opaque Rect.
617: *
618: * Returns TRUE if the Opaque Rect was handled.
619: ****************************************************************************/
620: BOOL bOpaqueRect(PPDEV ppdev, CLIPOBJ *pco, RECTL *prclOpaque, BRUSHOBJ *pboOpaque)
621:
622: {
623: BOOL b;
624: INT width,
625: height;
626:
627: ULONG XGAPixelOp,
628: ulXgaMask,
629: iSolidColor;
630:
631: PXGACPREGS pXgaCpRegs = ppdev->pXgaCpRegs;
632:
633:
634: DISPDBG((3, "XGA.DLL!bOpaqueRect - Entry\n"));
635:
636: b = bSetXgaClipping(ppdev, pco, &ulXgaMask);
637: if (b == FALSE)
638: return (b);
639:
640:
641: iSolidColor = pboOpaque->iSolidColor;
642: if (iSolidColor == -1)
643: return(FALSE);
644:
645: // Setup the BitBlt parameters.
646:
647: width = (prclOpaque->right - prclOpaque->left) - 1;
648: height = (prclOpaque->bottom - prclOpaque->top) - 1;
649:
650: pXgaCpRegs->XGAOpDim1 = width;
651: pXgaCpRegs->XGAOpDim2 = height;
652:
653: pXgaCpRegs->XGADestMapX = (USHORT) prclOpaque->left;
654: pXgaCpRegs->XGADestMapY = (USHORT) prclOpaque->top;
655:
656: pXgaCpRegs->XGAForeGrMix = XGA_S;
657: pXgaCpRegs->XGABackGrMix = XGA_S;
658:
659: pXgaCpRegs->XGAForeGrColorReg = iSolidColor;
660: pXgaCpRegs->XGABackGrColorReg = iSolidColor;
661:
662: // Now build the Pel Operation Register Op Code;
663:
664: XGAPixelOp = BS_BACK_COLOR | FS_FORE_COLOR |
665: STEP_PX_BLT |
666: SRC_PEL_MAP_A | DST_PEL_MAP_A |
667: PATT_FOREGROUND;
668:
669: XGAPixelOp |= ulXgaMask;
670:
671: pXgaCpRegs->XGAPixelOp = XGAPixelOp;
672:
673: vWaitForCoProcessor(ppdev, 10);
674:
675: return (TRUE);
676:
677:
678: }
679:
680:
681:
682: /******************************************************************************
683: * bSetXgaTextColorAndMix - Setup the XGA's Text Colors and mix modes
684: *****************************************************************************/
685: BOOL bSetXgaTextColorAndMix(PPDEV ppdev, MIX mix, BRUSHOBJ *pboFore, BRUSHOBJ *pboOpaque)
686: {
687: ULONG ulForeSolidColor;
688: BYTE jXgaForeMix;
689:
690: PXGACPREGS pXgaCpRegs = ppdev->pXgaCpRegs;
691:
692: // Pickup all the glyph attributes.
693:
694: jXgaForeMix = Rop2ToXgaRop[(mix & 0xF) - R2_BLACK];
695:
696: ulForeSolidColor = pboFore->iSolidColor;
697:
698: // Let the engine handle the non-solid brush cases.
699:
700: if (ulForeSolidColor == -1)
701: return(FALSE);
702:
703: // Set the XGA Attributes.
704:
705: pXgaCpRegs->XGAForeGrMix = jXgaForeMix;
706: pXgaCpRegs->XGABackGrMix = XGA_D;
707:
708: pXgaCpRegs->XGAForeGrColorReg = ulForeSolidColor;
709: }
710:
711:
712:
713:
714:
715: /*****************************************************************************
716: * pCacheFont - Make sure the glyphs we need in this font are cached.
717: * Return a pointer to the array of glyph caches.
718: *
719: * if there is an error, return NULL.
720: ****************************************************************************/
721: PCACHEDGLYPH pCacheFont(PPDEV ppdev, STROBJ *pstro, FONTOBJ *pfo)
722: {
723: ULONG iUniq;
724:
725: FONTINFO fi;
726:
727: PCACHEDFONT pcf,
728: pCachedFont;
729:
730: ULONG i,
731: iGlyph,
732: cFntGlyphs,
733: cStrGlyphs,
734: nGlyph,
735: iGlyphCache;
736:
737: UINT nSize;
738:
739: GLYPHPOS *pgp;
740:
741: GLYPHBITS *pgb;
742:
743: PCACHEDGLYPH pCachedGlyphs,
744: pcgNew,
745: pcg;
746:
747: ULONG cxGlyph,
748: cyGlyph,
749: GlyphBmPitchInPels,
750: GlyphBmPitchInBytes;
751:
752: PBYTE pLinXgaGlyphBuff;
753:
754: PCPALLOCNODE pcpan;
755:
756: HGLYPH hg;
757:
758: BOOL bFound;
759:
760: // Are we already doing any caching for this font?
761:
762: iUniq = pfo->iUniq;
763:
764: if (ppdev->pCachedFontsRoot == NULL)
765: {
766: // This is the first font.
767: // Allocate a node for it.
768:
769: ppdev->pCachedFontsRoot = (PCACHEDFONT) LocalAlloc(LPTR, sizeof(CACHEDFONT));
770: if (ppdev->pCachedFontsRoot == NULL)
771: {
772: DISPDBG((1, "XGA.DLL!pCacheFont - LocalAlloc of pCachedFontsRoot failed\n"));
773: return(NULL);
774: }
775:
776: pCachedFont = ppdev->pCachedFontsRoot;
777: pCachedFont->iUniq = iUniq;
778:
779: }
780: else
781: {
782: // Search for the font in the font list
783:
784: for (pcf = ppdev->pCachedFontsRoot; pcf != NULL; pcf = pcf->pcfNext)
785: {
786: if (pcf->iUniq == iUniq)
787: break;
788: }
789:
790: if (pcf != NULL)
791: {
792: pCachedFont = pcf;
793: }
794: else
795: {
796: // Allocate a Font Cache node.
797:
798: pCachedFont = (PCACHEDFONT) LocalAlloc(LPTR, sizeof(CACHEDFONT));
799: if (pCachedFont == NULL)
800: {
801: DISPDBG((1, "XGA.DLL!pCacheFont - LocalAlloc of pCachedFont failed\n"));
802: return(NULL);
803: }
804:
805: // Add this font to the beginning of the font list.
806:
807: pCachedFont->pcfNext = ppdev->pCachedFontsRoot;
808: ppdev->pCachedFontsRoot = pCachedFont;
809:
810: // Set the font ID for the font.
811:
812: pCachedFont->iUniq = iUniq;
813: }
814: }
815:
816: // If this font is new to the font cache, allocate the glyph cache.
817:
818: FONTOBJ_vGetInfo(pfo, sizeof(FONTINFO), &fi);
819: cFntGlyphs = fi.cGlyphsSupported;
820:
821: // This is where we clamp the size of the Font structures we are allocating.
822:
823: if (cFntGlyphs > MAX_GLYPHS_TO_ALLOC)
824: cFntGlyphs = MAX_GLYPHS_TO_ALLOC;
825:
826: if (pCachedFont->pCachedGlyphs == NULL)
827: {
828: // Get the font info.
829:
830: pCachedFont->cGlyphs = cFntGlyphs;
831:
832: // Allocate memory for the CachedGlyphs of this font.
833:
834: nSize = cFntGlyphs * sizeof(CACHEDGLYPH);
835:
836: pCachedFont->pCachedGlyphs = (PCACHEDGLYPH) LocalAlloc(LPTR, nSize);
837: if (pCachedFont->pCachedGlyphs == NULL)
838: {
839: DISPDBG((1, "XGA.DLL!pCacheFont - LocalAlloc of pCachedGlyphs failed\n"));
840: pCachedFont->cGlyphs = 0;
841: return(NULL);
842: }
843:
844: }
845:
846: // Add the glyphs we're concerned about to the Glyph Cache.
847:
848: STROBJ_bEnum(pstro, &cStrGlyphs, &pgp);
849:
850: pCachedGlyphs = pCachedFont->pCachedGlyphs;
851: for (iGlyph = 0; iGlyph < cStrGlyphs; iGlyph++)
852: {
853: // Get the glyph handle, this will be used as the index
854: // into the glyph cache for this font.
855:
856: iGlyphCache = (UINT) pgp[iGlyph].hg % cFntGlyphs;
857:
858: // Check if the glyph is already in the cache.
859:
860: hg = pgp[iGlyph].hg;
861: pcg = &(pCachedGlyphs[iGlyphCache]);
862: if (!(pcg->fl & VALID_GLYPH) || (pcg->hg != hg))
863: {
864: // The glyph element in the main hash table for this font
865: // is not for this glyph.
866: // Search the collision list to see if we have allocated
867: // a glyph node yet.
868:
869: bFound = FALSE;
870: for (pcg = &(pCachedGlyphs[iGlyphCache]);
871: pcg->pcgCollisionLink != END_COLLISIONS;
872: pcg = pcg->pcgCollisionLink)
873: {
874: if (pcg->hg == hg)
875: {
876: bFound = TRUE;
877: break;
878: }
879: }
880:
881: // If we found an allocated glyph node for this font,
882: // then continue the testing for glyphs.
883:
884: if (bFound == TRUE)
885: continue;
886:
887: // A glyph node has not been allocated for this glyph yet
888: // in the collision list, so search to the end of the collision
889: // and allocate the node.
890:
891: if (!(pCachedGlyphs[iGlyphCache].fl & VALID_GLYPH))
892: {
893: // The glyph element has not been allocated yet, so
894: // we will allocate it now.
895:
896: pcg = &(pCachedGlyphs[iGlyphCache]);
897: }
898: else
899: {
900: DISPDBG((2, "XGA.DLL!pCacheFont - Collision in the glyph hash table\n"));
901:
902: // Search for the end of the collision list.
903:
904: pcg = &(pCachedGlyphs[iGlyphCache]);
905:
906: while (pcg->pcgCollisionLink != END_COLLISIONS)
907: {
908: pcg = pcg->pcgCollisionLink;
909: }
910:
911: // Allocate a new font glyph node.
912:
913: pcgNew = (PCACHEDGLYPH) LocalAlloc(LPTR, sizeof(CACHEDGLYPH));
914: if (pcgNew == NULL)
915: {
916: DISPDBG((1, "XGA.DLL!pCacheFont - Local Alloc (pcgNew) failed\n"));
917: return (NULL);
918: }
919:
920: // Connect the end of the collision list to the new
921: // glyph node.
922:
923: pcg->pcgCollisionLink = pcgNew;
924:
925: // Set up the pointer to the node where going to init.
926:
927: pcg = pcgNew;
928:
929: }
930:
931:
932:
933: // Pickup the pointer to the glyph bits.
934:
935: pgb = pgp[iGlyph].pgdf->pgb;
936:
937: cxGlyph = pgb->sizlBitmap.cx;
938: cyGlyph = pgb->sizlBitmap.cy;
939:
940: GlyphBmPitchInBytes = CJ_SCAN(cxGlyph);
941: GlyphBmPitchInPels = GlyphBmPitchInBytes * 8;
942:
943: nGlyph = GlyphBmPitchInBytes * cyGlyph;
944:
945: // Allocate memory for the glyph data on the XGA.
946:
947: pcpan = (PCPALLOCNODE) hCpAlloc(ppdev ,nGlyph, XGA_LOCK_MEM);
948: if (pcpan == NULL)
949: {
950: DISPDBG((1, "XGA.DLL!pCacheFont - hCpAlloc failed\n"));
951: return(NULL);
952: }
953:
954: // Initialize the Glyph Cache node.
955:
956: pcg->fl |= VALID_GLYPH;
957: pcg->hg = pgp[iGlyph].hg;
958: pcg->pcgCollisionLink = END_COLLISIONS;
959: pcg->ptlOrigin = pgb->ptlOrigin;
960: pcg->sizlBitmap = pgb->sizlBitmap;
961:
962: pcg->BmPitchInPels = GlyphBmPitchInPels;
963: pcg->BmPitchInBytes = GlyphBmPitchInBytes;
964:
965: pcg->pcpan = pcpan;
966: pcg->pCpLinearMemory = pcpan->pCpLinearMemory;
967: pcg->ulCpPhysicalMemory = pcpan->ulCpPhysicalMemory;
968:
969: // Initialize the Glyph Cache data in XGA memory.
970:
971: pLinXgaGlyphBuff = pcpan->pCpLinearMemory;
972:
973: // Need to swap the bits with in the byte.
974: // I think there is an easier way.
975:
976: for (i = 0; i < nGlyph; i++)
977: {
978: pLinXgaGlyphBuff[i] = BITSWAP(pgb->aj[i]);
979: }
980: }
981: }
982:
983: return(pCachedGlyphs);
984:
985: }
986:
987: /****************************************************************************
988: * bBlowCache - Blow Away the Cache
989: ***************************************************************************/
990: BOOL bBlowCache(SURFOBJ *pso)
991: {
992: BOOL b;
993: PCACHEDFONT pcf,
994: pcfLast;
995:
996: // Traverse the CachedFonts list.
997: // Free all the system memory used for each font.
998:
999: for (pcf = ((PPDEV)pso->dhpdev)->pCachedFontsRoot; pcf != NULL; pcf = pcf->pcfNext)
1000: {
1001: LocalFree(pcf->pCachedGlyphs);
1002: }
1003:
1004: // Now free all the memory for the font nodes.
1005:
1006: for (pcf = ((PPDEV)pso->dhpdev)->pCachedFontsRoot; pcf != NULL; )
1007: {
1008: pcfLast = pcf;
1009: pcf = pcf->pcfNext;
1010: LocalFree(pcfLast);
1011: }
1012:
1013: ((PPDEV)pso->dhpdev)->pCachedFontsRoot = NULL;
1014:
1015: // Now Free all the memory used to maintain the XGA heap.
1016:
1017: b = bCpMmDestroyHeap((PPDEV)pso->dhpdev);
1018: if (b == FALSE)
1019: {
1020: DISPDBG((1, "XGA.DLL!bBlowCache - bCpMmDestroyHeap failed\n"));
1021: return (b);
1022: }
1023:
1024: // Now ReInitialize the XGA Heap.
1025:
1026: b = bCpMmInitHeap( (PPDEV)pso->dhpdev );
1027: if (b == FALSE)
1028: {
1029: DISPDBG((1, "XGA.DLL!bBlowCache - bCpMmInitHeap failed\n"));
1030: }
1031:
1032: return (b);
1033:
1034: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.