|
|
1.1 ! root 1: //-------------------------------------------------------------------------- ! 2: // ! 3: // Module Name: ENABLE.C ! 4: // ! 5: // Brief Description: This module contains the PSCRIPT driver's Enable ! 6: // and Disable functions and related routines. ! 7: // ! 8: // Author: Kent Settle (kentse) ! 9: // Created: 16-Oct-1990 ! 10: // ! 11: // Copyright (c) 1990 - 1992 Microsoft Corporation ! 12: // ! 13: // The Engine uses DosGetProcAddr to locate the driver's Enable and Disable ! 14: // functions. The first call the Engine makes is to initialize the driver. ! 15: // This function is usually called when the Engine has been asked to create ! 16: // the first DC for the device. bEnableDriver will return an array holding ! 17: // all the available driver entry points to the Engine. ! 18: // ! 19: // After calling bEnableDriver, the Engine will typically ask for a physical ! 20: // device to be created with dhpdevEnablePDEV. This call identifies the ! 21: // exact device and mode that the Engine wishes to access. The Engine's ! 22: // PDEV is not considered complete until the call to bCompletePDEV is made. ! 23: // ! 24: // Finally, a surface will be created for the physical device with ! 25: // hsurfEnableSurface. Only after a surface is created will graphics output ! 26: // calls be sent to the device. ! 27: // ! 28: // The functions dealing with driver initialization are as follows. ! 29: // ! 30: // DrvEnableDriver ! 31: // DrvEnablePDEV ! 32: // DrvRestartPDEV ! 33: // DrvCompletePDEV ! 34: // DrvEnableSurface ! 35: // DrvDisableSurface ! 36: // DrvDisablePDEV ! 37: // DrvDisableDriver ! 38: // ! 39: // 05-Feb-1993 Fri 19:46:19 updated -by- Daniel Chou (danielc) ! 40: // Redo halftone part so that engine will do all the work for us, also ! 41: // have engine create the the best standard pattern for our devices ! 42: // ! 43: //-------------------------------------------------------------------------- ! 44: ! 45: #define _HTUI_APIS_ ! 46: ! 47: #include "pscript.h" ! 48: #include "winbase.h" ! 49: #include "string.h" ! 50: #include "enable.h" ! 51: #include "tables.h" ! 52: #include "halftone.h" ! 53: #include "resource.h" ! 54: ! 55: // our DRVFN table which tells the engine where to find the ! 56: // routines we support. ! 57: ! 58: static DRVFN gadrvfn[] = ! 59: { ! 60: {INDEX_DrvEnablePDEV, (PFN)DrvEnablePDEV }, ! 61: {INDEX_DrvRestartPDEV, (PFN)DrvRestartPDEV }, ! 62: {INDEX_DrvCompletePDEV, (PFN)DrvCompletePDEV }, ! 63: {INDEX_DrvDisablePDEV, (PFN)DrvDisablePDEV }, ! 64: {INDEX_DrvEnableSurface, (PFN)DrvEnableSurface }, ! 65: {INDEX_DrvDisableSurface, (PFN)DrvDisableSurface }, ! 66: {INDEX_DrvBitBlt, (PFN)DrvBitBlt }, ! 67: {INDEX_DrvStretchBlt, (PFN)DrvStretchBlt }, ! 68: {INDEX_DrvCopyBits, (PFN)DrvCopyBits }, ! 69: {INDEX_DrvTextOut, (PFN)DrvTextOut }, ! 70: {INDEX_DrvQueryFont, (PFN)DrvQueryFont }, ! 71: {INDEX_DrvQueryFontTree, (PFN)DrvQueryFontTree }, ! 72: {INDEX_DrvQueryFontData, (PFN)DrvQueryFontData }, ! 73: {INDEX_DrvSendPage, (PFN)DrvSendPage }, ! 74: {INDEX_DrvStrokePath, (PFN)DrvStrokePath }, ! 75: {INDEX_DrvFillPath, (PFN)DrvFillPath }, ! 76: {INDEX_DrvStrokeAndFillPath,(PFN)DrvStrokeAndFillPath}, ! 77: {INDEX_DrvRealizeBrush, (PFN)DrvRealizeBrush }, ! 78: {INDEX_DrvStartPage, (PFN)DrvStartPage }, ! 79: {INDEX_DrvStartDoc, (PFN)DrvStartDoc }, ! 80: {INDEX_DrvEscape, (PFN)DrvEscape }, ! 81: {INDEX_DrvDrawEscape, (PFN)DrvDrawEscape }, ! 82: {INDEX_DrvEndDoc, (PFN)DrvEndDoc }, ! 83: {INDEX_DrvGetGlyphMode, (PFN)DrvGetGlyphMode }, ! 84: #ifdef INDEX_PAL ! 85: {INDEX_DrvDitherColor, (PFN)DrvDitherColor }, ! 86: #endif ! 87: {INDEX_DrvFontManagement, (PFN)DrvFontManagement }, ! 88: {INDEX_DrvQueryAdvanceWidths, (PFN)DrvQueryAdvanceWidths} ! 89: }; ! 90: ! 91: BYTE cxHTPatSize[] = { 2,2,4,4,6,6,8,8,10,10,12,12,14,14,16,16 }; ! 92: BYTE cyHTPatSize[] = { 2,2,4,4,6,6,8,8,10,10,12,12,14,14,16,16 }; ! 93: ! 94: #ifdef INDEX_PAL ! 95: ULONG PSMonoPalette[] = ! 96: { ! 97: RGB_BLACK, ! 98: RGB_WHITE ! 99: }; ! 100: ! 101: ULONG PSColorPalette[] = ! 102: { ! 103: RGB_BLACK, ! 104: RGB_RED, ! 105: RGB_GREEN, ! 106: RGB_YELLOW, ! 107: RGB_BLUE, ! 108: RGB_MAGENTA, ! 109: RGB_CYAN, ! 110: RGB_WHITE, ! 111: RGB_BLACK, ! 112: RGB_RED, ! 113: RGB_GREEN, ! 114: RGB_YELLOW, ! 115: RGB_BLUE, ! 116: RGB_MAGENTA, ! 117: RGB_CYAN, ! 118: RGB_WHITE ! 119: }; ! 120: #endif ! 121: ! 122: static DEVHTINFO DefDevHTInfo = { ! 123: ! 124: HT_FLAG_HAS_BLACK_DYE, ! 125: HT_PATSIZE_6x6_M, ! 126: 0, // fill in later ! 127: ! 128: { ! 129: { 6810, 3050, 0 }, // xr, yr, Yr ! 130: { 2260, 6550, 0 }, // xg, yg, Yg ! 131: { 1810, 500, 0 }, // xb, yb, Yb ! 132: { 2000, 2450, 0 }, // xc, yc, Yc ! 133: { 5210, 2100, 0 }, // xm, ym, Ym ! 134: { 4750, 5100, 0 }, // xy, yy, Yy ! 135: { 3324, 3474, 10000 }, // xw, yw, Yw ! 136: ! 137: 10000, // R gamma ! 138: 10000, // G gamma ! 139: 10000, // B gamma ! 140: ! 141: 1422, 952, // M/C, Y/C ! 142: 787, 495, // C/M, Y/M ! 143: 324, 248 // C/Y, M/Y ! 144: } ! 145: }; ! 146: ! 147: static COLORADJUSTMENT DefHTClrAdj = { ! 148: ! 149: sizeof(COLORADJUSTMENT), ! 150: 0, ! 151: ILLUMINANT_DEVICE_DEFAULT, ! 152: 20000, ! 153: 20000, ! 154: 20000, ! 155: REFERENCE_BLACK_MIN, ! 156: REFERENCE_WHITE_MAX, ! 157: 0, ! 158: 0, ! 159: 0, ! 160: 0 ! 161: }; ! 162: ! 163: ! 164: // global declarations. ! 165: ! 166: HMODULE ghmodDrv; // GLOBAL MODULE HANDLE. ! 167: ! 168: // macro to convert from .001 mm to 1/72 inch. ! 169: ! 170: #define MM001TOUSER(a) ((a * 72) / 25400) ! 171: ! 172: #define INSAINLY_LARGE_FORM 7200000 // 100,000 inches. ! 173: #define DEFAULT_MINIMUM_MEMORY 240 // 240k. ! 174: #define KBYTES_PER_FONT 60 // allow 60kb per downloaded font. ! 175: #define INITIAL_FORM_DELTA 16384 ! 176: ! 177: VOID IntersectImageableAreas(CURRENTFORM *, PSFORM *); ! 178: ! 179: // declarations of external routines. ! 180: ! 181: extern PNTPD GetNTPD(PDEVDATA, PWSTR); ! 182: extern BOOL SetDefaultPSDEVMODE(PSDEVMODE *, PWSTR, PNTPD, HANDLE); ! 183: extern BOOL ValidateSetDEVMODE(PSDEVMODE *, PSDEVMODE *, HANDLE, PNTPD); ! 184: extern int NameComp(CHAR *, CHAR *); ! 185: extern PNTFM GetFont(PDEVDATA, ULONG, HANDLE *); ! 186: extern DWORD ! 187: PickDefaultHTPatSize( ! 188: DWORD xDPI, ! 189: DWORD yDPI, ! 190: BOOL HTFormat8BPP ! 191: ); ! 192: ! 193: //#define TESTING ! 194: ! 195: //-------------------------------------------------------------------------- ! 196: // ! 197: // BOOL DrvEnableDriver( ! 198: // ULONG iEngineVersion, ! 199: // ULONG cb, ! 200: // PDRVENABLEDATA pded); ! 201: // ! 202: // Requests the driver to fill in a structure containing recognized ! 203: // functions and other control information. ! 204: // ! 205: // One-time initialization, such as the allocation of semaphores, may ! 206: // be performed at this time. The actual enabling of hardware, like ! 207: // a display device, should wait until dhpdevEnable is called. ! 208: // ! 209: // This is a required driver function. ! 210: // ! 211: // Parameters: ! 212: // ! 213: // iEngineVersion: ! 214: // DDI Version number of the Engine. This will be at least 0x00010000 ! 215: // for drivers written to this specification. ! 216: // ! 217: // cb: ! 218: // The count of bytes in the DRVENABLEDATA structure. The driver ! 219: // should not write more than this number of bytes into the structure. ! 220: // If the structure is longer than expected, then any extra fields ! 221: // should be left unmodified. ! 222: // ! 223: // pded: ! 224: // Pointer to a DRVENABLEDATA structure. The Engine will zero fill ! 225: // cb bytes of this structure before the call. The driver fills in ! 226: // its own data. ! 227: // ! 228: // The DRVENABLEDATA structure is of the following form: ! 229: // ! 230: // DRVENABLEDATA ! 231: // { ! 232: // ULONG iDriverVersion; // Driver DDI version ! 233: // ULONG c; // Number of drvfn entries ! 234: // DRVFN *pdrvfn; // Pointer to drvfn entries ! 235: // }; ! 236: // ! 237: // where the DRVFN structure is defined as: ! 238: // ! 239: // DRVFN ! 240: // { ! 241: // ULONG iFunc; // function index ! 242: // PFN pfn; // function address ! 243: // }; ! 244: // ! 245: // Returns: ! 246: // This function returns TRUE if the driver is enabled; it returns FALSE ! 247: // if the driver was not enabled. ! 248: // ! 249: // Comments: ! 250: // If the driver was not enabled, this function should log the proper ! 251: // error code. ! 252: // ! 253: // History: ! 254: // 16-Oct-1990 -by- Kent Settle (kentse) ! 255: // Created stub. ! 256: //-------------------------------------------------------------------------- ! 257: ! 258: BOOL DrvEnableDriver( ! 259: ULONG iEngineVersion, ! 260: ULONG cb, ! 261: PDRVENABLEDATA pded) ! 262: { ! 263: ghmodDrv = GetModuleHandle(L"pscript.dll"); ! 264: ! 265: // make sure we have a valid engine version. ! 266: ! 267: if (iEngineVersion < 0x00010000) ! 268: { ! 269: RIP("PSCRIPT!DrvEnableDriver: Invalid Engine Version."); ! 270: SetLastError(ERROR_INVALID_PARAMETER); ! 271: return(FALSE); ! 272: } ! 273: ! 274: // make sure we were given enough room for the DRVENABLEDATA. ! 275: ! 276: if (cb < sizeof(DRVENABLEDATA)) ! 277: { ! 278: RIP("PSCRIPT!DrvEnableDriver: Invalid cb."); ! 279: SetLastError(ERROR_INVALID_PARAMETER); ! 280: return(FALSE); ! 281: } ! 282: ! 283: // fill in the DRVENABLEDATA structure for the engine. ! 284: ! 285: //??? i gather we should check to make sure we do not ! 286: //??? write out more than cb bytes. -kentse. ! 287: ! 288: pded->iDriverVersion = DDI_DRIVER_VERSION; ! 289: pded->c = sizeof(gadrvfn) / sizeof(DRVFN); ! 290: pded->pdrvfn = gadrvfn; ! 291: ! 292: // One-time initialization, such as the allocation of semaphores, may ! 293: // be performed at this time. The actual enabling of hardware, like ! 294: // a display device, should wait until dhpdevEnable is called. ! 295: ! 296: //!!! loading a string table might be a good thing to do here. ! 297: ! 298: return(TRUE); ! 299: } ! 300: ! 301: ! 302: //-------------------------------------------------------------------------- ! 303: // DHPDEV DrvEnablePDEV( ! 304: // PDEVMODE pdriv, ! 305: // PSZ pszLogAddress, ! 306: // ULONG cPatterns, ! 307: // PHSURF ahsurfPatterns, ! 308: // ULONG cjCaps, ! 309: // PULONG aulCaps, ! 310: // ULONG cb, ! 311: // PDEVINFO pdevinfo, ! 312: // PSZ pszDataFile, ! 313: // PSZ pszDeviceName, ! 314: // HANDLE hDriver); ! 315: // ! 316: // Informs the driver that a new physical device (PDEV) is required. ! 317: // ! 318: // The device driver itself represents a logical device, which is managed ! 319: // by the Graphics Engine. A single device driver may manage several ! 320: // physical devices. These physical devices may be differentiated by: ! 321: // ! 322: // 1 Type of hardware. The same device driver might support the ! 323: // LaserWhiz, LaserWhiz II, and LaserWhiz Super. ! 324: // ! 325: // 2 Logical address. The same driver could support printers attached ! 326: // to LPT1, LPT2, COM1, etc. ! 327: // ! 328: // 3 Surfaces. I.e. a printer driver could be working on two print ! 329: // jobs simultaneously. The two surfaces represent the two pieces ! 330: // of paper that will be printed. ! 331: // ! 332: // Some display drivers might be able to support only one physical device, ! 333: // or one physical device at a time. In this case, they should return ! 334: // an error for any call from the Engine requesting a second physical ! 335: // device. ! 336: // ! 337: // The device driver should allocate any memory required to support the ! 338: // physical device at this time, except that the actual surface need not ! 339: // be supported until the Engine calls hsurfEnableSurface. This means ! 340: // that if the device surface requires a bitmap to be allocated, or a ! 341: // journal to be created, these allocations need not be done at this time. ! 342: // This is done as an optimization, since applications will often want to ! 343: // get information about a device long before they actually write on the ! 344: // device. Waiting before allocating a large bitmap, for example, can ! 345: // save valuable resources. ! 346: // ! 347: // This is a required driver function. ! 348: // ! 349: // Parameters: ! 350: // pdriv: ! 351: // Pointer to a PSDEVMODE structure. Environment settings requested ! 352: // by the application. (WIN 3.0). ! 353: // ! 354: // where the DEVMODE structure is defined as follows: ! 355: // ! 356: // typedef struct _DEVMODE ! 357: // { ! 358: // CHAR dmDeviceName[32]; ! 359: // SHORT dmSpecVersion; ! 360: // SHORT dmDriverVersion; ! 361: // SHORT dmSize; ! 362: // SHORT dmDriverExtra; ! 363: // LONG dmFields; ! 364: // SHORT dmOrientation; ! 365: // SHORT dmPaperSize; ! 366: // SHORT dmPaperLength; ! 367: // SHORT dmPaperWidth; ! 368: // SHORT dmScale; ! 369: // SHORT dmCopies; ! 370: // SHORT dmDefaultSource; ! 371: // SHORT dmPrintQuality; ! 372: // SHORT dmColor; ! 373: // SHORT dmDuplex; ! 374: // BYTE dmDriverData[1]; ! 375: // } DEVMODE, *PDEVMODE; ! 376: // ! 377: // pszLogAddress: ! 378: // Points to a string describing the logical address of the device. ! 379: // Examples: "LPT1", "COM2", etc. ! 380: // ! 381: // cPatterns: ! 382: // This is the count of HSURF fields in the buffer pointed to by ! 383: // aulCaps. The driver must not touch memory beyond the end of the ! 384: // buffer. ! 385: // ! 386: // ahsurfPatterns: ! 387: // Points to a buffer which is to be filled with surfaces representing ! 388: // the basic fill patterns. The following patterns must be defined ! 389: // in order. Each pattern is the same as defined for PM 1.2. ! 390: // ! 391: // o PATSYM_DENSE1 ! 392: // o PATSYM_DENSE2 ! 393: // o PATSYM_DENSE3 ! 394: // o PATSYM_DENSE4 ! 395: // o PATSYM_DENSE5 ! 396: // o PATSYM_DENSE6 ! 397: // o PATSYM_DENSE7 ! 398: // o PATSYM_DENSE8 ! 399: // o PATSYM_VERT ! 400: // o PATSYM_HORIZ ! 401: // o PATSYM_DIAG1 ! 402: // o PATSYM_DIAG2 ! 403: // o PATSYM_DIAG3 ! 404: // o PATSYM_DIAG4 ! 405: // o PATSYM_NOSHADE ! 406: // o PATSYM_SOLID ! 407: // o PATSYM_HALFTONE ! 408: // o PATSYM_HATCH ! 409: // o PATSYM_DIAGHATCH ! 410: // ! 411: // When the Engine needs to realize a brush with a standard pattern, ! 412: // it will call cbRealizeBrush with one of these surfaces. ! 413: // ! 414: // For raster devices, if the Engine is going to do any drawing on DIBs ! 415: // for the device, each of these surfaces must be a monochrome (one bit ! 416: // per pixel) Engine bitmap. It is the device driver's job to choose ! 417: // patterns that will look most like the standard patterns when written ! 418: // on the device surface. ! 419: // ! 420: // In the case of a vector device, the Engine will never be required ! 421: // to use these brushes in its support routines, so the surfaces can be ! 422: // device supported surfaces which the cbRealizeBrush code will recognize ! 423: // as the various standard patterns. ! 424: // ! 425: // The Engine will zero fill this buffer before the call. ! 426: // ! 427: // ??? Can we create these surfaces before bCompletePDEV??? ! 428: // ! 429: // cCaps: ! 430: // This is the count of ULONG fields in the buffer pointed to by ! 431: // aulCaps. The driver must not touch memory beyond the end of the ! 432: // buffer. ! 433: // ! 434: // aulCaps: ! 435: // Points to a buffer which is to be filled with the device caps array. ! 436: // The Engine has zero filled this buffer before the call was made. ! 437: // This is identical to the array returned by the QueryDeviceCaps call ! 438: // in PM 1.2, with the following exceptions. ! 439: // ! 440: // The fields CAPS_MOUSE_BUTTONS and CAPS_VIO_LOADABLE_FONTS no ! 441: // longer have any meaning and should be left zeroed. ! 442: // ! 443: // Three fields are added: ! 444: // ! 445: // CAPS_X_STYLE_STEP (call this dx) ! 446: // CAPS_Y_STYLE_STEP (call this dy) ! 447: // CAPS_DEN_STYLE_STEP (call this D) ! 448: // ! 449: // These fields define how a cosmetic line style should advance as ! 450: // we draw each pel of the line. The amount we advance for each ! 451: // pel is defined as a fraction which depends on whether the line ! 452: // is x-major or y-major. If the line extends over more pels in ! 453: // the horizontal direction than the vertical direction it is called ! 454: // x-major, and the style will advance by the fractional amount dx/D. ! 455: // Otherwise the line is y-major and the style advances by dy/D for ! 456: // each pel. ! 457: // ! 458: // The dots in the predefined line style LINETYPE_DOT are each one ! 459: // unit long. So if you define CAPS_X_STYLE_STEP to be 1 and ! 460: // CAPS_DEN_STYLE_STEP to be 5, a dotted horizontal line will consist ! 461: // of 5 pels on followed by 5 pels off, repeated. ! 462: // ! 463: // See the section titled Cosmetic Line Styling for a complete ! 464: // description of styling. ! 465: // ! 466: // Each of these three numbers must fit in a USHORT, even though ! 467: // the caps fields are ULONGs. ! 468: // ! 469: // These style steps are defined by the device driver to make sure ! 470: // that the dots and dashes in a line are a pleasing size on the ! 471: // output device. The horizontal and vertical steps may be different ! 472: // to correct for non trivial aspect ratios. For example, on an ! 473: // EGA display, whose pels are 33\% higher than they are wide, you ! 474: // could set: ! 475: // ! 476: // aulCaps[CAPS_X_STYLE_STEP] = 3; // For an EGA! ! 477: // aulCaps[CAPS_Y_STYLE_STEP] = 4; ! 478: // aulCaps[CAPS_DEN_STYLE_STEP] = 12; ! 479: // ! 480: // ! 481: // In this case, horizontal dotted lines are four on - four off, ! 482: // since the style advances by 3/12 or 1/4 for each pel. Vertical ! 483: // dotted lines are three on - three off. ! 484: // ! 485: // Styled lines look better if both the X and Y style steps divide ! 486: // evenly into the style denominator as they do in this example. ! 487: // This gives dashes and dots that are always the same length. ! 488: // ! 489: // The Engine needs this information so that its bitmap routines ! 490: // can emulate exactly what the device would do on its own surface. ! 491: // Applications may also want to access this information to determine ! 492: // exactly what pels will be turned on for styled lines. ! 493: // ! 494: // cbDevInfo: ! 495: // This is a count of the bytes in the DEVINFO structure pointed to ! 496: // by pdevinfo. The driver should modify no more than this number of ! 497: // bytes in the DEVINFO. ! 498: // ! 499: // pdevinfo: ! 500: // This structure provides information about the driver and the physical ! 501: // device. The driver should fill in as many fields as it understands, ! 502: // and leave the others untouched. The Engine will have zero filled ! 503: // this structure before this call. ! 504: // ! 505: // In general, these fields provide information needed by the Engine ! 506: // to support the device. Application programs do not have access to ! 507: // this information. ! 508: // ! 509: // flGraphicsCaps: ! 510: // These are flags describing the graphics capabilities that the ! 511: // driver has for this PDEV. The flags are: ! 512: // ! 513: // GCAPS_BEZIERS Can handle Beziers (cubic splines). ! 514: // GCAPS_GEOMETRICWIDE Can do geometric widening. ! 515: // GCAPS_ALTERNATEFILL Can do alternating fills. ! 516: // GCAPS_WINDINGFILL Can do winding mode fills. ! 517: // GCAPS_ROTATEBLT Can do an arbitrarily transformed Blt. ! 518: // GCAPS_BLANKRECT Can blank a rectangle in vDrawText. ! 519: // ! 520: // pffRaster: ! 521: // This is a pointer to the device's default raster font, if it has ! 522: // one. The pointer is NULL if the device has no default raster ! 523: // font. ! 524: // ! 525: // The Engine could also ask for this pointer directly with ! 526: // pvQueryResource(dhpdev,FONT,SFONT_RASTER). It is provided here ! 527: // as an optimization. ! 528: // ! 529: // pffVector: ! 530: // Same as the above, but points to the default vector font, if ! 531: // any. ! 532: // ! 533: // cxDither: ! 534: // ! 535: // cyDither: ! 536: // These are the dimensions of a dithered brush. If these are ! 537: // non-zero, the device is able to create a dithered brush for a ! 538: // given RGB color. See bDitherBrush. ! 539: // ! 540: // ! 541: // Returns: ! 542: // If this function is successful, it returns a handle which identifies ! 543: // the device; otherwise it returns 0x00000000. ! 544: // ! 545: // History: ! 546: // 16-Oct-1990 -by- Kent Settle (kentse) ! 547: // Created stub. ! 548: // ! 549: // 05-Feb-1993 Fri 19:44:35 updated -by- Daniel Chou (danielc) ! 550: // remove halftone stuff and let engine do the halftone work ! 551: // ! 552: //-------------------------------------------------------------------------- ! 553: ! 554: DHPDEV DrvEnablePDEV( ! 555: PDEVMODE pdriv, ! 556: PWSTR pwstrLogAddress, ! 557: ULONG cPatterns, ! 558: PHSURF ahsurfPatterns, ! 559: ULONG cjGdiInfo, ! 560: ULONG *pGdiInfo, ! 561: ULONG cb, ! 562: PDEVINFO pdevinfo, ! 563: PWSTR pwstrDataFile, ! 564: PWSTR pwstrDeviceName, ! 565: HANDLE hPrinter) ! 566: { ! 567: PDEVDATA pdev; // pointer to our device data block. ! 568: HANDLE hheap; ! 569: DWORD i; ! 570: PNTFM pntfm; ! 571: HANDLE hFontRes; ! 572: GDIINFO *pgdiinfo; ! 573: ! 574: UNREFERENCED_PARAMETER(pwstrLogAddress); ! 575: ! 576: // create a heap and allocate memory for our DEVDATA block. ! 577: ! 578: if (!(hheap = (HANDLE)HeapCreate(HEAP_NO_SERIALIZE, START_HEAP_SIZE, 0))) ! 579: { ! 580: RIP("PSCRIPT!DrvEnablePDEV: HeapCreate failed."); ! 581: return(0L); ! 582: } ! 583: ! 584: // allocate the pdev and store the heap handle in there. ! 585: ! 586: if (!(pdev = (PDEVDATA)HeapAlloc(hheap, 0, sizeof(DEVDATA)))) ! 587: { ! 588: RIP("PSCRIPT!DrvEnablePDEV: HeapAlloc for DEVDATA failed."); ! 589: return(0L); ! 590: } ! 591: ! 592: memset(pdev, 0, sizeof(DEVDATA)); ! 593: ! 594: pdev->hheap = hheap; ! 595: pdev->hPrinter = hPrinter; ! 596: pdev->pwstrDocName = (PWSTR)NULL; ! 597: ! 598: if (!(pdev->pwstrPPDFile = (PWSTR)HeapAlloc(pdev->hheap, 0, ! 599: ((wcslen(pwstrDataFile) + 1) * sizeof(WCHAR))))) ! 600: { ! 601: RIP("PSCRIPT!DrvEnablePDEV: HeapAlloc for pdev->pstrPPDFile failed."); ! 602: return(0L); ! 603: } ! 604: ! 605: // copy pszDataFile into the allocated memory pointed to by ! 606: // pdev->pwstrPPDFile. ! 607: ! 608: wcscpy(pdev->pwstrPPDFile, pwstrDataFile); ! 609: ! 610: // get the current printer information from the .PPD file and ! 611: // store a pointer to it in the DEVDATA structure. ! 612: ! 613: pdev->pntpd = GetNTPD(pdev, pdev->pwstrPPDFile); ! 614: ! 615: if (!pdev->pntpd) ! 616: { ! 617: RIP("PSCRIPT!DrvEnablePDEV: GetNTPD failed.\n"); ! 618: return(0L); ! 619: } ! 620: ! 621: // initialize our DEVMODE structure for the current printer. ! 622: ! 623: SetDefaultPSDEVMODE((PSDEVMODE *)&pdev->psdm, pwstrDeviceName, ! 624: pdev->pntpd, pdev->hPrinter); ! 625: ! 626: // call off to do the guts of the work. ! 627: ! 628: // validate the DEVMODE structure passed in by the user, if everything ! 629: // is OK, set the fields selected by the user. ! 630: ! 631: if (!ValidateSetDEVMODE((PSDEVMODE *)&pdev->psdm, (PSDEVMODE *)pdriv, ! 632: pdev->hPrinter, pdev->pntpd)) ! 633: { ! 634: RIP("PSCRIPT!DrvEnablePDEV: ValidateSetDEVMODE failed."); ! 635: SetLastError(ERROR_INVALID_PARAMETER); ! 636: return(0L); ! 637: } ! 638: ! 639: // ! 640: // Allocate memory for default user's color adjustment ! 641: // ! 642: ! 643: if (!(pdev->pvDrvHTData = (LPVOID)HeapAlloc(hheap, 0, sizeof(DRVHTINFO)))) { ! 644: ! 645: RIP("PSCRIPT!FillMyDevmode: HeapAlloc(DRVHTINFO) failed.\n"); ! 646: return(FALSE); ! 647: } ! 648: ! 649: ZeroMemory(pdev->pvDrvHTData, sizeof(DRVHTINFO)); ! 650: ! 651: // fill in our DEVDATA structure. ! 652: ! 653: if (!FillMyDevData(pdev)) ! 654: return(0); ! 655: ! 656: // fill in the device capabilities for the engine. ! 657: ! 658: vFillaulCaps(pdev, cjGdiInfo, pGdiInfo); ! 659: ! 660: // fill in DEVINFO structure. ! 661: ! 662: pgdiinfo = (GDIINFO *)pGdiInfo; ! 663: ! 664: if(!bFillMyDevInfo(pdev, cb, pdevinfo, pgdiinfo->ulHTPatternSize)) ! 665: return(0); ! 666: ! 667: // this is a good place to allocate room for all the font metrics to ! 668: // support all the device fonts. ! 669: ! 670: if (!(pdev->pfmtable = (PFMPAIR *)HeapAlloc(pdev->hheap, 0, ! 671: (DWORD)(sizeof(PFMPAIR) * pdevinfo->cFonts)))) ! 672: { ! 673: RIP("PSCRIPT!bFillMyDevInfo: HeapAlloc for pdev->pfmtable failed."); ! 674: return(FALSE); ! 675: } ! 676: ! 677: // initialize the pfm table. ! 678: ! 679: ZeroMemory(pdev->pfmtable, (pdevinfo->cFonts * sizeof(PFMPAIR))); ! 680: ! 681: for (i = 0; i < pdevinfo->cFonts; i++) ! 682: { ! 683: // get the font metrics for the specified font. ! 684: ! 685: if (!(pntfm = GetFont(pdev, (i + 1), &hFontRes))) ! 686: { ! 687: RIP("PSCRIPT!DrvEnablePDEV: GetFont failed.\n"); ! 688: return((DHPDEV)0); ! 689: } ! 690: ! 691: // save the resource handle with the NTFM structure. ! 692: ! 693: pdev->pfmtable[i].pntfm = pntfm; ! 694: pdev->pfmtable[i].hFontRes = hFontRes; ! 695: } ! 696: ! 697: ! 698: // ! 699: // We will zero out all the hSurface for the pattern so that engine can ! 700: // automatically simulate the staandard pattern for us ! 701: // ! 702: ! 703: ZeroMemory(ahsurfPatterns, sizeof(HSURF) * cPatterns); ! 704: ! 705: // return a pointer to our DEVDATA structure. it is supposed to ! 706: // be a handle, but we know it is a pointer. ! 707: ! 708: return((DHPDEV)pdev); ! 709: } ! 710: ! 711: ! 712: //-------------------------------------------------------------------------- ! 713: // BOOL DrvRestartPDEV( ! 714: // DHPDEV dhpdev, ! 715: // PDEVMODE pdriv, ! 716: // ULONG cPatterns, ! 717: // PHSURF ahsurfPatterns, ! 718: // ULONG cjGdiInfo, ! 719: // PGDIINFO pGdiInfo, ! 720: // ULONG cb, ! 721: // PDEVINFO pdevinfo); ! 722: // ! 723: // This call changes the device mode of an existing PDEV. This is used ! 724: // when an application wishes to print one document containing pages in ! 725: // different modes, like a mixture of portrait and landscape. ! 726: // ! 727: // The Engine will have called vDisableSurface before this call. In ! 728: // general, a change of mode will require a surface with a different ! 729: // shape. ! 730: // ! 731: // An error is returned if the new mode is not compatible with the ! 732: // previous mode. ! 733: // ! 734: // This call is required for output devices that want to allow mode ! 735: // changes in documents. ! 736: // ! 737: // Parameters: ! 738: // dhpdev: ! 739: // Identifies the existing PDEV to change. ! 740: // ! 741: // pdriv: ! 742: // Pointer to a PSDEVMODE structure. Enviroment settings requested ! 743: // by the application. (WIN 3.0) ! 744: // ! 745: // This is a pointer to the new PSDEVMODE. If the device name does not ! 746: // match the previous one, an error should be returned. If for any ! 747: // other reason the new mode is not compatible with the old mode, an ! 748: // error should be returned. ! 749: // ! 750: // Returns: ! 751: // This function returns TRUE if it was successful; otherwise it returns ! 752: // FALSE. ! 753: // ! 754: // Comments: ! 755: // All other arguments are the same as dhpdevEnablePDEV, and new caps and ! 756: // parameters should be returned for the new mode. ! 757: // ! 758: // History: ! 759: // 21-Oct-1990 -by- Kent Settle (kentse) ! 760: // Wrote it. ! 761: // 16-Oct-1990 -by- Kent Settle (kentse) ! 762: // Created stub. ! 763: // ! 764: // 05-Feb-1993 Fri 19:45:31 updated -by- Daniel Chou (danielc) ! 765: // Remove Disable halftone function since engine do the work ! 766: // ! 767: //-------------------------------------------------------------------------- ! 768: ! 769: BOOL DrvRestartPDEV( ! 770: DHPDEV dhpdev, ! 771: PDEVMODE pdriv, ! 772: ULONG cPatterns, ! 773: PHSURF ahsurfPatterns, ! 774: ULONG cjGdiInfo, ! 775: ULONG *pGdiInfo, ! 776: ULONG cb, ! 777: PDEVINFO pdevinfo) ! 778: { ! 779: PDEVDATA pdev; // pointer to our devdata. ! 780: GDIINFO *pgdiinfo; ! 781: ! 782: // since this call changes the device mode of an existing PDEV, ! 783: // make sure we have an existing, valid PDEV. ! 784: ! 785: pdev = (PDEVDATA)dhpdev; ! 786: ! 787: if (bValidatePDEV(pdev) == FALSE) ! 788: { ! 789: RIP("PSCRIPT!DrvRestartPDEV: invalid pdev.\n"); ! 790: SetLastError(ERROR_INVALID_PARAMETER); ! 791: return(FALSE); ! 792: } ! 793: ! 794: // validate the DEVMODE structure passed in by the user, if everything ! 795: // is OK, set the fields selected by the user. ! 796: ! 797: if (!ValidateSetDEVMODE((PSDEVMODE *)&pdev->psdm, (PSDEVMODE *)pdriv, ! 798: pdev->hPrinter, pdev->pntpd)) ! 799: { ! 800: RIP("PSCRIPT!DrvRestartPDEV: ValidateSetDEVMODE failed."); ! 801: SetLastError(ERROR_INVALID_PARAMETER); ! 802: return(FALSE); ! 803: } ! 804: ! 805: // set up the metrics for the current form. ! 806: ! 807: SetFormMetrics(pdev); ! 808: ! 809: // set number of copies, this may get overwritten by SETCOPYCOUNT escape. ! 810: ! 811: pdev->cCopies = pdev->psdm.dm.dmCopies; ! 812: ! 813: // set the scaling factor from the DEVMODE. ! 814: ! 815: pdev->psfxScale = LTOPSFX(pdev->psdm.dm.dmScale) / 100; ! 816: pdev->ScaledDPI = ((pdev->psdm.dm.dmPrintQuality * ! 817: pdev->psdm.dm.dmScale) / 100); ! 818: ! 819: // fill in the device capabilities for the engine. ! 820: ! 821: vFillaulCaps(pdev, cjGdiInfo, pGdiInfo); ! 822: ! 823: // fill in DEVINFO structure. ! 824: ! 825: pgdiinfo = (GDIINFO *)pGdiInfo; ! 826: ! 827: if(!bFillMyDevInfo(pdev, cb, pdevinfo, pgdiinfo->ulHTPatternSize)) ! 828: return(FALSE); ! 829: ! 830: // ! 831: // We will zero out all the hSurface for the pattern so that engine can ! 832: // automatically simulate the staandard pattern for us ! 833: // ! 834: ! 835: ZeroMemory(ahsurfPatterns, sizeof(HSURF) * cPatterns); ! 836: ! 837: ! 838: return(TRUE); ! 839: } ! 840: ! 841: ! 842: //-------------------------------------------------------------------------- ! 843: // VOID DrvCompletePDEV( ! 844: // DHPDEV dhpdev, ! 845: // HPDEV hpdev) ! 846: // ! 847: // The Engine calls this function when its installation of the physical ! 848: // device is complete. ! 849: // ! 850: // Parameters: ! 851: // dhpdev: ! 852: // This is a device PDEV handle returned from a call to ! 853: // dhpdevEnablePDEV. ! 854: // ! 855: // hpdev: ! 856: // This is the Engine's handle for the physical device being created. ! 857: // The driver should retain this handle for use when calling various ! 858: // Engine services. ! 859: // ! 860: // ! 861: // Returns: ! 862: // This function returns TRUE if it was successful; otherwise it returns ! 863: // FALSE. ! 864: // ! 865: // History: ! 866: // 21-Oct-1990 -by- Kent Settle (kentse) ! 867: // Wrote it. ! 868: // 16-Oct-1990 -by- Kent Settle (kentse) ! 869: // Created stub. ! 870: //-------------------------------------------------------------------------- ! 871: ! 872: VOID DrvCompletePDEV( ! 873: DHPDEV dhpdev, ! 874: HDEV hdev) ! 875: { ! 876: if (bValidatePDEV((PDEVDATA)dhpdev) == FALSE) ! 877: { ! 878: RIP("PSCRIPT!bCompletePDEV: invalid PDEV."); ! 879: SetLastError(ERROR_INVALID_PARAMETER); ! 880: return; ! 881: } ! 882: ! 883: // store the engine's handle to the physical device in our DEVDATA. ! 884: ! 885: ((PDEVDATA)dhpdev)->hdev = hdev; ! 886: ! 887: return; ! 888: } ! 889: ! 890: ! 891: //-------------------------------------------------------------------------- ! 892: // HSURF DrvEnableSurface( ! 893: // DHPDEV dhpdev); ! 894: // ! 895: // Requests that the driver create a surface for an existing physical ! 896: // device. ! 897: // ! 898: // Depending on the device and circumstances, the device might do any ! 899: // of the following to get the HSURF. ! 900: // ! 901: // 1 If the driver manages its own surface it should call the Engine ! 902: // service hsurfCreate to get a surface handle for it. ! 903: // ! 904: // 2 If the device has a surface which resembles a standard format ! 905: // bitmap it may want the Engine to manage the surface completely. ! 906: // In that case, the driver should call the Engine service hbmCreate ! 907: // with a pointer to the device pels, in order to get a bitmap ! 908: // handle for it. ! 909: // ! 910: // 3 If the device wants the Engine to collect the graphics directly ! 911: // on an Engine bitmap, the driver should also call hbmCreate, but ! 912: // have the Engine allocate space for the pels. ! 913: // ! 914: // 4 If the device wants the Engine to collect the graphics output ! 915: // in a journal, for replaying several times, it should call the ! 916: // Engine service hjnlCreate. ! 917: // ! 918: // As explained in the section on surfaces, any Engine bitmap handle or ! 919: // journal handle will be accepted as a valid surface handle. ! 920: // ! 921: // This call will only be made when there is no surface for the given ! 922: // PDEV. ! 923: // ! 924: // This is a required driver function. ! 925: // ! 926: // Parameters: ! 927: // dhpdev: ! 928: // This is a device PDEV handle returned from a call to ! 929: // dhpdevEnablePDEV. It identifies the physical device that the surface ! 930: // is to be created for. ! 931: // ! 932: // Returns: ! 933: // This function returns a handle that identifies the surface if it is ! 934: // successful; otherwise it returns 0x00000000. ! 935: // ! 936: // History: ! 937: // 16-Oct-1990 -by- Kent Settle (kentse) ! 938: // Created stub. ! 939: //-------------------------------------------------------------------------- ! 940: ! 941: HSURF DrvEnableSurface( ! 942: DHPDEV dhpdev) ! 943: { ! 944: PDEVDATA pdev; ! 945: PDRVHTINFO pDrvHTInfo; ! 946: SIZEL sizlDev; ! 947: ! 948: // get the pointer to our DEVDATA structure and make sure it is ours. ! 949: ! 950: pdev = (PDEVDATA)dhpdev; ! 951: ! 952: if (bValidatePDEV(pdev) == FALSE) ! 953: { ! 954: RIP("PSCRIPT!DrvEnableSurface: invalid pdev.\n"); ! 955: SetLastError(ERROR_INVALID_PARAMETER); ! 956: return(0L); ! 957: } ! 958: ! 959: pDrvHTInfo = (PDRVHTINFO)(pdev->pvDrvHTData); ! 960: ! 961: if (pDrvHTInfo->HTBmpFormat == BMF_4BPP) { ! 962: ! 963: if (!(pDrvHTInfo->pHTXB)) { ! 964: ! 965: if (!(pDrvHTInfo->pHTXB = (PHTXB)HeapAlloc(pdev->hheap, ! 966: 0, ! 967: HTXB_TABLE_SIZE))) { ! 968: ! 969: RIP("DrvEnableSurface: HeapAlloc(HTXB_TABLE_SIZE) failed.\n"); ! 970: return(0L); ! 971: } ! 972: } ! 973: ! 974: } else { ! 975: ! 976: if (pDrvHTInfo->pHTXB) { ! 977: ! 978: HeapFree(pdev->hheap, 0, (PVOID)pDrvHTInfo->pHTXB); ! 979: pDrvHTInfo->pHTXB = NULL; ! 980: } ! 981: } ! 982: ! 983: // ! 984: // Invalidate the PALXlate table, and initial any flags ! 985: // ! 986: ! 987: pDrvHTInfo->Flags = 0; ! 988: pDrvHTInfo->PalXlate[0] = 0xff; ! 989: pDrvHTInfo->HTPalXor = HTPALXOR_SRCCOPY; ! 990: ! 991: // call the engine to create a surface handle for us. ! 992: ! 993: // convert the imageable area from PostScript USER space into ! 994: // device space. ! 995: ! 996: sizlDev.cx = ((pdev->CurForm.imagearea.right - pdev->CurForm.imagearea.left) * ! 997: pdev->psdm.dm.dmPrintQuality) / PS_RESOLUTION; ! 998: ! 999: sizlDev.cy = ((pdev->CurForm.imagearea.top - pdev->CurForm.imagearea.bottom) * ! 1000: pdev->psdm.dm.dmPrintQuality) / PS_RESOLUTION; ! 1001: ! 1002: pdev->hsurf = EngCreateSurface((DHSURF)pdev, sizlDev); ! 1003: ! 1004: if (pdev->hsurf == 0L) ! 1005: { ! 1006: RIP("PSCRIPT!DrvEnableSurface: hsurfCreateSurface returned 0."); ! 1007: return(0L); ! 1008: } ! 1009: ! 1010: EngAssociateSurface(pdev->hsurf, (HDEV)pdev->hdev, ! 1011: (HOOK_BITBLT | HOOK_STRETCHBLT | HOOK_TEXTOUT | ! 1012: HOOK_STROKEPATH | HOOK_FILLPATH | HOOK_COPYBITS | ! 1013: HOOK_STROKEANDFILLPATH)); ! 1014: ! 1015: // allocate memory for output buffer. when the driver sends output to ! 1016: // the output channel, it gets put into the output buffer. when the ! 1017: // buffer is full, or the channel is closed, then the buffer contents ! 1018: // are flushed out the channel. ! 1019: ! 1020: pdev->ioChannel.pBuffer = HeapAlloc(pdev->hheap, 0, OUTPUT_BUFFER_SIZE); ! 1021: ! 1022: if (pdev->ioChannel.pBuffer == NULL) ! 1023: { ! 1024: RIP("DrvEnableSurface: HeapAlloc for output buffer failed.\n"); ! 1025: EngDeleteSurface(pdev->hsurf); ! 1026: return(0L); ! 1027: } ! 1028: ! 1029: memset(pdev->ioChannel.pBuffer, 0, OUTPUT_BUFFER_SIZE); ! 1030: ! 1031: // initialize output channel information. ! 1032: ! 1033: pdev->ioChannel.ulBufCount = 0; ! 1034: ! 1035: // return the handle to the caller. ! 1036: ! 1037: return(pdev->hsurf); ! 1038: } ! 1039: ! 1040: ! 1041: //-------------------------------------------------------------------------- ! 1042: // VOID DrvDisableSurface( ! 1043: // DHPDEV dhpdev) ! 1044: // ! 1045: // Informs the driver that the surface created for the PDEV by ! 1046: // hsurfEnableSurface is no longer needed. If the surface ties up ! 1047: // valuable resources, for example a lot of RAM, the surface should be ! 1048: // destroyed. If the surface is cheap to keep around, then the driver ! 1049: // may decide to hold onto it in case it's needed again. If the driver ! 1050: // does hold onto the surface it should definitely be deleted when the ! 1051: // PDEV is disabled! ! 1052: // ! 1053: // The Engine will always call this routine before calling vDisablePDEV ! 1054: // if the PDEV has an enabled surface. ! 1055: // ! 1056: // This is a required driver function. ! 1057: // ! 1058: // Parameters: ! 1059: // dhpdev: ! 1060: // This is the PDEV with which the surface is associated. ! 1061: // ! 1062: // ! 1063: // Returns: ! 1064: // This function does not return a value. ! 1065: // ! 1066: // History: ! 1067: // 16-Oct-1990 -by- Kent Settle (kentse) ! 1068: // Created stub. ! 1069: //-------------------------------------------------------------------------- ! 1070: ! 1071: VOID DrvDisableSurface( ! 1072: DHPDEV dhpdev) ! 1073: { ! 1074: PDEVDATA pdev; ! 1075: PDRVHTINFO pDrvHTInfo; ! 1076: ! 1077: // get the pointer to our DEVDATA structure and make sure it is ours. ! 1078: ! 1079: pdev = (PDEVDATA)dhpdev; ! 1080: ! 1081: if (bValidatePDEV(pdev) == FALSE) ! 1082: return; ! 1083: ! 1084: // ! 1085: // Free up xlate table ! 1086: // ! 1087: ! 1088: pDrvHTInfo = (PDRVHTINFO)(pdev->pvDrvHTData); ! 1089: ! 1090: if (pDrvHTInfo->pHTXB) { ! 1091: ! 1092: HeapFree(pdev->hheap, 0, (PVOID)pDrvHTInfo->pHTXB); ! 1093: pDrvHTInfo->pHTXB = NULL; ! 1094: } ! 1095: ! 1096: // free the memory used by the output buffer. ! 1097: ! 1098: if (pdev->ioChannel.pBuffer) ! 1099: { ! 1100: HeapFree(pdev->hheap, 0, (PVOID)pdev->ioChannel.pBuffer); ! 1101: pdev->ioChannel.pBuffer = NULL; ! 1102: } ! 1103: ! 1104: // delete our surface. ! 1105: ! 1106: if (pdev->hsurf != 0L); ! 1107: { ! 1108: // call the engine to delete the surface handle. ! 1109: ! 1110: EngDeleteSurface(pdev->hsurf); ! 1111: ! 1112: // zero out our the copy of the handle in our DEVDATA. ! 1113: ! 1114: pdev->hsurf = 0L; ! 1115: } ! 1116: } ! 1117: ! 1118: //-------------------------------------------------------------------------- ! 1119: // VOID DrvDisablePDEV( ! 1120: // DHPDEV dhpdev) ! 1121: // ! 1122: // Informs the driver that the given physical device is no longer needed. ! 1123: // At this time, the driver should free any memory and resources used by ! 1124: // the given PDEV. It should also free any surface that was created for ! 1125: // this PDEV, but not yet deleted. ! 1126: // ! 1127: // This is a required driver function. ! 1128: // ! 1129: // Parameters: ! 1130: // dhpdev: ! 1131: // The physical device which is to be disabled. ! 1132: // ! 1133: // Returns: ! 1134: // This function does not return a value. ! 1135: // ! 1136: // History: ! 1137: // 16-Oct-1990 -by- Kent Settle (kentse) ! 1138: // Created stub. ! 1139: // ! 1140: // 05-Feb-1993 Fri 19:47:19 updated -by- Daniel Chou (danielc) ! 1141: // Remove delete pattern surfaces, since engine created them ! 1142: // ! 1143: //-------------------------------------------------------------------------- ! 1144: ! 1145: VOID DrvDisablePDEV( ! 1146: DHPDEV dhpdev) ! 1147: { ! 1148: PDEVDATA pdev; ! 1149: DWORD i, cFonts; ! 1150: ! 1151: pdev = (PDEVDATA)dhpdev; ! 1152: ! 1153: if (bValidatePDEV(pdev) == FALSE) ! 1154: { ! 1155: RIP("PSCRIPT!DrvDisablePDEV: Invalid pdev.\n"); ! 1156: SetLastError(ERROR_INVALID_PARAMETER); ! 1157: return; ! 1158: } ! 1159: ! 1160: // free up the font resources. ! 1161: ! 1162: cFonts = pdev->cDeviceFonts + pdev->cSoftFonts; ! 1163: ! 1164: for (i = 0; i < cFonts; i++) ! 1165: { ! 1166: FreeFont(pdev, i + 1, pdev->pfmtable[i].hFontRes, ! 1167: pdev->pfmtable[i].pntfm); ! 1168: } ! 1169: ! 1170: // free up our default device palette. ! 1171: ! 1172: if (pdev->hpal) ! 1173: EngDeletePalette(pdev->hpal); ! 1174: ! 1175: // destroy the heap. ! 1176: ! 1177: if (!HeapDestroy(pdev->hheap)) ! 1178: RIP("vDisablePDEV: HeapDestroy failed.\n"); ! 1179: } ! 1180: ! 1181: ! 1182: //-------------------------------------------------------------------------- ! 1183: // VOID DrvDisableDriver() ! 1184: // ! 1185: // Informs the driver that the Engine will no longer be using it and ! 1186: // that it is about to be unloaded. All resources still allocated by ! 1187: // the driver should be freed. ! 1188: // ! 1189: // This is a required driver function. ! 1190: // ! 1191: // Parameters ! 1192: // None. ! 1193: // ! 1194: // Returns ! 1195: // This function does not return a value. ! 1196: // ! 1197: // History: ! 1198: // 16-Oct-1990 -by- Kent Settle (kentse) ! 1199: // Created stub. ! 1200: //-------------------------------------------------------------------------- ! 1201: ! 1202: VOID DrvDisableDriver() ! 1203: { ! 1204: return; ! 1205: } ! 1206: ! 1207: ! 1208: //-------------------------------------------------------------------------- ! 1209: // VOID FillMyDevData(pdev) ! 1210: // PDEVDATA pdev; // Pointer to our DEVDATA structure. ! 1211: // ! 1212: // This routine fills in our DEVDATA structure, using the PSDEVMODE passed ! 1213: // to us by the user. ! 1214: // ! 1215: // Parameters ! 1216: // pdev: ! 1217: // Pointer to our DEVDATA structure, which we will then fill in. ! 1218: // ! 1219: // Returns ! 1220: // This function does not return a value. ! 1221: // ! 1222: // History: ! 1223: // 18-Oct-1990 -by- Kent Settle (kentse) ! 1224: // Wrote it. ! 1225: //-------------------------------------------------------------------------- ! 1226: ! 1227: BOOL FillMyDevData(pdev) ! 1228: PDEVDATA pdev; // Pointer to our DEVDATA structure. ! 1229: { ! 1230: WCHAR wcbuf[64]; ! 1231: DWORD returnvalue; ! 1232: DWORD dwType, cb; ! 1233: BOOL bHostHalftoning; ! 1234: DWORD cbTable; ! 1235: TT_FONT_MAPPING *pTable; ! 1236: WCHAR *pbuf; ! 1237: ! 1238: // mark the DEVDATA structure as ours. ! 1239: ! 1240: pdev->dwID = DRIVER_ID; ! 1241: pdev->dwEndPDEV = DRIVER_ID; ! 1242: ! 1243: // set up the metrics for the current form. ! 1244: ! 1245: SetFormMetrics(pdev); ! 1246: ! 1247: // now, initialize the flags. ! 1248: ! 1249: pdev->dwFlags = 0L; ! 1250: ! 1251: // Get the current setting of the PS_HALFTONING flag from the ! 1252: // registry and initialize the check button. ! 1253: ! 1254: LoadString(ghmodDrv, (IDS_HALFTONE + STRING_BASE), ! 1255: wcbuf, (sizeof(wcbuf) / sizeof(wcbuf[0]))); ! 1256: ! 1257: returnvalue = GetPrinterData(pdev->hPrinter, wcbuf, &dwType, ! 1258: (LPBYTE)&bHostHalftoning, ! 1259: sizeof(bHostHalftoning), &cb); ! 1260: ! 1261: // printer halftoning is OFF by default. ie, use the system halftoning. ! 1262: ! 1263: if ((returnvalue != ERROR_SUCCESS) || (bHostHalftoning)) ! 1264: pdev->dwFlags &= ~PDEV_PSHALFTONE; ! 1265: else ! 1266: pdev->dwFlags |= PDEV_PSHALFTONE; ! 1267: ! 1268: // let's start at page 1. ! 1269: ! 1270: pdev->iPageNumber = 1; ! 1271: ! 1272: // set number of copies, this may get overwritten by SETCOPYCOUNT escape. ! 1273: ! 1274: pdev->cCopies = pdev->psdm.dm.dmCopies; ! 1275: ! 1276: LoadString(ghmodDrv, (IDS_FREEMEM + STRING_BASE), ! 1277: wcbuf, (sizeof(wcbuf) / sizeof(wcbuf[0]))); ! 1278: ! 1279: returnvalue = GetPrinterData(pdev->hPrinter, wcbuf, &dwType, ! 1280: (LPBYTE)&pdev->dwCurVM, ! 1281: sizeof(pdev->dwCurVM), &cb); ! 1282: ! 1283: if (returnvalue != ERROR_SUCCESS) ! 1284: pdev->dwCurVM = DEFAULT_MINIMUM_MEMORY; ! 1285: ! 1286: // make sure we have a useable value. ! 1287: ! 1288: pdev->dwCurVM = max(pdev->dwCurVM, DEFAULT_MINIMUM_MEMORY); ! 1289: ! 1290: pdev->iDLFonts = pdev->dwCurVM / KBYTES_PER_FONT; ! 1291: ! 1292: // see if the tray to form assignment table has been written out ! 1293: // to the registry. first check for the size of the table. ! 1294: ! 1295: LoadString(ghmodDrv, (IDS_TRAY_FORM_SIZE + STRING_BASE), ! 1296: wcbuf, (sizeof(wcbuf) / sizeof(wcbuf[0]))); ! 1297: ! 1298: returnvalue = GetPrinterData(pdev->hPrinter, wcbuf, &dwType, ! 1299: (LPBYTE)&cbTable, sizeof(cbTable), &cb); ! 1300: ! 1301: pdev->pTrayFormTable = (WCHAR *)NULL; ! 1302: ! 1303: if ((returnvalue == ERROR_SUCCESS) && (cbTable)) ! 1304: { ! 1305: // the table does exist in the registry, so allocate a buffer to ! 1306: // copy it into. ! 1307: ! 1308: if (!(pbuf = HeapAlloc(pdev->hheap, 0, cbTable))) ! 1309: { ! 1310: RIP("PSCRIPT!FillMyDevData: HeapAlloc for pbuf failed.\n"); ! 1311: return(FALSE); ! 1312: } ! 1313: ! 1314: // now grab the table itself from the registry. ! 1315: ! 1316: LoadString(ghmodDrv, (IDS_TRAY_FORM_TABLE + STRING_BASE), ! 1317: wcbuf, (sizeof(wcbuf) / sizeof(wcbuf[0]))); ! 1318: ! 1319: returnvalue = GetPrinterData(pdev->hPrinter, wcbuf, &dwType, ! 1320: (LPBYTE)pbuf, cbTable, &cb); ! 1321: ! 1322: if ((cb != cbTable) || (returnvalue != ERROR_SUCCESS)) ! 1323: { ! 1324: RIP("PSCRIPT!FillMyDevData: GetPrinterData for tray-form table failed.\n"); ! 1325: return(FALSE); ! 1326: } ! 1327: ! 1328: // set pointer in the PDEV. ! 1329: ! 1330: pdev->pTrayFormTable = pbuf; ! 1331: } ! 1332: ! 1333: // see if the font mapping tables have been written out ! 1334: // to the registry. if nothing has yet been written out, ! 1335: // write out the default mapping table. store the table in our ! 1336: // PDEV for user later. ! 1337: ! 1338: LoadString(ghmodDrv, (IDS_FONT_SUBST_SIZE + STRING_BASE), ! 1339: wcbuf, (sizeof(wcbuf) / sizeof(wcbuf[0]))); ! 1340: ! 1341: returnvalue = GetPrinterData(pdev->hPrinter, wcbuf, &dwType, ! 1342: (LPBYTE)&cbTable, sizeof(cbTable), &cb); ! 1343: ! 1344: if ((returnvalue == ERROR_SUCCESS) && (cbTable)) ! 1345: { ! 1346: // copy the font substitution table from the registry to our PDEV. ! 1347: ! 1348: if (!(pbuf = HeapAlloc(pdev->hheap, 0, cbTable))) ! 1349: { ! 1350: RIP("PSCRIPT!FillMyDevData: HeapAlloc for pbuf failed.\n"); ! 1351: return(FALSE); ! 1352: } ! 1353: ! 1354: LoadString(ghmodDrv, (IDS_FONT_SUBST_TABLE + STRING_BASE), ! 1355: wcbuf, (sizeof(wcbuf) / sizeof(wcbuf[0]))); ! 1356: ! 1357: returnvalue = GetPrinterData(pdev->hPrinter, wcbuf, &dwType, ! 1358: (LPBYTE)pbuf, cbTable, &cb); ! 1359: ! 1360: if ((cb != cbTable) || (returnvalue != ERROR_SUCCESS)) ! 1361: { ! 1362: RIP("PSCRIPT!FillMyDevData: GetPrinterData for subst table failed.\n"); ! 1363: return(FALSE); ! 1364: } ! 1365: ! 1366: // keep a pointer to the table in our PDEV. ! 1367: ! 1368: pdev->pTTSubstTable = pbuf; ! 1369: } ! 1370: else ! 1371: { ! 1372: // there is no font substitution table in the registry, so put a ! 1373: // copy of our default table in our PDEV. ! 1374: ! 1375: pTable = TTFontTable; ! 1376: ! 1377: // calculate how much of a buffer we will need for the table. ! 1378: ! 1379: // allow room for double NULL terminator. ! 1380: ! 1381: cb = 1; ! 1382: ! 1383: while (pTable->pwstrTTFont) ! 1384: { ! 1385: cb += (wcslen(pTable->pwstrTTFont) + 1) + ! 1386: (wcslen(pTable->pwstrDevFont) + 1); ! 1387: ! 1388: pTable++; ! 1389: } ! 1390: ! 1391: cb *= sizeof(WCHAR); ! 1392: ! 1393: // allocate buffer. ! 1394: ! 1395: if (!(pbuf = HeapAlloc(pdev->hheap, 0, cb))) ! 1396: { ! 1397: RIP("PSCRIPT!FillMyDevData: HeapAlloc for pbuf failed.\n"); ! 1398: return(FALSE); ! 1399: } ! 1400: ! 1401: // set pointer in our PDEV. ! 1402: ! 1403: pdev->pTTSubstTable = pbuf; ! 1404: ! 1405: // point back to start of table. ! 1406: ! 1407: pTable = TTFontTable; ! 1408: ! 1409: // now copy our default font mapping table into the buffer. ! 1410: ! 1411: while (pTable->pwstrTTFont) ! 1412: { ! 1413: wcscpy(pbuf, pTable->pwstrTTFont); ! 1414: pbuf += (wcslen(pTable->pwstrTTFont) + 1); ! 1415: ! 1416: wcscpy(pbuf, pTable->pwstrDevFont); ! 1417: pbuf += (wcslen(pTable->pwstrDevFont) + 1); ! 1418: ! 1419: pTable++; ! 1420: } ! 1421: ! 1422: // add the last NULL terminator; ! 1423: ! 1424: *pbuf = (WCHAR)'\0'; ! 1425: ! 1426: } ! 1427: ! 1428: // initialize the current graphics state. ! 1429: ! 1430: pdev->pcgsSave = NULL; ! 1431: ! 1432: memset(&pdev->cgs, 0, sizeof(CGS)); ! 1433: init_cgs(pdev); ! 1434: ! 1435: // allocate memory for the DLFONT structures. ! 1436: ! 1437: pdev->cgs.pDLFonts = (DLFONT *)HeapAlloc(pdev->hheap, 0, ! 1438: sizeof(DLFONT) * (pdev->iDLFonts + 1)); ! 1439: if (!pdev->cgs.pDLFonts) ! 1440: { ! 1441: RIP("PSCRIPT!FillMyDevData: HeapAlloc for pDLFont failed.\n"); ! 1442: return(FALSE); ! 1443: } ! 1444: ! 1445: // initialize the DLFONT array. ! 1446: ! 1447: memset(pdev->cgs.pDLFonts, 0, sizeof(DLFONT) * (pdev->iDLFonts + 1)); ! 1448: ! 1449: // set the scaling factor from the DEVMODE. ! 1450: ! 1451: pdev->psfxScale = LTOPSFX(pdev->psdm.dm.dmScale) / 100; ! 1452: pdev->ScaledDPI = ((pdev->psdm.dm.dmPrintQuality * ! 1453: pdev->psdm.dm.dmScale) / 100); ! 1454: ! 1455: return(TRUE); ! 1456: } ! 1457: ! 1458: ! 1459: //-------------------------------------------------------------------------- ! 1460: // BOOL bFillMyDevInfo(pdev, cb, pdevinfo, ulPatternSize) ! 1461: // PDEVDATA pdev; ! 1462: // ULONG cb; // size of pdevinfo structure. ! 1463: // PDEVINFO pdevinfo; // pointer to DEVINFO structure. ! 1464: // ULONG ulPatternSize; ! 1465: // ! 1466: // This routine fills in the DEVINFO structure pointed to by pdevinfo. ! 1467: // Since we have to worry about not writing out more than cb bytes to ! 1468: // pdevinfo, we will fill in a local buffer, then copy cb bytes to ! 1469: // pdevinfo. ! 1470: // ! 1471: // Parameters ! 1472: // cb: ! 1473: // Count of bytes to fill in DEVINFO structure. ! 1474: // ! 1475: // pdevinfo: ! 1476: // Pointer to DEVINFO structure to be filled in. ! 1477: // ! 1478: // Returns ! 1479: // This function returns TRUE if success, FALSE otherwise. ! 1480: // ! 1481: // History: ! 1482: // 14-Nov-1990 -by- Kent Settle (kentse) ! 1483: // Wrote it. ! 1484: //-------------------------------------------------------------------------- ! 1485: ! 1486: BOOL bFillMyDevInfo(pdev, cb, pdevinfo, ulPatternSize) ! 1487: PDEVDATA pdev; ! 1488: ULONG cb; // size of pdevinfo structure. ! 1489: PDEVINFO pdevinfo; // pointer to DEVINFO structure. ! 1490: ULONG ulPatternSize; ! 1491: { ! 1492: DEVINFO mydevinfo; ! 1493: TABLE_ENTRY *pTable; ! 1494: USHORT usDefFont; ! 1495: HANDLE hPFMFile; ! 1496: WCHAR wcbuf[MAX_PATH]; ! 1497: PWSTR pwstrPath; ! 1498: PWSTR pwstrFaceName; ! 1499: ULONG iFace; ! 1500: PSOFTFONTENTRY pSFList; ! 1501: DWORD cwBuf; ! 1502: WCHAR wstringbuf[256]; ! 1503: WIN32_FIND_DATA FileFindData; ! 1504: BOOL bFound; ! 1505: PSOFTFONTENTRY psfeTemp; ! 1506: DWORD cColors; ! 1507: ULONG *pulColors; ! 1508: ! 1509: // fill in the graphics capabilities flags. ! 1510: ! 1511: #ifdef INDEX_PAL ! 1512: mydevinfo.flGraphicsCaps = GCAPS_BEZIERS | GCAPS_GEOMETRICWIDE | ! 1513: GCAPS_ALTERNATEFILL | GCAPS_WINDINGFILL | ! 1514: GCAPS_DITHERONREALIZE | GCAPS_ARBRUSHSTROKE | ! 1515: GCAPS_COLOR_DITHER | GCAPS_MONO_DITHER | ! 1516: GCAPS_ARBRUSHTEXT | GCAPS_ARBRUSHOPAQUE | ! 1517: GCAPS_OPAQUERECT | GCAPS_HALFTONE; ! 1518: #else ! 1519: mydevinfo.flGraphicsCaps = GCAPS_BEZIERS | GCAPS_GEOMETRICWIDE | ! 1520: GCAPS_ALTERNATEFILL | GCAPS_WINDINGFILL | ! 1521: GCAPS_OPAQUERECT | GCAPS_HALFTONE; ! 1522: #endif ! 1523: ! 1524: // fill in default font information. first get the default facename. ! 1525: ! 1526: usDefFont = pdev->pntpd->usDefaultFont; ! 1527: ! 1528: pTable = (TABLE_ENTRY *)FontTable; ! 1529: ! 1530: while(pTable->szStr) ! 1531: { ! 1532: if ((USHORT)pTable->iValue == usDefFont) ! 1533: break; ! 1534: ! 1535: pTable++; ! 1536: } ! 1537: ! 1538: memset(&mydevinfo.lfDefaultFont, 0, sizeof(LOGFONT)); ! 1539: ! 1540: // convert to face name UNICODE, then store in LOGFONT structure. ! 1541: ! 1542: if (pTable->szStr) ! 1543: { ! 1544: if (!(pwstrFaceName = (PWSTR)HeapAlloc(pdev->hheap, 0, ! 1545: ((strlen(pTable->szStr) + 1) * 2)))) ! 1546: { ! 1547: RIP("PSCRIPT!bFillMyDevInfo: HeapAlloc for pwstrFaceName failed."); ! 1548: return(FALSE); ! 1549: } ! 1550: ! 1551: strcpy2WChar(pwstrFaceName, pTable->szStr); ! 1552: ! 1553: wcsncpy(mydevinfo.lfDefaultFont.lfFaceName, pwstrFaceName, ! 1554: (sizeof(mydevinfo.lfDefaultFont.lfFaceName) / 2)); ! 1555: ! 1556: HeapFree(pdev->hheap, 0, (PVOID)pwstrFaceName); ! 1557: } ! 1558: ! 1559: ! 1560: //!!! at some point, we need to fill in the rest of lfDefaultFont. ! 1561: ! 1562: // hardcoded for 10 point courier. ! 1563: ! 1564: #if 0 ! 1565: // get the font metrics for the default font. ! 1566: ! 1567: pfont = (BYTE *)pdev->pntpd + pdev->pntpd->loFonts; ! 1568: ! 1569: bFound = FALSE; ! 1570: ! 1571: for (iFace = 1; iFace <= (ULONG)pdev->pntpd->cFonts + 1; iFace++) ! 1572: { ! 1573: iFont = (ULONG)pfont[iFace - 1]; ! 1574: if (iFont == COURIER) ! 1575: { ! 1576: pntfm = pdev->pfmtable[iFace - 1].pntfm; ! 1577: bFound = TRUE; ! 1578: break; ! 1579: } ! 1580: } ! 1581: ! 1582: if (!bFound) ! 1583: { ! 1584: RIP("Default Courier font not found.\n"); ! 1585: return(FALSE); ! 1586: } ! 1587: #endif ! 1588: ! 1589: mydevinfo.lfDefaultFont.lfEscapement = 0; ! 1590: mydevinfo.lfDefaultFont.lfOrientation = 0; ! 1591: ! 1592: mydevinfo.lfDefaultFont.lfHeight = - (pdev->psdm.dm.dmPrintQuality*10+36) / 72; ! 1593: ! 1594: //!!! HACK - what should go here??? can we get avecharwith for this font? ! 1595: mydevinfo.lfDefaultFont.lfWidth = (27 * pdev->psdm.dm.dmPrintQuality) / 300; ! 1596: //!!! ! 1597: ! 1598: mydevinfo.lfDefaultFont.lfWeight = 400; ! 1599: mydevinfo.lfDefaultFont.lfItalic = 0; ! 1600: mydevinfo.lfDefaultFont.lfUnderline = 0; ! 1601: mydevinfo.lfDefaultFont.lfStrikeOut = 0; ! 1602: mydevinfo.lfDefaultFont.lfPitchAndFamily = FF_MODERN | FIXED_PITCH; ! 1603: ! 1604: // Copy default info ANSI_FIXED and ANSI_VARIABLE log fonts ! 1605: ! 1606: CopyMemory(&mydevinfo.lfAnsiVarFont, &mydevinfo.lfDefaultFont, sizeof(LOGFONT)); ! 1607: CopyMemory(&mydevinfo.lfAnsiFixFont, &mydevinfo.lfDefaultFont, sizeof(LOGFONT)); ! 1608: ! 1609: // Now insert ANSI_FIXED and ANSI_VAR facenames ! 1610: ! 1611: wcscpy((PWSTR)mydevinfo.lfAnsiVarFont.lfFaceName, L"Helvetica"); ! 1612: mydevinfo.lfAnsiVarFont.lfPitchAndFamily = FF_SWISS | VARIABLE_PITCH; ! 1613: ! 1614: wcscpy((PWSTR)mydevinfo.lfAnsiFixFont.lfFaceName, L"Courier"); ! 1615: mydevinfo.lfAnsiFixFont.lfPitchAndFamily = FF_MODERN | FIXED_PITCH; ! 1616: ! 1617: // get the count of device fonts for the current printer. ! 1618: ! 1619: mydevinfo.cFonts = (ULONG)pdev->pntpd->cFonts; ! 1620: pdev->cDeviceFonts = mydevinfo.cFonts; ! 1621: pdev->cSoftFonts = 0; ! 1622: ! 1623: // now add in any installed soft fonts. ! 1624: ! 1625: //!!! perhaps all the .PFM files should be put into one file at ! 1626: //!!! some stage, but this can be looked into later. -kentse. ! 1627: ! 1628: // copy the fully qualified path name of the data file into ! 1629: // local buffer. extract the directory name, as this is the ! 1630: // same directory font files are in. ! 1631: ! 1632: wcsncpy(wcbuf, pdev->pwstrPPDFile, MAX_PATH); ! 1633: ! 1634: pwstrPath = wcbuf; ! 1635: cwBuf = wcslen(wcbuf); ! 1636: pwstrPath += cwBuf; ! 1637: ! 1638: // back up over the data file name to get the subdirectory. ! 1639: ! 1640: while(*pwstrPath-- != (WCHAR)'\\') ! 1641: ; ! 1642: ! 1643: // overwrite the character after the backslash with the NULL ! 1644: // terminator. ! 1645: ! 1646: pwstrPath += 2; ! 1647: *pwstrPath = (WCHAR)'\0'; ! 1648: ! 1649: // append *.PFM to qualified path. ! 1650: ! 1651: LoadString(ghmodDrv, (IDS_ALL_PFM_FILES + STRING_BASE), ! 1652: wstringbuf, (sizeof(wstringbuf) / 2)); ! 1653: ! 1654: wcsncat(wcbuf, wstringbuf, (sizeof(wcbuf) / 2) - cwBuf); ! 1655: ! 1656: hPFMFile = FindFirstFile(wcbuf, &FileFindData); ! 1657: ! 1658: if (hPFMFile != (HANDLE)-1) ! 1659: { ! 1660: // we have at least one installed font. search for all the ! 1661: // font files, inserting them into a list for later use. ! 1662: ! 1663: // insert each font name found into the installed fonts ! 1664: // list box. ! 1665: ! 1666: bFound = TRUE; ! 1667: ! 1668: // allocate memory for the first element of a linked list of ! 1669: // softfonts. ! 1670: ! 1671: pdev->pSFList = (PSOFTFONTENTRY)HeapAlloc(pdev->hheap, 0, sizeof(SOFTFONTENTRY)); ! 1672: ! 1673: if (pdev->pSFList == NULL) ! 1674: { ! 1675: RIP("PSCRIPT!bFillMyDevInfo: HeapAlloc for pdev->pSFList failed.\n"); ! 1676: return(FALSE); ! 1677: } ! 1678: ! 1679: memset(pdev->pSFList, 0, sizeof(SOFTFONTENTRY)); ! 1680: ! 1681: pSFList = pdev->pSFList; ! 1682: pSFList->psfePrev = NULL; ! 1683: pSFList->psfeNext = NULL; ! 1684: ! 1685: // set the face number for the first softfont to be one greater ! 1686: // than the number of built in device fonts. ! 1687: ! 1688: iFace = mydevinfo.cFonts + 1; ! 1689: ! 1690: while(bFound) ! 1691: { ! 1692: // fill in the current SOFTFONTENTRY. ! 1693: ! 1694: pSFList->iFace = iFace++; ! 1695: pSFList->pwstrPFMFile = (PWSTR)HeapAlloc(pdev->hheap, 0, ! 1696: ((wcslen(FileFindData.cFileName) + 1) * sizeof(WCHAR))); ! 1697: ! 1698: if (pSFList->pwstrPFMFile == NULL) ! 1699: { ! 1700: RIP("PSCRIPT!bFillMyDevInfo: HeapAlloc for pSFList->pwstrPFMFile failed.\n"); ! 1701: return(FALSE); ! 1702: } ! 1703: ! 1704: wcscpy(pSFList->pwstrPFMFile, FileFindData.cFileName); ! 1705: ! 1706: // allocate memory for the next element in the linked list. ! 1707: ! 1708: pSFList->psfeNext = (struct _SOFTFONTENTRY *)HeapAlloc(pdev->hheap, 0, ! 1709: sizeof(SOFTFONTENTRY)); ! 1710: ! 1711: if (pSFList->psfeNext == NULL) ! 1712: { ! 1713: RIP("PSCRIPT!bFillMyDevInfo: HeapAlloc for pdev->pSFList failed.\n"); ! 1714: return(FALSE); ! 1715: } ! 1716: ! 1717: memset(pSFList->psfeNext, 0, sizeof(SOFTFONTENTRY)); ! 1718: ! 1719: // update count of supported fonts. ! 1720: ! 1721: pdev->cSoftFonts++; ! 1722: ! 1723: // initialize next entry in list, then move to it. ! 1724: ! 1725: psfeTemp = pSFList; ! 1726: pSFList = (PSOFTFONTENTRY)pSFList->psfeNext; ! 1727: pSFList->psfePrev = (struct _SOFTFONTENTRY *)psfeTemp; ! 1728: pSFList->psfeNext = NULL; ! 1729: ! 1730: bFound = FindNextFile(hPFMFile, &FileFindData); ! 1731: } ! 1732: } ! 1733: ! 1734: mydevinfo.cFonts = pdev->cDeviceFonts + pdev->cSoftFonts; ! 1735: ! 1736: // now that we know the number of softfonts that exist, allocate a ! 1737: // bit for each one, which will be set when the font is downloaded. ! 1738: ! 1739: pdev->cgs.pSFArray = (BYTE *)HeapAlloc(pdev->hheap, 0, ((pdev->cSoftFonts + 7) / 8)); ! 1740: ! 1741: if (pdev->cgs.pSFArray == NULL) ! 1742: { ! 1743: RIP("PSCRIPT!bFillMyDevInfo: HeapAlloc for pdev->cgs.pSFArray failed.\n"); ! 1744: return(FALSE); ! 1745: } ! 1746: ! 1747: memset(pdev->cgs.pSFArray, 0, ((pdev->cSoftFonts + 7) / 8)); ! 1748: ! 1749: // since this can get called from DrvRestartPDEV, delete a palette if one ! 1750: // exists, then create a new one. ! 1751: ! 1752: if (pdev->hpal) ! 1753: EngDeletePalette(pdev->hpal); ! 1754: ! 1755: // create the default device palette. let the engine know we are an ! 1756: // RGB device. ! 1757: ! 1758: #ifdef INDEX_PAL ! 1759: mydevinfo.cxDither = cxHTPatSize[ulPatternSize]; ! 1760: mydevinfo.cyDither = cyHTPatSize[ulPatternSize]; ! 1761: ! 1762: if ((pdev->pntpd->flFlags & COLOR_DEVICE) && ! 1763: (pdev->psdm.dm.dmColor == DMCOLOR_COLOR)) ! 1764: { ! 1765: cColors = 16; ! 1766: pulColors = PSColorPalette; ! 1767: mydevinfo.iDitherFormat = BMF_4BPP; ! 1768: } ! 1769: else ! 1770: { ! 1771: // fill in the palette for a monochrome device. put zero is black, ! 1772: // and 1 is white, 'cause that's that way windows likes it. ! 1773: ! 1774: cColors = 2; ! 1775: pulColors = PSMonoPalette; ! 1776: mydevinfo.iDitherFormat = BMF_1BPP; ! 1777: } ! 1778: ! 1779: if (!(mydevinfo.hpalDefault = EngCreatePalette(PAL_INDEXED, cColors, ! 1780: pulColors, 0, 0, 0))) ! 1781: #else ! 1782: ! 1783: // we don't want the engine doing any dithering for us, we are ! 1784: // a 24BPP device, let the printer do the work. ! 1785: ! 1786: mydevinfo.cxDither = 0; ! 1787: mydevinfo.cyDither = 0; ! 1788: ! 1789: mydevinfo.iDitherFormat = BMF_24BPP; ! 1790: ! 1791: if (!(mydevinfo.hpalDefault = EngCreatePalette(PAL_BGR, 0, 0, 0, 0, 0))) ! 1792: #endif ! 1793: { ! 1794: RIP("PSCRIPT!bFillMyDevInfo: EngCreatePalette failed.\n"); ! 1795: return(FALSE); ! 1796: } ! 1797: ! 1798: // store the palette handle in our PDEV. ! 1799: ! 1800: pdev->hpal = mydevinfo.hpalDefault; ! 1801: ! 1802: // now copy the DEVINFO structure. ! 1803: ! 1804: memcpy((LPVOID)pdevinfo, (LPVOID)&mydevinfo, cb); ! 1805: ! 1806: return(TRUE); ! 1807: } ! 1808: ! 1809: ! 1810: //-------------------------------------------------------------------------- ! 1811: // VOID vFillaulCaps(pdev, cjGdiInfo, pGdiInfo) ! 1812: // PDEVDATA pdev; ! 1813: // ULONG cjGdiInfo; ! 1814: // PGDIINFO pGdiInfo; ! 1815: // ! 1816: // This routine fills in the device caps for the engine. ! 1817: // ! 1818: // Parameters ! 1819: // cjGdiInfo: ! 1820: // Size of device capabilities buffer. This routine must not fill ! 1821: // beyond the given size of the buffer. ! 1822: // ! 1823: // pGdiInfo: ! 1824: // Pointer of place to store device caps. ! 1825: // ! 1826: // Returns ! 1827: // This function does not return a value. ! 1828: // ! 1829: // History: ! 1830: // 18-Oct-1990 -by- Kent Settle (kentse) ! 1831: // Wrote it. ! 1832: // ! 1833: // 05-Feb-1993 Fri 19:48:11 updated -by- Daniel Chou (danielc) ! 1834: // Set all halftone related data to gdiinfo, will get it from the ! 1835: // registry because we save them at UI pop up time ! 1836: //-------------------------------------------------------------------------- ! 1837: ! 1838: VOID vFillaulCaps(pdev, cjGdiInfo, pGdiInfo) ! 1839: PDEVDATA pdev; ! 1840: ULONG cjGdiInfo; ! 1841: ULONG *pGdiInfo; ! 1842: { ! 1843: DEVHTINFO CurDevHTInfo; ! 1844: PDRVHTINFO pDrvHTInfo; ! 1845: GDIINFO gdiinfo; ! 1846: DWORD dwType; ! 1847: DWORD cbNeeded; ! 1848: FLOAT tmpfloat; ! 1849: ! 1850: pDrvHTInfo = (PDRVHTINFO)pdev->pvDrvHTData; ! 1851: ! 1852: // make sure we don't overrun anything.. ! 1853: ! 1854: cjGdiInfo = min(cjGdiInfo, sizeof(GDIINFO)); ! 1855: ! 1856: // since we have to worry about the size of the buffer, and ! 1857: // we will most always be asked for full structure of information, ! 1858: // fill in the entire structure locally, then copy the appropriate ! 1859: // number of entries into the aulCaps buffer. ! 1860: ! 1861: //!!! need to check on the version number and what it means. ! 1862: // fill in the version number. ! 1863: ! 1864: gdiinfo.ulVersion = GDI_VERSION; ! 1865: ! 1866: // fill in the device classification index. ! 1867: ! 1868: gdiinfo.ulTechnology = DT_RASPRINTER; ! 1869: ! 1870: // fill in the printable area in millimeters. the printable areas ! 1871: // are provided in the PPD files in points. A point is 1/72 of an ! 1872: // inch. There are 25.4 mm per inch. So, if X is the width in ! 1873: // points, (X * 25.4) / 72 gives the number of millimeters. ! 1874: // We then take into account the scaling factor of 100% Things to ! 1875: // note: 2540 / 4 = 635. 72 / 4 = 18. ! 1876: ! 1877: // new item: make the number negative, and it is now micrometers. ! 1878: // this will make transforms just a bit more accurate. ! 1879: ! 1880: tmpfloat = (FLOAT)((pdev->CurForm.imagearea.right - ! 1881: pdev->CurForm.imagearea.left) * 635.0) / ! 1882: (18 * pdev->psdm.dm.dmScale); ! 1883: ! 1884: gdiinfo.ulHorzSize = (ULONG)-(LONG)(tmpfloat * 1000); ! 1885: ! 1886: tmpfloat = (FLOAT)((pdev->CurForm.imagearea.top - ! 1887: pdev->CurForm.imagearea.bottom) * 635.0) / ! 1888: (18 * pdev->psdm.dm.dmScale); ! 1889: ! 1890: gdiinfo.ulVertSize = (ULONG)-(LONG)(tmpfloat * 1000); ! 1891: ! 1892: // fill in the printable area in device units. the printable areas ! 1893: // are provided in the PPD files in points. A point is 1/72 of an ! 1894: // inch. The device resolution is given in device units per inch. ! 1895: // So if X is the width in points, (X * resolution) / 72 gives the ! 1896: // width in device units. ! 1897: ! 1898: gdiinfo.ulHorzRes = ((pdev->CurForm.imagearea.right - ! 1899: pdev->CurForm.imagearea.left) * ! 1900: pdev->psdm.dm.dmPrintQuality) / PS_RESOLUTION; ! 1901: ! 1902: gdiinfo.ulVertRes = ((pdev->CurForm.imagearea.top - ! 1903: pdev->CurForm.imagearea.bottom) * ! 1904: pdev->psdm.dm.dmPrintQuality) / PS_RESOLUTION; ! 1905: ! 1906: // fill in the default bitmap format information fields. ! 1907: ! 1908: gdiinfo.cBitsPixel = GDIINFO_BITSPERPEL; ! 1909: gdiinfo.cPlanes = 1; ! 1910: ! 1911: gdiinfo.ulDACRed = 0; ! 1912: gdiinfo.ulDACGreen = 0; ! 1913: gdiinfo.ulDACBlue = 0; ! 1914: ! 1915: // fill in number of physical, non-dithered colors printer can print. ! 1916: ! 1917: if (pdev->pntpd->flFlags & COLOR_DEVICE) ! 1918: gdiinfo.ulNumColors = NUM_PURE_COLORS; ! 1919: else ! 1920: gdiinfo.ulNumColors = NUM_PURE_GRAYS; ! 1921: ! 1922: gdiinfo.flRaster = 0; ! 1923: ! 1924: // it is assumed all postscript printers have 1:1 aspect ratio. ! 1925: // fill in the pixels per inch. ! 1926: ! 1927: gdiinfo.ulLogPixelsX = pdev->ScaledDPI; ! 1928: gdiinfo.ulLogPixelsY = pdev->ScaledDPI; ! 1929: ! 1930: // !!! [GilmanW] 16-Apr-1992 hack-attack ! 1931: // !!! Return the new flTextCaps flags. I think these are alright, but ! 1932: // !!! you better check them over, KentSe. ! 1933: ! 1934: gdiinfo.flTextCaps = ! 1935: TC_OP_CHARACTER /* Can do OutputPrecision CHARACTER */ ! 1936: | TC_OP_STROKE /* Can do OutputPrecision STROKE */ ! 1937: | TC_CP_STROKE /* Can do ClipPrecision STROKE */ ! 1938: | TC_CR_ANY /* Can do CharRotAbility ANY */ ! 1939: | TC_SF_X_YINDEP /* Can do ScaleFreedom X_YINDEPENDENT */ ! 1940: | TC_SA_DOUBLE /* Can do ScaleAbility DOUBLE */ ! 1941: | TC_SA_INTEGER /* Can do ScaleAbility INTEGER */ ! 1942: | TC_SA_CONTIN /* Can do ScaleAbility CONTINUOUS */ ! 1943: | TC_UA_ABLE /* Can do UnderlineAbility ABLE */ ! 1944: | TC_SO_ABLE; /* Can do StrikeOutAbility ABLE */ ! 1945: ! 1946: ! 1947: gdiinfo.xStyleStep = 1L; ! 1948: gdiinfo.yStyleStep = 1L; ! 1949: ! 1950: gdiinfo.ulAspectX = pdev->psdm.dm.dmPrintQuality; ! 1951: gdiinfo.ulAspectY = gdiinfo.ulAspectX; ! 1952: gdiinfo.ulAspectXY = (gdiinfo.ulAspectX * 1414) / 1000; // ~sqrt(2). ! 1953: ! 1954: // interesting value. it makes a dotted line have 25 dots per inch, ! 1955: // and it matches RASDD. ! 1956: ! 1957: gdiinfo.denStyleStep = pdev->psdm.dm.dmPrintQuality / 25; ! 1958: ! 1959: // let the world know of our margins!! ! 1960: ! 1961: gdiinfo.ptlPhysOffset.x = (pdev->CurForm.imagearea.left * ! 1962: pdev->psdm.dm.dmPrintQuality) / PS_RESOLUTION; ! 1963: ! 1964: gdiinfo.ptlPhysOffset.y = ((pdev->CurForm.sizlPaper.cy - ! 1965: pdev->CurForm.imagearea.top) * ! 1966: pdev->psdm.dm.dmPrintQuality) / ! 1967: PS_RESOLUTION; ! 1968: ! 1969: // let 'em know how big our piece of paper is. ! 1970: ! 1971: gdiinfo.szlPhysSize.cx = (pdev->CurForm.sizlPaper.cx * ! 1972: pdev->psdm.dm.dmPrintQuality) / PS_RESOLUTION; ! 1973: gdiinfo.szlPhysSize.cy = (pdev->CurForm.sizlPaper.cy * ! 1974: pdev->psdm.dm.dmPrintQuality) / PS_RESOLUTION; ! 1975: ! 1976: // !!! Where is the halftoning information? [donalds] ! 1977: ! 1978: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! 1979: // ! 1980: // We will do in following sequence, and exit the sequence if sucessful ! 1981: // ! 1982: // 1. Read from registry if one present (USER ADJUSTMENT) ! 1983: // 2. Read from mini driver's default if one present (DEVICE DEFAULT) ! 1984: // 3. Set standard halftone default (HALFTONE DEFAULT) ! 1985: // ! 1986: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! 1987: ! 1988: //====================================================================== ! 1989: // 1st: Try to see if user modify anything ! 1990: //====================================================================== ! 1991: ! 1992: if ((GetPrinterData(pdev->hPrinter, ! 1993: REGKEY_CUR_DEVHTINFO, ! 1994: &dwType, ! 1995: (BYTE *)&CurDevHTInfo, ! 1996: sizeof(DEVHTINFO), ! 1997: &cbNeeded) == NO_ERROR) && ! 1998: (cbNeeded == sizeof(DEVHTINFO))) { ! 1999: ! 2000: gdiinfo.ciDevice = CurDevHTInfo.ColorInfo; ! 2001: gdiinfo.ulDevicePelsDPI = (ULONG)CurDevHTInfo.DevPelsDPI; ! 2002: gdiinfo.ulHTPatternSize = (ULONG)CurDevHTInfo.HTPatternSize; ! 2003: ! 2004: } else { ! 2005: ! 2006: //!!! still need to do this post product 1. ! 2007: //================================================================== ! 2008: // 2nd: Try to see if .PPD has halftone data present ! 2009: //================================================================== ! 2010: ! 2011: //============================================================= ! 2012: // 3rd: SET HALFTONE STANDARD DEFAULT ! 2013: //============================================================= ! 2014: ! 2015: gdiinfo.ciDevice = DefDevHTInfo.ColorInfo; ! 2016: gdiinfo.ulDevicePelsDPI = (ULONG)DefDevHTInfo.DevPelsDPI; ! 2017: gdiinfo.ulHTPatternSize = PickDefaultHTPatSize(gdiinfo.ulLogPixelsX, ! 2018: gdiinfo.ulLogPixelsY, ! 2019: FALSE); ! 2020: } ! 2021: ! 2022: // ! 2023: // Validate this data, we do not want to have gdi go crazy. ! 2024: // ! 2025: ! 2026: if (gdiinfo.ulHTPatternSize > HT_PATSIZE_16x16_M) { ! 2027: ! 2028: gdiinfo.ulHTPatternSize = (ULONG)DefDevHTInfo.HTPatternSize; ! 2029: } ! 2030: ! 2031: //====================================================================== ! 2032: // 4th: Get default color adjustment if one exist in registry ! 2033: //====================================================================== ! 2034: ! 2035: if ((GetPrinterData(pdev->hPrinter, ! 2036: REGKEY_CUR_HTCLRADJ, ! 2037: &dwType, ! 2038: (BYTE *)&(pDrvHTInfo->ca), ! 2039: sizeof(COLORADJUSTMENT), ! 2040: &cbNeeded) != NO_ERROR) || ! 2041: (cbNeeded != sizeof(COLORADJUSTMENT)) || ! 2042: (pDrvHTInfo->ca.caSize != sizeof(COLORADJUSTMENT))) { ! 2043: ! 2044: pDrvHTInfo->ca = DefHTClrAdj; ! 2045: } ! 2046: ! 2047: // ! 2048: // PrimaryOrder ABC = RGB, which B=Plane1, G=Plane2, R=Plane3 ! 2049: // ! 2050: ! 2051: gdiinfo.flHTFlags = HT_FLAG_HAS_BLACK_DYE; ! 2052: #ifdef INDEX_PAL ! 2053: gdiinfo.ulPrimaryOrder = (ULONG)PRIMARY_ORDER_ABC; ! 2054: #else ! 2055: gdiinfo.ulPrimaryOrder = (ULONG)PRIMARY_ORDER_CBA; ! 2056: #endif ! 2057: ! 2058: if ((pdev->pntpd->flFlags & COLOR_DEVICE) && ! 2059: (pdev->psdm.dm.dmColor == DMCOLOR_COLOR)) { ! 2060: ! 2061: pDrvHTInfo->HTPalCount = 8; ! 2062: pDrvHTInfo->HTBmpFormat = (BYTE)BMF_4BPP; ! 2063: pDrvHTInfo->AltBmpFormat = (BYTE)BMF_1BPP; ! 2064: gdiinfo.ulHTOutputFormat = HT_FORMAT_4BPP; ! 2065: ! 2066: } else { ! 2067: ! 2068: pDrvHTInfo->HTPalCount = 2; ! 2069: pDrvHTInfo->HTBmpFormat = (BYTE)BMF_1BPP; ! 2070: pDrvHTInfo->AltBmpFormat = (BYTE)0xff; ! 2071: gdiinfo.ulHTOutputFormat = HT_FORMAT_1BPP; ! 2072: } ! 2073: ! 2074: pDrvHTInfo->Flags = 0; ! 2075: pDrvHTInfo->PalXlate[0] = 0xff; ! 2076: pDrvHTInfo->HTPalXor = HTPALXOR_SRCCOPY; ! 2077: ! 2078: // copy cjGdiInfo elements of gdiinfo to aulCaps. ! 2079: ! 2080: CopyMemory(pGdiInfo, &gdiinfo, cjGdiInfo); ! 2081: } ! 2082: ! 2083: ! 2084: ! 2085: //-------------------------------------------------------------------------- ! 2086: // BOOL bValidatePDEV(pdev) ! 2087: // PDEVDATA pdev; ! 2088: // ! 2089: // This routine validates the PDEVDATA. ! 2090: // ! 2091: // Parameters ! 2092: // pdev: ! 2093: // Pointer to DEVDATA structure. ! 2094: // ! 2095: // Returns ! 2096: // This function returns TRUE if the DEVDATA is valid, FALSE otherwise. ! 2097: // ! 2098: // History: ! 2099: // 21-Oct-1990 -by- Kent Settle (kentse) ! 2100: // Wrote it. ! 2101: //-------------------------------------------------------------------------- ! 2102: ! 2103: BOOL bValidatePDEV(pdev) ! 2104: PDEVDATA pdev; ! 2105: { ! 2106: if ((pdev == NULL) || (pdev->dwID != DRIVER_ID) || ! 2107: (pdev->dwEndPDEV != DRIVER_ID)) ! 2108: return(FALSE); ! 2109: ! 2110: return(TRUE); ! 2111: } ! 2112: ! 2113: ! 2114: //-------------------------------------------------------------------------- ! 2115: // VOID SetFormMetrics(pdev) ! 2116: // PDEVDATA pdev; ! 2117: // ! 2118: // This routine fills in a PSFORM structure for the current form. This ! 2119: // PSFORM structure is located within the DEVDATA structure. ! 2120: // ! 2121: // Parameters ! 2122: // pdev: ! 2123: // Pointer to DEVDATA structure. ! 2124: // ! 2125: // Returns ! 2126: // This function returns no value. ! 2127: // ! 2128: // History: ! 2129: // 13-Dec-1992 -by- Kent Settle (kentse) ! 2130: // Wrote it. ! 2131: //-------------------------------------------------------------------------- ! 2132: ! 2133: VOID SetFormMetrics(pdev) ! 2134: PDEVDATA pdev; ! 2135: { ! 2136: FORM_INFO_1 *pdbForm, *pdbForms; ! 2137: DWORD cbNeeded, cReturned, i; ! 2138: DEVMODE *pdevmode; ! 2139: PNTPD pntpd; ! 2140: BOOL bFound; ! 2141: ! 2142: pdevmode = &pdev->psdm.dm; ! 2143: pntpd = pdev->pntpd; ! 2144: ! 2145: // the first thing to do is to enumerate the forms database so we have ! 2146: // ready access to all the defined forms. ! 2147: ! 2148: bFound = FALSE; ! 2149: ! 2150: if (!EnumForms(pdev->hPrinter, 1, NULL, 0, &cbNeeded, &cReturned)) ! 2151: { ! 2152: if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) ! 2153: { ! 2154: if (pdbForms = (PFORM_INFO_1)HeapAlloc(pdev->hheap, 0, cbNeeded)) ! 2155: { ! 2156: if (EnumForms(pdev->hPrinter, 1, (LPBYTE)pdbForms, ! 2157: cbNeeded, &cbNeeded, &cReturned)) ! 2158: bFound = TRUE; ! 2159: } ! 2160: } ! 2161: } ! 2162: ! 2163: if (!bFound) ! 2164: { ! 2165: // enumeration of the font database failed. fill in default ! 2166: // values and hope for the best. ! 2167: ! 2168: SetCurrentFormToDefault(pdev); ! 2169: return; ! 2170: } ! 2171: ! 2172: // the idea here is to select the proper form from the DEVMODE structure. ! 2173: // there are three ways to do this. the REAL NT way of doing this is ! 2174: // that dmFormName will be filled in, then we can just grab the metrics ! 2175: // from the forms database. if dmFormName is not filled in, we then look ! 2176: // at dmPaperLength and dmPaperWidth. if these are filled in, then we ! 2177: // look through the forms database to see if we have a matching form. ! 2178: // if we can find one, we then check to see if it is loaded in a paper ! 2179: // tray. if it is, use it. if it is not, then use the default form. ! 2180: // the third method of selecting the form is to look at dmPaperSize. ! 2181: // dmPaperSize will be an index into the forms database. use this form. ! 2182: ! 2183: // one thing to keep in mind is that the CURRENTFORM structure stores ! 2184: // the form metrics in postscript USER coordinates, and the FORM_INFO_1 ! 2185: // structure uses .001 mm units. ! 2186: ! 2187: if ((pdevmode->dmFields & DM_PAPERLENGTH) && ! 2188: (pdevmode->dmFields & DM_PAPERWIDTH)) ! 2189: { ! 2190: // the user has supplied us with a custom form size. we will handle ! 2191: // this in the following way: search the forms database for a form ! 2192: // of matching size, if one is found, use it. otherwise, use the ! 2193: // default form. ! 2194: ! 2195: bFound = FALSE; ! 2196: pdbForm = pdbForms; ! 2197: ! 2198: for (i = 0; i < cReturned; i++) ! 2199: { ! 2200: if (((pdevmode->dmPaperWidth * 100) < pdbForm->Size.cx + 50) && ! 2201: ((pdevmode->dmPaperWidth * 100) > pdbForm->Size.cx - 50) && ! 2202: ((pdevmode->dmPaperLength * 100) < pdbForm->Size.cx + 50) && ! 2203: ((pdevmode->dmPaperLength * 100) > pdbForm->Size.cx - 50)) ! 2204: { ! 2205: // pdbForm now points to the specified form. fill in the CURRENTFORM ! 2206: // structure. ! 2207: ! 2208: FillInCURRENTFORM(pdev, pdbForm); ! 2209: ! 2210: bFound = TRUE; ! 2211: break; ! 2212: } ! 2213: ! 2214: pdbForm++; ! 2215: } ! 2216: ! 2217: if (!bFound) ! 2218: { ! 2219: // the specified form was not found, use the default. ! 2220: ! 2221: SetCurrentFormToDefault(pdev); ! 2222: HeapFree(pdev->hheap, 0, (PVOID)pdbForms); ! 2223: return; ! 2224: } ! 2225: ! 2226: ! 2227: } ! 2228: else if (pdevmode->dmFields & DM_PAPERSIZE) ! 2229: { ! 2230: // use default form if invalid dmPaperSize was supplied. ! 2231: ! 2232: if ((pdevmode->dmPaperSize < 0) || (pdevmode->dmPaperSize >= (int)cReturned)) ! 2233: { ! 2234: SetCurrentFormToDefault(pdev); ! 2235: HeapFree(pdev->hheap, 0, (PVOID)pdbForms); ! 2236: return; ! 2237: } ! 2238: ! 2239: // pdevmode->dmPaperSize should be a valid index into the forms ! 2240: // database. simply index into it to find the form. ! 2241: ! 2242: pdbForm = pdbForms; ! 2243: pdbForm += (pdevmode->dmPaperSize - DMPAPER_FIRST); ! 2244: ! 2245: // pdbForm now points to the specified form. fill in the CURRENTFORM ! 2246: // structure. ! 2247: ! 2248: FillInCURRENTFORM(pdev, pdbForm); ! 2249: } ! 2250: else if (pdevmode->dmFields & DM_FORMNAME) ! 2251: { ! 2252: // search each form in the forms database to find a form name match. ! 2253: ! 2254: bFound = FALSE; ! 2255: pdbForm = pdbForms; ! 2256: ! 2257: for (i = 0; i < cReturned; i++) ! 2258: { ! 2259: if (!(wcscmp(pdevmode->dmFormName, pdbForm->pName))) ! 2260: { ! 2261: // pdbForm now points to the specified form. fill in the CURRENTFORM ! 2262: // structure. ! 2263: ! 2264: FillInCURRENTFORM(pdev, pdbForm); ! 2265: ! 2266: bFound = TRUE; ! 2267: break; ! 2268: } ! 2269: ! 2270: pdbForm++; ! 2271: } ! 2272: ! 2273: if (!bFound) ! 2274: { ! 2275: // the specified form was not found, use the default. ! 2276: ! 2277: SetCurrentFormToDefault(pdev); ! 2278: HeapFree(pdev->hheap, 0, (PVOID)pdbForms); ! 2279: return; ! 2280: } ! 2281: } ! 2282: else ! 2283: { ! 2284: // no valid form was found in the DEVMODE structure, use the default. ! 2285: ! 2286: SetCurrentFormToDefault(pdev); ! 2287: HeapFree(pdev->hheap, 0, (PVOID)pdbForms); ! 2288: return; ! 2289: } ! 2290: } ! 2291: ! 2292: ! 2293: //-------------------------------------------------------------------------- ! 2294: // VOID SetCurrentFormToDefault(pdev) ! 2295: // PDEVDATA pdev; ! 2296: // ! 2297: // This routine fills the CURRENTFORM structure in the DEVDATA with the ! 2298: // default form, as defined by NTPD. ! 2299: // ! 2300: // Parameters ! 2301: // pdev: ! 2302: // Pointer to DEVDATA structure. ! 2303: // ! 2304: // Returns ! 2305: // This function returns no value. ! 2306: // ! 2307: // History: ! 2308: // 13-Dec-1992 -by- Kent Settle (kentse) ! 2309: // Wrote it. ! 2310: //-------------------------------------------------------------------------- ! 2311: ! 2312: VOID SetCurrentFormToDefault(pdev) ! 2313: PDEVDATA pdev; ! 2314: { ! 2315: PNTPD pntpd; ! 2316: PSFORM *pPSForm; ! 2317: DWORD i; ! 2318: ! 2319: pntpd = pdev->pntpd; ! 2320: ! 2321: // find the metrics for the default form. ! 2322: ! 2323: pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray); ! 2324: ! 2325: for (i = 0; i < pntpd->cPSForms; i++) ! 2326: { ! 2327: if (!(NameComp((CHAR *)pntpd + pntpd->loDefaultForm, ! 2328: (CHAR *)pntpd + pPSForm->loFormName))) ! 2329: { ! 2330: strcpy(pdev->CurForm.FormName, (CHAR *)pntpd + pntpd->loDefaultForm); ! 2331: strcpy(pdev->CurForm.PrinterForm, (CHAR *)pntpd + pntpd->loDefaultForm); ! 2332: pdev->CurForm.imagearea = pPSForm->imagearea; ! 2333: pdev->CurForm.sizlPaper = pPSForm->sizlPaper; ! 2334: AdjustForLandscape(pdev); ! 2335: return; ! 2336: } ! 2337: ! 2338: // point to the next PSFORM. ! 2339: ! 2340: pPSForm++; ! 2341: } ! 2342: ! 2343: // the default form was not found. select the first one in the ppd file. ! 2344: ! 2345: pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray); ! 2346: strcpy(pdev->CurForm.FormName, (CHAR *)pntpd + pPSForm->loFormName); ! 2347: strcpy(pdev->CurForm.PrinterForm, (CHAR *)pntpd + pPSForm->loFormName); ! 2348: pdev->CurForm.imagearea = pPSForm->imagearea; ! 2349: pdev->CurForm.sizlPaper = pPSForm->sizlPaper; ! 2350: ! 2351: AdjustForLandscape(pdev); ! 2352: } ! 2353: ! 2354: ! 2355: //-------------------------------------------------------------------------- ! 2356: // VOID AdjustForLandscape(pdev) ! 2357: // PDEVDATA pdev; ! 2358: // ! 2359: // This routine adjusts the CURRENTFORM structure in the DEVDATA, ! 2360: // depending on the orientation. ! 2361: // ! 2362: // Parameters ! 2363: // pdev: ! 2364: // Pointer to DEVDATA structure. ! 2365: // ! 2366: // Returns ! 2367: // This function returns no value. ! 2368: // ! 2369: // History: ! 2370: // 13-Dec-1992 -by- Kent Settle (kentse) ! 2371: // Wrote it. ! 2372: //-------------------------------------------------------------------------- ! 2373: ! 2374: VOID AdjustForLandscape(pdev) ! 2375: PDEVDATA pdev; ! 2376: { ! 2377: LONG lTmp; ! 2378: RECTL imagearea; ! 2379: ! 2380: // if we are about to print in landscape mode, flip over the form ! 2381: // metrics. ! 2382: ! 2383: if (pdev->psdm.dm.dmFields & DM_ORIENTATION) ! 2384: { ! 2385: if (pdev->psdm.dm.dmOrientation == DMORIENT_LANDSCAPE) ! 2386: { ! 2387: lTmp = pdev->CurForm.sizlPaper.cx; ! 2388: pdev->CurForm.sizlPaper.cx = pdev->CurForm.sizlPaper.cy; ! 2389: pdev->CurForm.sizlPaper.cy = lTmp; ! 2390: ! 2391: #ifdef LANDSCAPE_270_ROTATE ! 2392: imagearea.left = pdev->CurForm.sizlPaper.cx - ! 2393: pdev->CurForm.imagearea.top; ! 2394: imagearea.top = pdev->CurForm.imagearea.right; ! 2395: imagearea.right = pdev->CurForm.sizlPaper.cx - ! 2396: pdev->CurForm.imagearea.bottom; ! 2397: imagearea.bottom = pdev->CurForm.imagearea.left; ! 2398: #else // 90 degree rotate case. ! 2399: imagearea.left = pdev->CurForm.imagearea.bottom; ! 2400: imagearea.top = pdev->CurForm.sizlPaper.cy - ! 2401: pdev->CurForm.imagearea.left; ! 2402: imagearea.right = pdev->CurForm.imagearea.top; ! 2403: imagearea.bottom = pdev->CurForm.sizlPaper.cy - ! 2404: pdev->CurForm.imagearea.right; ! 2405: #endif ! 2406: ! 2407: pdev->CurForm.imagearea = imagearea; ! 2408: } ! 2409: } ! 2410: } ! 2411: ! 2412: ! 2413: //-------------------------------------------------------------------------- ! 2414: // VOID AdjustFormToPrinter(pdev) ! 2415: // PDEVDATA pdev; ! 2416: // ! 2417: // This routine searches the NTPD structure for a PSFORM structure which ! 2418: // matches the name specified by pwstrFormName. When it finds a match, it ! 2419: // intersects the imageable areas as defined in the CURRENTFORM structure ! 2420: // in the DEVDATA, and in the PSFORM structure in the NTPD. If a name match ! 2421: // is not found, then try to fit it to the smallest form which is large ! 2422: // enough to print on. ! 2423: // ! 2424: // Parameters ! 2425: // pdev: ! 2426: // Pointer to DEVDATA structure. ! 2427: // ! 2428: // Returns ! 2429: // This function returns no value. ! 2430: // ! 2431: // History: ! 2432: // 13-Dec-1992 -by- Kent Settle (kentse) ! 2433: // Wrote it. ! 2434: //-------------------------------------------------------------------------- ! 2435: ! 2436: VOID AdjustFormToPrinter(pdev) ! 2437: PDEVDATA pdev; ! 2438: { ! 2439: PNTPD pntpd; ! 2440: PSFORM *pPSForm; ! 2441: DWORD i; ! 2442: CURRENTFORM *pcurform; ! 2443: BOOL bFound; ! 2444: SIZEL sizldelta, sizltmp; ! 2445: ! 2446: // get some local pointers. ! 2447: ! 2448: pntpd = pdev->pntpd; ! 2449: pcurform = &pdev->CurForm; ! 2450: ! 2451: // find the printer's form metrics from the NTPD. ! 2452: ! 2453: pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray); ! 2454: ! 2455: // first try to match a form by name. ! 2456: ! 2457: bFound = FALSE; ! 2458: ! 2459: for (i = 0; i < pntpd->cPSForms; i++) ! 2460: { ! 2461: if (!(NameComp(pcurform->FormName, (CHAR *)pntpd + pPSForm->loFormName))) ! 2462: { ! 2463: // in this case, the printer form name and the database form ! 2464: // name are the same. ! 2465: ! 2466: // check to see if the form is changing within a document. ! 2467: ! 2468: if ((*pcurform->PrinterForm) && ! 2469: strncmp(pcurform->PrinterForm, pcurform->FormName, CCHFORMNAME)) ! 2470: pdev->dwFlags |= PDEV_CHANGEFORM; ! 2471: else ! 2472: pdev->dwFlags &= ~PDEV_CHANGEFORM; ! 2473: ! 2474: strncpy(pcurform->PrinterForm, pcurform->FormName, CCHFORMNAME); ! 2475: ! 2476: IntersectImageableAreas(pcurform, pPSForm); ! 2477: ! 2478: bFound = TRUE; ! 2479: break; ! 2480: } ! 2481: ! 2482: // point to the next PSFORM. ! 2483: ! 2484: pPSForm++; ! 2485: } ! 2486: ! 2487: // if we did not find a name match, try to locate a form by size. ! 2488: ! 2489: if (!bFound) ! 2490: { ! 2491: // get pointer to first form in NTPD. ! 2492: ! 2493: pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray); ! 2494: ! 2495: // sizldelta is used to hold the difference between form sizes. ! 2496: // initialize to large value. ! 2497: ! 2498: sizldelta.cx = sizldelta.cy = INITIAL_FORM_DELTA; ! 2499: ! 2500: for (i = 0; i < pntpd->cPSForms; i++) ! 2501: { ! 2502: sizltmp.cx = pPSForm->sizlPaper.cx - pcurform->sizlPaper.cx; ! 2503: sizltmp.cy = pPSForm->sizlPaper.cy - pcurform->sizlPaper.cy; ! 2504: ! 2505: // see if we have an exact match on size. ! 2506: ! 2507: if ((sizltmp.cx == 0) && (sizltmp.cy == 0)) ! 2508: { ! 2509: // we have an exact match on size, so overwrite the form ! 2510: // name with the name the printer knows about. ! 2511: ! 2512: strncpy(pcurform->PrinterForm, ! 2513: (CHAR *)pntpd + pPSForm->loFormName, CCHFORMNAME); ! 2514: ! 2515: IntersectImageableAreas(pcurform, pPSForm); ! 2516: ! 2517: bFound = TRUE; ! 2518: break; ! 2519: } ! 2520: ! 2521: // not an exact match, but see if we could fit on this form. ! 2522: ! 2523: if ((sizltmp.cx >= 0) && (sizltmp.cy >= 0)) ! 2524: { ! 2525: // we can fit on this form. let's see if it is the smallest. ! 2526: ! 2527: if ((sizltmp.cx <= sizldelta.cx) && ! 2528: (sizltmp.cy <= sizldelta.cy)) ! 2529: { ! 2530: // this form is the smallest yet. ! 2531: ! 2532: sizldelta = sizltmp; ! 2533: strncpy(pcurform->PrinterForm, ! 2534: (CHAR *)pntpd + pPSForm->loFormName, CCHFORMNAME); ! 2535: ! 2536: IntersectImageableAreas(pcurform, pPSForm); ! 2537: ! 2538: bFound = TRUE; ! 2539: } ! 2540: } ! 2541: ! 2542: // point to the next PSFORM. ! 2543: ! 2544: pPSForm++; ! 2545: } ! 2546: } ! 2547: ! 2548: // if we found a useable form, use it, otherwise set to default form. ! 2549: ! 2550: if (bFound) ! 2551: AdjustForLandscape(pdev); ! 2552: else ! 2553: SetCurrentFormToDefault(pdev); ! 2554: } ! 2555: ! 2556: ! 2557: //-------------------------------------------------------------------------- ! 2558: // VOID IntersectImageableAreas(pcurform, pPSForm); ! 2559: // CURRENTFORM *pcurform; ! 2560: // PSFORM *pPSForm; ! 2561: // ! 2562: // This routine intersects the imageable areas of the form found in the ! 2563: // forms database, with the printer form. ! 2564: // ! 2565: // Returns ! 2566: // This function returns no value. ! 2567: // ! 2568: // History: ! 2569: // 13-Dec-1992 -by- Kent Settle (kentse) ! 2570: // Wrote it. ! 2571: //-------------------------------------------------------------------------- ! 2572: ! 2573: VOID IntersectImageableAreas(pcurform, pPSForm) ! 2574: CURRENTFORM *pcurform; ! 2575: PSFORM *pPSForm; ! 2576: { ! 2577: pcurform->imagearea.left = max(pPSForm->imagearea.left, ! 2578: pcurform->imagearea.left); ! 2579: pcurform->imagearea.top = min(pPSForm->imagearea.top, ! 2580: pcurform->imagearea.top); ! 2581: pcurform->imagearea.right = min(pPSForm->imagearea.right, ! 2582: pcurform->imagearea.right); ! 2583: pcurform->imagearea.bottom = max(pPSForm->imagearea.bottom, ! 2584: pcurform->imagearea.bottom); ! 2585: } ! 2586: ! 2587: ! 2588: //-------------------------------------------------------------------------- ! 2589: // VOID FillInCURRENTFORM(pdev, pdbForm) ! 2590: // PDEVDATA pdev; ! 2591: // FORM_INFO_1 *pdbForm; ! 2592: // ! 2593: // This routine fills in the CURRENTFORM structure in the DEVDATA, using ! 2594: // the FORM_INFO_1 structure passed in. ! 2595: // ! 2596: // Parameters ! 2597: // pdev: ! 2598: // Pointer to DEVDATA structure. ! 2599: // ! 2600: // pdbForm: ! 2601: // Pointer to FORM_INFO_1 structure from forms database. ! 2602: // ! 2603: // Returns ! 2604: // This function returns no value. ! 2605: // ! 2606: // History: ! 2607: // 13-Dec-1992 -by- Kent Settle (kentse) ! 2608: // Wrote it. ! 2609: //-------------------------------------------------------------------------- ! 2610: ! 2611: VOID FillInCURRENTFORM(pdev, pdbForm) ! 2612: PDEVDATA pdev; ! 2613: FORM_INFO_1 *pdbForm; ! 2614: { ! 2615: DWORD i; ! 2616: ! 2617: // pdbForm now points to the specified form. fill in the CURRENTFORM ! 2618: // structure. ! 2619: ! 2620: // get the ANSI form name. ! 2621: ! 2622: i = wcslen(pdbForm->pName) + 1; ! 2623: ! 2624: WideCharToMultiByte(CP_ACP, 0, (LPWSTR)pdbForm->pName, i, ! 2625: (LPSTR)pdev->CurForm.FormName, i, NULL, NULL); ! 2626: ! 2627: pdev->CurForm.sizlPaper.cx = MM001TOUSER(pdbForm->Size.cx); ! 2628: pdev->CurForm.sizlPaper.cy = MM001TOUSER(pdbForm->Size.cy); ! 2629: ! 2630: // fill in the imageable area. NOTE: pdev->CurForm stores the ! 2631: // imageable area in USER coordinates. This means we need to ! 2632: // flip over the y coordinates. ! 2633: ! 2634: pdev->CurForm.imagearea.left = ! 2635: MM001TOUSER(pdbForm->ImageableArea.left); ! 2636: pdev->CurForm.imagearea.top = ! 2637: MM001TOUSER(pdbForm->Size.cy) - ! 2638: MM001TOUSER(pdbForm->ImageableArea.top); ! 2639: pdev->CurForm.imagearea.right = ! 2640: MM001TOUSER(pdbForm->ImageableArea.right); ! 2641: pdev->CurForm.imagearea.bottom = ! 2642: MM001TOUSER(pdbForm->Size.cy) - ! 2643: MM001TOUSER(pdbForm->ImageableArea.bottom); ! 2644: ! 2645: // make sure the printer can print it. ! 2646: ! 2647: AdjustFormToPrinter(pdev); ! 2648: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.