2 |
- |
1 |
/* Copyright (C) 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: gdevppla.c,v 1.4 2002/02/21 22:24:51 giles Exp $ */
|
|
|
18 |
/* Support for printer devices with planar buffering. */
|
|
|
19 |
#include "gdevprn.h"
|
|
|
20 |
#include "gdevmpla.h"
|
|
|
21 |
#include "gdevppla.h"
|
|
|
22 |
|
|
|
23 |
|
|
|
24 |
/* Set the buf_procs in a printer device to planar mode. */
|
|
|
25 |
int
|
|
|
26 |
gdev_prn_set_procs_planar(gx_device *dev)
|
|
|
27 |
{
|
|
|
28 |
gx_device_printer * const pdev = (gx_device_printer *)dev;
|
|
|
29 |
|
|
|
30 |
pdev->printer_procs.buf_procs.create_buf_device =
|
|
|
31 |
gdev_prn_create_buf_planar;
|
|
|
32 |
pdev->printer_procs.buf_procs.size_buf_device =
|
|
|
33 |
gdev_prn_size_buf_planar;
|
|
|
34 |
return 0;
|
|
|
35 |
}
|
|
|
36 |
|
|
|
37 |
/* Open a printer device, conditionally setting it to be planar. */
|
|
|
38 |
int
|
|
|
39 |
gdev_prn_open_planar(gx_device *dev, bool upb)
|
|
|
40 |
{
|
|
|
41 |
if (upb)
|
|
|
42 |
gdev_prn_set_procs_planar(dev);
|
|
|
43 |
return gdev_prn_open(dev);
|
|
|
44 |
}
|
|
|
45 |
|
|
|
46 |
/* Augment get/put_params to add UsePlanarBuffer. */
|
|
|
47 |
int
|
|
|
48 |
gdev_prn_get_params_planar(gx_device * pdev, gs_param_list * plist,
|
|
|
49 |
bool *pupb)
|
|
|
50 |
{
|
|
|
51 |
int ecode = gdev_prn_get_params(pdev, plist);
|
|
|
52 |
|
|
|
53 |
if (ecode < 0)
|
|
|
54 |
return ecode;
|
|
|
55 |
return param_write_bool(plist, "UsePlanarBuffer", pupb);
|
|
|
56 |
}
|
|
|
57 |
int
|
|
|
58 |
gdev_prn_put_params_planar(gx_device * pdev, gs_param_list * plist,
|
|
|
59 |
bool *pupb)
|
|
|
60 |
{
|
|
|
61 |
bool upb = *pupb;
|
|
|
62 |
int ecode = 0, code;
|
|
|
63 |
|
|
|
64 |
if (pdev->color_info.num_components > 1)
|
|
|
65 |
ecode = param_read_bool(plist, "UsePlanarBuffer", &upb);
|
|
|
66 |
code = gdev_prn_put_params(pdev, plist);
|
|
|
67 |
if (ecode >= 0)
|
|
|
68 |
ecode = code;
|
|
|
69 |
if (ecode >= 0)
|
|
|
70 |
*pupb = upb;
|
|
|
71 |
return ecode;
|
|
|
72 |
}
|
|
|
73 |
|
|
|
74 |
/* Set the buffer device to planar mode. */
|
|
|
75 |
private int
|
|
|
76 |
gdev_prn_set_planar(gx_device_memory *mdev, const gx_device *tdev)
|
|
|
77 |
{
|
|
|
78 |
int num_comp = tdev->color_info.num_components;
|
|
|
79 |
gx_render_plane_t planes[4];
|
|
|
80 |
int depth = tdev->color_info.depth / num_comp;
|
|
|
81 |
|
|
|
82 |
if (num_comp < 3 || num_comp > 4)
|
|
|
83 |
return_error(gs_error_rangecheck);
|
|
|
84 |
/* Round up the depth per plane to a power of 2. */
|
|
|
85 |
while (depth & (depth - 1))
|
|
|
86 |
--depth, depth = (depth | (depth >> 1)) + 1;
|
|
|
87 |
planes[3].depth = planes[2].depth = planes[1].depth = planes[0].depth =
|
|
|
88 |
depth;
|
|
|
89 |
/* We want the most significant plane to come out first. */
|
|
|
90 |
planes[0].shift = depth * (num_comp - 1);
|
|
|
91 |
planes[1].shift = planes[0].shift - depth;
|
|
|
92 |
planes[2].shift = planes[1].shift - depth;
|
|
|
93 |
planes[3].shift = 0;
|
|
|
94 |
return gdev_mem_set_planar(mdev, num_comp, planes);
|
|
|
95 |
}
|
|
|
96 |
|
|
|
97 |
/* Create a planar buffer device. */
|
|
|
98 |
int
|
|
|
99 |
gdev_prn_create_buf_planar(gx_device **pbdev, gx_device *target,
|
|
|
100 |
const gx_render_plane_t *render_plane,
|
|
|
101 |
gs_memory_t *mem, bool for_band)
|
|
|
102 |
{
|
|
|
103 |
int code = gx_default_create_buf_device(pbdev, target, render_plane, mem,
|
|
|
104 |
for_band);
|
|
|
105 |
|
|
|
106 |
if (code < 0)
|
|
|
107 |
return code;
|
|
|
108 |
if (gs_device_is_memory(*pbdev) /* == render_plane->index < 0 */) {
|
|
|
109 |
code = gdev_prn_set_planar((gx_device_memory *)*pbdev, *pbdev);
|
|
|
110 |
}
|
|
|
111 |
return code;
|
|
|
112 |
}
|
|
|
113 |
|
|
|
114 |
/* Determine the space needed by a planar buffer device. */
|
|
|
115 |
int
|
|
|
116 |
gdev_prn_size_buf_planar(gx_device_buf_space_t *space, gx_device *target,
|
|
|
117 |
const gx_render_plane_t *render_plane,
|
|
|
118 |
int height, bool for_band)
|
|
|
119 |
{
|
|
|
120 |
gx_device_memory mdev;
|
|
|
121 |
|
|
|
122 |
if (render_plane && render_plane->index >= 0)
|
|
|
123 |
return gx_default_size_buf_device(space, target, render_plane,
|
|
|
124 |
height, for_band);
|
|
|
125 |
mdev.color_info = target->color_info;
|
|
|
126 |
gdev_prn_set_planar(&mdev, target);
|
|
|
127 |
space->bits = gdev_mem_bits_size(&mdev, target->width, height);
|
|
|
128 |
space->line_ptrs = gdev_mem_line_ptrs_size(&mdev, target->width, height);
|
|
|
129 |
space->raster = bitmap_raster(target->width * mdev.planes[0].depth);
|
|
|
130 |
return 0;
|
|
|
131 |
}
|