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

1.1       root        1: /******************************Module*Header*******************************\
                      2: * Module Name: copybits.c
                      3: *
                      4: * DrvCopyBits
                      5: *
                      6: * Copyright (c) 1992 Microsoft Corporation
                      7: \**************************************************************************/
                      8: #include "driver.h"
                      9: #include "bitblt.h"
                     10: 
                     11: BOOL DrvCopyBits
                     12: (
                     13:     SURFOBJ  *psoTrg,
                     14:     SURFOBJ  *psoSrc,
                     15:     CLIPOBJ  *pco,
                     16:     XLATEOBJ *pxlo,
                     17:     PRECTL    prclTrg,
                     18:     PPOINTL   pptlSrc
                     19: )
                     20: {
                     21:     PDEVSURF    pdsurf;             // Pointer to a device surface
                     22: 
                     23:     LONG        lDelta;             // Delta to next scan of destination
                     24:     PVOID       pjDstScan0;         // Pointer to scan 0 of destination DIB
                     25:     ULONG      *pulXlate;           // Pointer to color xlate vector
                     26: 
                     27:     BOOL        bMore;              // Clip continuation flag
                     28:     ULONG       ircl;               // Clip enumeration rectangle index
                     29:     RECT_ENUM   cben;               // Clip enumerator
                     30:     RECTL       rclTemp;
                     31:     PRECTL      prcl;
                     32:     POINTL      ptlTemp;
                     33:     DEVSURF     dsurfSrc;
                     34:     PDEVSURF    pdsurfTrg;          // Pointer for target
                     35:     PDEVSURF    pdsurfSrc;          // Pointer for source if present
                     36:     INT iCopyDir;
                     37:     PFN_ScreenToScreenBlt pfn_Blt;
                     38:     RECT_ENUM   bben;               // Clip enumerator
                     39:     BYTE        jClipping;
                     40:     UCHAR      *pucDIB4ToVGAConvTables;
                     41: 
                     42: 
                     43: //    ASSERT(psoTrg  != (SURFOBJ *) NULL, "DrvCopyBits: NULL Pointer for Target\n");
                     44: //    ASSERT(psoSrc  != (SURFOBJ *) NULL, "DrvCopyBits: NULL Pointer for Source\n");
                     45: //    ASSERT(prclTrg != (RECTL *)   NULL, "DrvCopyBits: NULL Pointer for Rect\n");
                     46: //    ASSERT(pptlSrc != (POINTL *)  NULL, "DrvCopyBits: NULL Pointer for Point\n");
                     47: 
                     48: //    ASSERT(((psoTrg->dhsurf != (DHSURF) 0) || (psoSrc->dhsurf != (DHSURF) 0)),
                     49: //            "DrvCopyBits: No device surface involved\n");
                     50: 
                     51: // Check for device surface to device surface
                     52: 
                     53:     if ((psoTrg->iType == STYPE_DEVICE) && (psoSrc->iType == STYPE_DEVICE))
                     54:     {
                     55:         pdsurfTrg = (PDEVSURF) psoTrg->dhsurf;
                     56:         pdsurfSrc = (PDEVSURF) psoSrc->dhsurf;
                     57: 
                     58:     // It's a screen-to-screen aligned SRCCOPY; special-case it
                     59: 
                     60:     // Determine the direction in which the copy must proceed
                     61:     // Note that although we could detect cases where the source
                     62:     // and dest don't overlap and handle them top to bottom, all
                     63:     // copy directions are equally fast, so there's no reason to go
                     64:     // top to bottom except possibly that it looks better. But it
                     65:     // also takes time to detect non-overlap, so I'm not doing it
                     66: 
                     67:     // Set up the clipping type
                     68: 
                     69:         if (pco == (CLIPOBJ *) NULL)
                     70:         {
                     71:         // No CLIPOBJ provided, so we don't have to worry about clipping
                     72: 
                     73:             jClipping = DC_TRIVIAL;
                     74:         }
                     75:         else
                     76:         {
                     77:         // Use the CLIPOBJ-provided clipping
                     78: 
                     79:             jClipping = pco->iDComplexity;
                     80:         }
                     81: 
                     82: 
                     83:         if (pptlSrc->y >= prclTrg->top) {
                     84:             if (pptlSrc->x >= prclTrg->left) {
                     85:                 iCopyDir = CD_RIGHTDOWN;
                     86:             } else {
                     87:                 iCopyDir = CD_LEFTDOWN;
                     88:             }
                     89:         } else {
                     90:             if (pptlSrc->x >= prclTrg->left) {
                     91:                 iCopyDir = CD_RIGHTUP;
                     92:             } else {
                     93:                 iCopyDir = CD_LEFTUP;
                     94:             }
                     95:         }
                     96: 
                     97:         // These values are expected by vAlignedSrcCopy
                     98: //        ASSERT(((CD_RIGHTDOWN == 0) && (CD_LEFTDOWN == 1) &&
                     99: //               (CD_RIGHTUP == 2) && (CD_LEFTUP == 3)),
                    100: //               "DrvBitBlt: Bad clip enumeration direction constants");
                    101: 
                    102:         switch(jClipping) {
                    103: 
                    104:             case DC_TRIVIAL:
                    105:                 // Just copy the rectangle
                    106:                 if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) {
                    107:                     vAlignedSrcCopy(pdsurfTrg, prclTrg,
                    108:                                     pptlSrc, iCopyDir);
                    109:                 } else {
                    110:                     vNonAlignedSrcCopy(pdsurfTrg, prclTrg,
                    111:                                        pptlSrc, iCopyDir);
                    112:                 }
                    113:                 break;
                    114: 
                    115:             case DC_RECT:
                    116:                 // Clip the solid fill to the clip rectangle
                    117:                 if (!DrvIntersectRect(&rclTemp, prclTrg,
                    118:                                       &pco->rclBounds)) {
                    119:                     // Nothing to draw; completely clipped
                    120:                     return TRUE;
                    121:                 }
                    122: 
                    123:                 // Adjust the source point for clipping too
                    124:                 ptlTemp.x = pptlSrc->x + rclTemp.left - prclTrg->left;
                    125:                 ptlTemp.y = pptlSrc->y + rclTemp.top - prclTrg->top;
                    126: 
                    127:                 // Copy the clipped rectangle
                    128:                 if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) {
                    129:                     vAlignedSrcCopy(pdsurfTrg, &rclTemp, &ptlTemp,
                    130:                                     iCopyDir);
                    131:                 } else {
                    132:                     vNonAlignedSrcCopy(pdsurfTrg, &rclTemp, &ptlTemp,
                    133:                                        iCopyDir);
                    134:                 }
                    135:                 break;
                    136: 
                    137:             case DC_COMPLEX:
                    138: 
                    139:                 if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) {
                    140:                     pfn_Blt = vAlignedSrcCopy;
                    141:                 } else {
                    142:                     pfn_Blt = vNonAlignedSrcCopy;
                    143:                 }
                    144: 
                    145:                 CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES,
                    146:                                    iCopyDir, ENUM_RECT_LIMIT);
                    147: 
                    148:                 do {
                    149:                     bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben),
                    150:                                           (PVOID) &bben);
                    151: 
                    152:                     prcl = bben.arcl;
                    153:                     for (ircl = 0; ircl < bben.c; ircl++, prcl++) {
                    154: 
                    155:                         DrvIntersectRect(prcl,prcl,prclTrg);
                    156:                         // Adjust the source point for clipping too
                    157:                         ptlTemp.x = pptlSrc->x + prcl->left -
                    158:                                 prclTrg->left;
                    159:                         ptlTemp.y = pptlSrc->y + prcl->top -
                    160:                                 prclTrg->top;
                    161:                         pfn_Blt(pdsurfTrg, prcl,
                    162:                                 &ptlTemp, iCopyDir);
                    163: 
                    164:                     }
                    165:                 } while(bMore);
                    166:                 break;
                    167:         }
                    168:         return TRUE;
                    169:     }
                    170: 
                    171:     if (psoSrc->iType == STYPE_BITMAP) {
                    172: 
                    173:         // DIB to screen
                    174: 
                    175:         switch(psoSrc->iBitmapFormat)
                    176:         {
                    177:         case BMF_4BPP:  // special case compatible DIBs with no translation
                    178: 
                    179:             if ((pxlo == NULL) || (pxlo->flXlate == XO_TRIVIAL)) {
                    180: 
                    181:                 pucDIB4ToVGAConvTables =
                    182:                             ((PDEVSURF) psoTrg->dhsurf)->ppdev->
                    183:                             pucDIB4ToVGAConvTables;
                    184: 
                    185:                 // Make just enough of a fake DEVSURF for the source so that
                    186:                 // the DIB to VGA code can work
                    187: 
                    188:                 dsurfSrc.lNextScan = psoSrc->lDelta;
                    189:                 dsurfSrc.pvBitmapStart = psoSrc->pvScan0;
                    190: 
                    191:                 // Clip as needed
                    192: 
                    193:                 if ((pco == NULL) || (pco->iDComplexity == DC_TRIVIAL)) {
                    194: 
                    195:                     // No clipping, just copy the DIB to the VGA
                    196: 
                    197:                     vDIB2VGA((PDEVSURF) psoTrg->dhsurf, &dsurfSrc, prclTrg,
                    198:                             pptlSrc, pucDIB4ToVGAConvTables);
                    199: 
                    200:                 } else if (pco->iDComplexity == DC_RECT) {
                    201: 
                    202:                     // Clip the destination to the clip rectangle; we
                    203:                     // should never get a NULL result
                    204:                     if (DrvIntersectRect(&rclTemp, prclTrg, &pco->rclBounds)) {
                    205: 
                    206:                         // Adjust the source point for clipping too
                    207:                         ptlTemp.x = pptlSrc->x + rclTemp.left - prclTrg->left;
                    208:                         ptlTemp.y = pptlSrc->y + rclTemp.top - prclTrg->top;
                    209: 
                    210:                         // Blt the clipped rectangle
                    211:                         vDIB2VGA((PDEVSURF) psoTrg->dhsurf, &dsurfSrc,
                    212:                                 &rclTemp, &ptlTemp, pucDIB4ToVGAConvTables);
                    213:                     }
                    214:                     return(TRUE);
                    215: 
                    216:                 } else {    // DC_COMPLEX:
                    217: 
                    218:                     CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES,
                    219:                                        CD_ANY, ENUM_RECT_LIMIT);
                    220: 
                    221:                     do {
                    222:                         bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben),
                    223:                                               (PVOID) &bben);
                    224:                         prcl = bben.arcl;
                    225:                         for (ircl = 0; ircl < bben.c; ircl++, prcl++) {
                    226: 
                    227:                             // Clip the destination to the clip rectangle;
                    228:                             // we should never get a NULL result
                    229:                             DrvIntersectRect(prcl,prcl,prclTrg);
                    230: 
                    231:                             // Adjust the source point for clipping too
                    232:                             ptlTemp.x = pptlSrc->x + prcl->left -
                    233:                                     prclTrg->left;
                    234:                             ptlTemp.y = pptlSrc->y + prcl->top -
                    235:                                     prclTrg->top;
                    236: 
                    237:                             // Blt the clipped rectangle
                    238:                             vDIB2VGA((PDEVSURF) psoTrg->dhsurf,
                    239:                                     &dsurfSrc, prcl, &ptlTemp,
                    240:                                     pucDIB4ToVGAConvTables);
                    241:                         }
                    242:                     } while(bMore);
                    243: 
                    244:                 }
                    245: 
                    246:                 return(TRUE);
                    247:             }
                    248: 
                    249:         case BMF_1BPP:
                    250:         case BMF_8BPP:
                    251: 
                    252:             return(DrvBitBlt(psoTrg,
                    253:                              psoSrc,
                    254:                              (SURFOBJ *) NULL,
                    255:                              pco,
                    256:                              pxlo,
                    257:                              prclTrg,
                    258:                              pptlSrc,
                    259:                              (POINTL *) NULL,
                    260:                              (BRUSHOBJ *) NULL,
                    261:                              (POINTL *) NULL,
                    262:                              0x0000cccc));
                    263: 
                    264:         case BMF_8RLE:
                    265:         case BMF_4RLE:
                    266:             return(bRleBlt(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc));
                    267: 
                    268:         }
                    269:     }
                    270:     else
                    271:     {
                    272:     // screen to DIB
                    273: 
                    274: //        ASSERT(psoTrg->iType == STYPE_BITMAP, "ERROR CopyBits got 2 DIBs");
                    275: 
                    276:         if (psoTrg->iBitmapFormat == BMF_4BPP)
                    277:         {
                    278:             pdsurf = (PDEVSURF) psoSrc->dhsurf;
                    279: 
                    280:         // Get the data for the destination DIB.
                    281: 
                    282:             lDelta = psoTrg->lDelta;
                    283:             pjDstScan0 = (PBYTE) psoTrg->pvScan0;
                    284: 
                    285:         // Setup for any color translation which may be needed !!! Is any needed at all?
                    286: 
                    287:             if (pxlo == NULL)
                    288:             {
                    289:                 pulXlate = NULL;
                    290:             }
                    291:             else
                    292:             {
                    293:                 if (pxlo->flXlate & XO_TABLE)
                    294:                     pulXlate = pxlo->pulXlate;
                    295:                 else
                    296:                 {
                    297: //                    ASSERT(pxlo->flXlate & XO_TRIVIAL, "DrvCopyBits: Hopelessly complex translation\n");
                    298:                     pulXlate = (PULONG) NULL;
                    299:                 }
                    300:             }
                    301: 
                    302:         // Set up for clip enumeration.
                    303: 
                    304:             if (pco != (CLIPOBJ *) NULL)
                    305:             {
                    306:                 switch(pco->iDComplexity)
                    307:                 {
                    308:                 case DC_TRIVIAL:
                    309:                     bMore = FALSE;
                    310:                     cben.c = 1;
                    311:                     cben.arcl[0] = *prclTrg;        // Use the target for clipping
                    312:                     break;
                    313: 
                    314:                 case DC_RECT:
                    315:                     bMore = FALSE;
                    316:                     cben.c = 1;
                    317:                     cben.arcl[0] = pco->rclBounds; // Use the bounds for clipping
                    318:                     break;
                    319: 
                    320:                 case DC_COMPLEX:
                    321:                     bMore = TRUE;
                    322:                     cben.c = 0;
                    323:                     CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
                    324:                     break;
                    325:                 }
                    326:             }
                    327:             else
                    328:             {
                    329:                 bMore = FALSE;
                    330:                 cben.c = 1;
                    331:                 cben.arcl[0] = *prclTrg;            // Use the target for clipping
                    332:             }
                    333: 
                    334:         // Call the VGA conversion routine, adjusted for each rectangle
                    335: 
                    336:             do
                    337:             {
                    338:                 LONG    xSrc;
                    339:                 LONG    ySrc;
                    340:                 RECTL  *prcl;
                    341: 
                    342:                 if (bMore)
                    343:                     bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(cben), (PVOID) &cben);
                    344: 
                    345:                 for (ircl = 0; ircl < cben.c; ircl++)
                    346:                 {
                    347:                     prcl = &cben.arcl[ircl];
                    348: 
                    349:                     xSrc = pptlSrc->x + prcl->left - prclTrg->left;
                    350:                     ySrc = pptlSrc->y + prcl->top  - prclTrg->top;
                    351: 
                    352:                     vConvertVGA2DIB(pdsurf,
                    353:                                     xSrc,
                    354:                                     ySrc,
                    355:                                     pjDstScan0,
                    356:                                     prcl->left,
                    357:                                     prcl->top,
                    358:                                     prcl->right - prcl->left,
                    359:                                     prcl->bottom - prcl->top,
                    360:                                     lDelta,
                    361:                                     psoTrg->iBitmapFormat,
                    362:                                     pulXlate);
                    363:                 }
                    364:             } while (bMore);
                    365: 
                    366:             return(TRUE);
                    367:         }
                    368:     }
                    369: 
                    370: // This is how we do any formats that we don't support in our inner loops.
                    371: 
                    372:     return(SimCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc));
                    373: }
                    374: 
                    375: /******************************Public*Routine******************************\
                    376: * SimCopyBits
                    377: *
                    378: * This function simulates CopyBits for the driver when the driver is asked
                    379: * to blt to formats it does not support.  It converts any blt to be between
                    380: * the device's preferred format and the screen.
                    381: *
                    382: \**************************************************************************/
                    383: 
                    384: BOOL SimCopyBits
                    385: (
                    386:     SURFOBJ  *psoTrg,
                    387:     SURFOBJ  *psoSrc,
                    388:     CLIPOBJ  *pco,
                    389:     XLATEOBJ *pxlo,
                    390:     PRECTL    prclTrg,
                    391:     PPOINTL   pptlSrc
                    392: )
                    393: {
                    394:     HBITMAP  hbmTmp;
                    395:     SURFOBJ *psoTmp;
                    396:     RECTL    rclTmp;
                    397:     SIZEL    sizlTmp;
                    398:     BOOL     bReturn = FALSE;
                    399:     static POINTL ptl00 = {0,0};
                    400: 
                    401:     rclTmp.top = rclTmp.left = 0;
                    402:     rclTmp.right  = sizlTmp.cx = prclTrg->right - prclTrg->left;
                    403:     rclTmp.bottom = sizlTmp.cy = prclTrg->bottom - prclTrg->top;
                    404: 
                    405: // Create bitmap in our compatible format.
                    406: 
                    407:     hbmTmp = EngCreateBitmap(sizlTmp, sizlTmp.cx / 2, BMF_4BPP, 0, NULL);
                    408: 
                    409:     if (hbmTmp)
                    410:     {
                    411:         if ((psoTmp = EngLockSurface((HSURF)hbmTmp)) != NULL)
                    412:         {
                    413:             if (psoSrc->iType == STYPE_BITMAP)
                    414:             {
                    415:             // blting from DIB to screen
                    416: 
                    417:                 if (EngCopyBits(psoTmp, psoSrc, NULL, pxlo, &rclTmp, pptlSrc))
                    418:                 {
                    419:                 // Let DrvCopyBits do this easy case copy to screen.
                    420: 
                    421:                     bReturn = DrvCopyBits(psoTrg, psoTmp, pco, NULL, prclTrg, &ptl00);
                    422:                 }
                    423:             }
                    424:             else
                    425:             {
                    426:             // blting from screen to DIB
                    427: 
                    428:                 if (DrvCopyBits(psoTmp, psoSrc, NULL, NULL, &rclTmp, pptlSrc))
                    429:                 {
                    430:                 // Let EngCopyBits copy between DIBS
                    431: 
                    432:                     bReturn = EngCopyBits(psoTrg, psoTmp, pco, pxlo, prclTrg, &ptl00);
                    433:                 }
                    434:             }
                    435: 
                    436:             EngUnlockSurface(psoTmp);
                    437:         }
                    438: 
                    439:         EngDeleteSurface((HSURF)hbmTmp);
                    440:     }
                    441: 
                    442:     return(bReturn);
                    443: }

unix.superglobalmegacorp.com

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