Пример #1
0
/* Fill a rectangle. */
int
gz_fill_rectangle(int x, int y, int w, int h, gx_device_color *pdevc,
  gs_state *pgs)
{	gx_color_index darker = pdevc->color1;
	gx_color_index lighter;
	gx_device *dev = pgs->device->info;
	gx_bitmap *tile;
	int code;
#ifdef DEBUG
if ( gs_debug['q'] )
	printf("[q]x=%d y=%d w=%d h=%d  c1=%ld c2=%ld htl=%d\n",
		x, y, w, h, darker, (long)pdevc->color2,
		(long)pdevc->halftone_level);
#endif
	if ( color_is_pure(pdevc) )	/* no halftoning */
	   {	return (*dev->procs->fill_rectangle)(dev, x, y, w, h, darker);
	   }
	lighter = pdevc->color2;
	tile = pdevc->tile;
	/* See if the entire transfer falls within a single tile. */
	/* This is worth a quick check, because tiling is slow. */
	if ( w <= tile->width && h <= tile->height )
	   {	int xmod = x % tile->width, ymod;
		if ( xmod + w <= tile->width &&
		     (ymod = y % tile->height) + h <= tile->height
		   )
		   {	/* Just do a copy. */
			int raster = tile->raster;
			byte *tdata = tile->data + ymod * raster;
			return (color_is_color_halftone(pdevc) ?
				(*dev->procs->copy_color)(dev, tdata,
					xmod, raster, x, y, w, h) :
				(*dev->procs->copy_mono)(dev, tdata,
					xmod, raster, x, y, w, h,
					darker, lighter));
		   }
	   }
	/* Try to tile the rectangle primitively; */
	/* if this fails, use the default implementation. */
	if ( color_is_color_halftone(pdevc) )
		darker = lighter = gx_no_color_index;
	code = (*dev->procs->tile_rectangle)(dev, tile,
		x, y, w, h, darker, lighter);
	if ( code < 0 )
	   {	/* Use the default implementation */
		code = gx_default_tile_rectangle(dev, tile,
			x, y, w, h, darker, lighter);
	   }
	return code;
}
Пример #2
0
/* Note that this also does the right thing for colored tiles. */
static int
win_ddb_tile_rectangle(gx_device * dev, const gx_tile_bitmap * tile,
      int x, int y, int w, int h, gx_color_index czero, gx_color_index cone,
		       int px, int py)
{
    fit_fill(dev, x, y, w, h);
    if (czero != gx_no_color_index && cone != gx_no_color_index) {
	fill_rect(x, y, w, h, czero);
	czero = gx_no_color_index;
    }
    if (tile->raster == bmWidthBytes && tile->size.y <= bmHeight &&
	(px | py) == 0 && cone != gx_no_color_index
	) {			/* We can do this much more efficiently */
	/* by using the internal algorithms of copy_mono */
	/* and gx_default_tile_rectangle. */
	int width = tile->size.x;
	int height = tile->size.y;
	int rwidth = tile->rep_width;
	int irx = ((rwidth & (rwidth - 1)) == 0 ?	/* power of 2 */
		   x & (rwidth - 1) :
		   x % rwidth);
	int ry = y % tile->rep_height;
	int icw = width - irx;
	int ch = height - ry;
	int ex = x + w, ey = y + h;
	int fex = ex - width, fey = ey - height;
	int cx, cy;

	select_brush((int)cone);

	if (tile->id != wdev->bm_id || tile->id == gx_no_bitmap_id) {
	    wdev->bm_id = tile->id;
	    SetBitmapBits(wdev->hbmmono,
			  (DWORD) (bmWidthBytes * tile->size.y),
			  (BYTE *) tile->data);
	}
#define copy_tile(srcx, srcy, tx, ty, tw, th)\
  BitBlt(wdev->hdcbit, tx, ty, tw, th, wdev->hdcmono, srcx, srcy, rop_write_at_1s)

	if (ch > h)
	    ch = h;
	for (cy = y;;) {
	    if (w <= icw)
		copy_tile(irx, ry, x, cy, w, ch);
	    else {
		copy_tile(irx, ry, x, cy, icw, ch);
		cx = x + icw;
		while (cx <= fex) {
		    copy_tile(0, ry, cx, cy, width, ch);
		    cx += width;
		}
		if (cx < ex) {
		    copy_tile(0, ry, cx, cy, ex - cx, ch);
		}
	    }
	    if ((cy += ch) >= ey)
		break;
	    ch = (cy > fey ? ey - cy : height);
	    ry = 0;
	}

	win_update((gx_device_win *) dev);
	return 0;
    }
    return gx_default_tile_rectangle(dev, tile, x, y, w, h, czero, cone, px, py);
}