diff options
author | Igor Melichev <igor.melichev@artifex.com> | 2007-07-02 08:09:03 +0000 |
---|---|---|
committer | Igor Melichev <igor.melichev@artifex.com> | 2007-07-02 08:09:03 +0000 |
commit | 9d050bdb7ca8b2f41fcd508a935ccc0c123439ef (patch) | |
tree | d0315e816ce68f56048f194cd5fa992d89e7782c | |
parent | bf5b161d7c798d9c41e09dc6c8e6d40729493ee1 (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.h | 1 | ||||
-rw-r--r-- | gs/src/gxclist.c | 2 | ||||
-rw-r--r-- | gs/src/gxclpath.h | 5 | ||||
-rw-r--r-- | gs/src/gxclrast.c | 37 | ||||
-rw-r--r-- | gs/src/gxclrect.c | 89 |
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, |