summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Melichev <igor.melichev@artifex.com>2003-09-08 11:45:08 +0000
committerIgor Melichev <igor.melichev@artifex.com>2003-09-08 11:45:08 +0000
commit938a04f690e9d9722bc08b0be6928448a191009d (patch)
tree12f90ec2b16401c5ed6a7c24d79ac389a4e2f495
parent55d8b472360ed2333be34c85a31169f3034c1cc7 (diff)
Defining a new device virtual function fill_rectangle_hl_color.
This function is used to implement gs_rectfill and gs_fillpage with a high level color handling. DETAILS : The old device virtual function fill_rectangle has no way to pass a high level color. Therefore high level devices always used process colors with rectfill and fillpage. See gxdevcli.h for the definition of the new function. The new function is used to implement gs_rectfill and gs_fillpage in pdfwrite. gs_rectfill and gs_fillpage are modified to provide the new logics. gdevpdfd.c is reorganised with factoring out some common code parts. Fixes the bug #687024 "rectfill doesn't pass high level colors to device". This patch causes a MINOR DIFFERENCE in color in all Genoa tests with pdfwrite : a gray rectangle in the header gets a sligtly different gray value. Besides that, the following files render few differently due to coordinate rounding in pdfwrite : 245-13.ps 442-01.ps git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@4193 a1074d23-0009-0410-80fe-cf8c14f379e6
-rw-r--r--gs/src/gdevbbox.c1
-rw-r--r--gs/src/gdevdflt.c11
-rw-r--r--gs/src/gdevnfwd.c21
-rw-r--r--gs/src/gdevpdf.c3
-rw-r--r--gs/src/gdevpdfd.c147
-rw-r--r--gs/src/gdevpdfx.h1
-rw-r--r--gs/src/gdevrops.c3
-rw-r--r--gs/src/gsdps1.c27
-rw-r--r--gs/src/gspaint.c15
-rw-r--r--gs/src/gxclip.c3
-rw-r--r--gs/src/gxclip2.c3
-rw-r--r--gs/src/gxclipm.c3
-rw-r--r--gs/src/gxclist.c3
-rw-r--r--gs/src/gxdevcli.h21
-rw-r--r--gs/src/gxdevice.h2
-rw-r--r--gs/src/gxhldevc.c19
-rw-r--r--gs/src/gxhldevc.h7
-rw-r--r--gs/src/lib.mak4
18 files changed, 229 insertions, 65 deletions
diff --git a/gs/src/gdevbbox.c b/gs/src/gdevbbox.c
index 6a3849fae..953434b43 100644
--- a/gs/src/gdevbbox.c
+++ b/gs/src/gdevbbox.c
@@ -271,6 +271,7 @@ gx_device_bbox_init(gx_device_bbox * dev, gx_device * target)
set_dev_proc(dev, encode_color, gx_forward_encode_color);
set_dev_proc(dev, decode_color, gx_forward_decode_color);
set_dev_proc(dev, pattern_manage, gx_forward_pattern_manage);
+ set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
gx_device_set_target((gx_device_forward *)dev, target);
} else {
gx_device_fill_in_procs((gx_device *)dev);
diff --git a/gs/src/gdevdflt.c b/gs/src/gdevdflt.c
index 6f154acbb..8b123612d 100644
--- a/gs/src/gdevdflt.c
+++ b/gs/src/gdevdflt.c
@@ -529,6 +529,7 @@ gx_device_fill_in_procs(register gx_device * dev)
dev->color_info.opmode = GX_CINFO_OPMODE_NOT;
fill_dev_proc(dev, pattern_manage, gx_default_pattern_manage);
+ fill_dev_proc(dev, fill_rectangle_hl_color, gx_default_fill_rectangle_hl_color);
}
int
@@ -679,6 +680,16 @@ gx_default_pattern_manage(gx_device *pdev, gx_bitmap_id id,
return 0;
}
+int
+gx_default_fill_rectangle_hl_color(gx_device *pdev,
+ int x, int y, int width, int height,
+ const gs_imager_state *pis, const gx_drawing_color *pdcolor,
+ const gx_clip_path *pcpath)
+{
+ return_error(gs_error_rangecheck);
+}
+
+
/* ---------------- Default per-instance procedures ---------------- */
int
diff --git a/gs/src/gdevnfwd.c b/gs/src/gdevnfwd.c
index 1cf31a747..b948aa1b6 100644
--- a/gs/src/gdevnfwd.c
+++ b/gs/src/gdevnfwd.c
@@ -102,6 +102,7 @@ gx_device_forward_fill_in_procs(register gx_device_forward * dev)
fill_dev_proc(dev, encode_color, gx_forward_encode_color);
fill_dev_proc(dev, decode_color, gx_forward_decode_color);
fill_dev_proc(dev, pattern_manage, gx_forward_pattern_manage);
+ fill_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
gx_device_fill_in_procs((gx_device *) dev);
}
@@ -729,6 +730,23 @@ gx_forward_pattern_manage(gx_device * dev, gx_bitmap_id id,
return 0;
}
+int
+gx_forward_fill_rectangle_hl_color(gx_device *dev,
+ int x, int y, int width, int height,
+ const gs_imager_state *pis, const gx_drawing_color *pdcolor,
+ const gx_clip_path *pcpath)
+{
+ gx_device_forward * const fdev = (gx_device_forward *)dev;
+ gx_device *tdev = fdev->target;
+
+ /* Note that clist sets fdev->target == fdev,
+ so this function is unapplicable to clist. */
+ if (tdev == 0)
+ return_error(gs_error_rangecheck);
+ else
+ return dev_proc(tdev, fill_rectangle_hl_color)(tdev, x, y, width,
+ height, pis, pdcolor, NULL);
+}
/* ---------------- The null device(s) ---------------- */
@@ -804,7 +822,8 @@ private dev_proc_strip_copy_rop(null_strip_copy_rop);
gx_default_DevGray_get_color_comp_index,/* get_color_comp_index */\
gx_default_gray_fast_encode, /* encode_color */\
null_decode_color, /* decode_color */\
- gx_default_pattern_manage\
+ gx_default_pattern_manage,\
+ gx_default_fill_rectangle_hl_color\
}
const gx_device_null gs_null_device = {
diff --git a/gs/src/gdevpdf.c b/gs/src/gdevpdf.c
index 50a0c136d..c93dc97c5 100644
--- a/gs/src/gdevpdf.c
+++ b/gs/src/gdevpdf.c
@@ -175,7 +175,8 @@ const gx_device_pdf gs_pdfwrite_device =
NULL, /* get_color_comp_index */
NULL, /* encode_color */
NULL, /* decode_color */
- gdev_pdf_pattern_manage /* pattern_manage */
+ gdev_pdf_pattern_manage, /* pattern_manage */
+ gdev_pdf_fill_rectangle_hl_color /* fill_rectangle_hl_color */
},
psdf_initial_values(PSDF_VERSION_INITIAL, 0 /*false */ ), /* (!ASCII85EncodePages) */
PDF_COMPATIBILITY_LEVEL_INITIAL, /* CompatibilityLevel */
diff --git a/gs/src/gdevpdfd.c b/gs/src/gdevpdfd.c
index 2d540b07b..35fa1e47e 100644
--- a/gs/src/gdevpdfd.c
+++ b/gs/src/gdevpdfd.c
@@ -342,15 +342,13 @@ pdf_put_clip_path(gx_device_pdf * pdev, const gx_clip_path * pcpath)
* *pscale.
*/
private bool
-make_path_scaling(const gx_device_pdf *pdev, gx_path *ppath,
+make_rect_scaling(const gx_device_pdf *pdev, const gs_fixed_rect *bbox,
floatp prescale, double *pscale)
{
- gs_fixed_rect bbox;
double bmin, bmax;
- gx_path_bbox(ppath, &bbox);
- bmin = min(bbox.p.x / pdev->scale.x, bbox.p.y / pdev->scale.y) * prescale;
- bmax = max(bbox.q.x / pdev->scale.x, bbox.q.y / pdev->scale.y) * prescale;
+ bmin = min(bbox->p.x / pdev->scale.x, bbox->p.y / pdev->scale.y) * prescale;
+ bmax = max(bbox->q.x / pdev->scale.x, bbox->q.y / pdev->scale.y) * prescale;
if (bmin <= int2fixed(-MAX_USER_COORD) ||
bmax > int2fixed(MAX_USER_COORD)
) {
@@ -362,45 +360,27 @@ make_path_scaling(const gx_device_pdf *pdev, gx_path *ppath,
*pscale = 1;
return false;
}
-#undef MAX_USER_COORD
}
-/* ------ Driver procedures ------ */
-
-/* Fill a path. */
-int
-gdev_pdf_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath,
- const gx_fill_params * params,
+/*
+ * Prepare a fill with a color anc a clipping path.
+ * Return 1 if there is nothing to paint.
+ */
+private int
+prepare_fill_with_clip(gx_device_pdf *pdev, const gs_imager_state * pis,
+ gs_fixed_rect *box, bool have_path,
const gx_drawing_color * pdcolor, const gx_clip_path * pcpath)
{
- gx_device_pdf *pdev = (gx_device_pdf *) dev;
bool new_clip;
int code;
- /*
- * HACK: we fill an empty path in order to set the clipping path
- * and the color for writing text. If it weren't for this, we
- * could detect and skip empty paths before putting out the clip
- * path or the color. We also clip with an empty path in order
- * to advance currentpoint for show operations without actually
- * drawing anything.
- */
- bool have_path;
- gs_fixed_rect box = {{0, 0}, {0, 0}};
- have_path = !gx_path_is_void(ppath);
- if (!have_path && !pdev->vg_initial_set) {
- /* See lib/gs_pdfwr.ps about "initial graphic state". */
- pdf_prepare_initial_viewers_state(pdev, pis);
- pdf_reset_graphics(pdev);
- return 0;
- }
/*
* Check for an empty clipping path.
*/
if (pcpath) {
- gx_cpath_outer_box(pcpath, &box);
- if (box.p.x >= box.q.x || box.p.y >= box.q.y)
- return 0; /* empty clipping path */
+ gx_cpath_outer_box(pcpath, box);
+ if (box->p.x >= box->q.x || box->p.y >= box->q.y)
+ return 1; /* empty clipping path */
}
if (gx_dc_is_pure(pdcolor)) {
/*
@@ -408,7 +388,7 @@ gdev_pdf_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath
* which shouldn't cause the page to be opened.
*/
if (gx_dc_pure_color(pdcolor) == pdev->white && !is_in_page(pdev))
- return 0;
+ return 1;
}
new_clip = pdf_must_put_clip_path(pdev, pcpath);
if (have_path || pdev->context == PDF_IN_NONE || new_clip) {
@@ -422,9 +402,42 @@ gdev_pdf_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath
code = pdf_prepare_fill(pdev, pis);
if (code < 0)
return code;
- code = pdf_put_clip_path(pdev, pcpath);
+ return pdf_put_clip_path(pdev, pcpath);
+}
+
+/* ------ Driver procedures ------ */
+
+/* Fill a path. */
+int
+gdev_pdf_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath,
+ const gx_fill_params * params,
+ const gx_drawing_color * pdcolor, const gx_clip_path * pcpath)
+{
+ gx_device_pdf *pdev = (gx_device_pdf *) dev;
+ int code;
+ /*
+ * HACK: we fill an empty path in order to set the clipping path
+ * and the color for writing text. If it weren't for this, we
+ * could detect and skip empty paths before putting out the clip
+ * path or the color. We also clip with an empty path in order
+ * to advance currentpoint for show operations without actually
+ * drawing anything.
+ */
+ bool have_path;
+ gs_fixed_rect box = {{0, 0}, {0, 0}};
+
+ have_path = !gx_path_is_void(ppath);
+ if (!have_path && !pdev->vg_initial_set) {
+ /* See lib/gs_pdfwr.ps about "initial graphic state". */
+ pdf_prepare_initial_viewers_state(pdev, pis);
+ pdf_reset_graphics(pdev);
+ return 0;
+ }
+ code = prepare_fill_with_clip(pdev, pis, &box, have_path, pdcolor, pcpath);
if (code < 0)
return code;
+ if (code == 1)
+ return 0; /* Nothing to paint. */
if (pdf_setfillcolor((gx_device_vector *)pdev, pis, pdcolor) < 0)
return gx_default_fill_path(dev, pis, ppath, params, pdcolor,
pcpath);
@@ -433,13 +446,12 @@ gdev_pdf_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath
double scale;
gs_matrix smat;
gs_matrix *psmat = NULL;
-
- if (pcpath) {
- gs_fixed_rect box1;
+ gs_fixed_rect box1;
- code = gx_path_bbox(ppath, &box1);
- if (code < 0)
- return code;
+ code = gx_path_bbox(ppath, &box1);
+ if (code < 0)
+ return code;
+ if (pcpath) {
rect_intersect(box1, box);
if (box1.p.x > box1.q.x || box1.p.y > box1.q.y)
return 0; /* outside the clipping path */
@@ -448,7 +460,7 @@ gdev_pdf_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath
pprintg1(s, "%g i\n", params->flatness);
pdev->state.flatness = params->flatness;
}
- if (make_path_scaling(pdev, ppath, 1.0, &scale)) {
+ if (make_rect_scaling(pdev, &box1, 1.0, &scale)) {
gs_make_scaling(pdev->scale.x * scale, pdev->scale.y * scale,
&smat);
pdf_put_matrix(pdev, "q ", &smat, "cm\n");
@@ -477,6 +489,7 @@ gdev_pdf_stroke_path(gx_device * dev, const gs_imager_state * pis,
bool set_ctm;
gs_matrix mat;
double prescale = 1;
+ gs_fixed_rect bbox;
if (gx_path_is_void(ppath))
return 0; /* won't mark the page */
@@ -518,7 +531,8 @@ gdev_pdf_stroke_path(gx_device * dev, const gs_imager_state * pis,
prescale = (minor == 0 || minor > 1 ? 1 : 1 / minor);
}
- if (make_path_scaling(pdev, ppath, prescale, &path_scale)) {
+ gx_path_bbox(ppath, &bbox);
+ if (make_rect_scaling(pdev, &bbox, prescale, &path_scale)) {
scale /= path_scale;
if (set_ctm)
gs_matrix_scale(&mat, path_scale, path_scale, &mat);
@@ -545,3 +559,50 @@ gdev_pdf_stroke_path(gx_device * dev, const gs_imager_state * pis,
stream_puts(s, (set_ctm ? " Q\n" : "\n"));
return 0;
}
+
+/*
+ The fill_rectangle_hl_color device method.
+ See gxdevcli.h about return codes.
+ */
+int
+gdev_pdf_fill_rectangle_hl_color(gx_device *dev, int x, int y, int width, int height,
+ const gs_imager_state *pis, const gx_drawing_color *pdcolor,
+ const gx_clip_path *pcpath)
+{
+ int code;
+ gs_fixed_rect box1, box = {{0, 0}, {0, 0}};
+ gx_device_pdf *pdev = (gx_device_pdf *) dev;
+ double scale;
+ gs_matrix smat;
+ gs_matrix *psmat = NULL;
+
+ if (width == 0)
+ return 0;
+ code = prepare_fill_with_clip(pdev, pis, &box, true, pdcolor, pcpath);
+ if (code < 0)
+ return code;
+ if (code == 1)
+ return 0; /* Nothing to paint. */
+ code = pdf_setfillcolor((gx_device_vector *)pdev, pis, pdcolor);
+ if (code < 0)
+ return code;
+ box1.p.x = int2fixed(x);
+ box1.p.y = int2fixed(y);
+ box1.q.x = int2fixed(x + width);
+ box1.q.y = int2fixed(y + height);
+ if (pcpath)
+ rect_intersect(box1, box);
+ if (box1.p.x > box1.q.x || box1.p.y > box1.q.y)
+ return 0; /* outside the clipping path */
+ if (make_rect_scaling(pdev, &box1, 1.0, &scale)) {
+ gs_make_scaling(pdev->scale.x * scale, pdev->scale.y * scale, &smat);
+ pdf_put_matrix(pdev, "q ", &smat, "cm\n");
+ psmat = &smat;
+ }
+ pprintg4(pdev->strm, "%g %g %g %g re f\n",
+ fixed2float(box1.p.x) * scale, fixed2float(box1.p.y) * scale,
+ fixed2float(box1.q.x - box1.p.x) * scale, fixed2float(box1.q.y - box1.p.y) * scale);
+ if (psmat)
+ stream_puts(pdev->strm, "Q\n");
+ return 0;
+}
diff --git a/gs/src/gdevpdfx.h b/gs/src/gdevpdfx.h
index fe10fe753..3a9caa832 100644
--- a/gs/src/gdevpdfx.h
+++ b/gs/src/gdevpdfx.h
@@ -583,6 +583,7 @@ dev_proc_put_params(gdev_pdf_put_params);
/* In gdevpdft.c */
dev_proc_text_begin(gdev_pdf_text_begin);
dev_proc_pattern_manage(gdev_pdf_pattern_manage);
+dev_proc_fill_rectangle_hl_color(gdev_pdf_fill_rectangle_hl_color);
/* ================ Utility procedures ================ */
diff --git a/gs/src/gdevrops.c b/gs/src/gdevrops.c
index 2c0858828..883d42516 100644
--- a/gs/src/gdevrops.c
+++ b/gs/src/gdevrops.c
@@ -102,7 +102,8 @@ private const gx_device_rop_texture gs_rop_texture_device = {
gx_forward_get_color_comp_index,
gx_forward_encode_color,
gx_forward_decode_color,
- gx_forward_pattern_manage
+ gx_forward_pattern_manage,
+ gx_forward_fill_rectangle_hl_color
},
0, /* target */
lop_default /* log_op */
diff --git a/gs/src/gsdps1.c b/gs/src/gsdps1.c
index 38215e381..1176c36b3 100644
--- a/gs/src/gsdps1.c
+++ b/gs/src/gsdps1.c
@@ -25,6 +25,7 @@
#include "gxdevice.h"
#include "gxfixed.h"
#include "gxmatrix.h"
+#include "gxhldevc.h"
#include "gspath.h"
#include "gspath2.h" /* defines interface */
#include "gzpath.h"
@@ -146,18 +147,26 @@ gs_rectfill(gs_state * pgs, const gs_rect * pr, uint count)
gx_clip_path *pcpath;
uint rcount = count;
int code;
+ gx_device * pdev = pgs->device;
+ gx_device_color *pdc = pgs->dev_color;
+ const gs_imager_state *pis = (const gs_imager_state *)pgs;
+ bool hl_color_available = gx_hld_is_hl_color_available(pis, pdc);
+ bool hl_color = (hl_color_available &&
+ dev_proc(pdev, fill_rectangle_hl_color)(pdev,
+ 0, 0, 0, 0, pis, pdc, NULL) == 0);
gx_set_dev_color(pgs);
if ((is_fzero2(pgs->ctm.xy, pgs->ctm.yx) ||
is_fzero2(pgs->ctm.xx, pgs->ctm.yy)) &&
gx_effective_clip_path(pgs, &pcpath) >= 0 &&
clip_list_is_rectangle(gx_cpath_list(pcpath)) &&
- (pgs->dev_color->type == gx_dc_type_pure ||
- pgs->dev_color->type == gx_dc_type_ht_binary ||
- pgs->dev_color->type == gx_dc_type_ht_colored
+ (hl_color ||
+ pdc->type == gx_dc_type_pure ||
+ pdc->type == gx_dc_type_ht_binary ||
+ pdc->type == gx_dc_type_ht_colored
/* DeviceN todo: add wts case */) &&
gs_state_color_load(pgs) >= 0 &&
- (*dev_proc(pgs->device, get_alpha_bits)) (pgs->device, go_graphics)
+ (*dev_proc(pdev, get_alpha_bits)) (pdev, go_graphics)
<= 1 &&
(!pgs->overprint || !pgs->effective_overprint_mode)
) {
@@ -185,8 +194,14 @@ gs_rectfill(gs_state * pgs, const gs_rect * pr, uint count)
w = fixed2int_pixround(draw_rect.q.x) - x;
h = fixed2int_pixround(draw_rect.q.y) - y;
if (w > 0 && h > 0) {
- if (gx_fill_rectangle(x, y, w, h, pgs->dev_color, pgs) < 0)
- goto slow;
+ if (hl_color) {
+ if (dev_proc(pdev, fill_rectangle_hl_color)(pdev,
+ x, y, w, h, pis, pdc, pcpath) < 0)
+ goto slow;
+ } else {
+ if (gx_fill_rectangle(x, y, w, h, pdc, pgs) < 0)
+ goto slow;
+ }
}
}
return 0;
diff --git a/gs/src/gspaint.c b/gs/src/gspaint.c
index 2eab6d8cc..d9f281d17 100644
--- a/gs/src/gspaint.c
+++ b/gs/src/gspaint.c
@@ -31,6 +31,7 @@
#include "gxdevice.h"
#include "gxdevmem.h"
#include "gzcpath.h"
+#include "gxhldevc.h"
/* Define the nominal size for alpha buffers. */
#define abuf_nominal_SMALL 500
@@ -67,17 +68,23 @@ int
gs_fillpage(gs_state * pgs)
{
gx_device *dev;
- int code;
+ int code = 0;
gs_logical_operation_t save_lop;
-
+ bool hl_color_available = gx_hld_is_hl_color_available((gs_imager_state *)pgs,
+ pgs->dev_color);
gx_set_dev_color(pgs);
dev = gs_currentdevice(pgs);
/* Fill the page directly, ignoring clipping. */
/* Use the default RasterOp. */
save_lop = pgs->log_op;
gs_init_rop(pgs);
- code = gx_fill_rectangle(0, 0, dev->width, dev->height,
- pgs->dev_color, pgs);
+ if (hl_color_available)
+ code = dev_proc(pgs->device, fill_rectangle_hl_color)(pgs->device,
+ 0, 0, dev->width, dev->height,
+ (const gs_imager_state *)pgs, pgs->dev_color, NULL);
+ if (!hl_color_available || code == gs_error_rangecheck)
+ code = gx_fill_rectangle(0, 0, dev->width, dev->height,
+ pgs->dev_color, pgs);
pgs->log_op = save_lop;
if (code < 0)
return code;
diff --git a/gs/src/gxclip.c b/gs/src/gxclip.c
index bdf29bb3c..b54b8e5d6 100644
--- a/gs/src/gxclip.c
+++ b/gs/src/gxclip.c
@@ -98,7 +98,8 @@ private const gx_device_clip gs_clip_device =
gx_forward_get_color_comp_index,
gx_forward_encode_color,
gx_forward_decode_color,
- gx_forward_pattern_manage
+ gx_forward_pattern_manage,
+ gx_forward_fill_rectangle_hl_color
}
};
diff --git a/gs/src/gxclip2.c b/gs/src/gxclip2.c
index 4e0499564..db46c3149 100644
--- a/gs/src/gxclip2.c
+++ b/gs/src/gxclip2.c
@@ -90,7 +90,8 @@ private const gx_device_tile_clip gs_tile_clip_device =
gx_forward_get_color_comp_index,
gx_forward_encode_color,
gx_forward_decode_color,
- gx_forward_pattern_manage
+ gx_forward_pattern_manage,
+ gx_forward_fill_rectangle_hl_color
}
};
diff --git a/gs/src/gxclipm.c b/gs/src/gxclipm.c
index 31b764315..43475bf94 100644
--- a/gs/src/gxclipm.c
+++ b/gs/src/gxclipm.c
@@ -89,7 +89,8 @@ const gx_device_mask_clip gs_mask_clip_device =
gx_forward_get_color_comp_index,
gx_forward_encode_color,
gx_forward_decode_color,
- gx_forward_pattern_manage
+ gx_forward_pattern_manage,
+ gx_forward_fill_rectangle_hl_color
}
};
diff --git a/gs/src/gxclist.c b/gs/src/gxclist.c
index 296f4683b..41ee5193d 100644
--- a/gs/src/gxclist.c
+++ b/gs/src/gxclist.c
@@ -132,7 +132,8 @@ const gx_device_procs gs_clist_device_procs = {
gx_forward_get_color_comp_index,
gx_forward_encode_color,
gx_forward_decode_color,
- gx_default_pattern_manage
+ gx_default_pattern_manage,
+ gx_default_fill_rectangle_hl_color
};
/* ------ Define the command set and syntax ------ */
diff --git a/gs/src/gxdevcli.h b/gs/src/gxdevcli.h
index f1bcb40ff..32787ec65 100644
--- a/gs/src/gxdevcli.h
+++ b/gs/src/gxdevcli.h
@@ -1187,6 +1187,26 @@ typedef enum {
#define dev_proc_pattern_manage(proc)\
dev_t_proc_pattern_manage(proc, gx_device)
+/*
+ Fill rectangle with a high level color.
+ Return rangecheck, if the device can't handle the high level color.
+
+ The graphics library calls this function with degenerate (widths=0)
+ rectangles, to know whether the device can handle a rectangle with
+ the high level color. The device should skip such rectangles returning
+ a proper code.
+
+ Currently this function is used with gs_rectfill and gs_fillpage only.
+ In future it should be called while decomposing other objects.
+*/
+
+#define dev_t_proc_fill_rectangle_hl_color(proc, dev_t)\
+ int proc(dev_t *dev, int x, int y, int width, int height, \
+ const gs_imager_state *pis, const gx_drawing_color *pdcolor, \
+ const gx_clip_path *pcpath)
+#define dev_proc_fill_rectangle_hl_color(proc)\
+ dev_t_proc_fill_rectangle_hl_color(proc, gx_device)
+
/* Define the device procedure vector template proper. */
#define gx_device_proc_struct(dev_t)\
@@ -1244,6 +1264,7 @@ typedef enum {
dev_t_proc_encode_color((*encode_color), dev_t); \
dev_t_proc_decode_color((*decode_color), dev_t); \
dev_t_proc_pattern_manage((*pattern_manage), dev_t); \
+ dev_t_proc_fill_rectangle_hl_color((*fill_rectangle_hl_color), dev_t); \
}
diff --git a/gs/src/gxdevice.h b/gs/src/gxdevice.h
index 750d4988a..e6c3b806a 100644
--- a/gs/src/gxdevice.h
+++ b/gs/src/gxdevice.h
@@ -269,6 +269,7 @@ dev_proc_get_hardware_params(gx_default_get_hardware_params);
dev_proc_text_begin(gx_default_text_begin);
dev_proc_finish_copydevice(gx_default_finish_copydevice);
dev_proc_pattern_manage(gx_default_pattern_manage);
+dev_proc_fill_rectangle_hl_color(gx_default_fill_rectangle_hl_color);
/* BACKWARD COMPATIBILITY */
#define gx_non_imaging_create_compositor gx_null_create_compositor
@@ -339,6 +340,7 @@ dev_proc_get_color_comp_index(gx_forward_get_color_comp_index);
dev_proc_encode_color(gx_forward_encode_color);
dev_proc_decode_color(gx_forward_decode_color);
dev_proc_pattern_manage(gx_forward_pattern_manage);
+dev_proc_fill_rectangle_hl_color(gx_forward_fill_rectangle_hl_color);
/* ---------------- Implementation utilities ---------------- */
diff --git a/gs/src/gxhldevc.c b/gs/src/gxhldevc.c
index e9cf19f4d..18e9efc57 100644
--- a/gs/src/gxhldevc.c
+++ b/gs/src/gxhldevc.c
@@ -133,6 +133,20 @@ bool gx_hld_saved_color_same_cspace(const gx_hl_saved_color * psc1,
}
/*
+ * Check if a high level color is availavble.
+ */
+bool
+gx_hld_is_hl_color_available(const gs_imager_state * pis,
+ const gx_device_color * pdevc)
+{
+ const gs_state * pgs = gx_hld_get_gstate_ptr(pis);
+
+ if (pgs != NULL && pdevc != NULL && pdevc->ccolor_valid)
+ return true;
+ return false;
+}
+
+/*
* Get pointers to the current color space and client color.
*
* More description in src/gxhldevc.h
@@ -142,10 +156,9 @@ gx_hld_get_color_space_and_ccolor(const gs_imager_state * pis,
const gx_device_color * pdevc, const gs_color_space ** ppcs,
const gs_client_color ** ppcc)
{
- const gs_state * pgs = gx_hld_get_gstate_ptr(pis);
-
/* Check if the current color space was used to build the device color */
- if (pgs != NULL && pdevc != NULL && pdevc->ccolor_valid) {
+ if (gx_hld_is_hl_color_available(pis, pdevc)) {
+ const gs_state * pgs = gx_hld_get_gstate_ptr(pis);
const gs_color_space * pcs = pgs->color_space;
*ppcs = pcs;
diff --git a/gs/src/gxhldevc.h b/gs/src/gxhldevc.h
index 4acba672e..874c7a9c9 100644
--- a/gs/src/gxhldevc.h
+++ b/gs/src/gxhldevc.h
@@ -116,6 +116,13 @@ bool gx_hld_saved_color_same_cspace(const gx_hl_saved_color * psc1,
const gx_hl_saved_color * psc2);
/*
+ * Check if a high level color is availavble.
+ */
+bool
+gx_hld_is_hl_color_available(const gs_imager_state * pis,
+ const gx_device_color * pdevc);
+
+/*
* Return status from get_color_space_and_ccolor. See that routine for
* more information.
*
diff --git a/gs/src/lib.mak b/gs/src/lib.mak
index 84c6ba866..5a70d73af 100644
--- a/gs/src/lib.mak
+++ b/gs/src/lib.mak
@@ -823,7 +823,7 @@ $(GLOBJ)gsmatrix.$(OBJ) : $(GLSRC)gsmatrix.c $(GXERR) $(math__h) $(memory__h)\
$(GLOBJ)gspaint.$(OBJ) : $(GLSRC)gspaint.c $(GXERR) $(math__h) $(gpcheck_h)\
$(gspaint_h) $(gspath_h) $(gsropt_h)\
- $(gxdevmem_h) $(gxdevice_h) $(gxfixed_h) $(gxmatrix_h) $(gxpaint_h)\
+ $(gxdevmem_h) $(gxdevice_h) $(gxfixed_h) $(gxmatrix_h) $(gxpaint_h) $(gxhldevc_h)\
$(gzcpath_h) $(gzpath_h) $(gzstate_h)
$(GLCC) $(GLO_)gspaint.$(OBJ) $(C_) $(GLSRC)gspaint.c
@@ -2123,7 +2123,7 @@ $(GLD)dps2lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(dps2lib_)
$(GLOBJ)gsdps1.$(OBJ) : $(GLSRC)gsdps1.c $(GXERR) $(math__h)\
$(gsmatrix_h) $(gscoord_h) $(gspaint_h) $(gxdevice_h)\
$(gxfixed_h) $(gxmatrix_h) $(gspath_h) $(gspath2_h)\
- $(gxdevice_h) $(gxfixed_h) $(gxmatrix_h)\
+ $(gxdevice_h) $(gxfixed_h) $(gxmatrix_h) $(gxhldevc_h)\
$(gzpath_h) $(gzcpath_h) $(gzstate_h)
$(GLCC) $(GLO_)gsdps1.$(OBJ) $(C_) $(GLSRC)gsdps1.c