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

1.1       root        1: //--------------------------------------------------------------------------
                      2: //
                      3: // Module Name:  PATHS.C
                      4: //
                      5: // Brief Description:  This module contains the PSCRIPT driver's path
                      6: // rendering functions and related routines.
                      7: //
                      8: // Author:  Kent Settle (kentse)
                      9: // Created: 02-May-1991
                     10: //
                     11: //  26-Mar-1992 Thu 23:53:12 updated  -by-  Daniel Chou (danielc)
                     12: //      add the prclBound parameter to the bDoClipObj()
                     13: //
                     14: // Copyright (c) 1991 - 1992 Microsoft Corporation
                     15: //
                     16: // This Module contains the following functions:
                     17: //     DrvStrokePath
                     18: //     DrvFillPath
                     19: //     DrvStrokeAndFillPath
                     20: //--------------------------------------------------------------------------
                     21: 
                     22: #include "pscript.h"
                     23: #include "enable.h"
                     24: 
                     25: extern ULONG   PSMonoPalette[];
                     26: extern ULONG   PSColorPalette[];
                     27: 
                     28: extern BOOL bDoClipObj(PDEVDATA, CLIPOBJ *, RECTL *, RECTL *, BOOL *, BOOL *, DWORD);
                     29: 
                     30: BOOL DrvCommonPath(PDEVDATA, PATHOBJ *);
                     31: 
                     32: //--------------------------------------------------------------------------
                     33: // BOOL DrvStrokePath(pso, ppo, pco, pxo, pbo, pptlBrushOrg, plineattrs, mix)
                     34: // SURFOBJ      *pso;
                     35: // PATHOBJ      *ppo;
                     36: // CLIPOBJ      *pco;
                     37: // XFORMOBJ  *pxo;
                     38: // BRUSHOBJ  *pbo;
                     39: // PPOINTL       pptlBrushOrg;
                     40: // PLINEATTRS plineattrs;
                     41: // MIX   mix;
                     42: //
                     43: //
                     44: // Parameters:
                     45: //
                     46: // Returns:
                     47: //   This function returns TRUE.
                     48: //
                     49: // History:
                     50: //   02-May-1991    -by-    Kent Settle     [kentse]
                     51: //  Wrote it.
                     52: //--------------------------------------------------------------------------
                     53: 
                     54: BOOL DrvStrokePath(pso, ppo, pco, pxo, pbo, pptlBrushOrg, plineattrs, mix)
                     55: SURFOBJ   *pso;
                     56: PATHOBJ   *ppo;
                     57: CLIPOBJ   *pco;
                     58: XFORMOBJ  *pxo;
                     59: BRUSHOBJ  *pbo;
                     60: PPOINTL    pptlBrushOrg;
                     61: PLINEATTRS plineattrs;
                     62: MIX        mix;
                     63: {
                     64:     PDEVDATA   pdev;
                     65:     BOOL        bClipping;      // TRUE if there is a clip region.
                     66:     ULONG       ulColor;
                     67:     BOOL        bMoreClipping;  // TRUE if there is more clipping to handle.
                     68:     BOOL        bFirstClipPass;
                     69: #ifdef INDEX_PAL
                     70:     DEVBRUSH   *pBrush;
                     71:     ULONG      *pulColors;
                     72: #endif
                     73:     RECTFX      rcfxBound;
                     74:     RECTL       rclBound;
                     75: 
                     76:     UNREFERENCED_PARAMETER(mix);
                     77: 
                     78:     // get the pointer to our DEVDATA structure and make sure it is ours.
                     79: 
                     80:     pdev = (PDEVDATA) pso->dhpdev;
                     81: 
                     82:     if (bValidatePDEV(pdev) == FALSE)
                     83:     {
                     84:        RIP("PSCRIPT!DrvStrokePath: invalid pdev.\n");
                     85:        SetLastError(ERROR_INVALID_PARAMETER);
                     86:        return(FALSE);
                     87:     }
                     88: 
                     89:     // deal with LINEATTRS.
                     90: 
                     91:     if (!(ps_setlineattrs(pdev, plineattrs, pxo)))
                     92:         return(FALSE);
                     93: 
                     94:     // output the line color to stroke with.  do this before we handle
                     95:     // clipping, so the line color will remain beyond the gsave/grestore.
                     96: 
                     97: #ifdef INDEX_PAL
                     98:     // just output the solid color if there is one.
                     99: 
                    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:         ps_setrgbcolor(pdev, (PALETTEENTRY *)pulColors + pbo->iSolidColor);
                    109:     }
                    110:     else
                    111:     {
                    112:         // get the device brush to draw with.
                    113: 
                    114:         pBrush = (DEVBRUSH *)BRUSHOBJ_pvGetRbrush(pbo);
                    115: 
                    116:         if (!pBrush)
                    117:         {
                    118: #if DBG
                    119:             DbgPrint("DrvStrokePath: NULL pBrush.\n");
                    120: #endif
                    121:             // something is wrong! just output black path.
                    122: 
                    123:             ulColor = RGB_BLACK;
                    124:             ps_setrgbcolor(pdev, (PALETTEENTRY *)&ulColor);
                    125:         }
                    126:         else
                    127:         {
                    128:             if (pBrush->iSolidColor == NOT_SOLID_COLOR)
                    129:             {
                    130:                 // get the foreground color.
                    131: 
                    132:                 ps_setrgbcolor(pdev, ((PALETTEENTRY *)pulColors +
                    133:                                *(ULONG *)((PBYTE)pBrush + pBrush->offsetXlate +
                    134:                                sizeof(ULONG))));
                    135:             }
                    136:             else
                    137:             {
                    138:                 ps_setrgbcolor(pdev, (PALETTEENTRY *)&pBrush->iSolidColor);
                    139:             }
                    140:         }
                    141:     }
                    142: #else
                    143:     if (pbo->iSolidColor == NOT_SOLID_COLOR)
                    144:     {
                    145: //!!! this needs to be fixed!!! -kentse.
                    146:         ulColor = RGB_GRAY;
                    147: 
                    148:         ps_setrgbcolor(pdev, (BGR_PAL_ENTRY *)&ulColor);
                    149:     }
                    150:     else
                    151:     {
                    152:         // we have a solid brush, so simply output the line color.
                    153: 
                    154:         ps_setrgbcolor(pdev, (BGR_PAL_ENTRY *)&pbo->iSolidColor);
                    155:     }
                    156: #endif
                    157: 
                    158:     // get the bounding rectangle for the path.  this is used to checked
                    159:     // against the clipping for optimization.
                    160: 
                    161:     PATHOBJ_vGetBounds(ppo, &rcfxBound);
                    162: 
                    163:     // get a RECTL which is guaranteed to bound the path.
                    164: 
                    165:     rclBound.left = FXTOL(rcfxBound.xLeft);
                    166:     rclBound.top = FXTOL(rcfxBound.yTop);
                    167:     rclBound.right = FXTOL(rcfxBound.xRight + FIX_ONE);
                    168:     rclBound.bottom = FXTOL(rcfxBound.yBottom + FIX_ONE);
                    169: 
                    170:     bMoreClipping = TRUE;
                    171:     bFirstClipPass = TRUE;
                    172: 
                    173:     while (bMoreClipping)
                    174:     {
                    175:         // handle the clipping.
                    176: 
                    177:         if (bClipping = bDoClipObj(pdev, pco, NULL, &rclBound, &bMoreClipping,
                    178:                                    &bFirstClipPass, MAX_CLIP_RECTS))
                    179:             ps_clip(pdev, TRUE);
                    180: 
                    181:         if (!(DrvCommonPath(pdev, ppo)))
                    182:             return(FALSE);
                    183: 
                    184:         // now transform for geometric lines if necessary.
                    185: 
                    186:         if (plineattrs->fl & LA_GEOMETRIC)
                    187:             ps_geolinexform(pdev, plineattrs, pxo);
                    188: 
                    189:         // now stroke the path.
                    190: 
                    191:         ps_stroke(pdev, pbo, pptlBrushOrg);
                    192: 
                    193:         // restore the CTM if a transform for a geometric line was in effect.
                    194: 
                    195:         if (pdev->cgs.dwFlags & CGS_GEOLINEXFORM)
                    196:         {
                    197:             PrintString(pdev, "SM\n");
                    198:             pdev->cgs.dwFlags &= ~CGS_GEOLINEXFORM;
                    199:         }
                    200: 
                    201:         // restore the clip path to what it was before this call.
                    202: 
                    203:         if (bClipping)
                    204:             ps_restore(pdev, TRUE);
                    205:     }
                    206: 
                    207:     return(TRUE);
                    208: }
                    209: 
                    210: 
                    211: //--------------------------------------------------------------------------
                    212: // BOOL DrvFillPath(pso, ppo, pco, pbo, pptlBrushOrg, mix, flOptions)
                    213: // SURFOBJ     *pso;
                    214: // PATHOBJ     *ppo;
                    215: // CLIPOBJ     *pco;
                    216: // BRUSHOBJ *pbo;
                    217: // PPOINTL      pptlBrushOrg;
                    218: // MIX  mix;
                    219: // FLONG        flOptions;
                    220: //
                    221: // Parameters:
                    222: //
                    223: // Returns:
                    224: //   This function returns TRUE.
                    225: //
                    226: // History:
                    227: //   03-May-1991    -by-    Kent Settle     [kentse]
                    228: //  Wrote it.
                    229: //--------------------------------------------------------------------------
                    230: 
                    231: BOOL DrvFillPath(pso, ppo, pco, pbo, pptlBrushOrg, mix, flOptions)
                    232: SURFOBJ  *pso;
                    233: PATHOBJ  *ppo;
                    234: CLIPOBJ  *pco;
                    235: BRUSHOBJ *pbo;
                    236: PPOINTL   pptlBrushOrg;
                    237: MIX       mix;
                    238: FLONG     flOptions;
                    239: {
                    240:     PDEVDATA   pdev;
                    241:     RECTL       rclBounds;
                    242:     RECTFX      rcfxBounds;
                    243:     BOOL        bClipping;
                    244:     BOOL        bMoreClipping;
                    245:     BOOL        bFirstClipPass;
                    246: 
                    247:     // get the pointer to our DEVDATA structure and make sure it is ours.
                    248: 
                    249:     pdev = (PDEVDATA) pso->dhpdev;
                    250: 
                    251:     if (bValidatePDEV(pdev) == FALSE)
                    252:         return(FALSE);
                    253: 
                    254:     bMoreClipping = TRUE;
                    255:     bFirstClipPass = TRUE;
                    256: 
                    257:     while (bMoreClipping)
                    258:     {
                    259:         // get the bounding rectangle of the path to pass to ps_patfill.
                    260: 
                    261:         PATHOBJ_vGetBounds(ppo, &rcfxBounds);
                    262: 
                    263:         rclBounds.left = FXTOL(rcfxBounds.xLeft);
                    264:         rclBounds.right = FXTOL(rcfxBounds.xRight) + 1;
                    265:         rclBounds.top = FXTOL(rcfxBounds.yTop);
                    266:         rclBounds.bottom = FXTOL(rcfxBounds.yBottom) + 1;
                    267: 
                    268:         // if there is a clip region, clip to it.  we want to keep this
                    269:         // separate from the clip path.
                    270: 
                    271:         if (bClipping = bDoClipObj(pdev, pco, NULL, &rclBounds, &bMoreClipping,
                    272:                                    &bFirstClipPass, MAX_CLIP_RECTS))
                    273:         {
                    274:             if (flOptions & FP_WINDINGMODE)
                    275:                 ps_clip(pdev, TRUE);
                    276:             else
                    277:                 ps_clip(pdev, FALSE);
                    278:         }
                    279: 
                    280:         // if there was no clip region, we need to output a gsave before we
                    281:         // send the clip path, so we can blow it away when we are done.
                    282: 
                    283:         if (!bClipping)
                    284:             ps_save(pdev, TRUE);
                    285: 
                    286:         if (!(DrvCommonPath(pdev, ppo)))
                    287:         {
                    288:             RIP("PSCRIPT!DrvFillPath: invalid pdev.\n");
                    289:             SetLastError(ERROR_INVALID_PARAMETER);
                    290:             return(FALSE);
                    291:         }
                    292: 
                    293:         // now fill the path.
                    294: 
                    295:         if (!ps_patfill(pdev, pso, flOptions, pbo, pptlBrushOrg, mix, &rclBounds,
                    296:                         FALSE, TRUE))
                    297:             return(FALSE);
                    298: 
                    299:         ps_restore(pdev, TRUE);
                    300:     }
                    301: 
                    302:     return(TRUE);
                    303: }
                    304: 
                    305: 
                    306: //--------------------------------------------------------------------------
                    307: // BOOL DrvStrokeAndFillPath(pso, ppo, pco, pxo, pboStroke, plineattrs,
                    308: //                          pboFill, pptlBrushOrg, mixFill, flOptions)
                    309: // SURFOBJ      *pso;
                    310: // PATHOBJ      *ppo;
                    311: // CLIPOBJ      *pco;
                    312: // XFORMOBJ  *pxo;
                    313: // BRUSHOBJ  *pboStroke;
                    314: // PLINEATTRS plineattrs;
                    315: // BRUSHOBJ  *pboFill;
                    316: // PPOINTL       pptlBrushOrg;
                    317: // MIX   mixFill;
                    318: // FLONG         flOptions;
                    319: //
                    320: // Parameters:
                    321: //
                    322: // Returns:
                    323: //   This function returns TRUE.
                    324: //
                    325: // History:
                    326: //   03-May-1991    -by-    Kent Settle     [kentse]
                    327: //  Wrote it.
                    328: //--------------------------------------------------------------------------
                    329: 
                    330: BOOL DrvStrokeAndFillPath(pso, ppo, pco, pxo, pboStroke, plineattrs,
                    331:                          pboFill, pptlBrushOrg, mixFill, flOptions)
                    332: SURFOBJ   *pso;
                    333: PATHOBJ   *ppo;
                    334: CLIPOBJ   *pco;
                    335: XFORMOBJ  *pxo;
                    336: BRUSHOBJ  *pboStroke;
                    337: PLINEATTRS plineattrs;
                    338: BRUSHOBJ  *pboFill;
                    339: PPOINTL    pptlBrushOrg;
                    340: MIX        mixFill;
                    341: FLONG      flOptions;
                    342: {
                    343:     PDEVDATA   pdev;
                    344:     RECTL       rclBounds;
                    345:     RECTFX      rcfxBounds;
                    346:     BOOL       bClipping;
                    347:     ULONG       ulColor;
                    348:     BOOL        bMoreClipping;
                    349:     BOOL        bFirstClipPass;
                    350: #ifdef INDEX_PAL
                    351:     DEVBRUSH   *pBrush;
                    352:     ULONG      *pulColors;
                    353: #endif
                    354: 
                    355:     // get the pointer to our DEVDATA structure and make sure it is ours.
                    356: 
                    357:     pdev = (PDEVDATA) pso->dhpdev;
                    358: 
                    359:     if (bValidatePDEV(pdev) == FALSE)
                    360:         return(FALSE);
                    361: 
                    362:     // deal with LINEATTRS.
                    363: 
                    364:     if (!(ps_setlineattrs(pdev, plineattrs, pxo)))
                    365:         return(FALSE);
                    366: 
                    367:     // output the line color to stroke with.  do this before we handle
                    368:     // clipping, so the line color will remain beyond the gsave/grestore.
                    369: 
                    370: #ifdef INDEX_PAL
                    371:     // just output solid color if there is one.
                    372: 
                    373:     if ((pdev->pntpd->flFlags & COLOR_DEVICE) &&
                    374:         (pdev->psdm.dm.dmColor == DMCOLOR_COLOR))
                    375:         pulColors = PSColorPalette;
                    376:     else
                    377:         pulColors = PSMonoPalette;
                    378: 
                    379:     if (pboStroke->iSolidColor != NOT_SOLID_COLOR)
                    380:     {
                    381:         ps_setrgbcolor(pdev, (PALETTEENTRY *)pulColors + pboStroke->iSolidColor);
                    382:     }
                    383:     else
                    384:     {
                    385:         // get the device brush to draw with.
                    386: 
                    387:         pBrush = (DEVBRUSH *)BRUSHOBJ_pvGetRbrush(pboStroke);
                    388: 
                    389:         if (!pBrush)
                    390:         {
                    391: #if DBG
                    392:             DbgPrint("DrvStrokeAndFillPath: NULL pBrush.\n");
                    393: #endif
                    394:             // something is wrong! stroke with black.
                    395: 
                    396:             ulColor = RGB_BLACK;
                    397:             ps_setrgbcolor(pdev, (PALETTEENTRY *)&ulColor);
                    398:         }
                    399:         else
                    400:         {
                    401:             if (pBrush->iSolidColor == NOT_SOLID_COLOR)
                    402:             {
                    403:                 // get the foreground color.
                    404: 
                    405:                 ps_setrgbcolor(pdev, ((PALETTEENTRY *)pulColors +
                    406:                                *(ULONG *)((PBYTE)pBrush + pBrush->offsetXlate +
                    407:                                sizeof(ULONG))));
                    408:             }
                    409:             else
                    410:             {
                    411:                 ps_setrgbcolor(pdev, (PALETTEENTRY *)&pBrush->iSolidColor);
                    412:             }
                    413:         }
                    414:     }
                    415: #else
                    416:     if (pboStroke->iSolidColor == NOT_SOLID_COLOR)
                    417:     {
                    418: //!!! this needs to be fixed!!! -kentse.
                    419:         ulColor = RGB_GRAY;
                    420: 
                    421:         ps_setrgbcolor(pdev, (BGR_PAL_ENTRY *)&ulColor);
                    422:     }
                    423:     else
                    424:     {
                    425:         // we have a solid brush, so simply output the line color.
                    426: 
                    427:         ps_setrgbcolor(pdev, (BGR_PAL_ENTRY *)&pboStroke->iSolidColor);
                    428:     }
                    429: #endif
                    430: 
                    431:     bMoreClipping = TRUE;
                    432:     bFirstClipPass = TRUE;
                    433: 
                    434:     while (bMoreClipping)
                    435:     {
                    436:         // get the bounding rectangle of the path to pass to ps_patfill.
                    437: 
                    438:         PATHOBJ_vGetBounds(ppo, &rcfxBounds);
                    439: 
                    440:         rclBounds.left = FXTOL(rcfxBounds.xLeft);
                    441:         rclBounds.right = FXTOL(rcfxBounds.xRight) + 1;
                    442:         rclBounds.top = FXTOL(rcfxBounds.yTop);
                    443:         rclBounds.bottom = FXTOL(rcfxBounds.yBottom) + 1;
                    444: 
                    445:         // if there is a clip region, clip to it.  we want to keep this
                    446:         // separate from the clip path.
                    447: 
                    448:         if (bClipping = bDoClipObj(pdev, pco, NULL, &rclBounds, &bMoreClipping,
                    449:                                    &bFirstClipPass, MAX_CLIP_RECTS))
                    450:         {
                    451:             if (flOptions & FP_WINDINGMODE)
                    452:                 ps_clip(pdev, TRUE);
                    453:             else
                    454:                 ps_clip(pdev, FALSE);
                    455:         }
                    456: 
                    457:         // if there was no clip region, we need to output a gsave before we
                    458:         // send the clip path, so we can blow it away when we are done.
                    459: 
                    460:         if (!bClipping)
                    461:             ps_save(pdev, TRUE);
                    462: 
                    463:         if (!(DrvCommonPath(pdev, ppo)))
                    464:         {
                    465:             RIP("PSCRIPT!DrvStrokeAndFillPath: invalid pdev.\n");
                    466:             SetLastError(ERROR_INVALID_PARAMETER);
                    467:             return(FALSE);
                    468:         }
                    469: 
                    470:         // save the path.  then fill it.  then restore the path which
                    471:         // was wiped out when it was filled so we can stroke it.  TRUE
                    472:         // means to do a gsave, not a save command.
                    473: 
                    474:         if (!ps_save(pdev, TRUE))
                    475:             return(FALSE);
                    476: 
                    477:         if (!ps_patfill(pdev, pso, flOptions, pboFill, pptlBrushOrg, mixFill,
                    478:                         &rclBounds, FALSE, TRUE))
                    479:             return(FALSE);
                    480: 
                    481:         if (!ps_restore(pdev, TRUE))
                    482:             return(FALSE);
                    483: 
                    484:         // now transform for geometric lines if necessary.
                    485: 
                    486:         if (plineattrs->fl & LA_GEOMETRIC)
                    487:             ps_geolinexform(pdev, plineattrs, pxo);
                    488: 
                    489:         // now stroke the path.  remember that ps_patfill will have marked that
                    490:         // the path no longer exists.  since we surrounded it with gsave -
                    491:         // grestore, we know otherwise.
                    492: 
                    493:         pdev->cgs.dwFlags |= CGS_PATHEXISTS;
                    494:         ps_stroke(pdev, pboStroke, pptlBrushOrg);
                    495: 
                    496:         // restore the CTM if a transform for a geometric line was in effect.
                    497: 
                    498:         if (pdev->cgs.dwFlags & CGS_GEOLINEXFORM)
                    499:         {
                    500:             PrintString(pdev, "SM\n");
                    501:             pdev->cgs.dwFlags &= ~CGS_GEOLINEXFORM;
                    502:         }
                    503: 
                    504:         ps_restore(pdev, TRUE);
                    505:     }
                    506: 
                    507:     return(TRUE);
                    508: }
                    509: 
                    510: 
                    511: //--------------------------------------------------------------------------
                    512: // BOOL DrvCommonPath(pdev, ppo)
                    513: // PDEVDATA   pdev;
                    514: // PATHOBJ   *ppo;
                    515: //
                    516: //
                    517: // Parameters:
                    518: //
                    519: // Returns:
                    520: //   This function returns TRUE.
                    521: //
                    522: // History:
                    523: //   02-May-1991    -by-    Kent Settle     [kentse]
                    524: //  Wrote it.
                    525: //--------------------------------------------------------------------------
                    526: 
                    527: BOOL DrvCommonPath(pdev, ppo)
                    528: PDEVDATA   pdev;
                    529: PATHOBJ   *ppo;
                    530: {
                    531:     PATHDATA   pathdata;
                    532:     POINTL     ptl, ptl1, ptl2;
                    533:     POINTFIX    *pptfx;
                    534:     LONG       cPoints;
                    535:     BOOL       bMore;
                    536: 
                    537:     // before we enumerate the path, let's make sure we have a clean start.
                    538: 
                    539:     ps_newpath(pdev);
                    540: 
                    541:     // enumerate the path, doing what needs to be done along the way.
                    542: 
                    543:     PATHOBJ_vEnumStart(ppo);
                    544: 
                    545:     do
                    546:     {
                    547:         bMore = PATHOBJ_bEnum(ppo, &pathdata);
                    548: 
                    549:         // get a local pointer to the array of POINTFIX's.
                    550: 
                    551:         pptfx = pathdata.pptfx;
                    552:         cPoints = (LONG)pathdata.count;
                    553: 
                    554:         if (pathdata.flags & PD_BEGINSUBPATH)
                    555:         {
                    556:             // the first path begins a new subpath.  it is not connected
                    557:             // to the previous subpath.  note that if this flag is not
                    558:             // set, then the starting point for the first curve to be
                    559:             // drawn from this data is the last point returned in the
                    560:             // previous call.
                    561: 
                    562: #if 0
                    563:             if (pathdata.flags & PD_RESETSTYLE)
                    564:             {
                    565:                // this bit is defined only if this record begins a new
                    566:                 // subpath.  if set, it indicates that the style state
                    567:                 // should be reset to zero at the beginning of the subpath.
                    568:                 // if not set, the style state is defined by the
                    569:                 // LINEATTRS, or continues from the previous path.
                    570: 
                    571: #if DBG
                    572:                DbgPrint("DrvCommonPath: PD_RESETSTYLE flag set.\n");
                    573: #endif
                    574:                 //!!! fill in here - kentse
                    575:             }
                    576: #endif
                    577: 
                    578:             // begin the subpath within the printer by issuing a moveto
                    579:             // command.
                    580: 
                    581:             ptl.x = FXTOL(pptfx->x);
                    582:             ptl.y = FXTOL(pptfx->y);
                    583:             pptfx++;
                    584:             cPoints--;
                    585: 
                    586:             ps_moveto(pdev, &ptl);
                    587:         }
                    588: 
                    589:         if (pathdata.flags & PD_BEZIERS)
                    590:         {
                    591:             // if set, then each set of three control points returned for
                    592:             // this call describe a Bezier curve.  if clear then each
                    593:             // control point describes a line segment. a starting point
                    594:             // for either type is either explicit at the beginning of the
                    595:             // subpath, or implicit as the endpoint of the previous curve.
                    596: 
                    597:             // there had better be the correct number of points if we are
                    598:             // going to draw curves.
                    599: 
                    600:             if ((cPoints % 3) != 0)
                    601:             {
                    602:                RIP("PSCRIPT!DrvCommonPath: incompatible number of points.\n");
                    603:                SetLastError(ERROR_INVALID_PARAMETER);
                    604:                 return(FALSE);
                    605:             }
                    606: 
                    607:             // now draw the bezier for each set of points.
                    608: 
                    609:             while (cPoints > 0)
                    610:             {
                    611:                 ptl.x = FXTOL(pptfx->x);
                    612:                 ptl.y = FXTOL(pptfx->y);
                    613:                 pptfx++;
                    614:                 ptl1.x = FXTOL(pptfx->x);
                    615:                 ptl1.y = FXTOL(pptfx->y);
                    616:                 pptfx++;
                    617:                 ptl2.x = FXTOL(pptfx->x);
                    618:                 ptl2.y = FXTOL(pptfx->y);
                    619:                 pptfx++;
                    620: 
                    621:                 ps_curveto(pdev, &ptl, &ptl1, &ptl2);
                    622:                 cPoints -= 3;
                    623:             }
                    624:         }
                    625:         else
                    626:         {
                    627:             // draw the line segment for each point.
                    628: 
                    629:             while (cPoints-- > 0)
                    630:             {
                    631:                 ptl.x = FXTOL(pptfx->x);
                    632:                 ptl.y = FXTOL(pptfx->y);
                    633:                 pptfx++;
                    634: 
                    635:                 ps_lineto(pdev, &ptl);
                    636:             }
                    637:         }
                    638:     } while(bMore);
                    639: 
                    640:     if (pathdata.flags & PD_ENDSUBPATH)
                    641:     {
                    642:         // the last point in the array ends the subpath.  this subpath
                    643:         // may be open or closed depending on the PD_CLOSEFIGURE flag.
                    644:         // if there is more data to be returned in the path, then the
                    645:         // next record will begin a new subpath.  note that a single
                    646:         // record might begin and end a subpath.
                    647: 
                    648:         if (pathdata.flags & PD_CLOSEFIGURE)
                    649:         {
                    650:             // this bit is only defined if the record ends a subpath.  if
                    651:             // set, then there is an implicit line segment connecting
                    652:             // the last point of the subpath with the first point.  if
                    653:             // such a closed subpath is being stroked, then joins are used
                    654:             // all around the path, and there are no end caps. if this
                    655:             // flag is not set then the subpath is considered open, even
                    656:             // if the first and last points happen to be coincident.  in
                    657:             // that case, end caps should be drawn.  this flag is not
                    658:             // relevant for filling, since all subpaths are assumed closed
                    659:             // when a path is filled.
                    660: 
                    661:             ps_closepath(pdev);
                    662:         }
                    663:     }
                    664: 
                    665:     return(TRUE);
                    666: }

unix.superglobalmegacorp.com

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