summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/gdevabuf.c')
-rw-r--r--base/gdevabuf.c63
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,