1 /* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gdevp2up.c,v 1.6 2004/05/26 04:10:58 dan Exp $ */
18 /* A "2-up" PCX device for testing page objects. */
19 #include "gdevprn.h"
20 #include "gdevpccm.h"
21 #include "gxclpage.h"
22
23 extern gx_device_printer gs_pcx256_device;
24
25 /* ------ The device descriptors ------ */
26
27 /*
28 * Default X and Y resolution.
29 */
30 #define X_DPI 72
31 #define Y_DPI 72
32
33 /*
34 * Define the size of the rendering buffer.
35 */
36 #define RENDER_BUFFER_SPACE 500000
37
38 /* This device only supports SVGA 8-bit color. */
39
40 private dev_proc_open_device(pcx2up_open);
41 private dev_proc_print_page(pcx2up_print_page);
42
43 typedef struct gx_device_2up_s {
44 gx_device_common;
45 gx_prn_device_common;
46 bool have_odd_page;
47 gx_saved_page odd_page;
48 } gx_device_2up;
49
50 private const gx_device_procs pcx2up_procs =
51 prn_color_procs(pcx2up_open, gdev_prn_output_page, gdev_prn_close,
52 pc_8bit_map_rgb_color, pc_8bit_map_color_rgb);
53 gx_device_2up gs_pcx2up_device =
54 {prn_device_body(gx_device_2up, pcx2up_procs, "pcx2up",
55 DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
56 X_DPI, Y_DPI,
57 0, 0, 0, 0, /* margins */
58 3, 8, 5, 5, 6, 6, pcx2up_print_page)
59 };
60
61 /* Open the device. We reimplement this to force banding with */
62 /* delayed rasterizing. */
63 private int
pcx2up_open(gx_device * dev)64 pcx2up_open(gx_device * dev)
65 {
66 gx_device_printer *pdev = (gx_device_printer *) dev;
67 int code;
68 gdev_prn_space_params save_params;
69
70 save_params = pdev->space_params;
71 pdev->space_params.MaxBitmap = 0; /* force banding */
72 pdev->space_params.band.BandWidth =
73 dev->width * 2 + (int)(dev->HWResolution[0] * 2.0);
74 pdev->space_params.band.BandBufferSpace = RENDER_BUFFER_SPACE;
75 code = gdev_prn_open(dev);
76 pdev->space_params = save_params;
77 ((gx_device_2up *) dev)->have_odd_page = false;
78 return code;
79 }
80
81 /* Write the page. */
82 private int
pcx2up_print_page(gx_device_printer * pdev,FILE * file)83 pcx2up_print_page(gx_device_printer * pdev, FILE * file)
84 {
85 gx_device_2up *pdev2 = (gx_device_2up *) pdev;
86 const gx_device_printer *prdev_template =
87 (const gx_device_printer *)&gs_pcx2up_device;
88
89 if (!pdev2->have_odd_page) { /* This is the odd page, just save it. */
90 pdev2->have_odd_page = true;
91 return gdev_prn_save_page(pdev, &pdev2->odd_page, 1);
92 } else { /* This is the even page, do 2-up output. */
93 gx_saved_page even_page;
94 gx_placed_page pages[2];
95 int x_offset = (int)(pdev->HWResolution[0] * 0.5);
96 int y_offset = (int)(pdev->HWResolution[1] * 0.5);
97 int code = gdev_prn_save_page(pdev, &even_page, 1);
98 int prdev_size = prdev_template->params_size;
99 gx_device_printer *prdev;
100
101 #define rdev ((gx_device *)prdev)
102
103 if (code < 0)
104 return code;
105 /* Create the placed page list. */
106 pages[0].page = &pdev2->odd_page;
107 pages[0].offset.x = x_offset;
108 pages[0].offset.y = 0 /*y_offset */ ;
109 pages[1].page = &even_page;
110 pages[1].offset.x = pdev->width + x_offset * 3;
111 pages[1].offset.y = 0 /*y_offset */ ;
112 /* Create and open a device for rendering. */
113 prdev = (gx_device_printer *)
114 gs_alloc_bytes(pdev->memory, prdev_size,
115 "pcx2up_print_page(device)");
116 if (prdev == 0)
117 return_error(gs_error_VMerror);
118 memcpy(prdev, prdev_template, prdev_size);
119 check_device_separable((gx_device *)rdev);
120 gx_device_fill_in_procs(rdev);
121 set_dev_proc(prdev, open_device,
122 dev_proc(&gs_pcx256_device, open_device));
123 prdev->printer_procs.print_page =
124 gs_pcx256_device.printer_procs.print_page;
125 prdev->space_params.band =
126 pages[0].page->info.band_params; /* either one will do */
127 prdev->space_params.MaxBitmap = 0;
128 prdev->space_params.BufferSpace =
129 prdev->space_params.band.BandBufferSpace;
130 prdev->width = prdev->space_params.band.BandWidth;
131 prdev->OpenOutputFile = false;
132 code = (*dev_proc(rdev, open_device)) (rdev);
133 if (code < 0)
134 return code;
135 rdev->is_open = true;
136 prdev->file = pdev->file;
137 /* Render the pages. */
138 code = gdev_prn_render_pages(prdev, pages, 2);
139 /* Clean up. */
140 if (pdev->file != 0)
141 prdev->file = 0; /* don't close it */
142 gs_closedevice(rdev);
143 pdev2->have_odd_page = false;
144 return code;
145 #undef rdev
146 }
147 }
148