/* 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; }
/* 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); }