Annotation of ntddk/src/print/pscript/enable.c, revision 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.