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

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: }

unix.superglobalmegacorp.com

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