summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Melichev <igor.melichev@artifex.com>2007-07-02 08:09:03 +0000
committerIgor Melichev <igor.melichev@artifex.com>2007-07-02 08:09:03 +0000
commit9d050bdb7ca8b2f41fcd508a935ccc0c123439ef (patch)
treed0315e816ce68f56048f194cd5fa992d89e7782c
parentbf5b161d7c798d9c41e09dc6c8e6d40729493ee1 (diff)
Extend the clist language with fill_trapezoid.
DETAILS : It saves the clist file size with writing a higher level objects. The old code expands trapezoids with lots of rectangles. EXPECTED DIFFERENCES : None. git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@8095 a1074d23-0009-0410-80fe-cf8c14f379e6
-rw-r--r--gs/src/gxcldev.h1
-rw-r--r--gs/src/gxclist.c2
-rw-r--r--gs/src/gxclpath.h5
-rw-r--r--gs/src/gxclrast.c37
-rw-r--r--gs/src/gxclrect.c89
5 files changed, 131 insertions, 3 deletions
diff --git a/gs/src/gxcldev.h b/gs/src/gxcldev.h
index 201b71ca8..633ce84c0 100644
--- a/gs/src/gxcldev.h
+++ b/gs/src/gxcldev.h
@@ -282,6 +282,7 @@ dev_proc_copy_color(clist_copy_color);
dev_proc_copy_alpha(clist_copy_alpha);
dev_proc_strip_tile_rectangle(clist_strip_tile_rectangle);
dev_proc_strip_copy_rop(clist_strip_copy_rop);
+dev_proc_fill_trapezoid(clist_fill_trapezoid);
/* In gxclimag.c */
dev_proc_fill_mask(clist_fill_mask);
diff --git a/gs/src/gxclist.c b/gs/src/gxclist.c
index 26c70c1e2..a1b8aa9e7 100644
--- a/gs/src/gxclist.c
+++ b/gs/src/gxclist.c
@@ -124,7 +124,7 @@ const gx_device_procs gs_clist_device_procs = {
clist_fill_path,
clist_stroke_path,
clist_fill_mask,
- gx_default_fill_trapezoid,
+ clist_fill_trapezoid,
clist_fill_parallelogram,
clist_fill_triangle,
gx_default_draw_thin_line,
diff --git a/gs/src/gxclpath.h b/gs/src/gxclpath.h
index e125b6c25..6bde05125 100644
--- a/gs/src/gxclpath.h
+++ b/gs/src/gxclpath.h
@@ -142,9 +142,10 @@ typedef enum {
cmd_opv_stroke = 0xf6,
/* cmd_opv_htstroke = 0xf7, */ /* obsolete */
/* cmd_opv_colorstroke = 0xf8, */ /* obsolete */
- cmd_opv_polyfill = 0xf9
+ cmd_opv_polyfill = 0xf9,
/* cmd_opv_htpolyfill = 0xfa, */ /* obsolete */
/* cmd_opv_colorpolyfill = 0xfb */ /* obsolete */
+ cmd_opv_fill_trapezoid = 0xfc
} gx_cmd_xop;
/*
@@ -181,7 +182,7 @@ typedef enum {
"fill", "htfill", "colorfill", "eofill",\
"hteofill", "coloreofill", "stroke", "htstroke",\
"colorstroke", "polyfill", "htpolyfill", "colorpolyfill",\
- "?fc?", "?fd?", "?fe?", "?ff?"
+ "fill_trapezoid", "?fd?", "?fe?", "?ff?"
/*
* We represent path coordinates as 'fixed' values in a variable-length,
diff --git a/gs/src/gxclrast.c b/gs/src/gxclrast.c
index 362ca3ac5..411edd025 100644
--- a/gs/src/gxclrast.c
+++ b/gs/src/gxclrast.c
@@ -1384,6 +1384,43 @@ idata: data_size = 0;
code = clist_do_polyfill(tdev, ppath, &dev_color,
imager_state.log_op);
break;
+ case cmd_opv_fill_trapezoid:
+ {
+ gx_cmd_rect rl, rr;
+ gs_fixed_edge left, right;
+ fixed ybot, ytop;
+ int swap_axes, wh;
+ fixed x0f;
+ fixed y0f;
+
+ cmd_getw(left.start.x, cbp);
+ cmd_getw(left.start.y, cbp);
+ cmd_getw(left.end.x, cbp);
+ cmd_getw(left.end.y, cbp);
+ cmd_getw(right.start.x, cbp);
+ cmd_getw(right.start.y, cbp);
+ cmd_getw(right.end.x, cbp);
+ cmd_getw(right.end.y, cbp);
+ cmd_getw(ybot, cbp);
+ cmd_getw(ytop, cbp);
+ cmd_getw(swap_axes, cbp);
+ wh = swap_axes ? tdev->width : tdev->height;
+ x0f = int2fixed(swap_axes ? y0 : x0);
+ y0f = int2fixed(swap_axes ? x0 : y0);
+ left.start.x -= x0f;
+ left.start.y -= y0f;
+ left.end.x -= x0f;
+ left.end.y -= y0f;
+ right.start.x -= x0f;
+ right.start.y -= y0f;
+ right.end.x -= x0f;
+ right.end.y -= y0f;
+ code = gx_default_fill_trapezoid(tdev, &left, &right,
+ max(ybot - y0f, fixed_half),
+ min(ytop - y0f, int2fixed(wh)), swap_axes,
+ &dev_color, imager_state.log_op);
+ }
+ break;
default:
goto bad_op;
}
diff --git a/gs/src/gxclrect.c b/gs/src/gxclrect.c
index 08c74cbee..2aae37a3f 100644
--- a/gs/src/gxclrect.c
+++ b/gs/src/gxclrect.c
@@ -19,6 +19,8 @@
#include "gxdevice.h"
#include "gxdevmem.h" /* must precede gxcldev.h */
#include "gxcldev.h"
+#include "gxclpath.h"
+
/* ---------------- Writing utilities ---------------- */
@@ -132,6 +134,42 @@ cmd_write_rect_cmd(gx_device_clist_writer * cldev, gx_clist_state * pcls,
return 0;
}
+private int
+cmd_write_trapezoid_cmd(gx_device_clist_writer * cldev, gx_clist_state * pcls,
+ int op, const gs_fixed_edge *left, const gs_fixed_edge *right,
+ fixed ybot, fixed ytop, bool swap_axes)
+{
+ byte *dp;
+ int rcsize;
+ int code;
+
+ rcsize = 1 + cmd_sizew(left->start.x) + cmd_sizew(left->start.y)
+ + cmd_sizew(left->end.x) + cmd_sizew(left->end.y)
+ + cmd_sizew(right->start.x) + cmd_sizew(right->start.y)
+ + cmd_sizew(right->end.x) + cmd_sizew(right->end.y)
+ + cmd_sizew(ybot) + cmd_sizew(ytop) + cmd_sizew(swap_axes);
+ code = set_cmd_put_op(dp, cldev, pcls, op, rcsize);
+ if (code < 0)
+ return code;
+ dp++;
+ cmd_putw(left->start.x, dp);
+ cmd_putw(left->start.y, dp);
+ cmd_putw(left->end.x, dp);
+ cmd_putw(left->end.y, dp);
+ cmd_putw(right->start.x, dp);
+ cmd_putw(right->start.y, dp);
+ cmd_putw(right->end.x, dp);
+ cmd_putw(right->end.y, dp);
+ cmd_putw(ybot, dp);
+ cmd_putw(ytop, dp);
+ cmd_putw(swap_axes, dp);
+ if_debug6('L', " t%d:%d,%d,%d,%d %d\n",
+ rcsize - 1, left->start.x, left->start.y, left->end.x, left->end.y, ybot);
+ if_debug5('L', " t%d,%d,%d,%d %d\n",
+ right->start.x, right->start.y, right->end.x, right->end.y, ytop);
+ return 0;
+}
+
/* ---------------- Driver procedures ---------------- */
int
@@ -172,6 +210,57 @@ error_in_rect:
return 0;
}
+int
+clist_fill_trapezoid(gx_device * dev,
+ const gs_fixed_edge *left, const gs_fixed_edge *right,
+ fixed ybot, fixed ytop, bool swap_axes,
+ const gx_drawing_color *pdcolor, gs_logical_operation_t lop)
+{
+ gx_device_clist_writer * const cdev =
+ &((gx_device_clist *)dev)->writer;
+ int code;
+ cmd_rects_enum_t re;
+ int ry, rheight;
+
+ if (swap_axes) {
+ ry = fixed2int(min(left->start.x, left->end.x));
+ rheight = fixed2int_ceiling(max(right->start.x, right->end.x)) - ry;
+ } else {
+ ry = fixed2int(ybot);
+ rheight = fixed2int_ceiling(ytop) - ry;
+ }
+ fit_fill_h(dev, ry, rheight);
+ if (cdev->permanent_error < 0)
+ return (cdev->permanent_error);
+ RECT_ENUM_INIT(re, ry, rheight);
+ do {
+ RECT_STEP_INIT(re);
+ do {
+ code = cmd_put_drawing_color(cdev, re.pcls, pdcolor);
+ if (code < 0) {
+ /* Something went wrong, use the default implementation. */
+ return gx_default_fill_trapezoid(dev, left, right, ybot, ytop, swap_axes, pdcolor, lop);
+ }
+ code = cmd_update_lop(cdev, re.pcls, lop);
+ if (code >= 0) {
+ /* Dont't want to shorten the trapezoid by the band boundary,
+ keeping in mind a further optimization with writing same data to all bands. */
+ code = cmd_write_trapezoid_cmd(cdev, re.pcls, cmd_opv_fill_trapezoid, left, right,
+ ybot, ytop, swap_axes);
+ }
+ } while (RECT_RECOVER(code));
+ if (code < 0 && SET_BAND_CODE(code))
+ goto error_in_rect;
+ re.y += re.height;
+ continue;
+error_in_rect:
+ if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 &&
+ SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0))
+ return re.band_code;
+ } while (re.y < re.yend);
+ return 0;
+}
+
int
clist_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tile,
int rx, int ry, int rwidth, int rheight,