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

1.1       root        1: //--------------------------------------------------------------------------
                      2: //
                      3: // Module Name:  PSLAYER.C
                      4: //
                      5: // Brief Description:  This module contains the PSCRIPT driver's layer
                      6: // of PostScript translation routines.
                      7: //
                      8: // Author:  Kent Settle (kentse)
                      9: // Created: 17-Dec-1990
                     10: //
                     11: // Copyright (c) 1990 - 1992 Microsoft Corporation
                     12: //
                     13: // This module contains routines to handle the outputting of the PostScript
                     14: // language commands to the output channel.  One of the main functions of
                     15: // this pslayer is to help provide device independence, by shielding the
                     16: // output of the actual device resolution.  The NT PostScript driver will
                     17: // output all PostScript commands in POINTS space; that is 72 dots per inch.
                     18: // This is the default user coordinates for ALL PostScript printers, so we
                     19: // will use it.  As far as the DDI is concerned, it only knows of the actual
                     20: // device resolution.  This pslayer will convert between device coordinates
                     21: // and the PostScript user coordinates.
                     22: //
                     23: // Coordinates will be output to the device using PS_FIX (24.8) numbers.
                     24: // It may be useful, therefore to note the following relations using
                     25: // PS_FIX numbers.  PS_FIX / LONG = PS_FIX.  LONG * PS_FIX = PS_FIX.
                     26: // (PS_FIX * PS_FIX) >> 8 = PS_FIX.
                     27: //--------------------------------------------------------------------------
                     28: 
                     29: #include "pscript.h"
                     30: #include <memory.h>
                     31: #include "enable.h"
                     32: 
                     33: extern LONG iHipot(LONG, LONG);
                     34: 
                     35: //--------------------------------------------------------------------------
                     36: // VOID ps_setrgbcolor(pdev, pbgr)
                     37: // PDEVDATA        pdev;
                     38: // BGR_PAL_ENTRY  *pbgr;
                     39: //
                     40: // This routine is called by the driver to set the current color.  PostScript
                     41: // printers only know about the current color.    For example, if you are
                     42: // printing text in red and lines in blue, and you alternate printing text
                     43: // and a line, you also have to set the current color each time.
                     44: //
                     45: // For black and white devices the RGB color is converted to a gray scale
                     46: // between 0.0 (black) and 1.0 (white).
                     47: //
                     48: // Parameters:
                     49: //   pdev:
                     50: //     pointer to DEVDATA structure.
                     51: //
                     52: //   lColor:
                     53: //     RGB value of new color.
                     54: //
                     55: // Returns:
                     56: //   This function returns no value.
                     57: //
                     58: // History:
                     59: //   17-Dec-1990     -by-     Kent Settle     (kentse)
                     60: //  Wrote it.
                     61: //--------------------------------------------------------------------------
                     62: 
                     63: 
                     64: VOID ps_setrgbcolor(pdev, pbgr)
                     65: PDEVDATA        pdev;
                     66: BGR_PAL_ENTRY  *pbgr;
                     67: {
                     68:     PS_FIX psfxRed, psfxGreen, psfxBlue;
                     69:     PS_FIX psfxGray;
                     70: 
                     71:     // if the all colors to black flag is set, set all colors, except
                     72:     // white to black.
                     73: 
                     74:     if (pdev->psdm.dwFlags & PSDEVMODE_BLACK)
                     75:     {
                     76:         // if the last color was non-white and the new color is non-white,
                     77:         // or the last color was white and the new color is white, then
                     78:         // we want to leave the color alone.
                     79: 
                     80:         if (((pdev->cgs.ulColor != RGB_WHITE) && (*(ULONG *)pbgr != RGB_WHITE)) ||
                     81:             ((pdev->cgs.ulColor == RGB_WHITE) && (*(ULONG *)pbgr == RGB_WHITE)))
                     82:             return;
                     83: 
                     84:         // the color must be updated in the printer.
                     85: 
                     86:         if (*(ULONG *)pbgr == RGB_WHITE)
                     87:             PrintString(pdev, "1 g\n");
                     88:         else
                     89:             PrintString(pdev, "0 g\n");
                     90:     }
                     91:     else if (pdev->cgs.ulColor != *(ULONG *)pbgr)
                     92:     {
                     93:         // save the new color in the current graphics state structure.
                     94: 
                     95:         pdev->cgs.ulColor = *(ULONG *)pbgr;
                     96: 
                     97:         if (pdev->psdm.dm.dmColor == DMCOLOR_COLOR)
                     98:         {
                     99:             // each color component must be output to the printer
                    100:             // in the range from 0.0 to 1.0, so normalize to this
                    101:             // range by dividing by 255.
                    102: 
                    103:             psfxRed = LTOPSFX((ULONG)pbgr->bgrRed) / 255;
                    104:             psfxGreen = LTOPSFX((ULONG)pbgr->bgrGreen) / 255;
                    105:             psfxBlue = LTOPSFX((ULONG)pbgr->bgrBlue) / 255;
                    106: 
                    107:             // if each of the color components is equal, just output a
                    108:             // gray scale.  otherwise, output the RGB value.
                    109: 
                    110:            if ((psfxRed == psfxGreen) && (psfxRed == psfxBlue))
                    111:            {
                    112:                PrintPSFIX(pdev, 1, psfxRed);
                    113:                 PrintString(pdev, " g\n");
                    114:            }
                    115:            else
                    116:            {
                    117:                PrintPSFIX(pdev, 3, psfxRed, psfxGreen, psfxBlue);;
                    118:                 PrintString(pdev, " r\n");
                    119:            }
                    120:         }
                    121:         else
                    122:         {
                    123:             // convert the RGB color to a gray scale and output to the
                    124:             // printer.
                    125: 
                    126:             psfxGray = psfxRGBtoGray(pbgr);
                    127:            PrintPSFIX(pdev, 1, psfxGray);
                    128:             PrintString(pdev, " g\n");
                    129:         }
                    130:     }
                    131: }
                    132: 
                    133: 
                    134: //--------------------------------------------------------------------------
                    135: // VOID ps_newpath(pdev)
                    136: // PDEVDATA    pdev;
                    137: //
                    138: // This routine is called by the driver to issue a newpath command to
                    139: // the printer.
                    140: //
                    141: // Parameters:
                    142: //   pdev:
                    143: //     pointer to DEVDATA structure.
                    144: //
                    145: // Returns:
                    146: //   This function returns no value.
                    147: //
                    148: // History:
                    149: //   18-Dec-1990     -by-     Kent Settle     (kentse)
                    150: //  Wrote it.
                    151: //--------------------------------------------------------------------------
                    152: 
                    153: VOID ps_newpath(pdev)
                    154: PDEVDATA    pdev;
                    155: {
                    156:     if (pdev->cgs.dwFlags & CGS_PATHEXISTS)
                    157:     {
                    158:        PrintString(pdev, "n\n");
                    159: 
                    160:         // indicate that no path exists in the printer.
                    161: 
                    162:         pdev->cgs.dwFlags &= ~CGS_PATHEXISTS;
                    163:     }
                    164: }
                    165: 
                    166: 
                    167: //--------------------------------------------------------------------------
                    168: // BOOL ps_save(pdev, bgsave)
                    169: // PDEVDATA    pdev;
                    170: // BOOL        bgsave;
                    171: //
                    172: // This routine is called by the driver to save the current graphics state.
                    173: //
                    174: // Parameters:
                    175: //   pdev:
                    176: //     pointer to DEVDATA structure.
                    177: //
                    178: //   bgsave:
                    179: //     TRUE if to perform gsave instead of save.
                    180: //
                    181: // Returns:
                    182: //   This function returns no value.
                    183: //
                    184: // History:
                    185: //   18-Dec-1990     -by-     Kent Settle     (kentse)
                    186: //  Wrote it.
                    187: //   06-Nov-1991    -by-    Kent Settle     [kentse]
                    188: //  Rewrote it using linked list.
                    189: //--------------------------------------------------------------------------
                    190: 
                    191: BOOL ps_save(pdev, bgsave)
                    192: PDEVDATA       pdev;
                    193: BOOL   bgsave;
                    194: {
                    195:     CGS    *pcgs;
                    196:     CGS    *pNew;
                    197:     DLFONT *pDLFont;
                    198: 
                    199:     // save the current graphics state in a linked list.
                    200: 
                    201:     // get pointer to beginning of gsave linked list.
                    202: 
                    203:     pcgs = pdev->pcgsSave;
                    204: 
                    205:     // move to the last entry in the list.
                    206: 
                    207:     if (pcgs)
                    208:     {
                    209:        while(pcgs->pcgsNext)
                    210:            pcgs = pcgs->pcgsNext;
                    211:     }
                    212: 
                    213:     // allocate the new element of the linked list.
                    214: 
                    215:     if (!(pNew = (PCGS)HeapAlloc(pdev->hheap, 0, sizeof(CGS))))
                    216:     {
                    217:         RIP("PSCRIPT!ps_save: HeapAlloc for pNew failed.\n");
                    218:        return(FALSE);
                    219:     }
                    220: 
                    221:     // save the current graphics state in our new element.
                    222: 
                    223:     memcpy(pNew, &pdev->cgs, sizeof(CGS));
                    224: 
                    225:     // allocate a new set of DLFONT structures, then copy the existing ones
                    226:     // to the new ones.
                    227: 
                    228:     if (!(pNew->pDLFonts = (DLFONT *)HeapAlloc(pdev->hheap, 0,
                    229:                                               sizeof(DLFONT) * (pdev->iDLFonts + 1))))
                    230:     {
                    231:         RIP("PSCRIPT!ps_save: HeapAlloc for pDLFonts failed.\n");
                    232:         HeapFree(pdev->hheap, 0, (PVOID)pNew);
                    233:         return(FALSE);
                    234:     }
                    235: 
                    236:     pDLFont = pNew->pDLFonts;
                    237: 
                    238:     memcpy(pDLFont, pdev->cgs.pDLFonts, sizeof(DLFONT) * (pdev->iDLFonts));
                    239: 
                    240:     // clear out the last entry.
                    241: 
                    242:     pDLFont += pdev->iDLFonts;
                    243:     memset(pDLFont, 0, sizeof(DLFONT));
                    244: 
                    245:     // if this is first element in the list, set the pointer in our
                    246:     // pdev, else update list to point to new element.
                    247: 
                    248:     if (!pcgs)
                    249:        pdev->pcgsSave = pNew;
                    250:     else
                    251:        pcgs->pcgsNext = pNew;
                    252: 
                    253:     // initialize pointers in new element.
                    254: 
                    255:     pNew->pcgsPrev = pcgs;  // NULL if first gsave.
                    256:     pNew->pcgsNext = NULL;
                    257: 
                    258:     // output save command to printer.
                    259: 
                    260:     if (bgsave)
                    261:        PrintString(pdev, "gs\n");
                    262:     else
                    263:        PrintString(pdev, "save\n");
                    264: 
                    265:     return(TRUE);
                    266: }
                    267: 
                    268: 
                    269: //--------------------------------------------------------------------------
                    270: // BOOL ps_restore(pdev, bgrestore)
                    271: // PDEVDATA    pdev;
                    272: // BOOL        bgrestore;
                    273: //
                    274: // This routine is called by the driver to restore a previously saved
                    275: // graphics state.
                    276: //
                    277: // Parameters:
                    278: //   pdev:
                    279: //     pointer to DEVDATA structure.
                    280: //
                    281: // Returns:
                    282: //   This function returns no value.
                    283: //
                    284: // History:
                    285: //   18-Dec-1990     -by-     Kent Settle     (kentse)
                    286: //  Wrote it.
                    287: //   06-Nov-1991    -by-    Kent Settle     [kentse]
                    288: //  Rewrote it using linked list.
                    289: //   15-Feb-1993    -by-    Rob Kiesler
                    290: //  If a restore is being performed, reset pdev flags indicating that
                    291: //  the Adobe PS utility, pattern, and image procsets have been downloaded.
                    292: //--------------------------------------------------------------------------
                    293: 
                    294: BOOL ps_restore(pdev, bgrestore)
                    295: PDEVDATA       pdev;
                    296: BOOL   bgrestore;
                    297: {
                    298:     CGS    *pcgs;
                    299:     CGS    *pcgsTmp;
                    300:     DLFONT *pDLFont;
                    301: 
                    302:     // restore the current graphics state from the last element
                    303:     // of the graphics state save linked list.
                    304: 
                    305:     // get pointer to the linked list.
                    306: 
                    307:     pcgs = pdev->pcgsSave;
                    308: 
                    309:     // find the last element of the list.
                    310: 
                    311:     while (pcgs->pcgsNext)
                    312:        pcgs = pcgs->pcgsNext;
                    313: 
                    314:     // we are about to copy the last saved CGS from the linked list into the
                    315:     // current CGS.  therefore, we must free up memory used in the CGS before
                    316:     // we clobber the pointers.
                    317: 
                    318:     if  (pdev->cgs.pDLFonts)
                    319:     {
                    320:         // point to the last DLFONT structure.  this will have been filled
                    321:         // in iff we have hit our downloaded font threshold.  if it is filled
                    322:         // in, free up the hglyph vector.
                    323: 
                    324:         pDLFont = pdev->cgs.pDLFonts;
                    325:         pDLFont += pdev->iDLFonts;
                    326: 
                    327:         if (pDLFont->phgVector)
                    328:             HeapFree(pdev->hheap, 0, (PVOID)pDLFont->phgVector);
                    329: 
                    330:         HeapFree(pdev->hheap, 0, (PVOID)pdev->cgs.pDLFonts);
                    331:     }
                    332: 
                    333:     // restore the current graphics state.
                    334: 
                    335:     memcpy(&pdev->cgs, pcgs, sizeof(CGS));
                    336: 
                    337:     // back up one element, and free up the last element of the list.
                    338: 
                    339:     if (!(pcgsTmp = pcgs->pcgsPrev))
                    340:     {
                    341:        // restored back to original state.  clear out pointer to
                    342:        // linked list.
                    343: 
                    344:        pdev->pcgsSave = (CGS *)NULL;
                    345:     }
                    346:     else
                    347:     {
                    348:        // mark the current element as the last in the list.
                    349: 
                    350:        pcgsTmp->pcgsNext = (PCGS)NULL;
                    351:     }
                    352: 
                    353:     // free up the save CGS.
                    354: 
                    355:     HeapFree(pdev->hheap, 0, (PVOID)pcgs);
                    356: 
                    357:     if (bgrestore)
                    358:        PrintString(pdev, "gr\n");
                    359:     else
                    360:     {
                    361:       //
                    362:       // If the Adobe PS Utilites were downloaded, clean up after
                    363:       // them before blowing them away with the restore.
                    364:       //
                    365:       if (pdev->dwFlags & PDEV_UTILSSENT)
                    366:       {
                    367:          PrintString(pdev, "Adobe_WinNT_Driver_Gfx dup /terminate get exec\n");
                    368:          pdev->dwFlags &= ~(PDEV_UTILSSENT | PDEV_BMPPATSENT | PDEV_IMAGESENT);
                    369:       }
                    370:       PrintString(pdev, "restore\n");
                    371: 
                    372:     }
                    373: 
                    374:     return(TRUE);
                    375: }
                    376: 
                    377: 
                    378: //--------------------------------------------------------------------------
                    379: // VOID ps_clip(pdev, bWinding)
                    380: // PDEVDATA    pdev;
                    381: // BOOL        bWinding;
                    382: //
                    383: // This routine is called by the driver to intersect the current path with
                    384: // the clipping path and make this the nwe clipping path.  The winding
                    385: // number rule is used to determine the area clipped, if bWinding is TRUE.
                    386: //
                    387: // Parameters:
                    388: //   pdev:
                    389: //     pointer to DEVDATA structure.
                    390: //
                    391: // Returns:
                    392: //   This function returns no value.
                    393: //
                    394: // History:
                    395: //   13-Feb-1991     -by-     Kent Settle     (kentse)
                    396: //  Wrote it.
                    397: //--------------------------------------------------------------------------
                    398: 
                    399: VOID ps_clip(pdev, bWinding)
                    400: PDEVDATA    pdev;
                    401: BOOL       bWinding;
                    402: {
                    403:     // output the clip command to the printer, then output a newpath
                    404:     // command, since the clip command does not destroy the path in the
                    405:     // printer.
                    406: 
                    407:     if (bWinding)
                    408:        PrintString(pdev, "clip n\n");
                    409:     else
                    410:        PrintString(pdev, "eoclip n\n");
                    411: 
                    412:     // indicate that the path no longer exists.
                    413: 
                    414:     pdev->cgs.dwFlags &= ~CGS_PATHEXISTS;
                    415: }
                    416: 
                    417: 
                    418: //--------------------------------------------------------------------------
                    419: // VOID ps_show(pdev, pstro, flAccel, pdata)
                    420: // PDEVDATA    pdev;
                    421: // STROBJ     *pstro;
                    422: // FLONG       flAccel;
                    423: // TEXTDATA   *pdata;
                    424: //
                    425: // This routine is called by the driver to intersect the current path with
                    426: // the clipping path and make this the nwe clipping path.  The winding
                    427: // number rule is used to determine the area clipped, if bWinding is TRUE.
                    428: //
                    429: // Parameters:
                    430: //   pdev:
                    431: //     pointer to DEVDATA structure.
                    432: //
                    433: // Returns:
                    434: //   This function returns no value.
                    435: //
                    436: // History:
                    437: //   13-Feb-1991     -by-     Kent Settle     (kentse)
                    438: //  Wrote it.
                    439: //--------------------------------------------------------------------------
                    440: 
                    441: VOID ps_show(pdev, pstro, flAccel, pdata)
                    442: PDEVDATA    pdev;
                    443: STROBJ     *pstro;
                    444: FLONG       flAccel;
                    445: TEXTDATA   *pdata;
                    446: {
                    447:     // close the string and send out the show command, abreviated
                    448:     // by 't', or our version of the fixed pitched horizontal
                    449:     // show command 'H', or the proportional horizontal show
                    450:     // command 'h', or the fixed pitched vertical show command 'V',
                    451:     // or the proportional vertical show command 'v'.
                    452: 
                    453:     if ((flAccel == 0) || (flAccel & SO_FLAG_DEFAULT_PLACEMENT) ||
                    454:         (pstro->cGlyphs == 1))
                    455:         PrintString(pdev, ")t\n");
                    456:     else if (flAccel & SO_HORIZONTAL)
                    457:     {
                    458:         if (pstro->ulCharInc)
                    459:             PrintString(pdev, ")H\n");
                    460:         else
                    461:         {
                    462:             if (pdata->bJustification)
                    463:             {
                    464:                 // if we calculated the text justification, and it turns
                    465:                 // out the the justification widths are zero, just to
                    466:                 // a reguluar show command, otherwise it is time for
                    467:                 // awidthshow.
                    468: 
                    469:                 if ((pdata->ptSpace.x == 0) && (pdata->ptNonSpace.x == 0))
                    470:                     PrintString(pdev, ")t\n");
                    471:                 else
                    472:                     PrintString(pdev, ")aw\n");
                    473:             }
                    474:             else
                    475:                 PrintString(pdev, ")h\n");
                    476:         }
                    477:     }
                    478:     else
                    479:     {
                    480:         if (pstro->ulCharInc)
                    481:             PrintString(pdev, ")V\n");
                    482:         else
                    483:             PrintString(pdev, ")v\n");
                    484:     }
                    485: }
                    486: 
                    487: 
                    488: //--------------------------------------------------------------------------
                    489: // VOID ps_box(pdev, prectl)
                    490: // PDEVDATA    pdev;
                    491: // PRECTL    prectl;
                    492: //
                    493: // This routine is called by the driver to send box drawing commands to
                    494: // the printer.
                    495: //
                    496: // Parameters:
                    497: //   pdev:
                    498: //     Pointer to DEVDATA structure.
                    499: //
                    500: //   prectl:
                    501: //     Pointer to RECTL defining the box.
                    502: //
                    503: // Returns:
                    504: //   This function returns no value.
                    505: //
                    506: // History:
                    507: //   13-Feb-1991     -by-     Kent Settle     (kentse)
                    508: //  Wrote it.
                    509: //--------------------------------------------------------------------------
                    510: 
                    511: VOID ps_box(pdev, prectl)
                    512: PDEVDATA pdev;
                    513: PRECTL     prectl;
                    514: {
                    515:     RECTPSFX   rectpsfx;
                    516: 
                    517:     // output the box command to the printer.  remember to convert
                    518:     // between device resolution and PostScript user coordinates.
                    519: 
                    520:     // get a local copy of the rectangle, turn it into FIX numbers,
                    521:     // flip over the y coordinates since 0,0 is upper left under NT, and
                    522:     // 0,0 is lower left under PostScript.
                    523: 
                    524:     rectpsfx.xLeft = X72DPI(prectl->left);
                    525:     rectpsfx.yBottom = Y72DPI(prectl->bottom);
                    526:     rectpsfx.xRight = X72DPI(prectl->right);
                    527:     rectpsfx.yTop = Y72DPI(prectl->top);
                    528: 
                    529:     PrintPSFIX(pdev, 4, rectpsfx.xLeft, rectpsfx.yTop,
                    530:               rectpsfx.xRight, rectpsfx.yBottom);
                    531:     PrintString(pdev, " box\n");
                    532: 
                    533:     // indicate that a path now exists.
                    534: 
                    535:     pdev->cgs.dwFlags |= CGS_PATHEXISTS;
                    536: }
                    537: 
                    538: 
                    539: //--------------------------------------------------------------------------
                    540: // VOID ps_moveto(pdev, pptl)
                    541: // PDEVDATA    pdev;
                    542: // PPOINTL    pptl;
                    543: //
                    544: // This routine is called by the driver to update the current position
                    545: // in the printer.
                    546: //
                    547: // Parameters:
                    548: //   pdev:
                    549: //     Pointer to DEVDATA structure.
                    550: //
                    551: //   pptl:
                    552: //     Pointer to PPOINTL defining new current position.
                    553: //
                    554: // Returns:
                    555: //   This function returns no value.
                    556: //
                    557: // History:
                    558: //   26-Apr-1991     -by-     Kent Settle     (kentse)
                    559: //  Wrote it.
                    560: //--------------------------------------------------------------------------
                    561: 
                    562: VOID ps_moveto(pdev, pptl)
                    563: PDEVDATA     pdev;
                    564: PPOINTL      pptl;
                    565: {
                    566:     POINTPSFX  ptpsfx;
                    567: 
                    568:     // output the moveto command if new position is different from
                    569:     // the old position.  remember to flip from top to bottom, since
                    570:     // under NT 0,0 is top left, and under PostScript 0,0 is bottom left.
                    571:     // also, we should output a moveto command even if we are at the
                    572:     // current location, if a path does not exist.
                    573: 
                    574:     if ((pptl->x != pdev->cgs.ptlCurPos.x) ||
                    575:         (pptl->y != pdev->cgs.ptlCurPos.y) ||
                    576:         (!(pdev->cgs.dwFlags & CGS_PATHEXISTS)))
                    577:     {
                    578:        ptpsfx.x = X72DPI(pptl->x);
                    579:        ptpsfx.y = Y72DPI(pptl->y);
                    580: 
                    581:         // output PostScript user coordinates to the printer.
                    582: 
                    583:        PrintPSFIX(pdev, 2, ptpsfx.x, ptpsfx.y);
                    584:         PrintString(pdev, " M\n");
                    585: 
                    586:         // save the new current position in device coordinates.
                    587: 
                    588:         pdev->cgs.ptlCurPos = *pptl;
                    589: 
                    590:         // state that a path now exists in the printer.
                    591: 
                    592:         pdev->cgs.dwFlags |= CGS_PATHEXISTS;
                    593:     }
                    594: }
                    595: 
                    596: 
                    597: //--------------------------------------------------------------------------
                    598: // VOID ps_showpage(pdev)
                    599: // PDEVDATA    pdev;
                    600: //
                    601: // This routine issues a showpage command to the printer, and resets
                    602: // the current graphics state (which is done in the printer by the
                    603: // showpage command).
                    604: //
                    605: // Parameters:
                    606: //   pdev:
                    607: //     Pointer to DEVDATA structure.
                    608: //
                    609: // Returns:
                    610: //   This function returns no value.
                    611: //
                    612: // History:
                    613: //   01-May-1991     -by-     Kent Settle     (kentse)
                    614: //  Wrote it.
                    615: //--------------------------------------------------------------------------
                    616: 
                    617: VOID ps_showpage(pdev)
                    618: PDEVDATA    pdev;
                    619: {
                    620:     // output the eject command to the printer.
                    621: 
                    622:     PrintString(pdev, "showpage\n");
                    623: 
                    624:     init_cgs(pdev);
                    625: }
                    626: 
                    627: 
                    628: //--------------------------------------------------------------------------
                    629: // VOID init_cgs(pdev)
                    630: // PDEVDATA    pdev;
                    631: //
                    632: // This routine is called to reset the current graphics state.
                    633: //
                    634: // Parameters:
                    635: //   pdev:
                    636: //     Pointer to DEVDATA structure.
                    637: //
                    638: // Returns:
                    639: //   This function returns no value.
                    640: //
                    641: // History:
                    642: //   01-May-1991     -by-     Kent Settle     (kentse)
                    643: //  Wrote it.
                    644: //--------------------------------------------------------------------------
                    645: 
                    646: VOID init_cgs(pdev)
                    647: PDEVDATA    pdev;
                    648: {
                    649:     PCGS    pcgs;
                    650:     DWORD   i;
                    651:     DLFONT *pDLFont, *pDLFontSave;
                    652: 
                    653:     pcgs = &pdev->cgs;
                    654: 
                    655:     // save pointer to DLFONT structures.
                    656: 
                    657:     pDLFont = pdev->cgs.pDLFonts;
                    658:     pDLFontSave = pDLFont;
                    659: 
                    660:     // if any downloaded fonts currently exist, free up their memory.
                    661: 
                    662:     if (pDLFont)
                    663:     {
                    664:         for (i = 0; i < pcgs->cDownloadedFonts; i++)
                    665:         {
                    666:             if (pDLFont->phgVector)
                    667:                 HeapFree(pdev->hheap, 0, (PVOID)pDLFont->phgVector);
                    668: 
                    669:             pDLFont++;
                    670:         }
                    671:     }
                    672: 
                    673:     // clear all the softfont downloading bits, if any softfonts.
                    674: 
                    675:     if (pcgs->pSFArray)
                    676:        memset(pcgs->pSFArray, 0, ((pdev->cSoftFonts + 7) / 8));
                    677: 
                    678:     // initialize the entire structure to zero, then fill in the
                    679:     // elements we care about.
                    680: 
                    681:     memset(pcgs, 0, sizeof(CGS));
                    682: 
                    683:     pcgs->lineattrs.fl = LA_GEOMETRIC;
                    684:     pcgs->lineattrs.iJoin = JOIN_MITER;
                    685:     pcgs->lineattrs.iEndCap = ENDCAP_BUTT;
                    686:     pcgs->psfxLineWidth = 0;
                    687:     pcgs->lineattrs.eMiterLimit = (FLOAT)10.0;
                    688:     pcgs->ulColor = RGB_BLACK;
                    689:     pcgs->FontXform.eM11 = (float)1.0;
                    690:     pcgs->FontXform.eM22 = (float)1.0;
                    691:     pcgs->GeoLineXform.eM11 = (float)1.0;
                    692:     pcgs->GeoLineXform.eM22 = (float)1.0;
                    693:     pcgs->psfxScaleFactor = LTOPSFX(10L);
                    694: 
                    695:     // restore pointer to DLFONT structures.
                    696: 
                    697:     pcgs->pDLFonts = pDLFontSave;
                    698: }
                    699: 
                    700: 
                    701: //--------------------------------------------------------------------------
                    702: // VOID ps_stroke(pdev, pbo, pptl)
                    703: // PDEVDATA    pdev;
                    704: // BRUSHOBJ   *pbo;
                    705: // PPOINTL     pptl;
                    706: //
                    707: // This routine is called to stroke the current path.
                    708: //
                    709: // Parameters:
                    710: //   pdev:
                    711: //     Pointer to DEVDATA structure.
                    712: //
                    713: //   pbo:
                    714: //     Pointer to BRUSHOBJ to use for stroking.
                    715: //
                    716: //   pptl:
                    717: //     Pointer to POINTL to use for brush origin.
                    718: //
                    719: // Returns:
                    720: //   This function returns no value.
                    721: //
                    722: // History:
                    723: //   03-May-1991     -by-     Kent Settle     (kentse)
                    724: //  Wrote it.
                    725: //--------------------------------------------------------------------------
                    726: 
                    727: VOID ps_stroke(pdev, pbo, pptl)
                    728: PDEVDATA    pdev;
                    729: BRUSHOBJ   *pbo;
                    730: PPOINTL     pptl;
                    731: {
                    732:     UNREFERENCED_PARAMETER(pptl);
                    733: 
                    734:     // stroke the path if it exists.
                    735: 
                    736:     if (pdev->cgs.dwFlags & CGS_PATHEXISTS)
                    737:     {
                    738:         //!!! check into a path buffer.  - kentse.
                    739: 
                    740:        PrintString(pdev, "s\n");
                    741:     }
                    742: #if DBG
                    743:     else
                    744:         DbgPrint("PSCRIPT!ps_stroke: stroking a non-existent path.\n");
                    745: #endif
                    746: 
                    747:     // the path gets destroyed in the printer, when it is stroked, so
                    748:     // mark it as such.
                    749: 
                    750:     pdev->cgs.dwFlags &= ~CGS_PATHEXISTS;
                    751: }
                    752: 
                    753: 
                    754: //--------------------------------------------------------------------------
                    755: // VOID ps_lineto(pdev, pptl)
                    756: // PDEVDATA    pdev;
                    757: // PPOINTL    pptl;
                    758: //
                    759: // This routine is called by the driver to output a lineto command, as
                    760: // well as update the current position.
                    761: //
                    762: // Parameters:
                    763: //   pdev:
                    764: //     Pointer to DEVDATA structure.
                    765: //
                    766: //   pptl:
                    767: //     Pointer to PPOINTL defining new current position.
                    768: //
                    769: // Returns:
                    770: //   This function returns no value.
                    771: //
                    772: // History:
                    773: //   03-May-1991     -by-     Kent Settle     (kentse)
                    774: //  Wrote it.
                    775: //--------------------------------------------------------------------------
                    776: 
                    777: VOID ps_lineto(pdev, pptl)
                    778: PDEVDATA     pdev;
                    779: PPOINTL      pptl;
                    780: {
                    781:     POINTPSFX   ptpsfx;
                    782: 
                    783:     // output the lineto command and set the new current position in
                    784:     // the printer.  remember to flip from top to bottom, since
                    785:     // under NT 0,0 is top left, and under PostScript 0,0 is bottom left.
                    786: 
                    787:     if ((pptl->x != pdev->cgs.ptlCurPos.x) ||
                    788:         (pptl->y != pdev->cgs.ptlCurPos.y))
                    789:     {
                    790:        ptpsfx.x = X72DPI(pptl->x);
                    791:        ptpsfx.y = Y72DPI(pptl->y);
                    792: 
                    793:         // output the lineto command using PostScript user coordinates,
                    794:         // then update the current position.
                    795: 
                    796:        PrintPSFIX(pdev, 2, ptpsfx.x, ptpsfx.y);
                    797:         PrintString(pdev, " L\n");
                    798: 
                    799:         // save the new current position in device coordinates.
                    800: 
                    801:         pdev->cgs.ptlCurPos = *pptl;
                    802: 
                    803:         // mark that we do indeed have a path.
                    804: 
                    805:         pdev->cgs.dwFlags |= CGS_PATHEXISTS;
                    806:     }
                    807: }
                    808: 
                    809: 
                    810: //--------------------------------------------------------------------------
                    811: // VOID ps_curveto(pdev, pptl, pptl1, pptl2)
                    812: // PDEVDATA  pdev;
                    813: // PPOINTL   pptl;
                    814: // PPOINTL   pptl1;
                    815: // PPOINTL   pptl2;
                    816: //
                    817: // This routine is called by the driver to output a curveto command as well
                    818: // as update the current position.
                    819: //
                    820: // Parameters:
                    821: //   pdev:
                    822: //     Pointer to DEVDATA structure.
                    823: //
                    824: //   pptl, pptl1, pptl2:
                    825: //     Pointer to PPOINTLs defining the bezier curve to output.
                    826: //
                    827: // Returns:
                    828: //   This function returns no value.
                    829: //
                    830: // History:
                    831: //   03-May-1991     -by-     Kent Settle     (kentse)
                    832: //  Wrote it.
                    833: //--------------------------------------------------------------------------
                    834: 
                    835: VOID ps_curveto(pdev, pptl, pptl1, pptl2)
                    836: PDEVDATA     pdev;
                    837: PPOINTL      pptl;
                    838: PPOINTL      pptl1;
                    839: PPOINTL      pptl2;
                    840: {
                    841:     POINTPSFX   ptpsfx;
                    842:     POINTPSFX   ptpsfx1;
                    843:     POINTPSFX   ptpsfx2;
                    844: 
                    845:     // output the curveto command and set the new current position in
                    846:     // the printer.  remember to flip from top to bottom, since
                    847:     // under NT 0,0 is top left, and under PostScript 0,0 is bottom left.
                    848: 
                    849:     ptpsfx.x = X72DPI(pptl->x);
                    850:     ptpsfx.y = Y72DPI(pptl->y);
                    851:     ptpsfx1.x = X72DPI(pptl1->x);
                    852:     ptpsfx1.y = Y72DPI(pptl1->y);
                    853:     ptpsfx2.x = X72DPI(pptl2->x);
                    854:     ptpsfx2.y = Y72DPI(pptl2->y);
                    855: 
                    856:     // output the curveto command using PostScript user coordinates,
                    857:     // then update the current position to be the last point on the curve.
                    858: 
                    859:     PrintPSFIX(pdev, 6, ptpsfx.x, ptpsfx.y, ptpsfx1.x, ptpsfx1.y,
                    860:               ptpsfx2.x, ptpsfx2.y);
                    861:     PrintString(pdev, " c\n");
                    862: 
                    863:     // save the new current position in device coordinates.
                    864: 
                    865:     pdev->cgs.ptlCurPos = *pptl2;
                    866: 
                    867:     // mark that we do indeed have a path.
                    868: 
                    869:     pdev->cgs.dwFlags |= CGS_PATHEXISTS;
                    870: 
                    871:     return;
                    872: }
                    873: 
                    874: 
                    875: //--------------------------------------------------------------------------
                    876: // VOID ps_fill(pdev, flFillMode)
                    877: // PDEVDATA  pdev;
                    878: // FLONG     flFillMode;
                    879: //
                    880: // This routine is called by the driver to output a fill command to
                    881: // the printer.
                    882: //
                    883: // Parameters:
                    884: //   pdev:
                    885: //     Pointer to DEVDATA structure.
                    886: //
                    887: // Returns:
                    888: //   This function returns no value.
                    889: //
                    890: // History:
                    891: //   03-May-1991     -by-     Kent Settle     (kentse)
                    892: //  Wrote it.
                    893: //--------------------------------------------------------------------------
                    894: 
                    895: VOID ps_fill(pdev, flFillMode)
                    896: PDEVDATA pdev;
                    897: FLONG    flFillMode;
                    898: {
                    899:     // output the fill command if we have an existing path.
                    900: 
                    901:     if (pdev->cgs.dwFlags & CGS_PATHEXISTS)
                    902:     {
                    903:         //!!! check into path buffer.  - kentse.
                    904: 
                    905:         if (flFillMode & FP_WINDINGMODE)
                    906:         {
                    907:             // output the PostScript fill command to do a winding mode fill.
                    908: 
                    909:            PrintString(pdev, "f\n");
                    910:         }
                    911:         else
                    912:         {
                    913:             // output the PostScript eofill command to do an even odd, or
                    914:             // alternate fill.
                    915: 
                    916:            PrintString(pdev, "e\n");
                    917:         }
                    918: 
                    919:         // the fill operator deletes the path, so mark it as such.
                    920: 
                    921:         pdev->cgs.dwFlags &= ~CGS_PATHEXISTS;
                    922:     }
                    923: #if DBG
                    924:     else
                    925:         DbgPrint("PSCRIPT!ps_fill: filling non-existent path.\n");
                    926: #endif
                    927: }
                    928: 
                    929: 
                    930: //--------------------------------------------------------------------------
                    931: // VOID ps_closepath(pdev)
                    932: // PDEVDATA    pdev;
                    933: //
                    934: // This routine is called to close the current path.
                    935: //
                    936: // Parameters:
                    937: //   pdev:
                    938: //     Pointer to DEVDATA structure.
                    939: //
                    940: // Returns:
                    941: //   This function returns no value.
                    942: //
                    943: // History:
                    944: //   03-May-1991     -by-     Kent Settle     (kentse)
                    945: //  Wrote it.
                    946: //--------------------------------------------------------------------------
                    947: 
                    948: VOID ps_closepath(pdev)
                    949: PDEVDATA    pdev;
                    950: {
                    951:     // if a path exists, close it.
                    952: 
                    953:     if (pdev->cgs.dwFlags & CGS_PATHEXISTS)
                    954:        PrintString(pdev, "cp\n");
                    955: }
                    956: 
                    957: 
                    958: //--------------------------------------------------------------------------
                    959: // PS_FIX psfxRGBtoGray(pbgr)
                    960: // BGR_PAL_ENTRY  *pbgr;
                    961: //
                    962: // This routine is called to convert an RGB value to a gray scale.
                    963: //
                    964: // Parameters:
                    965: //   ppe:
                    966: //     pointer to PALETTEENTRY color to convert.
                    967: //
                    968: // Returns:
                    969: //   This function returns PS_FIX gray scale value.
                    970: //
                    971: // History:
                    972: //   21-May-1991     -by-     Kent Settle     (kentse)
                    973: //  Wrote it.
                    974: //--------------------------------------------------------------------------
                    975: 
                    976: 
                    977: PS_FIX psfxRGBtoGray(pbgr)
                    978: BGR_PAL_ENTRY  *pbgr;
                    979: {
                    980:     PS_FIX  psfxRed, psfxGreen, psfxBlue, psfxGray;
                    981: 
                    982:     // The gray value is computed as a normalized average of the
                    983:     // three color components.  The resultant gray level should
                    984:     // range from 0.0 to 1.0
                    985: 
                    986:     psfxRed = (ULONG)pbgr->bgrRed * PSFXPERCENT_RED;
                    987:     psfxGreen = (ULONG)pbgr->bgrGreen * PSFXPERCENT_GREEN;
                    988:     psfxBlue = (ULONG)pbgr->bgrBlue * PSFXPERCENT_BLUE;
                    989: 
                    990:     psfxGray = (PS_FIX)((psfxRed + psfxGreen + psfxBlue) / 255);
                    991: 
                    992:     return (psfxGray);
                    993: }
                    994: 
                    995: 
                    996: //--------------------------------------------------------------------------
                    997: // VOID ps_setlinewidth(pdev, psfxLineWidth)
                    998: // PDEVDATA     pdev;
                    999: // PS_FIX       psfxLineWidth;
                   1000: //
                   1001: // This routine is called by the driver to set the current geometric linewidth.
                   1002: // The line width is specified in USER coordinates (1/72 inch).
                   1003: //
                   1004: // Parameters:
                   1005: //   pdev:
                   1006: //     pointer to DEVDATA structure.
                   1007: //
                   1008: //   psfxLineWidth:
                   1009: //     linewidth to set.
                   1010: //
                   1011: // Returns:
                   1012: //   This function returns no value.
                   1013: //
                   1014: // History:
                   1015: //   05-July-1991       -by-     Kent Settle     (kentse)
                   1016: //  Wrote it.
                   1017: //--------------------------------------------------------------------------
                   1018: 
                   1019: VOID ps_setlinewidth(pdev, psfxLineWidth)
                   1020: PDEVDATA        pdev;
                   1021: PS_FIX          psfxLineWidth;
                   1022: {
                   1023:     // only update the linewidth if the new value differs from the old.
                   1024: 
                   1025:     if (pdev->cgs.psfxLineWidth != psfxLineWidth)
                   1026:     {
                   1027:         // update the linewidth in our current graphics state.
                   1028: 
                   1029:         pdev->cgs.psfxLineWidth = psfxLineWidth;
                   1030: 
                   1031:         // update the printer's linewidth.
                   1032: 
                   1033:        PrintPSFIX(pdev, 1, psfxLineWidth);
                   1034:         PrintString(pdev, " sl\n");
                   1035:     }
                   1036: 
                   1037:     return;
                   1038: }
                   1039: 
                   1040: 
                   1041: //--------------------------------------------------------------------------
                   1042: // BOOL ps_setlineattrs(pdev, plineattrs, pxo)
                   1043: // PDEVDATA    pdev;
                   1044: // PLINEATTRS  plineattrs;
                   1045: // XFORMOBJ   *pxo;
                   1046: //
                   1047: // This routine is called by the driver to set the current line attributes.
                   1048: //
                   1049: // Parameters:
                   1050: //   pdev:
                   1051: //     pointer to DEVDATA structure.
                   1052: //
                   1053: //   plineattrs:
                   1054: //     line attributes to set.
                   1055: //
                   1056: // Returns:
                   1057: //   This function returns no value.
                   1058: //
                   1059: // History:
                   1060: //   19-Mar-1992        -by-    Kent Settle     (kentse)
                   1061: //  Wrote it.
                   1062: //--------------------------------------------------------------------------
                   1063: 
                   1064: BOOL ps_setlineattrs(pdev, plineattrs, pxo)
                   1065: PDEVDATA    pdev;
                   1066: PLINEATTRS  plineattrs;
                   1067: XFORMOBJ   *pxo;
                   1068: {
                   1069:     ULONG   iJoin;
                   1070:     ULONG   iEndCap;
                   1071:     PS_FIX  psfxMiterLimit;
                   1072:     PS_FIX  psfxStyle, psfxScale;
                   1073:     PS_FIX  psfxWidth;
                   1074:     BOOL    bDiffer;
                   1075:     DWORD   i;
                   1076:     FLOAT  *pfloat1;
                   1077:     FLOAT  *pfloat2;
                   1078:     LONG   *plong1;
                   1079:     LONG   *plong2;
                   1080: 
                   1081:     // there are several line attributes which have meaning for a
                   1082:     // geometric line, but not for a cosmetic.  set each of them, if
                   1083:     // necessary.
                   1084: 
                   1085:     if (plineattrs->fl & LA_GEOMETRIC)
                   1086:     {
                   1087:         // update the line join value, if it differs from the old one.
                   1088: 
                   1089:         if (plineattrs->iJoin != pdev->cgs.lineattrs.iJoin)
                   1090:         {
                   1091:             // update the line join value in our current graphics state.
                   1092: 
                   1093:             pdev->cgs.lineattrs.iJoin = plineattrs->iJoin;
                   1094: 
                   1095:             // update the printer's line join.
                   1096: 
                   1097:             switch (plineattrs->iJoin)
                   1098:             {
                   1099:                 case JOIN_BEVEL:
                   1100:                     iJoin = PSCRIPT_JOIN_BEVEL;
                   1101:                     break;
                   1102: 
                   1103:                 case JOIN_ROUND:
                   1104:                     iJoin = PSCRIPT_JOIN_ROUND;
                   1105:                     break;
                   1106: 
                   1107:                 default:
                   1108:                     iJoin = PSCRIPT_JOIN_MITER;
                   1109:                     break;
                   1110:             }
                   1111: 
                   1112:             PrintDecimal(pdev, 1, iJoin);
                   1113:             PrintString(pdev, " j\n");
                   1114:         }
                   1115: 
                   1116:         // update the end cap value, if it differs from the old one.
                   1117: 
                   1118:         if (plineattrs->iEndCap != pdev->cgs.lineattrs.iEndCap)
                   1119:         {
                   1120:             // update the end cap value in our current graphics state.
                   1121: 
                   1122:             pdev->cgs.lineattrs.iEndCap = plineattrs->iEndCap;
                   1123: 
                   1124:             // update the printer's end cap value.
                   1125: 
                   1126:             switch (plineattrs->iEndCap)
                   1127:             {
                   1128:                 case ENDCAP_SQUARE:
                   1129:                     iEndCap = PSCRIPT_ENDCAP_SQUARE;
                   1130:                     break;
                   1131: 
                   1132:                 case ENDCAP_ROUND:
                   1133:                     iEndCap = PSCRIPT_ENDCAP_ROUND;
                   1134:                     break;
                   1135: 
                   1136:                 default:
                   1137:                     iEndCap = PSCRIPT_ENDCAP_BUTT;
                   1138:                     break;
                   1139:             }
                   1140: 
                   1141:             PrintDecimal(pdev, 1, iEndCap);
                   1142:             PrintString(pdev, " setlinecap\n");
                   1143:         }
                   1144: 
                   1145:         // a miter limit less than one does not make sense.  rather than
                   1146:         // returning an error in this case, just default to one.
                   1147: 
                   1148:         plineattrs->eMiterLimit = max(plineattrs->eMiterLimit, (FLOAT)1.0);
                   1149: 
                   1150:         // update the miter limit value, if it differs from the old one.
                   1151: 
                   1152:         if (plineattrs->eMiterLimit != pdev->cgs.lineattrs.eMiterLimit)
                   1153:         {
                   1154:             // update the miter limit value in our current graphics state.
                   1155: 
                   1156:             pdev->cgs.lineattrs.eMiterLimit = plineattrs->eMiterLimit;
                   1157: 
                   1158:             // update the printer's miter limit value.
                   1159: 
                   1160:             psfxMiterLimit = ETOPSFX(plineattrs->eMiterLimit);
                   1161:             PrintPSFIX(pdev, 1, psfxMiterLimit);
                   1162:             PrintString(pdev, " setmiterlimit\n");
                   1163:         }
                   1164: 
                   1165:         // update the geometric line width, if it differs from the old one.
                   1166:         // we use pdev->cgs.psfxLineWidth to check against rather than
                   1167:         // pdev->cgs.lineattrs.elWidth.e since we need to set the line width
                   1168:         // at times in the driver when we do not have access to the
                   1169:         // current transform to go from WORLD to DEVICE coordinates.
                   1170: 
                   1171:         psfxWidth = (ETOPSFX(plineattrs->elWidth.e) * PS_RESOLUTION) /
                   1172:                     pdev->psdm.dm.dmPrintQuality;
                   1173: 
                   1174:         if (psfxWidth != pdev->cgs.psfxLineWidth)
                   1175:         {
                   1176:             // update the line width value in our current graphics state.
                   1177: 
                   1178:             pdev->cgs.psfxLineWidth = psfxWidth;
                   1179: 
                   1180:             // update the printer's linewidth.  the linewidth is specified
                   1181:             // in user coordinates.
                   1182: 
                   1183:             PrintPSFIX(pdev, 1, psfxWidth);
                   1184:             PrintString(pdev, " sl\n");
                   1185:         }
                   1186: 
                   1187:         // time to deal with the line style.  note:  we don't want to output
                   1188:         // the style code unless something about the style has actually
                   1189:         // changed.  specifically, only if the cStyle, elStyleState, or any element
                   1190:         // of the array has changed will we output the code to change the
                   1191:         // style.
                   1192: 
                   1193:         bDiffer = FALSE;    // assume style the same.
                   1194: 
                   1195:         if ((plineattrs->cstyle != pdev->cgs.lineattrs.cstyle) ||
                   1196:             (plineattrs->elStyleState.e != pdev->cgs.lineattrs.elStyleState.e))
                   1197:             bDiffer = TRUE;
                   1198: 
                   1199:         if (!bDiffer)
                   1200:         {
                   1201:             pfloat1 = (FLOAT *)plineattrs->pstyle;
                   1202:             pfloat2 = (FLOAT *)pdev->cgs.lineattrs.pstyle;
                   1203: 
                   1204: #if DBG
                   1205:             if ((plineattrs->cstyle == 0) && (plineattrs->pstyle != NULL))
                   1206:             {
                   1207:                 RIP("PSCRIPT!ps_setlineattrs: cstyle == 0, but pstyle != NULL.\n");
                   1208:                 return(FALSE);
                   1209:             }
                   1210: #endif
                   1211: 
                   1212:             for (i = 0; i < plineattrs->cstyle; i++)
                   1213:             {
                   1214:                 if (*pfloat1++ != *pfloat2++)
                   1215:                 {
                   1216:                     bDiffer = TRUE;
                   1217:                     break;
                   1218:                 }
                   1219:             }
                   1220:         }
                   1221: 
                   1222:         // now change the line style in the printer, if something about
                   1223:         // it has changed.
                   1224: 
                   1225:         if (bDiffer)
                   1226:         {
                   1227:             // handle the solid line case.
                   1228: 
                   1229:             if ((plineattrs->pstyle == NULL) || (plineattrs->cstyle == 0))
                   1230:                 PrintString(pdev, "[]0 sd\n");
                   1231:             else    // not a solid line.
                   1232:             {
                   1233:                 PrintString(pdev, "[");
                   1234: 
                   1235:                 pfloat1 = (FLOAT *)plineattrs->pstyle;
                   1236: 
                   1237:                 for (i = 0; i < plineattrs->cstyle; i++)
                   1238:                 {
                   1239:                     psfxStyle = LTOPSFX((ETOL(*pfloat1++)) * PS_RESOLUTION) /
                   1240:                                pdev->psdm.dm.dmPrintQuality;
                   1241: 
                   1242:                     PrintPSFIX(pdev, 1, psfxStyle);
                   1243:                     PrintString(pdev, " ");
                   1244:                 }
                   1245: 
                   1246:                 PrintString(pdev, "]");
                   1247: 
                   1248:                 // output the style state in user coordinates.
                   1249: 
                   1250:                 psfxStyle = LTOPSFX((ETOL(plineattrs->elStyleState.e)) * PS_RESOLUTION) /
                   1251:                                    pdev->psdm.dm.dmPrintQuality;
                   1252: 
                   1253:                 PrintPSFIX(pdev, 1, psfxStyle);
                   1254:                 PrintString(pdev, " sd\n");
                   1255:             }
                   1256: 
                   1257:             // something in the lineattrs may have changed, update the cgs.
                   1258: 
                   1259:             if (pdev->cgs.lineattrs.pstyle)
                   1260:                 HeapFree(pdev->hheap, 0, (PVOID)pdev->cgs.lineattrs.pstyle);
                   1261: 
                   1262:             pdev->cgs.lineattrs = *plineattrs;
                   1263: 
                   1264:             // allocate space to copy the style array to.
                   1265: 
                   1266:             if (!(pfloat1 = (FLOAT *)HeapAlloc(pdev->hheap, 0,
                   1267:                                      sizeof(FLOAT) * plineattrs->cstyle)))
                   1268:             {
                   1269:                 RIP("PSCRIPT!ps_setlineattrs: HeapAlloc for pfloat1 failed.\n");
                   1270:                 return(FALSE);
                   1271:             }
                   1272: 
                   1273:             // copy the style array itself.
                   1274: 
                   1275:             pfloat2 = (FLOAT *)plineattrs->pstyle;
                   1276:             pdev->cgs.lineattrs.pstyle = (PFLOAT_LONG)pfloat1;
                   1277: 
                   1278:             for (i = 0; i < plineattrs->cstyle; i++)
                   1279:                 *pfloat1++ = *pfloat2++;
                   1280:         }
                   1281:     }
                   1282:     else    // cosmetic lines.
                   1283:     {
                   1284:         // now handle cosmetic lines.  iJoin, iEndCap and eMiterLimit make
                   1285:         // no sense for cosmetic lines, so we won't worry about them.
                   1286: 
                   1287:         psfxWidth = LTOPSFX(plineattrs->elWidth.l * PS_RESOLUTION) /
                   1288:                            pdev->psdm.dm.dmPrintQuality;
                   1289: 
                   1290:         // update the cosmetic line width, if it differs from the old one.
                   1291:         // we use pdev->cgs.psfxLineWidth to check against rather than
                   1292:         // pdev->cgs.lineattrs.elWidth.e since we need to set the line width
                   1293:         // at times in the driver when we do not have access to the
                   1294:         // current transform to go from WORLD to DEVICE coordinates.
                   1295: 
                   1296:         if (psfxWidth != pdev->cgs.psfxLineWidth)
                   1297:         {
                   1298:             // update the line width value in our current graphics state.
                   1299: 
                   1300:             pdev->cgs.psfxLineWidth = psfxWidth;
                   1301: 
                   1302:             // update the printer's linewidth.  the linewidth is specified
                   1303:             // in user coordinates.
                   1304: 
                   1305:             PrintPSFIX(pdev, 1, psfxWidth);
                   1306:             PrintString(pdev, " sl\n");
                   1307:         }
                   1308: 
                   1309:         // the LA_ALTERNATE linestyle is a special cosmetic line style, where
                   1310:         // every other pel is on.  well, if we have a printer with 2500 dpi,
                   1311:         // do we really want every other pel on?  i don't think so.  so,
                   1312:         // for now at least, we will simply turn on every other user coordinate
                   1313:         // pel.
                   1314: 
                   1315:         if (plineattrs->fl & LA_ALTERNATE)
                   1316:         {
                   1317: //!!! perhaps we really want to do a .5 setgray.  what about color.  -kentse.
                   1318: 
                   1319:             PrintString(pdev, "[1] ");
                   1320:             psfxStyle = LTOPSFX(plineattrs->elStyleState.l * PS_RESOLUTION) /
                   1321:                                 pdev->psdm.dm.dmPrintQuality;
                   1322: 
                   1323:             PrintPSFIX(pdev, 1, psfxStyle);
                   1324:             PrintString(pdev, " sd\n");
                   1325:         }
                   1326:         else
                   1327:         {
                   1328:             // time to deal with the line style.  note:  we don't want to output
                   1329:             // the style code unless something about the style has actually
                   1330:             // changed.  specifically, only if the cStyle, elStyleState, or any element
                   1331:             // of the array has changed will we output the code to change the
                   1332:             // style.
                   1333: 
                   1334:             bDiffer = FALSE;    // assume style the same.
                   1335: 
                   1336:             if ((plineattrs->cstyle != pdev->cgs.lineattrs.cstyle) ||
                   1337:                 (plineattrs->elStyleState.l != pdev->cgs.lineattrs.elStyleState.l))
                   1338:                 bDiffer = TRUE;
                   1339: 
                   1340:             if (!bDiffer)
                   1341:             {
                   1342:                 plong1 = (LONG *)plineattrs->pstyle;
                   1343:                 plong2 = (LONG *)pdev->cgs.lineattrs.pstyle;
                   1344: 
                   1345: #if DBG
                   1346:                 if ((plineattrs->cstyle == 0) && (plineattrs->pstyle != NULL))
                   1347:                 {
                   1348:                     RIP("PSCRIPT!ps_setlineattrs: cstyle == 0, but pstyle != NULL.\n");
                   1349:                     return(FALSE);
                   1350:                 }
                   1351: #endif
                   1352: 
                   1353:                 for (i = 0; i < plineattrs->cstyle; i++)
                   1354:                 {
                   1355:                     if (*plong1++ != *plong2++)
                   1356:                     {
                   1357:                         bDiffer = TRUE;
                   1358:                         break;
                   1359:                     }
                   1360:                 }
                   1361:             }
                   1362: 
                   1363:             // now change the line style in the printer, if something about
                   1364:             // it has changed.
                   1365: 
                   1366:             if (bDiffer)
                   1367:             {
                   1368:                 // handle the solid line case.
                   1369: 
                   1370:                 if ((plineattrs->pstyle == NULL) || (plineattrs->cstyle == 0))
                   1371:                     PrintString(pdev, "[]0 sd\n");
                   1372:                 else    // not a solid line.
                   1373:                 {
                   1374:                     PrintString(pdev, "[");
                   1375: 
                   1376:                     plong1 = (LONG *)plineattrs->pstyle;
                   1377: 
                   1378:                     // get style scaling factor.
                   1379: 
                   1380:                     psfxScale = LTOPSFX(pdev->psdm.dm.dmPrintQuality / 25);
                   1381:                     psfxScale = (psfxScale * PS_RESOLUTION) /
                   1382:                                 pdev->psdm.dm.dmPrintQuality;
                   1383: 
                   1384:                     for (i = 0; i < plineattrs->cstyle; i++)
                   1385:                     {
                   1386:                         psfxStyle = (*plong1++) * psfxScale;
                   1387: 
                   1388:                         PrintPSFIX(pdev, 1, psfxStyle);
                   1389:                         PrintString(pdev, " ");
                   1390:                     }
                   1391: 
                   1392:                     PrintString(pdev, "]");
                   1393:                     psfxStyle = plineattrs->elStyleState.l * psfxScale;
                   1394: 
                   1395:                     PrintPSFIX(pdev, 1, psfxStyle);
                   1396:                     PrintString(pdev, " sd\n");
                   1397:                 }
                   1398: 
                   1399:                 // something in the lineattrs may have changed, update the cgs.
                   1400: 
                   1401:                 if (pdev->cgs.lineattrs.pstyle)
                   1402:                     HeapFree(pdev->hheap, 0, (PVOID)pdev->cgs.lineattrs.pstyle);
                   1403: 
                   1404:                 pdev->cgs.lineattrs = *plineattrs;
                   1405: 
                   1406:                 // allocate space to copy the style array to.
                   1407: 
                   1408:                 if (!(plong1 = (LONG *)HeapAlloc(pdev->hheap, 0,
                   1409:                                          sizeof(LONG) * plineattrs->cstyle)))
                   1410:                 {
                   1411:                     RIP("PSCRIPT!ps_setlineattrs: HeapAlloc for plong1 failed.\n");
                   1412:                     return(FALSE);
                   1413:                 }
                   1414: 
                   1415:                 // copy the style array itself.
                   1416: 
                   1417:                 plong2 = (LONG *)plineattrs->pstyle;
                   1418:                 pdev->cgs.lineattrs.pstyle = (PFLOAT_LONG)plong1;
                   1419: 
                   1420:                 for (i = 0; i < plineattrs->cstyle; i++)
                   1421:                     *plong1++ = *plong2++;
                   1422:             }
                   1423:         }
                   1424: 
                   1425:     }
                   1426: 
                   1427:     return(TRUE);
                   1428: }
                   1429: 
                   1430: 
                   1431: //--------------------------------------------------------------------------
                   1432: // VOID ps_geolinexform(pdev, plineattrs, pxo)
                   1433: // PDEVDATA    pdev;
                   1434: // PLINEATTRS  plineattrs;
                   1435: // XFORMOBJ   *pxo;
                   1436: //
                   1437: // This routine is called by the driver to set the current line attributes.
                   1438: //
                   1439: // Parameters:
                   1440: //   pdev:
                   1441: //     pointer to DEVDATA structure.
                   1442: //
                   1443: //   plineattrs:
                   1444: //     line attributes to set.
                   1445: //
                   1446: // Returns:
                   1447: //   This function returns no value.
                   1448: //
                   1449: // History:
                   1450: //   12-Mar-1993        -by-    Kent Settle     (kentse)
                   1451: //  Wrote it.
                   1452: //--------------------------------------------------------------------------
                   1453: 
                   1454: VOID ps_geolinexform(pdev, plineattrs, pxo)
                   1455: PDEVDATA    pdev;
                   1456: PLINEATTRS  plineattrs;
                   1457: XFORMOBJ   *pxo;
                   1458: {
                   1459:     ULONG   ulComplexity;
                   1460:     PS_FIX  psfxM11, psfxM12, psfxM21, psfxM22, psfxdx, psfxdy;
                   1461: 
                   1462:     // update the printer's geometric line width.  the line width
                   1463:     // is given in WORLD coordinates for a geometric line.  it needs
                   1464:     // to be transformed into DEVICE space.
                   1465: 
                   1466:     ulComplexity = XFORMOBJ_iGetXform(pxo, &pdev->cgs.GeoLineXform);
                   1467: 
                   1468:     // assume no transform will be done.
                   1469: 
                   1470:     pdev->cgs.dwFlags &= ~CGS_GEOLINEXFORM;
                   1471: 
                   1472:     switch(ulComplexity)
                   1473:     {
                   1474:         case GX_IDENTITY:
                   1475:             // there will be nothing to do in this case.
                   1476: 
                   1477:             break;
                   1478: 
                   1479:         case GX_SCALE:
                   1480:             // output scale command, rather than entire transform.
                   1481: 
                   1482:             psfxM11 = ETOPSFX(pdev->cgs.GeoLineXform.eM11);
                   1483: 
                   1484:             psfxM22 = ETOPSFX(pdev->cgs.GeoLineXform.eM22);
                   1485: 
                   1486:             // save the current CTM, then output the scale command.
                   1487:             // DrvStrokePath and DrvStrokeAndFillPath are
                   1488:             // responsible for restoring the CTM.
                   1489: 
                   1490:             PrintString(pdev, "CM ");
                   1491:             PrintPSFIX(pdev, 2, psfxM11, psfxM22);
                   1492:             PrintString(pdev, " scale\n");
                   1493: 
                   1494:             pdev->cgs.dwFlags |= CGS_GEOLINEXFORM;
                   1495: 
                   1496:             break;
                   1497: 
                   1498:         default:
                   1499:             // output a general transform.
                   1500: 
                   1501:             psfxM11 = ETOPSFX(pdev->cgs.GeoLineXform.eM11);
                   1502: 
                   1503:             psfxM12 = ETOPSFX(pdev->cgs.GeoLineXform.eM12);
                   1504: 
                   1505:             psfxM21 = ETOPSFX(pdev->cgs.GeoLineXform.eM21);
                   1506: 
                   1507:             psfxM22 = ETOPSFX(pdev->cgs.GeoLineXform.eM22);
                   1508: 
                   1509:             psfxdx = ETOPSFX(pdev->cgs.GeoLineXform.eDx);
                   1510: 
                   1511:             psfxdy = ETOPSFX(pdev->cgs.GeoLineXform.eDy);
                   1512: 
                   1513:             // save the current CTM, then output the concat command.
                   1514:             // DrvStrokePath and DrvStrokeAndFillPath are
                   1515:             // responsible for restoring the CTM.
                   1516: 
                   1517:             PrintString(pdev, "CM ");
                   1518:             PrintString(pdev, "[");
                   1519:             PrintPSFIX(pdev, 6, psfxM11, psfxM12, psfxM21, psfxM22,
                   1520:                        psfxdx, psfxdy);
                   1521:             PrintString(pdev, "] concat\n");
                   1522: 
                   1523:             pdev->cgs.dwFlags |= CGS_GEOLINEXFORM;
                   1524: 
                   1525:             break;
                   1526:     }
                   1527: }
                   1528: 
                   1529: //--------------------------------------------------------------------------
                   1530: // VOID ps_begin_eps(pdev)
                   1531: // VOID ps_end_eps(pdev)
                   1532: //
                   1533: // These routines are called by the driver to issue commands to bracket EPS
                   1534: // files to the printer.  They conform to the Guidelines for Importing EPS
                   1535: // Files version 3.0 by Adobe.
                   1536: //
                   1537: // Parameters:
                   1538: //   pdev:
                   1539: //     pointer to DEVDATA structure.
                   1540: //
                   1541: // Returns:
                   1542: //   None.
                   1543: //
                   1544: // History:
                   1545: //   Sat May 08 15:15:01 1993          -by-    Hock San Lee    [hockl]
                   1546: //  Wrote it.
                   1547: //--------------------------------------------------------------------------
                   1548: 
                   1549: PSZ apszEPSProc[] =
                   1550:     {
                   1551:     "/BeginEPSF {/b4_Inc_state save def /dict_count countdictstack def",
                   1552:     "/op_count count 1 sub def userdict begin /showpage {} def",
                   1553:     "0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin",
                   1554:     "10 setmiterlimit [] 0 setdash newpath",
                   1555:     "/languagelevel where {pop languagelevel 1 ne",
                   1556:     "{false setstrokeadjust false setoverprint} if } if } bind def",
                   1557:     "/EndEPSF {count op_count sub {pop} repeat",
                   1558:     "countdictstack dict_count sub {end} repeat b4_Inc_state restore} bind def",
                   1559:     NULL
                   1560:     };
                   1561: 
                   1562: VOID ps_begin_eps(pdev)
                   1563: PDEVDATA    pdev;
                   1564: {
                   1565:     PSZ        *ppsz;
                   1566: 
                   1567:     // emit the EPS procedures if necessary.
                   1568: 
                   1569:     if (!(pdev->cgs.dwFlags & CGS_EPS_PROC))
                   1570:     {
                   1571:         ppsz = apszEPSProc;
                   1572:         while (*ppsz)
                   1573:         {
                   1574:             PrintString(pdev, *ppsz++);
                   1575:             PrintString(pdev, "\n");
                   1576:         }
                   1577: 
                   1578:         pdev->cgs.dwFlags |= CGS_EPS_PROC;
                   1579:     }
                   1580: 
                   1581:     PrintString(pdev, "BeginEPSF\n");
                   1582: }
                   1583: 
                   1584: VOID ps_end_eps(pdev)
                   1585: PDEVDATA    pdev;
                   1586: {
                   1587:     if (!(pdev->cgs.dwFlags & CGS_EPS_PROC))
                   1588:     {
                   1589:         RIP("PSCRIPT!ps_end_eps: EndEPSF not defined.\n");
                   1590:     }
                   1591: 
                   1592:     PrintString(pdev, "EndEPSF\n");
                   1593: }

unix.superglobalmegacorp.com

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