[gs-commits] ghostpdl branch, gs9.28-temp-for-testing, updated. gs9.28-temp-for-testing-tag-1-g72e3efc
[email protected] (Robin Watts)
| Newsgroups | gmane.comp.printing.ghostscript.cvs |
|---|---|
| Message-ID | <[email protected]> |
The ghostpdl branch, gs9.28-temp-for-testing has been updated
via 72e3efc7d0b732060b2507bfa4d859c79ebc420e (commit)
from 3a9b8ab4233e8157194092a43638d9f88d94ff92 (commit)
----------------------------------------------------------------------
commit 72e3efc7d0b732060b2507bfa4d859c79ebc420e
Author: Robin Watts <[email protected]>
Date: Thu Aug 22 18:24:49 2019 +0100
Fix deep color transparent pattern problems.
Transparency buffers are held as native endian. Pattern cache
tiles are held as big endian. When we make pattern cache tiles
from transparency buffers we therefore need a conversion.
diff --git a/base/gdevp14.c b/base/gdevp14.c
index 6a7a8a7..5e32683 100644
--- a/base/gdevp14.c
+++ b/base/gdevp14.c
@@ -1973,6 +1973,17 @@ pdf14_grayspot_get_color_mapping_procs(const gx_device * dev)
return &pdf14_DeviceGrayspot_procs;
}
+static void
+be_rev_cpy(uint16_t *dst,const uint16_t *src,int n)
+{
+ for (; n != 0; n--) {
+ uint16_t in = *src++;
+ ((byte *)dst)[0] = in>>8;
+ ((byte *)dst)[1] = in;
+ dst++;
+ }
+}
+
/* Used to pass along information about the buffer created by the
pdf14 device. This is used by the pattern accumulator when the
pattern contains transparency. Note that if free_device is true then
@@ -2035,14 +2046,28 @@ pdf14_get_buffer_information(const gx_device * dev,
return gs_error_VMerror;
transbuff->mem = mem;
- for (j = 0; j < transbuff->n_chan; j++) {
- buff_ptr_src = buf->data + j * buf->planestride +
- buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
- buff_ptr_des = transbuff->transbytes + j * planestride;
- for (k = 0; k < height; k++) {
- memcpy(buff_ptr_des, buff_ptr_src, rowstride);
- buff_ptr_des += rowstride;
- buff_ptr_src += buf->rowstride;
+ if (transbuff->deep) {
+ /* FIXME: */
+ for (j = 0; j < transbuff->n_chan; j++) {
+ buff_ptr_src = buf->data + j * buf->planestride +
+ buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
+ buff_ptr_des = transbuff->transbytes + j * planestride;
+ for (k = 0; k < height; k++) {
+ be_rev_cpy((uint16_t *)buff_ptr_des, (const uint16_t *)buff_ptr_src, rowstride>>1);
+ buff_ptr_des += rowstride;
+ buff_ptr_src += buf->rowstride;
+ }
+ }
+ } else {
+ for (j = 0; j < transbuff->n_chan; j++) {
+ buff_ptr_src = buf->data + j * buf->planestride +
+ buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
+ buff_ptr_des = transbuff->transbytes + j * planestride;
+ for (k = 0; k < height; k++) {
+ memcpy(buff_ptr_des, buff_ptr_src, rowstride);
+ buff_ptr_des += rowstride;
+ buff_ptr_src += buf->rowstride;
+ }
}
}
@@ -2055,14 +2080,33 @@ pdf14_get_buffer_information(const gx_device * dev,
transbuff->transbytes = buf->data;
transbuff->mem = buf->memory;
buf->data = NULL; /* So that the buffer is not freed */
+ if (transbuff->deep) {
+ /* We have the data in native endian. We need it in big endian. Do an in-place conversion. */
+ /* FIXME: This is a nop on big endian machines. Is the compiler smart enough to spot that? */
+ uint16_t *buff_ptr;
+ int j, k, z;
+ int rowstride = transbuff->rowstride>>1;
+ int planestride = transbuff->planestride;
+ for (j = 0; j < transbuff->n_chan; j++) {
+ buff_ptr = (uint16_t *)(transbuff->transbytes + j * planestride);
+ for (k = 0; k < height; k++) {
+ for (z = 0; z < width; z++) {
+ uint16_t in = buff_ptr[z];
+ ((byte *)(&buff_ptr[z]))[0] = in>>8;
+ ((byte *)(&buff_ptr[z]))[1] = in;
+ }
+ buff_ptr += rowstride;
+ }
+ }
+ }
}
#if RAW_DUMP
/* Dump the buffer that should be going into the pattern */;
- dump_raw_buffer(buf->memory,
- height, width, transbuff->n_chan,
- transbuff->planestride, transbuff->rowstride,
- "pdf14_pattern_buff", transbuff->transbytes,
- transbuff->deep);
+ dump_raw_buffer_be(buf->memory,
+ height, width, transbuff->n_chan,
+ transbuff->planestride, transbuff->rowstride,
+ "pdf14_pattern_buff", transbuff->transbytes,
+ transbuff->deep);
global_index++;
#endif
/* Go ahead and free up the pdf14 device */
@@ -3592,7 +3636,7 @@ pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id);
code = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin,
curr_clip_rect->xmax, curr_clip_rect->ymax, ptile,
- fill_trans_buffer, phase, pdev, pdevc);
+ fill_trans_buffer, phase, pdev, pdevc, 1);
curr_clip_rect = curr_clip_rect->next;
}
} else if (cpath_intersection.rect_list->list.count == 1) {
@@ -3610,7 +3654,7 @@ pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
cpath_intersection.rect_list->list.single.ymin,
cpath_intersection.rect_list->list.single.xmax,
cpath_intersection.rect_list->list.single.ymax,
- ptile, fill_trans_buffer, phase, pdev, pdevc);
+ ptile, fill_trans_buffer, phase, pdev, pdevc, 1);
}
} else {
/* Clist pattern with transparency. Create a clip device from our
@@ -3626,7 +3670,7 @@ pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
phase.y = pdevc->phase.y;
code = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, rect.q.x, rect.q.y,
ptile, fill_trans_buffer, phase,
- dev, pdevc);
+ dev, pdevc, 1);
}
/* We're done drawing with the pattern, remove the reference to the
diff --git a/base/gxblend.c b/base/gxblend.c
index 15b8e9b..f3bf38d 100644
--- a/base/gxblend.c
+++ b/base/gxblend.c
@@ -1743,7 +1743,7 @@ art_pdf_composite_pixel_alpha_16(uint16_t *gs_restrict dst, const uint16_t *gs_r
{
int a_b, a_s;
unsigned int a_r;
- int tmp;
+ unsigned int tmp;
int src_scale;
int c_b, c_s;
int i;
@@ -1771,7 +1771,7 @@ art_pdf_composite_pixel_alpha_16(uint16_t *gs_restrict dst, const uint16_t *gs_r
/* todo: verify that a_r is nonzero in all cases */
/* Compute a_s / a_r in 16.16 format */
- src_scale = ((a_s << 16) + (a_r >> 1)) / a_r;
+ src_scale = ((unsigned int)((a_s << 16) + (a_r >> 1))) / a_r;
if (first_spot != 0) {
/* Do compositing with blending */
diff --git a/base/gxp1fill.c b/base/gxp1fill.c
index bb4efc8..61eae3f 100644
--- a/base/gxp1fill.c
+++ b/base/gxp1fill.c
@@ -612,7 +612,8 @@ gx_dc_colored_masked_fill_rect(const gx_device_color * pdevc,
*/
static int
tile_by_steps_trans(tile_fill_trans_state_t * ptfs, int x0, int y0, int w0, int h0,
- gx_pattern_trans_t *fill_trans_buffer, const gx_color_tile * ptile)
+ gx_pattern_trans_t *fill_trans_buffer, const gx_color_tile * ptile,
+ int native16)
{
int x1 = x0 + w0, y1 = y0 + h0;
int i0, i1, j0, j1, i, j;
@@ -705,12 +706,23 @@ tile_by_steps_trans(tile_fill_trans_state_t * ptfs, int x0, int y0, int w0, int
y > fill_trans_buffer->rect.q.y || y+h < 0)
continue; /* skip the fill (can breakpoint here) */
ptile->ttrans->pat_trans_fill(x, y, x+w, y+h, px, py, ptile,
- fill_trans_buffer);
+ fill_trans_buffer, native16);
}
}
return 0;
}
+static void
+be_rev_cpy(uint16_t *dst,const uint16_t *src,int n)
+{
+ for (; n != 0; n--) {
+ uint16_t in = *src++;
+ ((byte *)dst)[0] = in>>8;
+ ((byte *)dst)[1] = in;
+ dst++;
+ }
+}
+
/* This does the case of tiling with simple tiles. Since it is not commented
* anywhere note that simple means that the tile size is the same as the step
* matrix size and the cross terms in the step matrix are 0. Hence a simple
@@ -721,7 +733,8 @@ tile_by_steps_trans(tile_fill_trans_state_t * ptfs, int x0, int y0, int w0, int
void
tile_rect_trans_simple(int xmin, int ymin, int xmax, int ymax,
int px, int py, const gx_color_tile *ptile,
- gx_pattern_trans_t *fill_trans_buffer)
+ gx_pattern_trans_t *fill_trans_buffer,
+ int native16)
{
int kk, jj, ii, h, w;
int buff_out_y_offset, buff_out_x_offset;
@@ -795,39 +808,79 @@ tile_rect_trans_simple(int xmin, int ymin, int xmax, int ymax,
if (right_copy_width < 0)
right_copy_width = 0;
- for (kk = 0; kk < src_planes; kk++) {
+ if (deep && native16) {
+ /* fill_trans_buffer is in native endian. ptile is in big endian. */
+ /* Convert as we copy. */
+ for (kk = 0; kk < src_planes; kk++) {
- ptr_out = buff_out + kk * fill_trans_buffer->planestride;
- ptr_in = buff_in + kk * ptile->ttrans->planestride;
- if (fill_trans_buffer->has_shape && kk == fill_trans_buffer->n_chan)
- ptr_out += fill_trans_buffer->planestride; /* tag plane follows shape plane */
+ ptr_out = buff_out + kk * fill_trans_buffer->planestride;
+ ptr_in = buff_in + kk * ptile->ttrans->planestride;
+ if (fill_trans_buffer->has_shape && kk == fill_trans_buffer->n_chan)
+ ptr_out += fill_trans_buffer->planestride; /* tag plane follows shape plane */
- for (jj = 0; jj < h; jj++, ptr_out += fill_trans_buffer->rowstride) {
+ for (jj = 0; jj < h; jj++, ptr_out += fill_trans_buffer->rowstride) {
- in_row_offset = ((jj + dy) % ptile->ttrans->height);
- if (in_row_offset >= ptile->ttrans->rect.q.y)
- continue;
- in_row_offset -= ptile->ttrans->rect.p.y;
- if (in_row_offset < 0)
- continue;
- row_ptr = ptr_in + in_row_offset * ptile->ttrans->rowstride;
+ in_row_offset = ((jj + dy) % ptile->ttrans->height);
+ if (in_row_offset >= ptile->ttrans->rect.q.y)
+ continue;
+ in_row_offset -= ptile->ttrans->rect.p.y;
+ if (in_row_offset < 0)
+ continue;
+ row_ptr = ptr_in + in_row_offset * ptile->ttrans->rowstride;
- /* This is the case when we have no blending. */
- ptr_out_temp = ptr_out;
+ /* This is the case when we have no blending. */
+ ptr_out_temp = ptr_out;
- /* Left part */
- memcpy( ptr_out_temp, row_ptr + left_copy_offset, left_copy_width<<deep);
- ptr_out_temp += left_width<<deep;
+ /* Left part */
+ be_rev_cpy((uint16_t *)ptr_out_temp, (uint16_t *)(row_ptr + left_copy_offset), left_copy_width);
+ ptr_out_temp += left_width<<deep;
- /* Now the full tiles */
+ /* Now the full tiles */
- for ( ii = 0; ii < num_full_tiles; ii++){
- memcpy( ptr_out_temp, row_ptr, mid_copy_width<<deep);
- ptr_out_temp += tile_width<<deep;
+ for ( ii = 0; ii < num_full_tiles; ii++){
+ be_rev_cpy((uint16_t *)ptr_out_temp, (uint16_t *)row_ptr, mid_copy_width);
+ ptr_out_temp += tile_width<<deep;
+ }
+
+ /* Now the remainder */
+ be_rev_cpy((uint16_t *)ptr_out_temp, (uint16_t *)row_ptr, right_copy_width);
}
+ }
+ } else {
+ for (kk = 0; kk < src_planes; kk++) {
+
+ ptr_out = buff_out + kk * fill_trans_buffer->planestride;
+ ptr_in = buff_in + kk * ptile->ttrans->planestride;
+ if (fill_trans_buffer->has_shape && kk == fill_trans_buffer->n_chan)
+ ptr_out += fill_trans_buffer->planestride; /* tag plane follows shape plane */
+
+ for (jj = 0; jj < h; jj++, ptr_out += fill_trans_buffer->rowstride) {
+
+ in_row_offset = ((jj + dy) % ptile->ttrans->height);
+ if (in_row_offset >= ptile->ttrans->rect.q.y)
+ continue;
+ in_row_offset -= ptile->ttrans->rect.p.y;
+ if (in_row_offset < 0)
+ continue;
+ row_ptr = ptr_in + in_row_offset * ptile->ttrans->rowstride;
+
+ /* This is the case when we have no blending. */
+ ptr_out_temp = ptr_out;
- /* Now the remainder */
- memcpy( ptr_out_temp, row_ptr, right_copy_width<<deep);
+ /* Left part */
+ memcpy( ptr_out_temp, row_ptr + left_copy_offset, left_copy_width<<deep);
+ ptr_out_temp += left_width<<deep;
+
+ /* Now the full tiles */
+
+ for ( ii = 0; ii < num_full_tiles; ii++){
+ memcpy( ptr_out_temp, row_ptr, mid_copy_width<<deep);
+ ptr_out_temp += tile_width<<deep;
+ }
+
+ /* Now the remainder */
+ memcpy( ptr_out_temp, row_ptr, right_copy_width<<deep);
+ }
}
}
@@ -952,6 +1005,7 @@ do_tile_rect_trans_blend(int xmin, int ymin, int xmax, int ymax,
}
}
+/* In this version, source data is big endian, dest is native endian */
static void
do_tile_rect_trans_blend_16(int xmin, int ymin, int xmax, int ymax,
int px, int py, const gx_color_tile *ptile,
@@ -1023,6 +1077,119 @@ do_tile_rect_trans_blend_16(int xmin, int ymin, int xmax, int ymax,
/* Data is stored in big endian, but must be processed in native */
#define GET16_BE2NATIVE(v) \
((((byte *)(v))[0]<<8) | (((byte *)(v))[1]))
+
+ /* The color values. This needs to be optimized */
+ for (kk = 0; kk < num_chan; kk++) {
+ dst[kk] = *(buff_ptr + kk * (fill_trans_buffer->planestride>>1));
+ src[kk] = GET16_BE2NATIVE(tile_ptr + kk * (ptile->ttrans->planestride>>1));
+ }
+
+ /* Blend */
+ art_pdf_composite_pixel_alpha_16(dst, src, ptile->ttrans->n_chan-1,
+ ptile->blending_mode, ptile->ttrans->n_chan-1,
+ ptile->ttrans->blending_procs, p14dev);
+
+ /* Store the color values */
+ for (kk = 0; kk < num_chan; kk++) {
+ *(buff_ptr + kk * (fill_trans_buffer->planestride>>1)) = dst[kk];
+ }
+ /* Now handle the blending of the tag. NB: dst tag_offset follows shape */
+ if (tag_offset > 0) {
+ int src_tag = GET16_BE2NATIVE(tile_ptr + (num_chan * ptile->ttrans->planestride>>1));
+ int dst_tag = *(buff_ptr + (tag_offset * fill_trans_buffer->planestride>>1));
+
+ dst_tag |= src_tag; /* simple blend combines tags */
+ *(buff_ptr + (tag_offset * fill_trans_buffer->planestride>>1)) = dst_tag;
+ }
+ }
+ }
+#undef GET16_BE2NATIVE
+
+ /* If the group we are filling has a shape plane fill that now */
+ /* Note: Since this was a virgin group push we can just blast it with
+ * 255 */
+ if (fill_trans_buffer->has_shape) {
+ buff_ptr = buff_out + fill_trans_buffer->n_chan * (fill_trans_buffer->planestride>>1);
+
+ for (jj = 0; jj < h; jj++) {
+ memset(buff_ptr, 255, w*2);
+ buff_ptr += fill_trans_buffer->rowstride>>1;
+ }
+ }
+}
+
+/* In this version, both source and dest data is big endian */
+static void
+do_tile_rect_trans_blend_16be(int xmin, int ymin, int xmax, int ymax,
+ int px, int py, const gx_color_tile *ptile,
+ gx_pattern_trans_t *fill_trans_buffer)
+{
+ int kk, jj, ii, h, w;
+ int buff_out_y_offset, buff_out_x_offset;
+ uint16_t *buff_out, *buff_in;
+ uint16_t *buff_ptr, *row_ptr_in, *row_ptr_out;
+ uint16_t *tile_ptr;
+ int in_row_offset;
+ int dx, dy;
+ uint16_t src[PDF14_MAX_PLANES];
+ uint16_t dst[PDF14_MAX_PLANES];
+ int tile_width = ptile->ttrans->width;
+ int tile_height = ptile->ttrans->height;
+ int num_chan = ptile->ttrans->n_chan; /* Includes alpha */
+ int tag_offset = fill_trans_buffer->n_chan + (fill_trans_buffer->has_shape ? 1 : 0);
+ pdf14_device *p14dev = (pdf14_device *) fill_trans_buffer->pdev14;
+
+ if (fill_trans_buffer->has_tags == 0)
+ tag_offset = 0;
+
+ buff_out_y_offset = ymin - fill_trans_buffer->rect.p.y;
+ buff_out_x_offset = xmin - fill_trans_buffer->rect.p.x;
+
+ h = ymax - ymin;
+ w = xmax - xmin;
+
+ if (h <= 0 || w <= 0) return;
+
+ /* Calc dx, dy within the entire (conceptual) input tile. */
+ dx = (xmin + px) % tile_width;
+ dy = (ymin + py) % tile_height;
+
+ buff_out = (uint16_t *)(void *)(fill_trans_buffer->transbytes +
+ buff_out_y_offset * fill_trans_buffer->rowstride +
+ buff_out_x_offset*2);
+
+ buff_in = (uint16_t *)(void *)ptile->ttrans->transbytes;
+
+ for (jj = 0; jj < h; jj++){
+
+ in_row_offset = (jj + dy) % ptile->ttrans->height;
+ if (in_row_offset >= ptile->ttrans->rect.q.y)
+ continue;
+ in_row_offset -= ptile->ttrans->rect.p.y;
+ if (in_row_offset < 0)
+ continue;
+ row_ptr_in = buff_in + in_row_offset * (ptile->ttrans->rowstride>>1);
+
+ row_ptr_out = buff_out + jj * (fill_trans_buffer->rowstride>>1);
+
+ for (ii = 0; ii < w; ii++) {
+ int x_in_offset = (dx + ii) % ptile->ttrans->width;
+
+ if (x_in_offset >= ptile->ttrans->rect.q.x)
+ continue;
+ x_in_offset -= ptile->ttrans->rect.p.x;
+ if (x_in_offset < 0)
+ continue;
+ tile_ptr = row_ptr_in + x_in_offset;
+ buff_ptr = row_ptr_out + ii;
+
+ /* We need to blend here. The blending mode from the current
+ imager state is used.
+ */
+
+ /* Data is stored in big endian, but must be processed in native */
+#define GET16_BE2NATIVE(v) \
+ ((((byte *)(v))[0]<<8) | (((byte *)(v))[1]))
#define PUT16_NATIVE2BE(p,v) \
((((byte *)(p))[0] = v>>8), (((byte *)(p))[1] = v))
@@ -1068,7 +1235,8 @@ do_tile_rect_trans_blend_16(int xmin, int ymin, int xmax, int ymax,
void
tile_rect_trans_blend(int xmin, int ymin, int xmax, int ymax,
int px, int py, const gx_color_tile *ptile,
- gx_pattern_trans_t *fill_trans_buffer)
+ gx_pattern_trans_t *fill_trans_buffer,
+ int native16)
{
pdf14_buf *buf = fill_trans_buffer->buf;
@@ -1083,12 +1251,15 @@ tile_rect_trans_blend(int xmin, int ymin, int xmax, int ymax,
if (buf->dirty.q.y < ymax)
buf->dirty.q.y = ymax;
- if (ptile->ttrans->deep)
+ if (!ptile->ttrans->deep)
+ do_tile_rect_trans_blend(xmin, ymin, xmax, ymax,
+ px, py, ptile, fill_trans_buffer);
+ else if (native16)
do_tile_rect_trans_blend_16(xmin, ymin, xmax, ymax,
px, py, ptile, fill_trans_buffer);
else
- do_tile_rect_trans_blend(xmin, ymin, xmax, ymax,
- px, py, ptile, fill_trans_buffer);
+ do_tile_rect_trans_blend_16be(xmin, ymin, xmax, ymax,
+ px, py, ptile, fill_trans_buffer);
}
/* This version does a rect fill with the transparency object */
@@ -1124,7 +1295,7 @@ gx_dc_pat_trans_fill_rectangle(const gx_device_color * pdevc, int x, int y,
#endif
code = gx_trans_pattern_fill_rect(x, y, x+w, y+h, ptile,
ptile->ttrans->fill_trans_buffer, phase,
- dev, pdevc);
+ dev, pdevc, 0);
return code;
}
@@ -1135,7 +1306,8 @@ gx_trans_pattern_fill_rect(int xmin, int ymin, int xmax, int ymax,
gx_color_tile *ptile,
gx_pattern_trans_t *fill_trans_buffer,
gs_int_point phase, gx_device *dev,
- const gx_device_color * pdevc)
+ const gx_device_color * pdevc,
+ int native16)
{
tile_fill_trans_state_t state_trans;
tile_fill_state_t state_clist_trans;
@@ -1166,7 +1338,7 @@ gx_trans_pattern_fill_rect(int xmin, int ymin, int xmax, int ymax,
ptile->ttrans->height);
tile_rect_trans_simple(xmin, ymin, xmax, ymax, px, py, ptile,
- fill_trans_buffer);
+ fill_trans_buffer, native16);
} else {
if (ptile->cdev == NULL) {
/* No clist for the pattern, but a complex case
@@ -1174,7 +1346,8 @@ gx_trans_pattern_fill_rect(int xmin, int ymin, int xmax, int ymax,
and does partial rect fills with tiles that fall into this
transformed bbox */
code = tile_by_steps_trans(&state_trans, xmin, ymin, xmax-xmin,
- ymax-ymin, fill_trans_buffer, ptile);
+ ymax-ymin, fill_trans_buffer, ptile,
+ native16);
} else {
/* clist for the trans tile. This uses the pdf14 device as a target
diff --git a/base/gxpcolor.h b/base/gxpcolor.h
index 989a163..c12fa31 100644
--- a/base/gxpcolor.h
+++ b/base/gxpcolor.h
@@ -167,7 +167,8 @@ struct gx_pattern_trans_s {
void *buf;
void (* pat_trans_fill)(int xmin, int ymin, int xmax, int ymax, int px,
int py, const gx_color_tile *ptile,
- gx_pattern_trans_t *fill_trans_buffer);
+ gx_pattern_trans_t *fill_trans_buffer,
+ int native16);
int (* image_render)(gx_image_enum * penum, const byte * buffer,
int data_x, uint w, int h, gx_device * dev);
};
@@ -336,20 +337,23 @@ int gx_trans_pattern_fill_rect(int xmin, int ymin, int xmax, int ymax,
gx_color_tile *ptile,
gx_pattern_trans_t *fill_trans_buffer,
gs_int_point phase, gx_device *dev,
- const gx_device_color * pdevc);
+ const gx_device_color * pdevc,
+ int native16);
gx_pattern_trans_t* new_pattern_trans_buff(gs_memory_t *mem);
void tile_rect_trans_simple(int xmin, int ymin, int xmax, int ymax, int px,
int py, const gx_color_tile *ptile,
- gx_pattern_trans_t *fill_trans_buffer);
+ gx_pattern_trans_t *fill_trans_buffer,
+ int native16);
/* This is used for the case when we may have overlapping tiles.
We need to get better detection for this as
it would be best to avoid doing it if not needed. */
void tile_rect_trans_blend(int xmin, int ymin, int xmax, int ymax, int px,
int py, const gx_color_tile *ptile,
- gx_pattern_trans_t *fill_trans_buffer);
+ gx_pattern_trans_t *fill_trans_buffer,
+ int native16);
/* File a colored pattern with white */
int gx_erase_colored_pattern(gs_gstate *pgs);
Summary of changes:
base/gdevp14.c | 76 ++++++++++++++----
base/gxblend.c | 4 +-
base/gxp1fill.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++++--------
base/gxpcolor.h | 12 ++-
4 files changed, 278 insertions(+), 57 deletions(-)