Annotation of ntddk/src/video/displays/vga/copybits.c, revision 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.