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