17dd7cddfSDavid du Colombier /* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
27dd7cddfSDavid du Colombier
3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier implied.
57dd7cddfSDavid du Colombier
6*593dc095SDavid du Colombier This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier
10*593dc095SDavid du Colombier For more information about licensing, please refer to
11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier
17*593dc095SDavid du Colombier /* $Id: gxp1fill.c,v 1.6 2004/08/05 20:15:09 stefan Exp $ */
187dd7cddfSDavid du Colombier /* PatternType 1 filling algorithms */
197dd7cddfSDavid du Colombier #include "math_.h"
207dd7cddfSDavid du Colombier #include "gx.h"
217dd7cddfSDavid du Colombier #include "gserrors.h"
227dd7cddfSDavid du Colombier #include "gsrop.h"
237dd7cddfSDavid du Colombier #include "gsmatrix.h"
247dd7cddfSDavid du Colombier #include "gxcspace.h" /* for gscolor2.h */
257dd7cddfSDavid du Colombier #include "gxcolor2.h"
267dd7cddfSDavid du Colombier #include "gxdcolor.h"
277dd7cddfSDavid du Colombier #include "gxdevcli.h"
287dd7cddfSDavid du Colombier #include "gxdevmem.h"
297dd7cddfSDavid du Colombier #include "gxclip2.h"
307dd7cddfSDavid du Colombier #include "gxpcolor.h"
317dd7cddfSDavid du Colombier #include "gxp1impl.h"
327dd7cddfSDavid du Colombier
337dd7cddfSDavid du Colombier /* Define the state for tile filling. */
347dd7cddfSDavid du Colombier typedef struct tile_fill_state_s {
357dd7cddfSDavid du Colombier
367dd7cddfSDavid du Colombier /* Original arguments */
377dd7cddfSDavid du Colombier
387dd7cddfSDavid du Colombier const gx_device_color *pdevc; /* pattern color */
397dd7cddfSDavid du Colombier int x0, y0, w0, h0;
407dd7cddfSDavid du Colombier gs_logical_operation_t lop;
417dd7cddfSDavid du Colombier const gx_rop_source_t *source;
427dd7cddfSDavid du Colombier
437dd7cddfSDavid du Colombier /* Variables set at initialization */
447dd7cddfSDavid du Colombier
457dd7cddfSDavid du Colombier gx_device_tile_clip cdev;
467dd7cddfSDavid du Colombier gx_device *pcdev; /* original device or &cdev */
477dd7cddfSDavid du Colombier const gx_strip_bitmap *tmask;
487dd7cddfSDavid du Colombier gs_int_point phase;
497dd7cddfSDavid du Colombier
507dd7cddfSDavid du Colombier /* Following are only for uncolored patterns */
517dd7cddfSDavid du Colombier
527dd7cddfSDavid du Colombier dev_color_proc_fill_rectangle((*fill_rectangle));
537dd7cddfSDavid du Colombier
547dd7cddfSDavid du Colombier /* Following are only for colored patterns */
557dd7cddfSDavid du Colombier
567dd7cddfSDavid du Colombier const gx_rop_source_t *rop_source;
577dd7cddfSDavid du Colombier gx_device *orig_dev;
587dd7cddfSDavid du Colombier int xoff, yoff; /* set dynamically */
597dd7cddfSDavid du Colombier
607dd7cddfSDavid du Colombier } tile_fill_state_t;
617dd7cddfSDavid du Colombier
627dd7cddfSDavid du Colombier /* Initialize the filling state. */
637dd7cddfSDavid du Colombier private int
tile_fill_init(tile_fill_state_t * ptfs,const gx_device_color * pdevc,gx_device * dev,bool set_mask_phase)647dd7cddfSDavid du Colombier tile_fill_init(tile_fill_state_t * ptfs, const gx_device_color * pdevc,
657dd7cddfSDavid du Colombier gx_device * dev, bool set_mask_phase)
667dd7cddfSDavid du Colombier {
677dd7cddfSDavid du Colombier gx_color_tile *m_tile = pdevc->mask.m_tile;
687dd7cddfSDavid du Colombier int px, py;
697dd7cddfSDavid du Colombier
707dd7cddfSDavid du Colombier ptfs->pdevc = pdevc;
717dd7cddfSDavid du Colombier if (m_tile == 0) { /* no clipping */
727dd7cddfSDavid du Colombier ptfs->pcdev = dev;
737dd7cddfSDavid du Colombier ptfs->phase = pdevc->phase;
747dd7cddfSDavid du Colombier return 0;
757dd7cddfSDavid du Colombier }
767dd7cddfSDavid du Colombier ptfs->pcdev = (gx_device *) & ptfs->cdev;
777dd7cddfSDavid du Colombier ptfs->tmask = &m_tile->tmask;
787dd7cddfSDavid du Colombier ptfs->phase.x = pdevc->mask.m_phase.x;
797dd7cddfSDavid du Colombier ptfs->phase.y = pdevc->mask.m_phase.y;
807dd7cddfSDavid du Colombier /*
817dd7cddfSDavid du Colombier * For non-simple tiles, the phase will be reset on each pass of the
827dd7cddfSDavid du Colombier * tile_by_steps loop, but for simple tiles, we must set it now.
837dd7cddfSDavid du Colombier */
847dd7cddfSDavid du Colombier if (set_mask_phase && m_tile->is_simple) {
857dd7cddfSDavid du Colombier px = imod(-(int)(m_tile->step_matrix.tx - ptfs->phase.x + 0.5),
867dd7cddfSDavid du Colombier m_tile->tmask.rep_width);
877dd7cddfSDavid du Colombier py = imod(-(int)(m_tile->step_matrix.ty - ptfs->phase.y + 0.5),
887dd7cddfSDavid du Colombier m_tile->tmask.rep_height);
897dd7cddfSDavid du Colombier } else
907dd7cddfSDavid du Colombier px = py = 0;
91*593dc095SDavid du Colombier return tile_clip_initialize(&ptfs->cdev, ptfs->tmask, dev, px, py, dev->memory);
92*593dc095SDavid du Colombier /* leak ? was NULL memoryptr */
937dd7cddfSDavid du Colombier }
947dd7cddfSDavid du Colombier
957dd7cddfSDavid du Colombier /*
967dd7cddfSDavid du Colombier * Fill with non-standard X and Y stepping.
977dd7cddfSDavid du Colombier * ptile is pdevc->colors.pattern.{m,p}_tile.
987dd7cddfSDavid du Colombier * tbits_or_tmask is whichever of tbits and tmask is supplying
997dd7cddfSDavid du Colombier * the tile size.
1007dd7cddfSDavid du Colombier * This implementation could be sped up considerably!
1017dd7cddfSDavid du Colombier */
1027dd7cddfSDavid du Colombier private int
tile_by_steps(tile_fill_state_t * ptfs,int x0,int y0,int w0,int h0,const gx_color_tile * ptile,const gx_strip_bitmap * tbits_or_tmask,int (* fill_proc)(const tile_fill_state_t * ptfs,int x,int y,int w,int h))1037dd7cddfSDavid du Colombier tile_by_steps(tile_fill_state_t * ptfs, int x0, int y0, int w0, int h0,
1047dd7cddfSDavid du Colombier const gx_color_tile * ptile,
1057dd7cddfSDavid du Colombier const gx_strip_bitmap * tbits_or_tmask,
106*593dc095SDavid du Colombier int (*fill_proc) (const tile_fill_state_t * ptfs,
107*593dc095SDavid du Colombier int x, int y, int w, int h))
1087dd7cddfSDavid du Colombier {
1097dd7cddfSDavid du Colombier int x1 = x0 + w0, y1 = y0 + h0;
1107dd7cddfSDavid du Colombier int i0, i1, j0, j1, i, j;
1117dd7cddfSDavid du Colombier gs_matrix step_matrix; /* translated by phase */
1127dd7cddfSDavid du Colombier int code;
1137dd7cddfSDavid du Colombier
1147dd7cddfSDavid du Colombier ptfs->x0 = x0, ptfs->w0 = w0;
1157dd7cddfSDavid du Colombier ptfs->y0 = y0, ptfs->h0 = h0;
1167dd7cddfSDavid du Colombier step_matrix = ptile->step_matrix;
1177dd7cddfSDavid du Colombier step_matrix.tx -= ptfs->phase.x;
1187dd7cddfSDavid du Colombier step_matrix.ty -= ptfs->phase.y;
1197dd7cddfSDavid du Colombier {
1207dd7cddfSDavid du Colombier gs_rect bbox; /* bounding box in device space */
1217dd7cddfSDavid du Colombier gs_rect ibbox; /* bounding box in stepping space */
1227dd7cddfSDavid du Colombier double bbw = ptile->bbox.q.x - ptile->bbox.p.x;
1237dd7cddfSDavid du Colombier double bbh = ptile->bbox.q.y - ptile->bbox.p.y;
1247dd7cddfSDavid du Colombier double u0, v0, u1, v1;
1257dd7cddfSDavid du Colombier
1267dd7cddfSDavid du Colombier bbox.p.x = x0, bbox.p.y = y0;
1277dd7cddfSDavid du Colombier bbox.q.x = x1, bbox.q.y = y1;
1287dd7cddfSDavid du Colombier gs_bbox_transform_inverse(&bbox, &step_matrix, &ibbox);
1297dd7cddfSDavid du Colombier if_debug10('T',
1307dd7cddfSDavid du Colombier "[T]x,y=(%d,%d) w,h=(%d,%d) => (%g,%g),(%g,%g), offset=(%g,%g)\n",
1317dd7cddfSDavid du Colombier x0, y0, w0, h0,
1327dd7cddfSDavid du Colombier ibbox.p.x, ibbox.p.y, ibbox.q.x, ibbox.q.y,
1337dd7cddfSDavid du Colombier step_matrix.tx, step_matrix.ty);
1347dd7cddfSDavid du Colombier /*
1357dd7cddfSDavid du Colombier * If the pattern is partly transparent and XStep/YStep is smaller
1367dd7cddfSDavid du Colombier * than the device space BBox, we need to ensure that we cover
1377dd7cddfSDavid du Colombier * each pixel of the rectangle being filled with *every* pattern
1387dd7cddfSDavid du Colombier * that overlaps it, not just *some* pattern copy.
1397dd7cddfSDavid du Colombier */
1407dd7cddfSDavid du Colombier u0 = ibbox.p.x - max(ptile->bbox.p.x, 0) - 0.000001;
1417dd7cddfSDavid du Colombier v0 = ibbox.p.y - max(ptile->bbox.p.y, 0) - 0.000001;
1427dd7cddfSDavid du Colombier u1 = ibbox.q.x - min(ptile->bbox.q.x, 0) + 0.000001;
1437dd7cddfSDavid du Colombier v1 = ibbox.q.y - min(ptile->bbox.q.y, 0) + 0.000001;
1447dd7cddfSDavid du Colombier if (!ptile->is_simple)
1457dd7cddfSDavid du Colombier u0 -= bbw, v0 -= bbh, u1 += bbw, v1 += bbh;
1467dd7cddfSDavid du Colombier i0 = (int)floor(u0);
1477dd7cddfSDavid du Colombier j0 = (int)floor(v0);
1487dd7cddfSDavid du Colombier i1 = (int)ceil(u1);
1497dd7cddfSDavid du Colombier j1 = (int)ceil(v1);
1507dd7cddfSDavid du Colombier }
1517dd7cddfSDavid du Colombier if_debug4('T', "[T]i=(%d,%d) j=(%d,%d)\n", i0, i1, j0, j1);
1527dd7cddfSDavid du Colombier for (i = i0; i < i1; i++)
1537dd7cddfSDavid du Colombier for (j = j0; j < j1; j++) {
1547dd7cddfSDavid du Colombier int x = (int)(step_matrix.xx * i +
1557dd7cddfSDavid du Colombier step_matrix.yx * j + step_matrix.tx);
1567dd7cddfSDavid du Colombier int y = (int)(step_matrix.xy * i +
1577dd7cddfSDavid du Colombier step_matrix.yy * j + step_matrix.ty);
1587dd7cddfSDavid du Colombier int w = tbits_or_tmask->size.x;
1597dd7cddfSDavid du Colombier int h = tbits_or_tmask->size.y;
1607dd7cddfSDavid du Colombier int xoff, yoff;
1617dd7cddfSDavid du Colombier
1627dd7cddfSDavid du Colombier if_debug4('T', "[T]i=%d j=%d x,y=(%d,%d)", i, j, x, y);
1637dd7cddfSDavid du Colombier if (x < x0)
1647dd7cddfSDavid du Colombier xoff = x0 - x, x = x0, w -= xoff;
1657dd7cddfSDavid du Colombier else
1667dd7cddfSDavid du Colombier xoff = 0;
1677dd7cddfSDavid du Colombier if (y < y0)
1687dd7cddfSDavid du Colombier yoff = y0 - y, y = y0, h -= yoff;
1697dd7cddfSDavid du Colombier else
1707dd7cddfSDavid du Colombier yoff = 0;
1717dd7cddfSDavid du Colombier if (x + w > x1)
1727dd7cddfSDavid du Colombier w = x1 - x;
1737dd7cddfSDavid du Colombier if (y + h > y1)
1747dd7cddfSDavid du Colombier h = y1 - y;
1757dd7cddfSDavid du Colombier if_debug6('T', "=>(%d,%d) w,h=(%d,%d) x/yoff=(%d,%d)\n",
1767dd7cddfSDavid du Colombier x, y, w, h, xoff, yoff);
1777dd7cddfSDavid du Colombier if (w > 0 && h > 0) {
1787dd7cddfSDavid du Colombier if (ptfs->pcdev == (gx_device *) & ptfs->cdev)
1797dd7cddfSDavid du Colombier tile_clip_set_phase(&ptfs->cdev,
1807dd7cddfSDavid du Colombier imod(xoff - x, ptfs->tmask->rep_width),
1817dd7cddfSDavid du Colombier imod(yoff - y, ptfs->tmask->rep_height));
1827dd7cddfSDavid du Colombier /* Set the offsets for colored pattern fills */
1837dd7cddfSDavid du Colombier ptfs->xoff = xoff;
1847dd7cddfSDavid du Colombier ptfs->yoff = yoff;
1857dd7cddfSDavid du Colombier code = (*fill_proc) (ptfs, x, y, w, h);
1867dd7cddfSDavid du Colombier if (code < 0)
1877dd7cddfSDavid du Colombier return code;
1887dd7cddfSDavid du Colombier }
1897dd7cddfSDavid du Colombier }
1907dd7cddfSDavid du Colombier return 0;
1917dd7cddfSDavid du Colombier }
1927dd7cddfSDavid du Colombier
1937dd7cddfSDavid du Colombier /* Fill a rectangle with a colored Pattern. */
1947dd7cddfSDavid du Colombier /* Note that we treat this as "texture" for RasterOp. */
1957dd7cddfSDavid du Colombier private int
tile_colored_fill(const tile_fill_state_t * ptfs,int x,int y,int w,int h)1967dd7cddfSDavid du Colombier tile_colored_fill(const tile_fill_state_t * ptfs,
1977dd7cddfSDavid du Colombier int x, int y, int w, int h)
1987dd7cddfSDavid du Colombier {
1997dd7cddfSDavid du Colombier gx_color_tile *ptile = ptfs->pdevc->colors.pattern.p_tile;
2007dd7cddfSDavid du Colombier gs_logical_operation_t lop = ptfs->lop;
2017dd7cddfSDavid du Colombier const gx_rop_source_t *source = ptfs->source;
2027dd7cddfSDavid du Colombier const gx_rop_source_t *rop_source = ptfs->rop_source;
2037dd7cddfSDavid du Colombier gx_device *dev = ptfs->orig_dev;
2047dd7cddfSDavid du Colombier int xoff = ptfs->xoff, yoff = ptfs->yoff;
2057dd7cddfSDavid du Colombier gx_strip_bitmap *bits = &ptile->tbits;
2067dd7cddfSDavid du Colombier const byte *data = bits->data;
2077dd7cddfSDavid du Colombier bool full_transfer = (w == ptfs->w0 && h == ptfs->h0);
2087dd7cddfSDavid du Colombier gx_bitmap_id source_id =
2097dd7cddfSDavid du Colombier (full_transfer ? rop_source->id : gx_no_bitmap_id);
2107dd7cddfSDavid du Colombier int code;
2117dd7cddfSDavid du Colombier
2127dd7cddfSDavid du Colombier if (source == NULL && lop_no_S_is_T(lop))
2137dd7cddfSDavid du Colombier code = (*dev_proc(ptfs->pcdev, copy_color))
2147dd7cddfSDavid du Colombier (ptfs->pcdev, data + bits->raster * yoff, xoff,
2157dd7cddfSDavid du Colombier bits->raster,
2167dd7cddfSDavid du Colombier (full_transfer ? bits->id : gx_no_bitmap_id),
2177dd7cddfSDavid du Colombier x, y, w, h);
2187dd7cddfSDavid du Colombier else {
2197dd7cddfSDavid du Colombier gx_strip_bitmap data_tile;
2207dd7cddfSDavid du Colombier
2217dd7cddfSDavid du Colombier data_tile.data = (byte *) data; /* actually const */
2227dd7cddfSDavid du Colombier data_tile.raster = bits->raster;
2237dd7cddfSDavid du Colombier data_tile.size.x = data_tile.rep_width = ptile->tbits.size.x;
2247dd7cddfSDavid du Colombier data_tile.size.y = data_tile.rep_height = ptile->tbits.size.y;
2257dd7cddfSDavid du Colombier data_tile.id = bits->id;
2267dd7cddfSDavid du Colombier data_tile.shift = data_tile.rep_shift = 0;
2277dd7cddfSDavid du Colombier code = (*dev_proc(dev, strip_copy_rop))
2287dd7cddfSDavid du Colombier (dev,
2297dd7cddfSDavid du Colombier rop_source->sdata + (y - ptfs->y0) * rop_source->sraster,
2307dd7cddfSDavid du Colombier rop_source->sourcex + (x - ptfs->x0),
2317dd7cddfSDavid du Colombier rop_source->sraster, source_id,
2327dd7cddfSDavid du Colombier (rop_source->use_scolors ? rop_source->scolors : NULL),
2337dd7cddfSDavid du Colombier &data_tile, NULL,
2347dd7cddfSDavid du Colombier x, y, w, h,
2357dd7cddfSDavid du Colombier imod(xoff - x, data_tile.rep_width),
2367dd7cddfSDavid du Colombier imod(yoff - y, data_tile.rep_height),
2377dd7cddfSDavid du Colombier lop);
2387dd7cddfSDavid du Colombier }
2397dd7cddfSDavid du Colombier return code;
2407dd7cddfSDavid du Colombier }
2417dd7cddfSDavid du Colombier int
gx_dc_pattern_fill_rectangle(const gx_device_color * pdevc,int x,int y,int w,int h,gx_device * dev,gs_logical_operation_t lop,const gx_rop_source_t * source)2427dd7cddfSDavid du Colombier gx_dc_pattern_fill_rectangle(const gx_device_color * pdevc, int x, int y,
2437dd7cddfSDavid du Colombier int w, int h, gx_device * dev,
2447dd7cddfSDavid du Colombier gs_logical_operation_t lop,
2457dd7cddfSDavid du Colombier const gx_rop_source_t * source)
2467dd7cddfSDavid du Colombier {
2477dd7cddfSDavid du Colombier gx_color_tile *ptile = pdevc->colors.pattern.p_tile;
2487dd7cddfSDavid du Colombier const gx_rop_source_t *rop_source = source;
2497dd7cddfSDavid du Colombier gx_rop_source_t no_source;
2507dd7cddfSDavid du Colombier gx_strip_bitmap *bits;
2517dd7cddfSDavid du Colombier tile_fill_state_t state;
2527dd7cddfSDavid du Colombier int code;
2537dd7cddfSDavid du Colombier
2547dd7cddfSDavid du Colombier if (ptile == 0) /* null pattern */
2557dd7cddfSDavid du Colombier return 0;
2567dd7cddfSDavid du Colombier if (rop_source == NULL)
2577dd7cddfSDavid du Colombier set_rop_no_source(rop_source, no_source, dev);
2587dd7cddfSDavid du Colombier bits = &ptile->tbits;
2597dd7cddfSDavid du Colombier code = tile_fill_init(&state, pdevc, dev, false);
2607dd7cddfSDavid du Colombier if (code < 0)
2617dd7cddfSDavid du Colombier return code;
2627dd7cddfSDavid du Colombier if (ptile->is_simple) {
2637dd7cddfSDavid du Colombier int px =
2647dd7cddfSDavid du Colombier imod(-(int)(ptile->step_matrix.tx - state.phase.x + 0.5),
2657dd7cddfSDavid du Colombier bits->rep_width);
2667dd7cddfSDavid du Colombier int py =
2677dd7cddfSDavid du Colombier imod(-(int)(ptile->step_matrix.ty - state.phase.y + 0.5),
2687dd7cddfSDavid du Colombier bits->rep_height);
2697dd7cddfSDavid du Colombier
2707dd7cddfSDavid du Colombier if (state.pcdev != dev)
2717dd7cddfSDavid du Colombier tile_clip_set_phase(&state.cdev, px, py);
2727dd7cddfSDavid du Colombier if (source == NULL && lop_no_S_is_T(lop))
2737dd7cddfSDavid du Colombier code = (*dev_proc(state.pcdev, strip_tile_rectangle))
2747dd7cddfSDavid du Colombier (state.pcdev, bits, x, y, w, h,
2757dd7cddfSDavid du Colombier gx_no_color_index, gx_no_color_index, px, py);
2767dd7cddfSDavid du Colombier else
2777dd7cddfSDavid du Colombier code = (*dev_proc(state.pcdev, strip_copy_rop))
2787dd7cddfSDavid du Colombier (state.pcdev,
2797dd7cddfSDavid du Colombier rop_source->sdata, rop_source->sourcex,
2807dd7cddfSDavid du Colombier rop_source->sraster, rop_source->id,
2817dd7cddfSDavid du Colombier (rop_source->use_scolors ? rop_source->scolors : NULL),
2827dd7cddfSDavid du Colombier bits, NULL, x, y, w, h, px, py, lop);
2837dd7cddfSDavid du Colombier } else {
2847dd7cddfSDavid du Colombier state.lop = lop;
2857dd7cddfSDavid du Colombier state.source = source;
2867dd7cddfSDavid du Colombier state.rop_source = rop_source;
2877dd7cddfSDavid du Colombier state.orig_dev = dev;
2887dd7cddfSDavid du Colombier code = tile_by_steps(&state, x, y, w, h, ptile,
2897dd7cddfSDavid du Colombier &ptile->tbits, tile_colored_fill);
2907dd7cddfSDavid du Colombier }
2917dd7cddfSDavid du Colombier return code;
2927dd7cddfSDavid du Colombier }
2937dd7cddfSDavid du Colombier
2947dd7cddfSDavid du Colombier /* Fill a rectangle with an uncolored Pattern. */
2957dd7cddfSDavid du Colombier /* Note that we treat this as "texture" for RasterOp. */
2967dd7cddfSDavid du Colombier private int
tile_masked_fill(const tile_fill_state_t * ptfs,int x,int y,int w,int h)2977dd7cddfSDavid du Colombier tile_masked_fill(const tile_fill_state_t * ptfs,
2987dd7cddfSDavid du Colombier int x, int y, int w, int h)
2997dd7cddfSDavid du Colombier {
3007dd7cddfSDavid du Colombier if (ptfs->source == NULL)
3017dd7cddfSDavid du Colombier return (*ptfs->fill_rectangle)
3027dd7cddfSDavid du Colombier (ptfs->pdevc, x, y, w, h, ptfs->pcdev, ptfs->lop, NULL);
3037dd7cddfSDavid du Colombier else {
3047dd7cddfSDavid du Colombier const gx_rop_source_t *source = ptfs->source;
3057dd7cddfSDavid du Colombier gx_rop_source_t step_source;
3067dd7cddfSDavid du Colombier
3077dd7cddfSDavid du Colombier step_source.sdata = source->sdata + (y - ptfs->y0) * source->sraster;
3087dd7cddfSDavid du Colombier step_source.sourcex = source->sourcex + (x - ptfs->x0);
3097dd7cddfSDavid du Colombier step_source.sraster = source->sraster;
3107dd7cddfSDavid du Colombier step_source.id = (w == ptfs->w0 && h == ptfs->h0 ?
3117dd7cddfSDavid du Colombier source->id : gx_no_bitmap_id);
3127dd7cddfSDavid du Colombier step_source.scolors[0] = source->scolors[0];
3137dd7cddfSDavid du Colombier step_source.scolors[1] = source->scolors[1];
3147dd7cddfSDavid du Colombier step_source.use_scolors = source->use_scolors;
3157dd7cddfSDavid du Colombier return (*ptfs->fill_rectangle)
3167dd7cddfSDavid du Colombier (ptfs->pdevc, x, y, w, h, ptfs->pcdev, ptfs->lop, &step_source);
3177dd7cddfSDavid du Colombier }
3187dd7cddfSDavid du Colombier }
3197dd7cddfSDavid du Colombier int
gx_dc_pure_masked_fill_rect(const gx_device_color * pdevc,int x,int y,int w,int h,gx_device * dev,gs_logical_operation_t lop,const gx_rop_source_t * source)3207dd7cddfSDavid du Colombier gx_dc_pure_masked_fill_rect(const gx_device_color * pdevc,
3217dd7cddfSDavid du Colombier int x, int y, int w, int h, gx_device * dev,
3227dd7cddfSDavid du Colombier gs_logical_operation_t lop,
3237dd7cddfSDavid du Colombier const gx_rop_source_t * source)
3247dd7cddfSDavid du Colombier {
3257dd7cddfSDavid du Colombier gx_color_tile *ptile = pdevc->mask.m_tile;
3267dd7cddfSDavid du Colombier tile_fill_state_t state;
3277dd7cddfSDavid du Colombier int code;
3287dd7cddfSDavid du Colombier
3297dd7cddfSDavid du Colombier /*
3307dd7cddfSDavid du Colombier * This routine should never be called if there is no masking,
3317dd7cddfSDavid du Colombier * but we leave the checks below just in case.
3327dd7cddfSDavid du Colombier */
3337dd7cddfSDavid du Colombier code = tile_fill_init(&state, pdevc, dev, true);
3347dd7cddfSDavid du Colombier if (code < 0)
3357dd7cddfSDavid du Colombier return code;
3367dd7cddfSDavid du Colombier if (state.pcdev == dev || ptile->is_simple)
3377dd7cddfSDavid du Colombier return (*gx_dc_type_data_pure.fill_rectangle)
3387dd7cddfSDavid du Colombier (pdevc, x, y, w, h, state.pcdev, lop, source);
3397dd7cddfSDavid du Colombier else {
3407dd7cddfSDavid du Colombier state.lop = lop;
3417dd7cddfSDavid du Colombier state.source = source;
3427dd7cddfSDavid du Colombier state.fill_rectangle = gx_dc_type_data_pure.fill_rectangle;
3437dd7cddfSDavid du Colombier return tile_by_steps(&state, x, y, w, h, ptile, &ptile->tmask,
3447dd7cddfSDavid du Colombier tile_masked_fill);
3457dd7cddfSDavid du Colombier }
3467dd7cddfSDavid du Colombier }
3477dd7cddfSDavid du Colombier int
gx_dc_binary_masked_fill_rect(const gx_device_color * pdevc,int x,int y,int w,int h,gx_device * dev,gs_logical_operation_t lop,const gx_rop_source_t * source)3487dd7cddfSDavid du Colombier gx_dc_binary_masked_fill_rect(const gx_device_color * pdevc,
3497dd7cddfSDavid du Colombier int x, int y, int w, int h, gx_device * dev,
3507dd7cddfSDavid du Colombier gs_logical_operation_t lop,
3517dd7cddfSDavid du Colombier const gx_rop_source_t * source)
3527dd7cddfSDavid du Colombier {
3537dd7cddfSDavid du Colombier gx_color_tile *ptile = pdevc->mask.m_tile;
3547dd7cddfSDavid du Colombier tile_fill_state_t state;
3557dd7cddfSDavid du Colombier int code;
3567dd7cddfSDavid du Colombier
3577dd7cddfSDavid du Colombier code = tile_fill_init(&state, pdevc, dev, true);
3587dd7cddfSDavid du Colombier if (code < 0)
3597dd7cddfSDavid du Colombier return code;
3607dd7cddfSDavid du Colombier if (state.pcdev == dev || ptile->is_simple)
3617dd7cddfSDavid du Colombier return (*gx_dc_type_data_ht_binary.fill_rectangle)
3627dd7cddfSDavid du Colombier (pdevc, x, y, w, h, state.pcdev, lop, source);
3637dd7cddfSDavid du Colombier else {
3647dd7cddfSDavid du Colombier state.lop = lop;
3657dd7cddfSDavid du Colombier state.source = source;
3667dd7cddfSDavid du Colombier state.fill_rectangle = gx_dc_type_data_ht_binary.fill_rectangle;
3677dd7cddfSDavid du Colombier return tile_by_steps(&state, x, y, w, h, ptile, &ptile->tmask,
3687dd7cddfSDavid du Colombier tile_masked_fill);
3697dd7cddfSDavid du Colombier }
3707dd7cddfSDavid du Colombier }
3717dd7cddfSDavid du Colombier int
gx_dc_colored_masked_fill_rect(const gx_device_color * pdevc,int x,int y,int w,int h,gx_device * dev,gs_logical_operation_t lop,const gx_rop_source_t * source)3727dd7cddfSDavid du Colombier gx_dc_colored_masked_fill_rect(const gx_device_color * pdevc,
3737dd7cddfSDavid du Colombier int x, int y, int w, int h, gx_device * dev,
3747dd7cddfSDavid du Colombier gs_logical_operation_t lop,
3757dd7cddfSDavid du Colombier const gx_rop_source_t * source)
3767dd7cddfSDavid du Colombier {
3777dd7cddfSDavid du Colombier gx_color_tile *ptile = pdevc->mask.m_tile;
3787dd7cddfSDavid du Colombier tile_fill_state_t state;
3797dd7cddfSDavid du Colombier int code;
3807dd7cddfSDavid du Colombier
3817dd7cddfSDavid du Colombier code = tile_fill_init(&state, pdevc, dev, true);
3827dd7cddfSDavid du Colombier if (code < 0)
3837dd7cddfSDavid du Colombier return code;
3847dd7cddfSDavid du Colombier if (state.pcdev == dev || ptile->is_simple)
3857dd7cddfSDavid du Colombier return (*gx_dc_type_data_ht_colored.fill_rectangle)
3867dd7cddfSDavid du Colombier (pdevc, x, y, w, h, state.pcdev, lop, source);
3877dd7cddfSDavid du Colombier else {
3887dd7cddfSDavid du Colombier state.lop = lop;
3897dd7cddfSDavid du Colombier state.source = source;
3907dd7cddfSDavid du Colombier state.fill_rectangle = gx_dc_type_data_ht_colored.fill_rectangle;
3917dd7cddfSDavid du Colombier return tile_by_steps(&state, x, y, w, h, ptile, &ptile->tmask,
3927dd7cddfSDavid du Colombier tile_masked_fill);
3937dd7cddfSDavid du Colombier }
3947dd7cddfSDavid du Colombier }
395