diff options
Diffstat (limited to 'base/gdevabuf.c')
-rw-r--r-- | base/gdevabuf.c | 63 |
1 files changed, 46 insertions, 17 deletions
diff --git a/base/gdevabuf.c b/base/gdevabuf.c index d9c45a28..e937299d 100644 --- a/base/gdevabuf.c +++ b/base/gdevabuf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2019 Artifex Software, Inc. +/* Copyright (C) 2001-2020 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -191,7 +191,7 @@ gs_make_mem_abuf_device(gx_device_memory * adev, gs_memory_t * mem, adev->mapped_x = mapped_x; set_dev_proc(adev, close_device, mem_abuf_close); set_dev_proc(adev, get_clipping_box, mem_abuf_get_clipping_box); - if (!devn) + if (!devn) adev->save_hl_color = NULL; /* This is the test for when we flush the the buffer as to what copy_alpha type use */ @@ -235,7 +235,7 @@ abuf_flush_block(gx_device_memory * adev, int y) * (see gsbitops.c), we can't expand the box only to pixel * boundaries: int alpha_mask = -1 << adev->log2_alpha_bits; - * Instead, we must expand it to byte boundaries, + * Instead, we must expand it to byte boundaries, */ int alpha_mask = ~7; gs_int_rect bbox; @@ -249,7 +249,7 @@ abuf_flush_block(gx_device_memory * adev, int y) adev->raster, bits, draster, &adev->log2_scale, adev->log2_alpha_bits); /* Set up with NULL when adev initialized */ - if (adev->save_hl_color == NULL) { + if (adev->save_hl_color == NULL) { return (*dev_proc(target, copy_alpha)) (target, bits, 0, draster, gx_no_bitmap_id, (adev->mapped_x + bbox.p.x) >> @@ -304,21 +304,25 @@ typedef struct y_transfer_s { int transfer_y; int transfer_height; } y_transfer; -static void +static int y_transfer_init(y_transfer * pyt, gx_device * dev, int ty, int th) { gx_device_memory * const mdev = (gx_device_memory *)dev; int bh = 1 << mdev->log2_scale.y; if (ty < mdev->mapped_y || ty > mdev->mapped_y + mdev->mapped_height) { - abuf_flush(mdev); + int code = abuf_flush(mdev); + if (code < 0) + return code; mdev->mapped_y = ty & -bh; mdev->mapped_height = bh; - memset(scan_line_base(mdev, 0), 0, bh * mdev->raster); + memset(scan_line_base(mdev, 0), 0, (size_t)bh * mdev->raster); } pyt->y_next = ty; pyt->height_left = th; pyt->transfer_height = 0; + + return 0; } /* while ( yt.height_left > 0 ) { y_transfer_next(&yt, mdev); ... } */ static int @@ -348,7 +352,7 @@ y_transfer_next(y_transfer * pyt, gx_device * dev) mdev->mapped_height = mh += bh; } memset(scan_line_base(mdev, (ms == 0 ? mh : ms) - bh), - 0, bh * mdev->raster); + 0, (size_t)bh * mdev->raster); } /* Now we know that my <= ty < my + mh. */ tby = ty - my + ms; @@ -380,6 +384,7 @@ mem_abuf_copy_mono(gx_device * dev, { gx_device_memory * const mdev = (gx_device_memory *)dev; y_transfer yt; + int code; if (zero != gx_no_color_index || one == gx_no_color_index) return_error(gs_error_undefinedresult); @@ -387,11 +392,18 @@ mem_abuf_copy_mono(gx_device * dev, fit_copy_xyw(dev, base, sourcex, sraster, id, x, y, w, h); /* don't limit h */ if (w <= 0 || h <= 0) return 0; + if (mdev->mapped_height != 0 && mdev->save_color != one) { + /* Color has changed. Better flush. */ + int code = abuf_flush(mdev); + if (code < 0) + return code; + } mdev->save_color = one; - y_transfer_init(&yt, dev, y, h); + code = y_transfer_init(&yt, dev, y, h); + if (code < 0) + return code; while (yt.height_left > 0) { - int code = y_transfer_next(&yt, dev); - + code = y_transfer_next(&yt, dev); if (code < 0) return code; (*dev_proc(&mem_mono_device, copy_mono)) (dev, @@ -410,16 +422,24 @@ mem_abuf_fill_rectangle(gx_device * dev, int x, int y, int w, int h, { gx_device_memory * const mdev = (gx_device_memory *)dev; y_transfer yt; + int code; x -= mdev->mapped_x; fit_fill_xy(dev, x, y, w, h); fit_fill_w(dev, x, w); /* don't limit h */ /* or check w <= 0, h <= 0 */ + if (mdev->mapped_height != 0 && mdev->save_color != color) { + /* Color has changed. Better flush. */ + int code = abuf_flush(mdev); + if (code < 0) + return code; + } mdev->save_color = color; - y_transfer_init(&yt, dev, y, h); + code = y_transfer_init(&yt, dev, y, h); + if (code < 0) + return code; while (yt.height_left > 0) { - int code = y_transfer_next(&yt, dev); - + code = y_transfer_next(&yt, dev); if (code < 0) return code; (*dev_proc(&mem_mono_device, fill_rectangle)) (dev, @@ -442,17 +462,26 @@ mem_abuf_fill_rectangle_hl_color(gx_device * dev, const gs_fixed_rect *rect, int y = fixed2int(rect->p.y); int w = fixed2int(rect->q.x) - x; int h = fixed2int(rect->q.y) - y; + int code; (void)pgs; x -= mdev->mapped_x; fit_fill_xy(dev, x, y, w, h); fit_fill_w(dev, x, w); /* don't limit h */ /* or check w <= 0, h <= 0 */ + if (mdev->mapped_height != 0 && + memcmp(mdev->save_hl_color, pdcolor, sizeof(*pdcolor)) != 0) { + /* Color has changed. Better flush. */ + int code = abuf_flush(mdev); + if (code < 0) + return code; + } mdev->save_hl_color = pdcolor; - y_transfer_init(&yt, dev, y, h); + code = y_transfer_init(&yt, dev, y, h); + if (code < 0) + return code; while (yt.height_left > 0) { - int code = y_transfer_next(&yt, dev); - + code = y_transfer_next(&yt, dev); if (code < 0) return code; (*dev_proc(&mem_mono_device, fill_rectangle)) (dev, |