|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.