|
|
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.