1 /* Copyright (C) 2001-2012 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
13    CA  94903, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* Page object management */
18 #include "gdevprn.h"
19 #include "gxcldev.h"
20 #include "gxclpage.h"
21 
22 /* Save a page. */
23 int
gdev_prn_save_page(gx_device_printer * pdev,gx_saved_page * page,int num_copies)24 gdev_prn_save_page(gx_device_printer * pdev, gx_saved_page * page,
25                    int num_copies)
26 {
27     gx_device_clist *cdev = (gx_device_clist *) pdev;
28 
29     /* Make sure we are banding. */
30     if (!pdev->buffer_space)
31         return_error(gs_error_rangecheck);
32     if (strlen(pdev->dname) >= sizeof(page->dname))
33         return_error(gs_error_limitcheck);
34     {
35         gx_device_clist_writer * const pcldev =
36             (gx_device_clist_writer *)pdev;
37         int code;
38 
39         if ((code = clist_end_page(pcldev)) < 0 ||
40             (code = cdev->common.page_info.io_procs->fclose(pcldev->page_cfile, pcldev->page_cfname, false)) < 0 ||
41             (code = cdev->common.page_info.io_procs->fclose(pcldev->page_bfile, pcldev->page_bfname, false)) < 0
42             )
43             return code;
44         /* Save the device information. */
45         memcpy(&page->device, pdev, sizeof(gx_device));
46         strcpy(page->dname, pdev->dname);
47         /* Save the page information. */
48         page->info = pcldev->page_info;
49         page->info.cfile = 0;
50         page->info.bfile = 0;
51     }
52     /* Save other information. */
53     page->num_copies = num_copies;
54     return (*gs_clist_device_procs.open_device) ((gx_device *) pdev);
55 }
56 
57 /* Render an array of saved pages. */
58 int
gdev_prn_render_pages(gx_device_printer * pdev,const gx_placed_page * ppages,int count)59 gdev_prn_render_pages(gx_device_printer * pdev,
60                       const gx_placed_page * ppages, int count)
61 {
62     gx_device_clist_reader * const pcldev =
63         (gx_device_clist_reader *)pdev;
64 
65     /* Check to make sure the pages are compatible with the device. */
66     {
67         int i;
68 
69         for (i = 0; i < count; ++i) {
70             const gx_saved_page *page = ppages[i].page;
71 
72             /* We would like to fully check the color representation, */
73             /* but we don't have enough information to do that. */
74             if (strcmp(page->dname, pdev->dname) != 0 ||
75                 memcmp(&page->device.color_info, &pdev->color_info,
76                        sizeof(pdev->color_info)) != 0
77                 )
78                 return_error(gs_error_rangecheck);
79             /* Currently we don't allow translation in Y. */
80             if (ppages[i].offset.y != 0)
81                 return_error(gs_error_rangecheck);
82             /* Make sure the band parameters are compatible. */
83             if (page->info.band_params.BandBufferSpace !=
84                 pdev->buffer_space ||
85                 page->info.band_params.BandWidth !=
86                 pdev->width
87                 )
88                 return_error(gs_error_rangecheck);
89             /* Currently we require all band heights to be the same. */
90             if (i > 0 && page->info.band_params.BandHeight !=
91                          ppages[0].page->info.band_params.BandHeight)
92                 return_error(gs_error_rangecheck);
93         }
94     }
95     /* Set up the page list in the device. */
96     /****** SHOULD FACTOR THIS OUT OF clist_render_init ******/
97     pcldev->ymin = pcldev->ymax = 0;
98     pcldev->pages = ppages;
99     pcldev->num_pages = count;
100     pcldev->offset_map = NULL;
101     pcldev->icc_table = NULL;
102     pcldev->icc_cache_cl = NULL;
103     /* Render the pages. */
104     {
105         int code = (*dev_proc(pdev, output_page))
106             ((gx_device *) pdev, ppages[0].page->num_copies, true);
107 
108         /* Delete the temporary files. */
109         int i;
110 
111         for (i = 0; i < count; ++i) {
112             const gx_saved_page *page = ppages[i].page;
113 
114             pcldev->page_info.io_procs->unlink(page->info.cfname);
115             pcldev->page_info.io_procs->unlink(page->info.bfname);
116         }
117         return code;
118     }
119 }
120