Annotation of ntddk/src/video/displays/vga/bitblt.c, revision 1.1.1.1

1.1       root        1: /******************************Module*Header*******************************\
                      2: * Module Name: bitblt.c
                      3: *
                      4: * BitBlt
                      5: *
                      6: * Copyright (c) 1992 Microsoft Corporation
                      7: \**************************************************************************/
                      8: #include "driver.h"
                      9: #include "bitblt.h"
                     10: 
                     11: BOOL bConvertBrush(BRUSHINST *pbri);
                     12: VOID vCompiledBlt(PDEVSURF,LONG,LONG,PDEVSURF,LONG,LONG,
                     13:                   LONG,LONG,ULONG,BRUSHINST *,ULONG,ULONG,ULONG *,POINTL *);
                     14: 
                     15: /******************************Public*Data*********************************\
                     16: * ROP translation table
                     17: *
                     18: * Translates the usual ternary rop into A-vector notation.  Each bit in
                     19: * this new notation corresponds to a term in a polynomial translation of
                     20: * the rop.
                     21: *
                     22: * Rop(D,S,P) = a + a D + a S + a P + a  DS + a  DP + a  SP + a   DSP
                     23: *               0   d     s     p     ds      dp      sp      dsp
                     24: *
                     25: * History:
                     26: *  24-Aug-1990 -by- Donald Sidoroff [donalds]
                     27: * Added it as a global table for the VGA driver.
                     28: \**************************************************************************/
                     29: 
                     30: BYTE gajRop[] =
                     31: {
                     32:     0x00, 0xff, 0xb2, 0x4d, 0xd4, 0x2b, 0x66, 0x99,
                     33:     0x90, 0x6f, 0x22, 0xdd, 0x44, 0xbb, 0xf6, 0x09,
                     34:     0xe8, 0x17, 0x5a, 0xa5, 0x3c, 0xc3, 0x8e, 0x71,
                     35:     0x78, 0x87, 0xca, 0x35, 0xac, 0x53, 0x1e, 0xe1,
                     36:     0xa0, 0x5f, 0x12, 0xed, 0x74, 0x8b, 0xc6, 0x39,
                     37:     0x30, 0xcf, 0x82, 0x7d, 0xe4, 0x1b, 0x56, 0xa9,
                     38:     0x48, 0xb7, 0xfa, 0x05, 0x9c, 0x63, 0x2e, 0xd1,
                     39:     0xd8, 0x27, 0x6a, 0x95, 0x0c, 0xf3, 0xbe, 0x41,
                     40:     0xc0, 0x3f, 0x72, 0x8d, 0x14, 0xeb, 0xa6, 0x59,
                     41:     0x50, 0xaf, 0xe2, 0x1d, 0x84, 0x7b, 0x36, 0xc9,
                     42:     0x28, 0xd7, 0x9a, 0x65, 0xfc, 0x03, 0x4e, 0xb1,
                     43:     0xb8, 0x47, 0x0a, 0xf5, 0x6c, 0x93, 0xde, 0x21,
                     44:     0x60, 0x9f, 0xd2, 0x2d, 0xb4, 0x4b, 0x06, 0xf9,
                     45:     0xf0, 0x0f, 0x42, 0xbd, 0x24, 0xdb, 0x96, 0x69,
                     46:     0x88, 0x77, 0x3a, 0xc5, 0x5c, 0xa3, 0xee, 0x11,
                     47:     0x18, 0xe7, 0xaa, 0x55, 0xcc, 0x33, 0x7e, 0x81,
                     48:     0x80, 0x7f, 0x32, 0xcd, 0x54, 0xab, 0xe6, 0x19,
                     49:     0x10, 0xef, 0xa2, 0x5d, 0xc4, 0x3b, 0x76, 0x89,
                     50:     0x68, 0x97, 0xda, 0x25, 0xbc, 0x43, 0x0e, 0xf1,
                     51:     0xf8, 0x07, 0x4a, 0xb5, 0x2c, 0xd3, 0x9e, 0x61,
                     52:     0x20, 0xdf, 0x92, 0x6d, 0xf4, 0x0b, 0x46, 0xb9,
                     53:     0xb0, 0x4f, 0x02, 0xfd, 0x64, 0x9b, 0xd6, 0x29,
                     54:     0xc8, 0x37, 0x7a, 0x85, 0x1c, 0xe3, 0xae, 0x51,
                     55:     0x58, 0xa7, 0xea, 0x15, 0x8c, 0x73, 0x3e, 0xc1,
                     56:     0x40, 0xbf, 0xf2, 0x0d, 0x94, 0x6b, 0x26, 0xd9,
                     57:     0xd0, 0x2f, 0x62, 0x9d, 0x04, 0xfb, 0xb6, 0x49,
                     58:     0xa8, 0x57, 0x1a, 0xe5, 0x7c, 0x83, 0xce, 0x31,
                     59:     0x38, 0xc7, 0x8a, 0x75, 0xec, 0x13, 0x5e, 0xa1,
                     60:     0xe0, 0x1f, 0x52, 0xad, 0x34, 0xcb, 0x86, 0x79,
                     61:     0x70, 0x8f, 0xc2, 0x3d, 0xa4, 0x5b, 0x16, 0xe9,
                     62:     0x08, 0xf7, 0xba, 0x45, 0xdc, 0x23, 0x6e, 0x91,
                     63:     0x98, 0x67, 0x2a, 0xd5, 0x4c, 0xb3, 0xfe, 0x01
                     64: };
                     65: 
                     66: 
                     67: /******************************Public*Data*********************************\
                     68: * ROP to mix translation table
                     69: *
                     70: * Table to translate ternary raster ops to mixes (binary raster ops). Ternary
                     71: * raster ops that can't be translated to mixes are translated to 0 (0 is not
                     72: * a valid mix).
                     73: *
                     74: \**************************************************************************/
                     75: 
                     76: UCHAR jRop3ToMix[256] = {
                     77:     R2_BLACK, 0, 0, 0, 0, R2_NOTMERGEPEN, 0, 0,
                     78:     0, 0, R2_MASKNOTPEN, 0, 0, 0, 0, R2_NOTCOPYPEN,
                     79:     0, 0, 0, 0, 0, 0, 0, 0,
                     80:     0, 0, 0, 0, 0, 0, 0, 0,
                     81:     0, 0, 0, 0, 0, 0, 0, 0,
                     82:     0, 0, 0, 0, 0, 0, 0, 0,
                     83:     0, 0, 0, 0, 0, 0, 0, 0,
                     84:     0, 0, 0, 0, 0, 0, 0, 0,
                     85:     0, 0, 0, 0, 0, 0, 0, 0,
                     86:     0, 0, 0, 0, 0, 0, 0, 0,
                     87:     R2_MASKPENNOT, 0, 0, 0, 0, R2_NOT, 0, 0,
                     88:     0, 0, R2_XORPEN, 0, 0, 0, 0, R2_NOTMASKPEN,
                     89:     0, 0, 0, 0, 0, 0, 0, 0,
                     90:     0, 0, 0, 0, 0, 0, 0, 0,
                     91:     0, 0, 0, 0, 0, 0, 0, 0,
                     92:     0, 0, 0, 0, 0, 0, 0, 0,
                     93:     0, 0, 0, 0, 0, 0, 0, 0,
                     94:     0, 0, 0, 0, 0, 0, 0, 0,
                     95:     0, 0, 0, 0, 0, 0, 0, 0,
                     96:     0, 0, 0, 0, 0, 0, 0, 0,
                     97:     R2_MASKPEN, 0, 0, 0, 0, R2_NOTXORPEN, 0, 0,
                     98:     0, 0, R2_NOP, 0, 0, 0, 0, R2_MERGENOTPEN,
                     99:     0, 0, 0, 0, 0, 0, 0, 0,
                    100:     0, 0, 0, 0, 0, 0, 0, 0,
                    101:     0, 0, 0, 0, 0, 0, 0, 0,
                    102:     0, 0, 0, 0, 0, 0, 0, 0,
                    103:     0, 0, 0, 0, 0, 0, 0, 0,
                    104:     0, 0, 0, 0, 0, 0, 0, 0,
                    105:     0, 0, 0, 0, 0, 0, 0, 0,
                    106:     0, 0, 0, 0, 0, 0, 0, 0,
                    107:     R2_COPYPEN, 0, 0, 0, 0, R2_MERGEPENNOT, 0, 0,
                    108:     0, 0, R2_MERGEPEN, 0, 0, 0, 0, R2_WHITE
                    109: };
                    110: 
                    111: 
                    112: /******************************Public*Routine******************************\
                    113: * VOID DrvBitBlt(pso,pso,pso,pco,pxlo,prcl,pptl,pptl,pdbrush,pptl,rop4)
                    114: *
                    115: * Bitblt.
                    116: *
                    117: \**************************************************************************/
                    118: 
                    119: BOOL DrvBitBlt
                    120: (
                    121:     SURFOBJ    *psoTrg,             // Target surface
                    122:     SURFOBJ    *psoSrc,             // Source surface
                    123:     SURFOBJ    *psoMask,            // Mask
                    124:     CLIPOBJ    *pco,                // Clip through this
                    125:     XLATEOBJ   *pxlo,               // Color translation
                    126:     RECTL      *prclTrg,            // Target offset and extent
                    127:     POINTL     *pptlSrc,            // Source offset
                    128:     POINTL     *pptlMask,           // Mask offset
                    129:     BRUSHOBJ   *pbo,                // Pointer to brush object
                    130:     POINTL     *pptlBrush,          // Brush offset
                    131:     ROP4        rop4                // Raster operation
                    132: )
                    133: {
                    134:     BYTE        jForeRop;           // Foreground rop in A-vector notation
                    135:     BYTE        jBackRop;           // Background rop in A-vector notation
                    136:     BYTE        jORedRops;          // jForeRop | jBackRop
                    137:     BRUSHINST   bri;                // Instance of a brush
                    138:     BRUSHINST  *pbri;               // Pointer to a brush instance
                    139: 
                    140:     DEVSURF     dsurfSrc;           // For source if a DIB
                    141:     PDEVSURF    pdsurfTrg;          // Pointer for target
                    142:     PDEVSURF    pdsurfSrc;          // Pointer for source if present
                    143: 
                    144:     ULONG       iSolidColor;        // Solid color for solid brushes
                    145:     BOOL        bMore;              // Clip continuation flag
                    146:     ULONG       ircl;               // Clip enumeration rectangle index
                    147:     RECT_ENUM   bben;               // Clip enumerator
                    148:     ULONG      *pulXlate;           // Pointer to color xlate vector
                    149:     BYTE        jClipping;
                    150:     MIX         mix;                // Mix, when solid fill performed
                    151:     RECTL       rclTemp;
                    152:     ULONG       ulBkColor;
                    153:     ULONG       ulFgColor;
                    154:     PRECTL      prcl;
                    155:     POINTL      ptlTemp;
                    156:     UCHAR      *pucDIB4ToVGAConvTables;
                    157:     VOID        (*pfnPatBlt)(PDEVSURF,ULONG,PRECTL,MIX, BRUSHINST *,PPOINTL);
                    158: 
                    159: 
                    160: // Let the engine handle the stuff we can't yet do.
                    161:     if (psoSrc != (SURFOBJ *) NULL) {
                    162:         if ((psoSrc->iBitmapFormat != BMF_1BPP)   &&
                    163:             (psoSrc->iBitmapFormat != BMF_4BPP)   &&
                    164:             (psoSrc->iBitmapFormat != BMF_8BPP)) {
                    165: 
                    166:             return(EngBitBlt(psoTrg,psoSrc,psoMask,
                    167:                              pco,pxlo,prclTrg,pptlSrc,pptlMask,
                    168:                              pbo,pptlBrush,rop4));
                    169: 
                    170:         } else {
                    171:             // We only handle SRCCOPY screen-to-screen blts right now
                    172:             if ((psoSrc->dhsurf == psoTrg->dhsurf) && (rop4 != 0x0000CCCC)) {
                    173: 
                    174:                 return(EngBitBlt(psoTrg,psoSrc,psoMask,
                    175:                                   pco,pxlo,prclTrg,pptlSrc,pptlMask,
                    176:                                   pbo,pptlBrush,rop4));
                    177:             }
                    178:         }
                    179:     }
                    180: 
                    181:     if ((rop4 & 0x000000FF) != ((rop4 >> 8) & 0x000000FF)) {
                    182: 
                    183:         return(EngBitBlt(psoTrg,psoSrc,psoMask,
                    184:                           pco,pxlo,prclTrg,pptlSrc,pptlMask,
                    185:                           pbo,pptlBrush,rop4));
                    186:     }
                    187: 
                    188:     // Get the target surface's pointer. The target must always be a device
                    189:     // surface
                    190: 
                    191:     pdsurfTrg = (PDEVSURF) psoTrg->dhsurf;
                    192: 
                    193:     // Set up the clipping type
                    194:     if (pco == (CLIPOBJ *) NULL) {
                    195:         // No CLIPOBJ provided, so we don't have to worry about clipping
                    196:         jClipping = DC_TRIVIAL;
                    197:     } else {
                    198:         // Use the CLIPOBJ-provided clipping
                    199:         jClipping = pco->iDComplexity;
                    200:     }
                    201: 
                    202: 
                    203:     // Break the rops with the VGA as the destination surface into two classes,
                    204:     // those that can call special case static code (currently: vTrgBlt(solid
                    205:     // fills) and vAlignedSrcCopy (aligned srccopy blts)), and those that must
                    206:     // call the compiled blt code
                    207: 
                    208:     if (pdsurfTrg->iFormat == BMF_PHYSDEVICE) {
                    209: 
                    210:         // Masked cases must be handled differently
                    211: 
                    212:         if ((rop4 & 0xFF) == ((rop4 >> 8) & 0xFF)) {
                    213: 
                    214:             // Special case static code for no-mask cases
                    215: 
                    216:             // Calculate mix from ROP if possible (not possible if it's truly a
                    217:             // ternary rop or a real rop4, but we can treat all pure binary
                    218:             // rops as mixes rather than rop4s)
                    219:             mix = jRop3ToMix[rop4 & 0xFF];
                    220:             pbri = (BRUSHINST *)NULL;
                    221: 
                    222:             switch (mix) {
                    223:                 case R2_MASKNOTPEN:
                    224:                 case R2_NOTCOPYPEN:
                    225:                 case R2_XORPEN:
                    226:                 case R2_MASKPEN:
                    227:                 case R2_NOTXORPEN:
                    228:                 case R2_MERGENOTPEN:
                    229:                 case R2_COPYPEN:
                    230:                 case R2_MERGEPEN:
                    231:                 case R2_NOTMERGEPEN:
                    232:                 case R2_MASKPENNOT:
                    233:                 case R2_NOTMASKPEN:
                    234:                 case R2_MERGEPENNOT:
                    235:                     // vTrgBlt can only handle solid color fills
                    236:                     if (pbo->iSolidColor != 0xffffffff)
                    237:                     {
                    238:                         iSolidColor = pbo->iSolidColor;
                    239:                     }
                    240:                     else
                    241:                     {
                    242:                         // TrgBlt can only handle solid brushes, but let's
                    243:                         // see if we can use our special case pattern code.
                    244:                         //
                    245:                         pbri = (BRUSHINST *)pbo->pvRbrush;
                    246:                         if (pbri == (BRUSHINST *)NULL)
                    247:                         {
                    248:                             pbri = (BRUSHINST *)BRUSHOBJ_pvGetRbrush(pbo);
                    249: 
                    250:                             if (pbri == (BRUSHINST *)NULL)
                    251:                             {
                    252:                                 return(EngBitBlt(psoTrg, psoSrc, psoMask, pco,
                    253:                                         pxlo, prclTrg, pptlSrc, pptlMask, pbo,
                    254:                                         pptlBrush, rop4));
                    255:                             }
                    256:                         }
                    257: 
                    258:                         // We currently only do mono patterns.
                    259: 
                    260:                         pfnPatBlt = vMonoPatBlt;
                    261: 
                    262:                         if (pbri->usStyle != BRI_MONO_PATTERN)
                    263:                                pfnPatBlt = vClrPatBlt;
                    264: 
                    265:                         // We only support non-8 wide brushes with R2_COPYPEN
                    266: 
                    267:                         if ((mix != R2_COPYPEN) && (pbri->RealWidth != 8))
                    268:                             break;
                    269: 
                    270:                     }
                    271:                 // Rops that are implicit solid colors
                    272: 
                    273:                 case R2_NOT:
                    274:                 case R2_WHITE:
                    275:                 case R2_BLACK:
                    276:                     // We can do a special-case solid fill
                    277: 
                    278:                     switch(jClipping) {
                    279:                         case DC_TRIVIAL:
                    280: 
                    281:                             // Just fill the rectangle with a solid color
                    282:                             if (pbri == (BRUSHINST *)NULL)
                    283:                             {
                    284:                                 vTrgBlt(pdsurfTrg, 1, prclTrg, mix,
                    285:                                         iSolidColor);
                    286:                             }
                    287:                             else
                    288:                             {
                    289:                                 (*pfnPatBlt)(pdsurfTrg, 1, prclTrg, mix,
                    290:                                         pbri, pptlBrush);
                    291:                             }
                    292:                             break;
                    293: 
                    294:                         case DC_RECT:
                    295: 
                    296:                             // Clip the solid fill to the clip rectangle
                    297:                             if (!DrvIntersectRect(&rclTemp, prclTrg,
                    298:                                     &pco->rclBounds)) {
                    299:                                 return(TRUE);
                    300:                             }
                    301: 
                    302:                             // Fill the clipped rectangle
                    303:                             if (pbri == (BRUSHINST *)NULL)
                    304:                             {
                    305:                                 vTrgBlt(pdsurfTrg, 1, &rclTemp, mix,
                    306:                                         iSolidColor);
                    307:                             }
                    308:                             else
                    309:                             {
                    310:                                 (*pfnPatBlt)(pdsurfTrg, 1, &rclTemp, mix,
                    311:                                         pbri, pptlBrush);
                    312:                             }
                    313:                             break;
                    314: 
                    315:                         case DC_COMPLEX:
                    316: 
                    317:                             CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES,
                    318:                                                CD_ANY, ENUM_RECT_LIMIT);
                    319: 
                    320:                             do {
                    321:                                 bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben),
                    322:                                                       (PVOID) &bben);
                    323: 
                    324:                                 for (ircl = 0; ircl < bben.c; ircl++) {
                    325:                                     PRECTL prcl = &bben.arcl[ircl];
                    326: 
                    327:                                     DrvIntersectRect(prcl,prcl,prclTrg);
                    328: 
                    329:                                     if (pbri == (BRUSHINST *)NULL) {
                    330: 
                    331:                                         vTrgBlt(pdsurfTrg, 1, prcl, mix,
                    332:                                                 iSolidColor);
                    333:                                     } else  {
                    334: 
                    335:                                         (*pfnPatBlt)(pdsurfTrg, 1, prcl, mix,
                    336:                                             pbri, pptlBrush);
                    337:                                     }
                    338:                                 }
                    339:                             } while(bMore);
                    340:                     }
                    341: 
                    342:                 case R2_NOP:
                    343:                     return TRUE;
                    344: 
                    345:                 default:
                    346:                     break;
                    347:             }
                    348: 
                    349:             // Not a special-case solid fill; see if it's a screen-to-screen
                    350:             // SRCCOPY blt, another of our special cases
                    351: 
                    352:             if (rop4 == 0x0000CCCC) {
                    353: 
                    354:                 // SRCCOPY blt
                    355: 
                    356:                 if (psoSrc->dhsurf == psoTrg->dhsurf) {
                    357: 
                    358:                     INT iCopyDir;
                    359:                     PFN_ScreenToScreenBlt pfn_Blt;
                    360: 
                    361:                     // It's a screen-to-screen SRCCOPY; special-case it
                    362: 
                    363:                     // Determine the direction in which the copy must proceed
                    364:                     // Note that although we could detect cases where the source
                    365:                     // and dest don't overlap and handle them top to bottom, all
                    366:                     // copy directions are equally fast, so there's no reason to go
                    367:                     // top to bottom except possibly that it looks better. But it
                    368:                     // also takes time to detect non-overlap, so I'm not doing it
                    369: 
                    370:                     if (pptlSrc->y >= prclTrg->top) {
                    371:                         if (pptlSrc->x >= prclTrg->left) {
                    372:                             iCopyDir = CD_RIGHTDOWN;
                    373:                         } else {
                    374:                             iCopyDir = CD_LEFTDOWN;
                    375:                         }
                    376:                     } else {
                    377:                         if (pptlSrc->x >= prclTrg->left) {
                    378:                             iCopyDir = CD_RIGHTUP;
                    379:                         } else {
                    380:                             iCopyDir = CD_LEFTUP;
                    381:                         }
                    382:                     }
                    383: 
                    384:                     // These values are expected by vAlignedSrcCopy
                    385: 
                    386:                     switch(jClipping) {
                    387: 
                    388:                     case DC_TRIVIAL:
                    389:                         // Just copy the rectangle
                    390:                         if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) {
                    391:                             vAlignedSrcCopy(pdsurfTrg, prclTrg,
                    392:                                             pptlSrc, iCopyDir);
                    393:                         } else {
                    394:                             vNonAlignedSrcCopy(pdsurfTrg, prclTrg,
                    395:                                                pptlSrc, iCopyDir);
                    396:                         }
                    397:                         break;
                    398: 
                    399:                     case DC_RECT:
                    400:                         // Clip the solid fill to the clip rectangle
                    401:                         if (!DrvIntersectRect(&rclTemp, prclTrg, &pco->rclBounds))
                    402:                         {
                    403:                             return(TRUE);
                    404:                         }
                    405: 
                    406:                         // Adjust the source point for clipping too
                    407:                         ptlTemp.x = pptlSrc->x + rclTemp.left - prclTrg->left;
                    408:                         ptlTemp.y = pptlSrc->y + rclTemp.top - prclTrg->top;
                    409: 
                    410:                         // Copy the clipped rectangle
                    411:                         if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) {
                    412:                             vAlignedSrcCopy(pdsurfTrg, &rclTemp, &ptlTemp,
                    413:                                             iCopyDir);
                    414:                         } else {
                    415:                             vNonAlignedSrcCopy(pdsurfTrg, &rclTemp, &ptlTemp,
                    416:                                                iCopyDir);
                    417:                         }
                    418:                         break;
                    419: 
                    420:                     case DC_COMPLEX:
                    421: 
                    422:                         if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) {
                    423:                             pfn_Blt = vAlignedSrcCopy;
                    424:                         } else {
                    425:                             pfn_Blt = vNonAlignedSrcCopy;
                    426:                         }
                    427: 
                    428:                         CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES,
                    429:                                            iCopyDir, ENUM_RECT_LIMIT);
                    430: 
                    431:                         do {
                    432:                             bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben),
                    433:                                                   (PVOID) &bben);
                    434: 
                    435:                             for (ircl = 0; ircl < bben.c; ircl++) {
                    436:                                 PRECTL prcl = &bben.arcl[ircl];
                    437: 
                    438:                                 DrvIntersectRect(prcl,prcl,prclTrg);
                    439: 
                    440:                                 // Adjust the source point for clipping too
                    441:                                 ptlTemp.x = pptlSrc->x + prcl->left -
                    442:                                         prclTrg->left;
                    443:                                 ptlTemp.y = pptlSrc->y + prcl->top -
                    444:                                         prclTrg->top;
                    445:                                 pfn_Blt(pdsurfTrg, prcl,
                    446:                                         &ptlTemp, iCopyDir);
                    447:                             }
                    448:                         } while(bMore);
                    449:                         break;
                    450:                     }
                    451: 
                    452:                     return TRUE;
                    453: 
                    454:                 } else if ((psoSrc->iType == STYPE_BITMAP) &&
                    455:                          (psoSrc->iBitmapFormat == BMF_4BPP) &&
                    456:                          ((pxlo == NULL) || (pxlo->flXlate == XO_TRIVIAL))) {
                    457: 
                    458:                     // Special case DIB4 to VGA copy if no translation
                    459: 
                    460:                     pucDIB4ToVGAConvTables =
                    461:                             ((PDEVSURF) psoTrg->dhsurf)->ppdev->
                    462:                             pucDIB4ToVGAConvTables;
                    463: 
                    464:                     // Make just enough of a fake DEVSURF for the source so
                    465:                     // that the DIB to VGA code can work
                    466: 
                    467:                     dsurfSrc.lNextScan = psoSrc->lDelta;
                    468:                     dsurfSrc.pvBitmapStart = psoSrc->pvScan0;
                    469: 
                    470:                     // Clip as needed
                    471: 
                    472:                     if ((pco == NULL) || (pco->iDComplexity == DC_TRIVIAL)) {
                    473: 
                    474:                         // No clipping, just copy the DIB to the VGA
                    475: 
                    476:                         vDIB2VGA((PDEVSURF) psoTrg->dhsurf, &dsurfSrc,
                    477:                                 prclTrg, pptlSrc, pucDIB4ToVGAConvTables);
                    478: 
                    479:                     } else if (pco->iDComplexity == DC_RECT) {
                    480: 
                    481:                         // Clip the destination to the clip rectangle; we
                    482:                         // should never get a NULL result
                    483:                         if (DrvIntersectRect(&rclTemp, prclTrg, &pco->rclBounds)) {
                    484: 
                    485:                             // Adjust the source point for clipping too
                    486:                             ptlTemp.x = pptlSrc->x + rclTemp.left - prclTrg->left;
                    487:                             ptlTemp.y = pptlSrc->y + rclTemp.top - prclTrg->top;
                    488: 
                    489:                             // Blt the clipped rectangle
                    490:                             vDIB2VGA((PDEVSURF) psoTrg->dhsurf, &dsurfSrc,
                    491:                                     &rclTemp, &ptlTemp, pucDIB4ToVGAConvTables);
                    492:                         }
                    493:                         return(TRUE);
                    494: 
                    495:                     } else {    // DC_COMPLEX:
                    496: 
                    497:                         CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES,
                    498:                                            CD_ANY, ENUM_RECT_LIMIT);
                    499: 
                    500:                         do {
                    501:                             bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben),
                    502:                                                   (PVOID) &bben);
                    503:                             prcl = bben.arcl;
                    504:                             for (ircl = 0; ircl < bben.c; ircl++, prcl++) {
                    505: 
                    506:                                 // Clip the destination to the clip rectangle;
                    507:                                 // we should never get a NULL result
                    508: 
                    509:                                 DrvIntersectRect(prcl,prcl,prclTrg);
                    510: 
                    511:                                 // Adjust the source point for clipping too
                    512:                                 ptlTemp.x = pptlSrc->x + prcl->left -
                    513:                                         prclTrg->left;
                    514:                                 ptlTemp.y = pptlSrc->y + prcl->top -
                    515:                                         prclTrg->top;
                    516: 
                    517:                                 // Blt the clipped rectangle
                    518:                                 vDIB2VGA((PDEVSURF) psoTrg->dhsurf,
                    519:                                         &dsurfSrc, prcl, &ptlTemp,
                    520:                                         pucDIB4ToVGAConvTables);
                    521:                             }
                    522:                         } while(bMore);
                    523:                     }
                    524: 
                    525:                     return(TRUE);
                    526: 
                    527:                 }
                    528:             }
                    529:         }
                    530:     }
                    531: 
                    532: 
                    533: // Couldn't be special cased.  Set up to call the old kludged compiling code.
                    534: 
                    535: 
                    536:     {
                    537:         LONG    xSrc;
                    538:         LONG    ySrc;
                    539:         RECTL  *prcl;
                    540: 
                    541: 
                    542:         // Translate the rop from old notation into two A-vector rops
                    543: 
                    544:         jForeRop = gajRop[rop4 & 0xff];
                    545:         jBackRop = gajRop[(rop4 >> 8) & 0xff];
                    546:         jORedRops = jForeRop | jBackRop;
                    547: 
                    548: 
                    549:         // Get the source surface if a source is needed.  The source may be any of
                    550:         // 1) the screen, 2) a device managed bitmap, 3) an engine bitmap
                    551: 
                    552:         if (jORedRops & AVEC_NEED_SOURCE) {
                    553: 
                    554:             if (psoSrc->dhsurf == (DHSURF) 0) {
                    555:                 // Source is an engine bitmap
                    556: #ifdef FIREWALLS
                    557:                 dsurfSrc.ident = 0x46525354;         // "TSRF"
                    558: #endif
                    559:                 dsurfSrc.flSurf   = DS_DIB;          // Supporting a DIB
                    560:                 dsurfSrc.iFormat  = (BYTE)psoSrc->iBitmapFormat;
                    561:                 dsurfSrc.sizlSurf = psoSrc->sizlBitmap;
                    562:                 dsurfSrc.lNextScan = psoSrc->lDelta;
                    563:                 dsurfSrc.pvScan0   = psoSrc->pvScan0;
                    564:                 dsurfSrc.pvBitmapStart = psoSrc->pvScan0;
                    565:                 dsurfSrc.pvConv    = pdsurfTrg->pvConv;
                    566: 
                    567:                 pdsurfSrc = &dsurfSrc;      // Construct source into here
                    568: 
                    569:             } else {
                    570:                 // Source is a device format bitmap or the device itself
                    571:                 pdsurfSrc = (PDEVSURF) psoSrc->dhsurf;
                    572:             }
                    573:         } else {
                    574:             pdsurfSrc  = (PDEVSURF) NULL;       // Assume no source
                    575:         }
                    576: 
                    577: 
                    578:         // If a brush is required, do what is necessary to get it.  We might be
                    579:         // able to just use the solid color accelerator, we might have to force it
                    580:         // to be realized (which could fail).
                    581: 
                    582:         if (jORedRops & AVEC_NEED_PATTERN) {
                    583: 
                    584:             // See if there is a solid color accelerator for the brush.  If so
                    585:             // we can just pick it up and use it.
                    586: 
                    587:             if (pbo->iSolidColor != 0xffffffff) {
                    588:                 bri.usStyle = BRI_SOLID;
                    589:                 bri.fjAccel =
                    590:                         (BYTE)((pbo->iSolidColor & COLOR_BITS) | SOLID_BRUSH);
                    591:                 pbri = &bri;
                    592:             } else {
                    593:             // If there is no realization of the brush, we must force it
                    594: 
                    595:                 if (pbo->pvRbrush == (PVOID)NULL)
                    596:                 {
                    597:                     pbri = (BRUSHINST *)BRUSHOBJ_pvGetRbrush(pbo);
                    598: 
                    599:                     if (pbri == (BRUSHINST *)NULL)
                    600:                     {
                    601:                         return(EngBitBlt(psoTrg, psoSrc, psoMask, pco, pxlo,
                    602:                                 prclTrg, pptlSrc, pptlMask, pbo, pptlBrush,
                    603:                                 rop4));
                    604:                     }
                    605:                 }
                    606:                 else
                    607:                 {
                    608:                     pbri = (BRUSHINST *)pbo->pvRbrush;
                    609:                 }
                    610: 
                    611:                 if (!bConvertBrush(pbri)) {
                    612:                     return(EngBitBlt(psoTrg, psoSrc, psoMask, pco, pxlo,
                    613:                             prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, rop4));
                    614:                 }
                    615:             }
                    616:         }
                    617: 
                    618: 
                    619: 
                    620:         // Determine if color translation is required.  If so, then get the
                    621:         // color translation vector.  if no source is involved, then no
                    622:         // xlateobj will have been passed.
                    623: 
                    624:         if ((jORedRops & AVEC_NEED_SOURCE) &&
                    625:             (pxlo != NULL) &&
                    626:             (pxlo->flXlate & XO_TABLE))
                    627:         {
                    628:             pulXlate = pxlo->pulXlate;
                    629:             ulFgColor = pulXlate[0] << 24;  // Mono --> color translation
                    630:             ulBkColor = pulXlate[1] << 24;
                    631:         }
                    632:         else
                    633:         {
                    634:             pulXlate   = (PULONG) NULL;         // No xlate vector
                    635:         }
                    636: 
                    637: 
                    638:         // Note: blts where VGA memory is both the source and the destination
                    639:         // should never make it to this point; it's assumed that the VGA is the
                    640:         // destination and the destination only
                    641:         // BUGBUG this must be changed when we support DFBs, to make VGAs
                    642:         // possibly neither source nor destination, and (maybe?) source but DFB
                    643:         // dest
                    644: 
                    645:         // Perform blt with specified clipping.
                    646:         // BUGBUG only top->bottom blts are currently supported
                    647: 
                    648:         switch(jClipping) {
                    649: 
                    650:             RECTL   rclTemp;
                    651: 
                    652:             case DC_RECT:
                    653:                 if (!DrvIntersectRect(&rclTemp, prclTrg, &pco->rclBounds)) {
                    654:                     break;
                    655:                 }
                    656: 
                    657:                 // Adjust the source (if any) accordingly
                    658:                 if (jORedRops & AVEC_NEED_SOURCE) {
                    659:                     pptlSrc->x += rclTemp.left - prclTrg->left;
                    660:                     pptlSrc->y += rclTemp.top - prclTrg->top;
                    661:                 }
                    662: 
                    663:                 *prclTrg = rclTemp;
                    664: 
                    665:             case DC_TRIVIAL:
                    666: 
                    667:                 // Cycle through all banks that the blt dest spans
                    668: 
                    669:                 // If the proper bank for the top scan line of
                    670:                 // the blt dest isn't mapped in, map it in
                    671:                 if ((prclTrg->top < pdsurfTrg->rcl1WindowClip.top) ||
                    672:                        (prclTrg->top >= pdsurfTrg->rcl1WindowClip.bottom)) {
                    673: 
                    674:                     // Map in the bank containing the top line of the blt dest
                    675:                     pdsurfTrg->pfnBankControl(pdsurfTrg,
                    676:                                            prclTrg->top,
                    677:                                            JustifyTop);
                    678:                 }
                    679: 
                    680:                 // Now draw the part of the rect that's in each bank
                    681:                 for (;;) {
                    682: 
                    683:                     // Clip the blt dest to the bank
                    684:                     DrvIntersectRect(&rclTemp, prclTrg,
                    685:                             &pdsurfTrg->rcl1WindowClip);
                    686: 
                    687:                     // Adjust the source (if any) accordingly
                    688:                     if (jORedRops & AVEC_NEED_SOURCE) {
                    689:                         xSrc = pptlSrc->x + rclTemp.left - prclTrg->left;
                    690:                         ySrc = pptlSrc->y + rclTemp.top - prclTrg->top;
                    691:                     }
                    692: 
                    693:                     vCompiledBlt(pdsurfTrg,
                    694:                                  rclTemp.left,
                    695:                                  rclTemp.top,
                    696:                                  pdsurfSrc,
                    697:                                  xSrc,
                    698:                                  ySrc,
                    699:                                  rclTemp.right  - rclTemp.left,
                    700:                                  rclTemp.bottom - rclTemp.top,
                    701:                                  rop4,
                    702:                                  pbri,
                    703:                                  ulBkColor,
                    704:                                  ulFgColor,
                    705:                                  pulXlate,
                    706:                                  pptlBrush);
                    707: 
                    708:                     // Done if this bank contains the last line of the blt
                    709:                     if (prclTrg->bottom <=
                    710:                             pdsurfTrg->rcl1WindowClip.bottom) {
                    711:                         break;
                    712:                     }
                    713: 
                    714:                     // Map in the next bank
                    715:                     pdsurfTrg->pfnBankControl(pdsurfTrg,
                    716:                                               pdsurfTrg->rcl1WindowClip.bottom,
                    717:                                               JustifyTop);
                    718:                 }
                    719: 
                    720:                 break;
                    721: 
                    722: 
                    723:             case DC_COMPLEX:
                    724: 
                    725:                 CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
                    726:                 bMore = TRUE;
                    727: 
                    728:                 do {
                    729:                     if (bMore) {
                    730:                         // Enumerate more clip rects
                    731:                         bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben),
                    732:                                               (PVOID) &bben);
                    733:                     }
                    734: 
                    735:                     // Draw the portion of the blt dest that intersects each
                    736:                     // clip rect in turn
                    737:                     for (ircl = 0; ircl < bben.c; ircl++) {
                    738: 
                    739:                         prcl = &bben.arcl[ircl];
                    740: 
                    741:                         // Find the intersection of the target rect and the
                    742:                         // current clip rect, then draw all banks of the
                    743:                         // clipped target rect, if it's not NULL
                    744:                         DrvIntersectRect(prcl, prcl, prclTrg);
                    745: 
                    746:                         // Cycle through all banks that the blt dest spans
                    747: 
                    748:                         // If the proper bank for the top scan line of
                    749:                         // the blt dest isn't mapped in, map it in
                    750:                         if ((prcl->top <
                    751:                              pdsurfTrg->rcl1WindowClip.top) ||
                    752:                             (prcl->top >=
                    753:                              pdsurfTrg->rcl1WindowClip.bottom)) {
                    754: 
                    755:                             // Map in the bank containing the top line of
                    756:                             // the blt dest
                    757:                             pdsurfTrg->pfnBankControl(pdsurfTrg,
                    758:                                                       prcl->top,
                    759:                                                       JustifyTop);
                    760:                         }
                    761: 
                    762:                         // Now draw the part of the clipped rect that's in
                    763:                         // each bank
                    764:                         for (;;) {
                    765: 
                    766:                             RECTL   rclTemp;
                    767: 
                    768:                             // Clip the blt dest to the bank
                    769:                             DrvIntersectRect(&rclTemp, prcl,
                    770:                                              &pdsurfTrg->rcl1WindowClip);
                    771: 
                    772:                             // Adjust the source (if any) accordingly
                    773:                             if (jORedRops & AVEC_NEED_SOURCE) {
                    774:                                 xSrc = pptlSrc->x + rclTemp.left -
                    775:                                         prclTrg->left;
                    776:                                 ySrc = pptlSrc->y + rclTemp.top -
                    777:                                         prclTrg->top;
                    778:                             }
                    779: 
                    780:                             vCompiledBlt(pdsurfTrg,
                    781:                                          rclTemp.left,
                    782:                                          rclTemp.top,
                    783:                                          pdsurfSrc,
                    784:                                          xSrc,
                    785:                                          ySrc,
                    786:                                          rclTemp.right  - rclTemp.left,
                    787:                                          rclTemp.bottom - rclTemp.top,
                    788:                                          rop4,
                    789:                                          pbri,
                    790:                                          ulBkColor,
                    791:                                          ulFgColor,
                    792:                                          pulXlate,
                    793:                                          pptlBrush);
                    794: 
                    795:                             // Done if this bank contains the last line of
                    796:                             // the blt
                    797:                             if (prcl->bottom <=
                    798:                                     pdsurfTrg->rcl1WindowClip.bottom) {
                    799:                                 break;
                    800:                             }
                    801: 
                    802:                             // Map in the next bank
                    803:                             pdsurfTrg->pfnBankControl(pdsurfTrg,
                    804:                                           pdsurfTrg->rcl1WindowClip.bottom,
                    805:                                           JustifyTop);
                    806:                         }
                    807:                     }
                    808:                 } while(bMore);
                    809: 
                    810:                 break;
                    811: 
                    812:         }   // switch(jClipping);
                    813: 
                    814:     }
                    815: 
                    816:     return TRUE;
                    817: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.