summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/gdevbbox.c')
-rw-r--r--base/gdevbbox.c226
1 files changed, 85 insertions, 141 deletions
diff --git a/base/gdevbbox.c b/base/gdevbbox.c
index 542124a9..ac5c2e8b 100644
--- a/base/gdevbbox.c
+++ b/base/gdevbbox.c
@@ -52,14 +52,45 @@ static dev_proc_fill_parallelogram(bbox_fill_parallelogram);
static dev_proc_fill_triangle(bbox_fill_triangle);
static dev_proc_draw_thin_line(bbox_draw_thin_line);
static dev_proc_strip_tile_rectangle(bbox_strip_tile_rectangle);
-static dev_proc_strip_copy_rop(bbox_strip_copy_rop);
static dev_proc_strip_copy_rop2(bbox_strip_copy_rop2);
static dev_proc_strip_tile_rect_devn(bbox_strip_tile_rect_devn);
static dev_proc_begin_typed_image(bbox_begin_typed_image);
-static dev_proc_create_compositor(bbox_create_compositor);
+static dev_proc_composite(bbox_composite);
static dev_proc_text_begin(bbox_text_begin);
static dev_proc_fillpage(bbox_fillpage);
+static void
+bbox_initialize_device_procs(gx_device *dev)
+{
+ set_dev_proc(dev, open_device, bbox_open_device);
+ set_dev_proc(dev, get_initial_matrix, gx_upright_get_initial_matrix);
+ set_dev_proc(dev, output_page, bbox_output_page);
+ set_dev_proc(dev, close_device, bbox_close_device);
+ set_dev_proc(dev, map_rgb_color, gx_default_gray_map_rgb_color);
+ set_dev_proc(dev, map_color_rgb, gx_default_gray_map_color_rgb);
+ set_dev_proc(dev, fill_rectangle, bbox_fill_rectangle);
+ set_dev_proc(dev, copy_mono, bbox_copy_mono);
+ set_dev_proc(dev, copy_color, bbox_copy_color);
+ set_dev_proc(dev, get_params, bbox_get_params);
+ set_dev_proc(dev, put_params, bbox_put_params);
+ set_dev_proc(dev, get_page_device, gx_page_device_get_page_device);
+ set_dev_proc(dev, copy_alpha, bbox_copy_alpha);
+ set_dev_proc(dev, fill_path, bbox_fill_path);
+ set_dev_proc(dev, stroke_path, bbox_stroke_path);
+ set_dev_proc(dev, fill_mask, bbox_fill_mask);
+ set_dev_proc(dev, fill_trapezoid, bbox_fill_trapezoid);
+ set_dev_proc(dev, fill_parallelogram, bbox_fill_parallelogram);
+ set_dev_proc(dev, fill_triangle, bbox_fill_triangle);
+ set_dev_proc(dev, draw_thin_line, bbox_draw_thin_line);
+ set_dev_proc(dev, strip_tile_rectangle, bbox_strip_tile_rectangle);
+ set_dev_proc(dev, begin_typed_image, bbox_begin_typed_image);
+ set_dev_proc(dev, composite, bbox_composite);
+ set_dev_proc(dev, text_begin, bbox_text_begin);
+ set_dev_proc(dev, fillpage, bbox_fillpage);
+ set_dev_proc(dev, strip_copy_rop2, bbox_strip_copy_rop2);
+ set_dev_proc(dev, strip_tile_rect_devn, bbox_strip_tile_rect_devn);
+}
+
/* The device prototype */
/*
* Normally this would be static, but if the device is going to be used
@@ -85,82 +116,11 @@ gx_device_bbox gs_bbox_device =
/*
* Define the device as 8-bit gray scale to avoid computing halftones.
*/
- std_device_dci_body(gx_device_bbox, 0, "bbox",
+ std_device_dci_body(gx_device_bbox, bbox_initialize_device_procs, "bbox",
MAX_COORD, MAX_COORD,
MAX_RESOLUTION, MAX_RESOLUTION,
1, 8, 255, 0, 256, 1),
- {bbox_open_device,
- gx_upright_get_initial_matrix,
- NULL, /* sync_output */
- bbox_output_page,
- bbox_close_device,
- gx_default_gray_map_rgb_color,
- gx_default_gray_map_color_rgb,
- bbox_fill_rectangle,
- NULL, /* tile_rectangle */
- bbox_copy_mono,
- bbox_copy_color,
- NULL, /* draw_line */
- NULL, /* get_bits */
- bbox_get_params,
- bbox_put_params,
- gx_default_map_cmyk_color,
- NULL, /* get_xfont_procs */
- NULL, /* get_xfont_device */
- gx_default_map_rgb_alpha_color,
- gx_page_device_get_page_device,
- NULL, /* get_alpha_bits */
- bbox_copy_alpha,
- NULL, /* get_band */
- NULL, /* copy_rop */
- bbox_fill_path,
- bbox_stroke_path,
- bbox_fill_mask,
- bbox_fill_trapezoid,
- bbox_fill_parallelogram,
- bbox_fill_triangle,
- bbox_draw_thin_line,
- gx_default_begin_image,
- NULL, /* image_data */
- NULL, /* end_image */
- bbox_strip_tile_rectangle,
- bbox_strip_copy_rop,
- NULL, /* get_clipping_box */
- bbox_begin_typed_image,
- NULL, /* get_bits_rectangle */
- gx_default_map_color_rgb_alpha,
- bbox_create_compositor,
- NULL, /* get_hardware_params */
- bbox_text_begin,
- NULL, /* finish_copydevice */
- NULL, /* begin_transparency_group */
- NULL, /* end_transparency_group */
- NULL, /* begin_transparency_mask */
- NULL, /* end_transparency_mask */
- NULL, /* discard_transparency_layer */
- NULL, /* get_color_mapping_procs */
- NULL, /* get_color_comp_index */
- NULL, /* encode_color */
- NULL, /* decode_color */
- NULL, /* pattern_manage */
- NULL, /* fill_rectangle_hl_color */
- NULL, /* include_color_space */
- NULL, /* fill_linear_color_scanline */
- NULL, /* fill_linear_color_trapezoid */
- NULL, /* fill_linear_color_triangle */
- NULL, /* update_spot_equivalent_colors */
- NULL, /* ret_devn_params */
- bbox_fillpage, /* fillpage */
- NULL, /* push_transparency_state */
- NULL, /* pop_transparency_state */
- NULL, /* put_image */
- NULL, /* dev_spec_op */
- NULL, /* copy_planes */
- NULL, /* get_profile */
- NULL, /* set_graphics_type_tag */
- bbox_strip_copy_rop2,
- bbox_strip_tile_rect_devn
- },
+ { 0 },
0, /* target */
1, /*true *//* free_standing */
1 /*true *//* forward_open_close */
@@ -275,15 +235,15 @@ bbox_close_device(gx_device * dev)
void
gx_device_bbox_init(gx_device_bbox * dev, gx_device * target, gs_memory_t *mem)
{
- gx_device_init((gx_device *) dev, (const gx_device *)&gs_bbox_device,
- (target ? target->memory : mem), true);
+ /* Can never fail */
+ (void)gx_device_init((gx_device *) dev, (const gx_device *)&gs_bbox_device,
+ (target ? target->memory : mem), true);
if (target) {
gx_device_forward_fill_in_procs((gx_device_forward *) dev);
set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color);
set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb);
set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color);
- set_dev_proc(dev, map_rgb_alpha_color, gx_forward_map_rgb_alpha_color);
set_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs);
set_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index);
set_dev_proc(dev, encode_color, gx_forward_encode_color);
@@ -417,7 +377,8 @@ bbox_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
{
gx_device_bbox *const bdev = (gx_device_bbox *) dev;
gx_device *tdev = bdev->target;
- /* gx_forward_fill_rectangle doesn't exist */
+ /* gx_forward_fill_rectangle exists, but does the wrong thing in
+ * the event of a NULL target, so open code it here. */
int code =
(tdev == 0 ? 0 :
dev_proc(tdev, fill_rectangle)(tdev, x, y, w, h, color));
@@ -432,7 +393,8 @@ bbox_copy_mono(gx_device * dev, const byte * data,
gx_color_index zero, gx_color_index one)
{
gx_device_bbox *const bdev = (gx_device_bbox *) dev;
- /* gx_forward_copy_mono doesn't exist */
+ /* gx_forward_copy_mono exists, but does the wrong thing in
+ * the event of a NULL target, so open code it here. */
gx_device *tdev = bdev->target;
int code =
(tdev == 0 ? 0 :
@@ -451,7 +413,8 @@ bbox_copy_color(gx_device * dev, const byte * data,
int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h)
{
gx_device_bbox *const bdev = (gx_device_bbox *) dev;
- /* gx_forward_copy_color doesn't exist */
+ /* gx_forward_copy_color exists, but does the wrong thing in
+ * the event of a NULL target, so open code it here. */
gx_device *tdev = bdev->target;
int code =
(tdev == 0 ? 0 :
@@ -468,7 +431,8 @@ bbox_copy_alpha(gx_device * dev, const byte * data, int data_x,
gx_color_index color, int depth)
{
gx_device_bbox *const bdev = (gx_device_bbox *) dev;
- /* gx_forward_copy_alpha doesn't exist */
+ /* gx_forward_copy_alpha exists, but does the wrong thing in
+ * the event of a NULL target, so open code it here. */
gx_device *tdev = bdev->target;
int code =
(tdev == 0 ? 0 :
@@ -512,29 +476,6 @@ bbox_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tiles,
}
static int
-bbox_strip_copy_rop(gx_device * dev,
- const byte * sdata, int sourcex, uint sraster,
- gx_bitmap_id id,
- const gx_color_index * scolors,
- const gx_strip_bitmap * textures,
- const gx_color_index * tcolors,
- int x, int y, int w, int h,
- int phase_x, int phase_y, gs_logical_operation_t lop)
-{
- gx_device_bbox *const bdev = (gx_device_bbox *) dev;
- /* gx_forward_strip_copy_rop doesn't exist */
- gx_device *tdev = bdev->target;
- int code =
- (tdev == 0 ? 0 :
- dev_proc(tdev, strip_copy_rop)
- (tdev, sdata, sourcex, sraster, id, scolors,
- textures, tcolors, x, y, w, h, phase_x, phase_y, lop));
-
- BBOX_ADD_INT_RECT(bdev, x, y, x + w, y + h);
- return code;
-}
-
-static int
bbox_strip_copy_rop2(gx_device * dev,
const byte * sdata, int sourcex, uint sraster,
gx_bitmap_id id,
@@ -546,7 +487,8 @@ bbox_strip_copy_rop2(gx_device * dev,
uint planar_height)
{
gx_device_bbox *const bdev = (gx_device_bbox *) dev;
- /* gx_forward_strip_copy_rop doesn't exist */
+ /* gx_forward_strip_copy_rop2 exists, but does the wrong thing in
+ * the event of a NULL target, so open code it here. */
gx_device *tdev = bdev->target;
int code =
(tdev == 0 ? 0 :
@@ -817,8 +759,7 @@ bbox_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath,
gx_device_bbox *const bdev = (gx_device_bbox *) dev;
gx_device *tdev = bdev->target;
dev_proc_fill_path((*fill_path)) =
- (tdev == 0 ? dev_proc(&gs_null_device, fill_path) :
- dev_proc(tdev, fill_path));
+ (tdev == 0 ? NULL : dev_proc(tdev, fill_path));
int code;
gx_drawing_color devc;
@@ -846,18 +787,25 @@ bbox_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath,
* If the path lies within the already accumulated box, just draw
* on the target.
*/
- if (BBOX_IN_RECT(bdev, &ibox))
+ if (BBOX_IN_RECT(bdev, &ibox)) {
+ /* If we have no target device, just exit */
+ if (fill_path == NULL)
+ return 0;
return fill_path(tdev, pgs, ppath, params, pdevc, pcpath);
- /*
- * If the target uses the default algorithm, just draw on the
- * bbox device.
- */
- if (tdev != 0 && fill_path == gx_default_fill_path)
- return fill_path(dev, pgs, ppath, params, pdevc, pcpath);
- /* Draw on the target now. */
- code = fill_path(tdev, pgs, ppath, params, pdevc, pcpath);
- if (code < 0)
- return code;
+ }
+ if (tdev != 0) {
+ /*
+ * If the target uses the default algorithm, just draw on the
+ * bbox device.
+ */
+ if (fill_path == gx_default_fill_path)
+ return fill_path(dev, pgs, ppath, params, pdevc, pcpath);
+ /* Draw on the target now. */
+ code = fill_path(tdev, pgs, ppath, params, pdevc, pcpath);
+ if (code < 0)
+ return code;
+ }
+
/* Previously we would use the path bbox above usually, but that bbox is
* inaccurate for curves, because it considers the control points of the
* curves to be included whcih of course they are not. Now we scan-convert
@@ -873,7 +821,9 @@ bbox_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath,
code = gx_default_fill_path(dev, pgs, ppath, params, &devc, pcpath);
bdev->target = tdev;
return code;
- } else
+ } else if (fill_path == NULL)
+ return 0;
+ else
return fill_path(tdev, pgs, ppath, params, pdevc, pcpath);
}
@@ -950,8 +900,9 @@ bbox_fill_mask(gx_device * dev,
pdcolor, depth, lop, pcpath);
bdev->target = tdev;
} else {
- /* Just use the mask bounding box. */
- BBOX_ADD_INT_RECT(bdev, x, y, x + w, y + h);
+ if (w > 0 && h > 0)
+ /* Just use the mask bounding box. */
+ BBOX_ADD_INT_RECT(bdev, x, y, x + w, y + h);
}
return code;
}
@@ -1010,15 +961,8 @@ bbox_image_begin(const gs_gstate * pgs, const gs_matrix * pmat,
pbe->x0 = prect->p.x, pbe->x1 = prect->q.x;
pbe->y = prect->p.y, pbe->height = prect->q.y - prect->p.y;
} else {
- gs_int_point size;
- int code = (*pic->type->source_size) (pgs, pic, &size);
-
- if (code < 0) {
- gs_free_object(memory, pbe, "bbox_image_begin");
- return code;
- }
- pbe->x0 = 0, pbe->x1 = size.x;
- pbe->y = 0, pbe->height = size.y;
+ pbe->x0 = 0, pbe->x1 = pic->Width;
+ pbe->y = 0, pbe->height = pic->Height;
}
*ppbe = pbe;
return 0;
@@ -1051,7 +995,7 @@ bbox_begin_typed_image(gx_device * dev,
if (code < 0)
return code;
/*
- * If there is no target, we still have to call default_begin_image
+ * If there is no target, we still have to call default_begin_typed_image
* to get the correct num_planes and plane_depths.
*/
{
@@ -1145,8 +1089,9 @@ bbox_image_plane_data(gx_image_enum_common_t * info,
bx2, by2, &devc, lop_default);
bdev->target = tdev;
} else {
- /* Just use the bounding box. */
- BBOX_ADD_RECT(bdev, ibox.p.x, ibox.p.y, ibox.q.x, ibox.q.y);
+ /* Just use the bounding box if the image is not 0 width or height */
+ if (ibox.p.x != ibox.q.x && ibox.p.y != ibox.q.y)
+ BBOX_ADD_RECT(bdev, ibox.p.x, ibox.p.y, ibox.q.x, ibox.q.y);
}
return code;
}
@@ -1218,7 +1163,7 @@ static const gx_device_bbox_procs_t box_procs_forward = {
};
static int
-bbox_create_compositor(gx_device * dev,
+bbox_composite(gx_device * dev,
gx_device ** pcdev, const gs_composite_t * pcte,
gs_gstate * pgs, gs_memory_t * memory, gx_device *cindev)
{
@@ -1241,7 +1186,7 @@ bbox_create_compositor(gx_device * dev,
{
gx_device *temp_cdev;
gx_device_bbox *bbcdev;
- int code = (*dev_proc(target, create_compositor))
+ int code = (*dev_proc(target, composite))
(target, &temp_cdev, pcte, pgs, memory, cindev);
/* If the target did not create a new compositor then we are done. */
@@ -1251,7 +1196,7 @@ bbox_create_compositor(gx_device * dev,
}
bbcdev = gs_alloc_struct_immovable(memory, gx_device_bbox,
&st_device_bbox,
- "bbox_create_compositor");
+ "bbox_composite");
if (bbcdev == 0) {
(*dev_proc(temp_cdev, close_device)) (temp_cdev);
return_error(gs_error_VMerror);
@@ -1272,13 +1217,12 @@ bbox_create_compositor(gx_device * dev,
static int
bbox_text_begin(gx_device * dev, gs_gstate * pgs,
const gs_text_params_t * text, gs_font * font,
- gx_path * path, const gx_device_color * pdcolor,
const gx_clip_path * pcpath,
- gs_memory_t * memory, gs_text_enum_t ** ppenum)
+ gs_text_enum_t ** ppenum)
{
gx_device_bbox *const bdev = (gx_device_bbox *) dev;
- int code = gx_default_text_begin(dev, pgs, text, font, path, pdcolor,
- pcpath, memory, ppenum);
+ int code = gx_default_text_begin(dev, pgs, text, font,
+ pcpath, ppenum);
if (code >=0 && bdev->target != NULL) {
/* See note on imaging_dev in gxtext.h */