Annotation of ntddk/src/print/pscript/patfill.c, revision 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.