Annotation of ntddk/src/print/pscript/patfill.c, revision 1.1.1.1

1.1       root        1: //--------------------------------------------------------------------------
                      2: //
                      3: // Module Name:  PATFILL.C
                      4: //
                      5: // Brief Description:  This module contains the PSCRIPT driver's pattern
                      6: //                    filling routines.
                      7: //
                      8: // Author:  Kent Settle (kentse)
                      9: // Created: 12-Dec-1990
                     10: //
                     11: // Copyright (c) 1990 - 1992 Microsoft Corporation
                     12: //
                     13: //--------------------------------------------------------------------------
                     14: 
                     15: #include "pscript.h"
                     16: #include "patfill.h"
                     17: #include "enable.h"
                     18: 
                     19: VOID vPatfill_Base(PDEVDATA, FLONG, BGR_PAL_ENTRY *, MIX);
                     20: 
                     21: #ifdef INDEX_PAL
                     22: extern ULONG   PSMonoPalette[];
                     23: extern ULONG   PSColorPalette[];
                     24: #endif
                     25: 
                     26: //--------------------------------------------------------------------------
                     27: // BOOL ps_patfill(pdev, pso, flFillMethod, pbo, pptlBrushOrg, mix,
                     28: //                 prclBound, bInvertPat, bFillPath)
                     29: // PDEVDATA    pdev;
                     30: // SURFOBJ    *pso;
                     31: // FLONG       flFillMethod;
                     32: // BRUSHOBJ   *pbo;
                     33: // PPOINTL     pptlBrushOrg;
                     34: // MIX         mix;
                     35: // RECTL      *prclBound;
                     36: // BOOL        bInvertPat;
                     37: // BOOL        bFillPath;      // TRUE if fill path is defined in printer.
                     38: //
                     39: // Parameters:
                     40: //
                     41: // Returns:
                     42: //   This function returns no value.
                     43: //
                     44: // History:
                     45: //   17-Mar-1993    updated -by-  Rob Kiesler
                     46: //  For non-1BPP pattern brushes, create the target bitmap to be passed
                     47: //  to the engine in the same format as the brush pattern.
                     48: //   10-Feb-1993    updated -by-  Rob Kiesler
                     49: //  Let the PS Interpreter perform tiling of 1BPP Pattern Brushes.
                     50: //   03-May-1991    -by-    Kent Settle     [kentse]
                     51: //  Wrote it.
                     52: //--------------------------------------------------------------------------
                     53: 
                     54: BOOL ps_patfill(pdev, pso, flFillMethod, pbo, pptlBrushOrg, mix,
                     55:                 prclBound, bInvertPat, bFillPath)
                     56: PDEVDATA    pdev;
                     57: SURFOBJ    *pso;
                     58: FLONG       flFillMethod;
                     59: BRUSHOBJ   *pbo;
                     60: PPOINTL     pptlBrushOrg;
                     61: MIX         mix;
                     62: RECTL      *prclBound;
                     63: BOOL        bInvertPat;
                     64: BOOL        bFillPath;      // TRUE if fill path is defined in printer.
                     65: {
                     66:     DEVBRUSH       *pBrush;
                     67:     ULONG           iPatternIndex;
                     68:     BGR_PAL_ENTRY   bgr;
                     69:     BGR_PAL_ENTRY  *pbgr;
                     70:     BGR_PAL_ENTRY  *pbgrTmp;
                     71:     ULONG           ulRed, ulGreen, ulBlue;
                     72:     PSZ             pszFill;
                     73:     SIZEL           sizlMem;
                     74:     HBITMAP         hbmMem;
                     75:     SURFOBJ        *psoMem;
                     76:     RECTL           rclTarget;
                     77:     POINTL          ptl, ptlOrg;
                     78:     LPSTR          *plpstr;
                     79:     ROP4            rop4;
                     80:     RECTPSFX        rectpsfx;
                     81:     ULONG           ulNextScan;
                     82:     ULONG           ulWidthBytes;
                     83:     ULONG           ulStartByte;
                     84:     ULONG           cCnt;
                     85:     ULONG           cCurScan;
                     86:     ULONG           cCurByte;
                     87:     ULONG           cBytes;
                     88:     LONG            ShiftBits;
                     89:     BYTE            curByte;
                     90:     PBYTE           pbPat;
                     91:     ULONG           ulbpp;
                     92: #ifdef INDEX_PAL
                     93:     ULONG          *pulColors;
                     94:     ULONG           iFormat;
                     95: #endif
                     96: 
                     97:     // just output the solid color if there is one.
                     98: 
                     99: #ifdef INDEX_PAL
                    100:     if ((pdev->pntpd->flFlags & COLOR_DEVICE) &&
                    101:         (pdev->psdm.dm.dmColor == DMCOLOR_COLOR))
                    102:         pulColors = PSColorPalette;
                    103:     else
                    104:         pulColors = PSMonoPalette;
                    105: 
                    106:     if (pbo->iSolidColor != NOT_SOLID_COLOR)
                    107:     {
                    108:         prgb = (PALETTEENTRY *)pulColors + pbo->iSolidColor;
                    109:         iPatternIndex = HS_SOLID;
                    110:     }
                    111:     else
                    112:     {
                    113:         // get the device brush to draw with.
                    114: 
                    115:         pBrush = (DEVBRUSH *)BRUSHOBJ_pvGetRbrush(pbo);
                    116: 
                    117:         if (!pBrush)
                    118:         {
                    119:             RIP("ps_patfill:  pBrush is NULL.\n");
                    120:             return(FALSE);
                    121:         }
                    122:         else
                    123:         {
                    124:             if (pBrush->iSolidColor == NOT_SOLID_COLOR)
                    125:             {
                    126:                 // get the foreground color.
                    127: 
                    128:                 prgb = (PALETTEENTRY *)pulColors +
                    129:                        *(ULONG *)((PBYTE)pBrush + pBrush->offsetXlate +
                    130:                        sizeof(ULONG));
                    131: 
                    132:                 // get the index for the pattern.
                    133: 
                    134:                 iPatternIndex = pBrush->iPatIndex;
                    135:             }
                    136:             else
                    137:             {
                    138:                 prgb = (PALETTEENTRY *)&pBrush->iSolidColor;
                    139:                 iPatternIndex = HS_SOLID;
                    140:             }
                    141:         }
                    142:     }
                    143: #else
                    144:     pbgr = (BGR_PAL_ENTRY *)&pbo->iSolidColor;
                    145:     iPatternIndex = HS_SOLID;
                    146: 
                    147:     if (pbo->iSolidColor == NOT_SOLID_COLOR)
                    148:     {
                    149:         // get the device brush to draw with.
                    150: 
                    151:         pBrush = (DEVBRUSH *)BRUSHOBJ_pvGetRbrush(pbo);
                    152: 
                    153:         if (!pBrush)
                    154:         {
                    155:             RIP("ps_patfill:  pBrush is NULL.\n");
                    156:             return(FALSE);
                    157:         }
                    158: 
                    159:         // get the foreground color.
                    160: 
                    161:         pbgr = (BGR_PAL_ENTRY *)((PBYTE)pBrush + pBrush->offsetXlate +
                    162:                 sizeof(ULONG));
                    163: 
                    164:         // get the index for the pattern.
                    165: 
                    166:         iPatternIndex = pBrush->iPatIndex;
                    167:     }
                    168: #endif
                    169: 
                    170:     // now handle the different patterns.  the PostScript driver handles
                    171:     // patterns in the following manner:  at DrvEnablePDEV time we created
                    172:     // bitmaps for each of the patterns, in the event that someone actually
                    173:     // wants to draw with the pattern in a compatible bitmap.  assuming
                    174:     // someone is not doing something silly like that, we have been called
                    175:     // here to handle the pattern filling.  at DrvRealizeBrush time, the
                    176:     // driver does a lookup in our internal table to determine the pattern
                    177:     // index from the bitmap handle (pBrush->iPatIndex).  since bltting
                    178:     // these patterns would be SLOW, we will draw them in reasonable
                    179:     // ways, depeding on the pattern.
                    180: 
                    181:     switch(iPatternIndex)
                    182:     {
                    183:         case HS_DENSE1:
                    184:         case HS_DENSE2:
                    185:         case HS_DENSE3:
                    186:         case HS_DENSE4:
                    187:         case HS_DENSE5:
                    188:         case HS_DENSE6:
                    189:         case HS_DENSE7:
                    190:         case HS_DENSE8:
                    191:            // Seperate the Red, Green, and Blue color planes.
                    192: 
                    193: #ifdef INDEX_PAL
                    194:             ulRed = (ULONG)prgb->peRed;
                    195:             ulGreen = (ULONG)prgb->peGreen;
                    196:             ulBlue = (ULONG)prgb->peBlue;
                    197: #else
                    198:             ulRed = (ULONG)pbgr->bgrRed;
                    199:             ulGreen = (ULONG)pbgr->bgrGreen;
                    200:             ulBlue = (ULONG)pbgr->bgrBlue;
                    201: #endif
                    202: 
                    203:             // adjust their intensities by the pattern percentage.
                    204: 
                    205:            ulRed += PSFXTOL((255L - ulRed) *
                    206:                                     apsfxPatGray[iPatternIndex - HS_DENSE1]);
                    207:            ulGreen += PSFXTOL((255L - ulGreen) *
                    208:                                     apsfxPatGray[iPatternIndex - HS_DENSE1]);
                    209:            ulBlue += PSFXTOL((255L - ulBlue) *
                    210:                                     apsfxPatGray[iPatternIndex - HS_DENSE1]);
                    211: 
                    212:            // Recombine the Red, Green, and Blue values into an RGB color
                    213: 
                    214: #ifdef INDEX_PAL
                    215:             rgb.peRed = (BYTE)ulRed;
                    216:             rgb.peGreen = (BYTE)ulGreen;
                    217:             rgb.peBlue = (BYTE)ulBlue;
                    218: #else
                    219:             bgr.bgrRed = (BYTE)ulRed;
                    220:             bgr.bgrGreen = (BYTE)ulGreen;
                    221:             bgr.bgrBlue = (BYTE)ulBlue;
                    222: #endif
                    223: 
                    224:             pbgr = &bgr;
                    225: 
                    226:             // fall through to the HS_SOLID code, with pe set up for
                    227:             // the shading.
                    228: 
                    229:         case HS_SOLID:
                    230:             ps_setrgbcolor(pdev, pbgr);
                    231:             ps_fill(pdev, flFillMethod);
                    232:             break;
                    233: 
                    234:         case HS_NOSHADE:
                    235:             // just destroy the path.  there is no filling to do.
                    236: 
                    237:             ps_newpath(pdev);
                    238:             break;
                    239: 
                    240:         case HS_HALFTONE:
                    241:            // Seperate the Red, Green, and Blue color planes.
                    242: 
                    243: #ifdef INDEX_PAL
                    244:             ulRed = (ULONG)prgb->peRed;
                    245:             ulGreen = (ULONG)prgb->peGreen;
                    246:             ulBlue = (ULONG)prgb->peBlue;
                    247: #else
                    248:             ulRed = (ULONG)pbgr->bgrRed;
                    249:             ulGreen = (ULONG)pbgr->bgrGreen;
                    250:             ulBlue = (ULONG)pbgr->bgrBlue;
                    251: #endif
                    252:             // adjust their intensities by one half.
                    253: 
                    254:            ulRed += PSFXTOL((255L - ulRed) * PSFXONEHALF);
                    255:            ulGreen += PSFXTOL((255L - ulGreen) * PSFXONEHALF);
                    256:            ulBlue += PSFXTOL((255L - ulBlue) * PSFXONEHALF);
                    257: 
                    258:            // Recombine the Red, Green, and Blue values into an RGB color
                    259: 
                    260: #ifdef INDEX_PAL
                    261:             rgb.peRed = (BYTE)ulRed;
                    262:             rgb.peGreen = (BYTE)ulGreen;
                    263:             rgb.peBlue = (BYTE)ulBlue;
                    264: #else
                    265:             bgr.bgrRed = (BYTE)ulRed;
                    266:             bgr.bgrGreen = (BYTE)ulGreen;
                    267:             bgr.bgrBlue = (BYTE)ulBlue;
                    268: #endif
                    269:             ps_setrgbcolor(pdev, &bgr);
                    270:             ps_fill(pdev, flFillMethod);
                    271:             break;
                    272: 
                    273:         // if we get this far, we either have one of the hatched brushes,
                    274:         // or a user defined bitmap pattern.
                    275: 
                    276:         case HS_HORIZONTAL:
                    277:         case HS_VERTICAL:
                    278:         case HS_BDIAGONAL1:
                    279:         case HS_BDIAGONAL:
                    280:         case HS_FDIAGONAL1:
                    281:         case HS_FDIAGONAL:
                    282:         case HS_CROSS:
                    283:         case HS_DIAGCROSS:
                    284:             // set the foreground color.  check to see if the invert pattern
                    285:             // flag is set, and reverse the colors if so.
                    286: 
                    287:             if (bInvertPat)
                    288:             {
                    289: #ifdef INDEX_PAL
                    290:                 prgbTmp = prgb;
                    291:                 prgb = (BGR_PAL_ENTRY *)pulColors +
                    292:                        *(ULONG *)((PBYTE)pBrush + pBrush->offsetXlate);
                    293: #else
                    294:                 pbgrTmp = pbgr;
                    295:                 pbgr = (BGR_PAL_ENTRY *)((PBYTE)pBrush + pBrush->offsetXlate);
                    296: #endif
                    297:             }
                    298: 
                    299:             ps_setrgbcolor(pdev, pbgr);
                    300: 
                    301:             // if the background is not transparent, save the path, fill the path
                    302:             // with the background color, then restore the path.
                    303: 
                    304:             if (((mix >> 8) & 0xFF) != R2_NOP)
                    305:             {
                    306:             // this section of code does a gsave, fills the background
                    307:            // color, and then a grestore.      it does this so that the
                    308:             // foreground pattern can then be drawn.  TRUE means to do
                    309:             // a gsave, not a save command.
                    310: 
                    311:                 if (!ps_save(pdev, TRUE))
                    312:                     return(FALSE);
                    313: 
                    314: #ifdef INDEX_PAL
                    315:                 if (bInvertPat)
                    316:                     prgb = prgbTmp;
                    317:                 else
                    318:                     prgb = (BGR_PAL_ENTRY *)pulColors +
                    319:                            *(ULONG *)((PBYTE)pBrush + pBrush->offsetXlate);
                    320: #else
                    321:                 if (bInvertPat)
                    322:                     pbgr = pbgrTmp;
                    323:                 else
                    324:                     pbgr = (BGR_PAL_ENTRY *)((PBYTE)pBrush + pBrush->offsetXlate);
                    325: #endif
                    326: 
                    327:                 ps_setrgbcolor(pdev, pbgr);
                    328:                 ps_fill(pdev, flFillMethod);
                    329: 
                    330:                 if (!ps_restore(pdev, TRUE))
                    331:                     return(FALSE);
                    332:             }
                    333: 
                    334:             // if the base pattern definitions code has not yet been downloaded
                    335:             // to the printer, do it now.
                    336: 
                    337:             if(!(pdev->cgs.dwFlags & CGS_BASEPATSENT))
                    338:             {
                    339:                plpstr = apszBase;
                    340:                        while (*plpstr)
                    341:                        {
                    342:                          PrintString(pdev, (PSZ)*plpstr++);
                    343:                          PrintString(pdev, "\n");
                    344:                        }
                    345:                pdev->cgs.dwFlags |= CGS_BASEPATSENT;
                    346:             }
                    347: 
                    348:                // we will do a gsave/grestore around the pattern fill. TRUE
                    349:                // means to do a gsave, not a save command.
                    350: 
                    351:                if (!ps_save(pdev, TRUE))
                    352:                       return(FALSE);
                    353: 
                    354:             // let the printer know which fill method to use.
                    355: 
                    356:             if (flFillMethod & FP_WINDINGMODE)
                    357:                 pszFill = "psize";
                    358:             else
                    359:                 pszFill = "eopsize";
                    360: 
                    361:             // make sure the linewidth for the patterns is .01 inch.
                    362: 
                    363:             ps_setlinewidth(pdev, PSFX_DEFAULT_LINEWIDTH);
                    364: 
                    365:             // output the specific command for each pattern.
                    366: 
                    367:             switch(iPatternIndex)
                    368:             {
                    369:                case HS_HORIZONTAL:
                    370:                    PrintString(pdev, pszFill);
                    371:                    PrintString(pdev, " phoriz ");
                    372:                     break;
                    373: 
                    374:                case HS_VERTICAL:
                    375:                    PrintString(pdev, "90 rotate ");
                    376:                    PrintString(pdev, pszFill);
                    377:                    PrintString(pdev, " phoriz ");
                    378:                     break;
                    379: 
                    380:                case HS_BDIAGONAL1:
                    381:                     PrintString(pdev, "30 rotate ");
                    382:                    PrintString(pdev, pszFill);
                    383:                    PrintString(pdev, " phoriz ");
                    384:                    break;
                    385: 
                    386:                case HS_BDIAGONAL:
                    387:                     PrintString(pdev, "45 rotate ");
                    388:                    PrintString(pdev, pszFill);
                    389:                    PrintString(pdev, " phoriz ");
                    390:                     break;
                    391: 
                    392:                case HS_FDIAGONAL1:
                    393:                     PrintString(pdev, "-30 rotate ");
                    394:                    PrintString(pdev, pszFill);
                    395:                    PrintString(pdev, " phoriz ");
                    396:                     break;
                    397: 
                    398:                case HS_FDIAGONAL:
                    399:                     PrintString(pdev, "-45 rotate ");
                    400:                    PrintString(pdev, pszFill);
                    401:                    PrintString(pdev, " phoriz ");
                    402:                     break;
                    403: 
                    404:                case HS_CROSS:
                    405:                    PrintString(pdev, "gs ");
                    406:                    PrintString(pdev, pszFill);
                    407:                    PrintString(pdev, " phoriz gr 90 rotate ");
                    408:                    PrintString(pdev, pszFill);
                    409:                    PrintString(pdev, " phoriz ");
                    410:                     break;
                    411: 
                    412:                case HS_DIAGCROSS:
                    413:                    PrintString(pdev, "gs 45 rotate ");
                    414:                    PrintString(pdev, pszFill);
                    415:                    PrintString(pdev, " phoriz gr -45 rotate ");
                    416:                    PrintString(pdev, pszFill);
                    417:                    PrintString(pdev, " phoriz ");
                    418:                     break;
                    419:             }
                    420: 
                    421:            if (!ps_restore(pdev, TRUE))
                    422:                return(FALSE);
                    423: 
                    424:             ps_newpath(pdev);
                    425:             break;
                    426: 
                    427:         default:
                    428:             // we have a user defined bitmap pattern.  the bitmap
                    429:             // can be monochrome or color.  the initial method for
                    430:             // filling with a bitmap pattern will be as follows:
                    431:             //
                    432:             //
                    433:             // If the bitmap is 1BPP, download the PS pattern
                    434:             // tiling procest if neccessary and invoke the "prf"
                    435:             // operator which will tile the bitmap pattern into the
                    436:             // destination rectangle.
                    437:             //
                    438:             // If the bitmap is >1BPP, a memory bitmap the size of the
                    439:             // bounding rectangle will be created, and filled with the
                    440:             // pattern.  this memory bitmap will then be blted to the
                    441:             // printer which will handle clipping to the path.
                    442:             //
                    443:             // NOTE: current windows implementation uses only the
                    444:             // upper/lower left 8x8 bits of the bitmap for the pattern,
                    445:             // no matter what size the bitmap itself is.  for now we
                    446:             // will print the entire bitmap as the pattern.  supposedly,
                    447:             // future engine functionality will support this.
                    448: 
                    449:             // since we have a user defined pattern, and we will be
                    450:             // calling BitBlt to do the work, we want to clip to the
                    451:             // path which was defined in DrvCommonPath.
                    452: 
                    453:             if (bFillPath)
                    454:             {
                    455:                 if (flFillMethod & FP_WINDINGMODE)
                    456:                     ps_clip(pdev, TRUE);
                    457:                 else
                    458:                     ps_clip(pdev, FALSE);
                    459:             }
                    460: 
                    461:             // a path will have been defined in the printer before calling
                    462:             // ps_patfill to fill to.  since user defined patterns do not
                    463:             // use the fill command, we do not want a path sitting around
                    464:             // in the printer.
                    465: 
                    466:             ps_newpath(pdev);
                    467: 
                    468:             //!!! OPTIMIZATION !!!
                    469:             //!!! perhaps if we have a monochrome bitmap, we should
                    470:             //!!! define it as a character of a font, then tile that
                    471:             //!!! character over the clip path.
                    472: 
                    473:            sizlMem.cx = prclBound->right - prclBound->left;
                    474:             sizlMem.cy = prclBound->bottom - prclBound->top;
                    475: 
                    476:             //
                    477:             // If this is a 1BPP Bitmap Brush, generate PS code
                    478:             // to handle it.
                    479:             //
                    480: 
                    481:             if (pBrush->iFormat == BMF_1BPP)
                    482:             {
                    483:                 //
                    484:                 // Check to see if any of the PS bitmap pattern code
                    485:                 // has been downloaded.
                    486:                 //
                    487:                 if(!(pdev->dwFlags & PDEV_UTILSSENT))
                    488:                 {
                    489:                     //
                    490:                     //  Download the Adobe PS Utilities Procset.
                    491:                     //
                    492:                     PrintString(pdev, "/Adobe_WinNT_Driver_Gfx 175 dict dup begin\n");
                    493:                     if (!bSendPSProcSet(pdev, UTILS))
                    494:                     {
                    495:                            RIP("PSCRIPT!ps_patfill: Couldn't download Utils Procset.\n");
                    496:                            return(FALSE);
                    497:                     }
                    498:                     PrintString(pdev, "end def\n[ 1.000 0 0 1.000 0 0 ] Adobe_WinNT_Driver_Gfx dup /initialize get exec\n");
                    499:                     pdev->dwFlags |= PDEV_UTILSSENT;
                    500:                 }
                    501: 
                    502:                 if(!(pdev->dwFlags & PDEV_BMPPATSENT))
                    503:                 {
                    504:                     //
                    505:                     //  Download the Adobe PS Pattern Bitmap Procset.
                    506:                     //
                    507:                     PrintString(pdev, "Adobe_WinNT_Driver_Gfx begin\n");
                    508:                     if (!bSendPSProcSet(pdev, PATTERN))
                    509:                     {
                    510:                            RIP("PSCRIPT!ps_patfill: Couldn't download Pattern Bmp Procset.\n");
                    511:                            return(FALSE);
                    512:                     }
                    513:                     PrintString(pdev, "end reinitialize\n");
                    514:                     pdev->dwFlags |= PDEV_BMPPATSENT;
                    515: 
                    516:                 }
                    517: 
                    518:                 //
                    519:                 // First Convert Destination Rect Coordinates to fixed
                    520:                 // point.
                    521:                 //
                    522:                 rectpsfx.xLeft = X72DPI(prclBound->left);
                    523:                 rectpsfx.yBottom = Y72DPI(prclBound->bottom);
                    524: 
                    525:                 //
                    526:                 // Compute the destination rectangle extents, and convert
                    527:                 // to fixed point.
                    528:                 //
                    529:                 rectpsfx.xRight = ((prclBound->right - prclBound->left)
                    530:                     * PS_FIX_RESOLUTION)  / pdev->psdm.dm.dmPrintQuality;
                    531:                 rectpsfx.yTop = ((prclBound->bottom - prclBound->top)
                    532:                     * PS_FIX_RESOLUTION) / pdev->psdm.dm.dmPrintQuality;
                    533: 
                    534:                 PrintPSFIX(pdev, 4, rectpsfx.xLeft, rectpsfx.yBottom,
                    535:                            rectpsfx.xRight, rectpsfx.yTop);
                    536: 
                    537:                 //
                    538:                 // Get the bg color from the pBrush and convert to
                    539:                 // PS format.
                    540:                 //
                    541: #ifdef INDEX_PAL
                    542:                 prgb = (BGR_PAL_ENTRY *)pulColors +
                    543:                        *(ULONG *)((PBYTE)pBrush + pBrush->offsetXlate);
                    544: #else
                    545:                 pbgr = (BGR_PAL_ENTRY *)((PBYTE)pBrush + pBrush->offsetXlate);
                    546: #endif
                    547: 
                    548:                 PrintString(pdev, " [");
                    549:                 PrintPSFIX(pdev, 3, LTOPSFX((ULONG)pbgr->bgrRed) / 255,
                    550:                            LTOPSFX((ULONG)pbgr->bgrGreen) / 255,
                    551:                            LTOPSFX((ULONG)pbgr->bgrBlue) / 255);
                    552:                 PrintString(pdev, " false]");
                    553: 
                    554:                 //
                    555:                 // Get the fg color from the pBrush and convert to
                    556:                 // PS format.
                    557:                 //
                    558: 
                    559: #ifdef INDEX_PAL
                    560:                 prgb = (BGR_PAL_ENTRY *)pulColors +
                    561:                        *(ULONG *)((PBYTE)pBrush + pBrush->offsetXlate +
                    562:                        sizeof(ULONG));
                    563: #else
                    564:                 pbgr = (BGR_PAL_ENTRY *)((PBYTE)pBrush + pBrush->offsetXlate +
                    565:                                          sizeof(ULONG));
                    566: #endif
                    567: 
                    568:                 PrintString(pdev, " [");
                    569: 
                    570:                 PrintPSFIX(pdev, 3, LTOPSFX((ULONG)pbgr->bgrRed) / 255,
                    571:                                     LTOPSFX((ULONG)pbgr->bgrGreen) / 255,
                    572:                                     LTOPSFX((ULONG)pbgr->bgrBlue) / 255);
                    573:                 PrintString(pdev, " false] ");
                    574: 
                    575:                 //
                    576:                 // Send down the pattern x and y extents.
                    577:                 //
                    578:                 PrintDecimal(pdev, 2, pBrush->sizlBitmap.cx,
                    579:                                pBrush->sizlBitmap.cy);
                    580: 
                    581:                 //
                    582:                 // Compute the width in bytes of each scanline in the
                    583:                 // pattern bitmap, rounded to the nearest dword boundary.
                    584:                 //
                    585:                 ulWidthBytes = (pBrush->sizlBitmap.cx + 7) / 8;
                    586:                 ulNextScan = ((pBrush->sizlBitmap.cx + 31) / 32) << 2;
                    587: 
                    588:                 PrintString(pdev," <");
                    589: 
                    590:                 //
                    591:                 // Send the pattern bitmap. The PS pattern fill operator
                    592:                 // doesn't need the padding bytes at the end of each
                    593:                 // scanline.
                    594:                 //
                    595:                 pbPat = pBrush->ajBits;
                    596: 
                    597:                 if (!pptlBrushOrg->y && !pptlBrushOrg->x)
                    598:                 {
                    599:                     //
                    600:                     // The brush pattern doesn't require rotation,
                    601:                     // send it down a scanline at a time.
                    602:                     //
                    603:                     for (cCnt = 0;cCnt < (ULONG)pBrush->sizlBitmap.cy;cCnt++)
                    604:                     {
                    605:                         vHexOut(pdev, pbPat, ulWidthBytes);
                    606:                         pbPat += ulNextScan;
                    607:                     }
                    608:                 }
                    609:                 else
                    610:                 {
                    611: 
                    612:                     //
                    613:                     // The Brush pattern requires rotation. Calculate the
                    614:                     // byte offset of the x origin.
                    615:                     //
                    616: 
                    617:                     // let's first yank the origin to somewhere inside our
                    618:                     // bitmap.
                    619: 
                    620:                     ptlOrg.x = pptlBrushOrg->x % pBrush->sizlBitmap.cx;
                    621:                     if (ptlOrg.x < 0)
                    622:                         ptlOrg.x = ptlOrg.x + pBrush->sizlBitmap.cx;
                    623: 
                    624:                     ptlOrg.y = pptlBrushOrg->y % pBrush->sizlBitmap.cy;
                    625:                     if (ptlOrg.y < 0)
                    626:                         ptlOrg.y = ptlOrg.y + pBrush->sizlBitmap.cy;
                    627: 
                    628:                     ulStartByte = ptlOrg.x / 8;
                    629: 
                    630:                     if (!(ShiftBits = ptlOrg.x % 8))
                    631:                     {
                    632:                         //
                    633:                         // The x origin is byte aligned. Apply the proper
                    634:                         // byte rotation and send a scanline (or a partial
                    635:                         // scanline) at a time.
                    636:                         //
                    637:                         for (cCnt = 0;cCnt < (ULONG)pBrush->sizlBitmap.cy;cCnt++)
                    638:                         {
                    639:                             cCurScan = ((cCnt + ptlOrg.y) % pBrush->sizlBitmap.cy)
                    640:                                         * ulNextScan;
                    641:                             vHexOut(pdev, &(pbPat[cCurScan + ulStartByte]),
                    642:                                          ulWidthBytes - ulStartByte);
                    643:                             if (ulStartByte)
                    644:                                 vHexOut(pdev, &(pbPat[cCurScan]), ulStartByte);
                    645:                         }
                    646:                     }
                    647:                     else
                    648:                     {
                    649:                         //
                    650:                         // The x origin is not byte aligned, rotate and send
                    651:                         // the pattern bitmap a byte at a time.
                    652:                         //
                    653:                         for (cCnt = 0;cCnt < (ULONG)pBrush->sizlBitmap.cy;cCnt++)
                    654:                         {
                    655:                             cCurScan = ((cCnt + ptlOrg.y) % pBrush->sizlBitmap.cy)
                    656:                                           * ulNextScan;
                    657:                             for (cBytes = 0;cBytes < ulWidthBytes;cBytes++)
                    658:                             {
                    659:                                 cCurByte = (cBytes + ulStartByte) % ulWidthBytes;
                    660:                                 curByte = pbPat[cCurScan + cCurByte] >> ShiftBits;
                    661:                                 cCurByte = ++cCurByte % ulWidthBytes;
                    662:                                 curByte |=  (pbPat[cCurScan + cCurByte] << (8 - ShiftBits));
                    663:                                 vHexOut(pdev, &curByte, 1);
                    664:                             }
                    665:                         }
                    666:                     }
                    667:                 }
                    668: 
                    669:                 //
                    670:                 // Close the pattern data array object, and invoke the
                    671:                 // prf (pattern rect fill) operator.
                    672:                 //
                    673:                 PrintString(pdev,"> prf\n");
                    674:                 break;
                    675:             }
                    676: 
                    677:             // create a memory bitmap which is the size of the
                    678:             // bounding box of the current path, and is compatible
                    679:             // with the pattern bitmap.
                    680: 
                    681: 
                    682:             //
                    683:             // Compute the scanline delta. First get then number of
                    684:             // pels/scanline.
                    685:             //
                    686:             ulNextScan = sizlMem.cx;
                    687: 
                    688:             //
                    689:                    // times how many bits per pel.
                    690:                    //
                    691:             switch (pBrush->iFormat)
                    692:                    {
                    693:                        case BMF_4BPP:
                    694:                            ulbpp = 4;
                    695:                            break;
                    696:                
                    697:                        case BMF_8BPP:
                    698:                            ulbpp = 8;
                    699:                            break;
                    700:                
                    701:                        case BMF_16BPP:
                    702:                            ulbpp = 16;
                    703:                            break;
                    704:                
                    705:                        case BMF_24BPP:
                    706:                            ulbpp = 24;
                    707:                            break;
                    708:                
                    709:                        case BMF_32BPP:
                    710:                            ulbpp = 32;
                    711:                             break;
                    712:                    }
                    713: 
                    714:             ulNextScan *= ulbpp;
                    715: 
                    716:             //
                    717:             // Now convert ulNextScan to the number of bytes per scanline,
                    718:             // taking into account that scanlines are padded out to 32 bit
                    719:             // boundaries.
                    720:             //
                    721:                    ulNextScan = ((ulNextScan + 31) / 32) * 4;
                    722: 
                    723: #ifdef INDEX_PAL
                    724:             if ((pdev->pntpd->flFlags & COLOR_DEVICE) &&
                    725:                 (pdev->psdm.dm.dmColor == DMCOLOR_COLOR))
                    726:                 iFormat = BMF_4BPP;
                    727:             else
                    728:                 iFormat = BMF_1BPP;
                    729: 
                    730:             hbmMem = EngCreateBitmap(sizlMem, ulNextScan, iFormat,
                    731:                                     pBrush->flBitmap, (PVOID)NULL);
                    732: #else
                    733:             hbmMem = EngCreateBitmap(sizlMem, ulNextScan, BMF_24BPP,
                    734:                                     pBrush->flBitmap, (PVOID)NULL);
                    735: #endif
                    736: 
                    737:             if (hbmMem == 0)
                    738:             {
                    739:                        RIP("PSCRIPT!ps_patfill:  EngCreateBitmap for hbmMem failed.\n");
                    740:                        return(FALSE);
                    741:             }
                    742: 
                    743:             // get the SURFOBJ for the memory bitmap.
                    744: 
                    745:             psoMem = (SURFOBJ *)EngLockSurface((HSURF)hbmMem);
                    746: 
                    747:             if (psoMem == (SURFOBJ *)NULL)
                    748:             {
                    749:                        RIP("ps_patfill: EngLockSurface for psoMem failed.\n");
                    750:                        EngDeleteSurface((HSURF)hbmMem);
                    751:                        return(FALSE);
                    752:             }
                    753: 
                    754:             // do a patcopy into the memory bitmap.
                    755: 
                    756:                rclTarget.left = 0;
                    757:                rclTarget.top = 0;
                    758:                rclTarget.right = sizlMem.cx;
                    759:                rclTarget.bottom = sizlMem.cy;
                    760: 
                    761:             if (bInvertPat)
                    762:                 rop4 = 0x5A5A;      // invert pattern.
                    763:             else
                    764:                 rop4 = 0xF0F0;      // patcopy.
                    765: 
                    766:             if (!(EngBitBlt(psoMem, (SURFOBJ *)NULL, (SURFOBJ *)NULL,
                    767:                             (CLIPOBJ *)NULL, (XLATEOBJ *)NULL, &rclTarget,
                    768:                             (PPOINTL)NULL, (PPOINTL)NULL, pbo,
                    769:                             pptlBrushOrg, rop4)))
                    770:             {
                    771:                 RIP("ps_patfill: EngBitBlt pat to mem failed.\n");
                    772:                        EngUnlockSurface(psoMem);
                    773:                 EngDeleteSurface((HSURF)hbmMem);
                    774:                        return(FALSE);
                    775:             }
                    776: 
                    777:             // now that the memory bitmap is filled with the pattern,
                    778:             // bitblt it to the printer.  the printer will handle clipping.
                    779: 
                    780:             // source origin.
                    781: 
                    782:             ptl.x = 0;
                    783:             ptl.y = 0;
                    784: 
                    785:             if (!(DrvBitBlt(pso, psoMem, (SURFOBJ *)NULL,
                    786:                             (CLIPOBJ *)NULL, (XLATEOBJ *)NULL, prclBound,
                    787:                             &ptl, (PPOINTL)NULL, pbo,
                    788:                             pptlBrushOrg, 0xCCCC)))
                    789:             {
                    790:                 RIP("ps_patfill: EngBitBlt mem to printer failed.\n");
                    791:                        EngUnlockSurface(psoMem);
                    792:                 EngDeleteSurface((HSURF)hbmMem);
                    793:                        return(FALSE);
                    794:             }
                    795: 
                    796:             // release stuff.
                    797: 
                    798:             if (psoMem)
                    799:             {
                    800:                 EngUnlockSurface(psoMem);
                    801:                 EngDeleteSurface((HSURF)hbmMem);
                    802:             }
                    803:     }
                    804: 
                    805:     return(TRUE);
                    806: }

unix.superglobalmegacorp.com

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