/* Get the device parameters. */ int gs_get_device_or_hw_params(gx_device * orig_dev, gs_param_list * plist, bool is_hardware) { /* * We must be prepared to copy the device if it is the read-only * prototype. */ gx_device *dev; int code; if (orig_dev->memory) dev = orig_dev; else { code = gs_copydevice(&dev, orig_dev, plist->memory); if (code < 0) return code; } gx_device_set_procs(dev); fill_dev_proc(dev, get_params, gx_default_get_params); fill_dev_proc(dev, get_page_device, gx_default_get_page_device); fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits); code = (is_hardware ? (*dev_proc(dev, get_hardware_params)) (dev, plist) : (*dev_proc(dev, get_params)) (dev, plist)); if (dev != orig_dev) gx_device_retain(dev, false); /* frees the copy */ return code; }
/* * The default implementation for non-memory devices uses get_bits_rectangle * to read out the pixels, the memory device implementation to do the * operation, and copy_color to write the pixels back. */ int gx_default_strip_copy_rop(gx_device * dev, const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, const gx_color_index * scolors, const gx_strip_bitmap * textures, const gx_color_index * tcolors, int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop) { int depth = dev->color_info.depth; gs_memory_t *mem = dev->memory; const gx_device_memory *mdproto = gdev_mem_device_for_bits(depth); gx_device_memory mdev; uint draster; byte *row = 0; gs_int_rect rect; int max_height; int block_height; int code; int py; #ifdef DEBUG if (gs_debug_c('b')) trace_copy_rop("gx_default_strip_copy_rop", dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); #endif if (mdproto == 0) return_error(gs_error_rangecheck); if (sdata == 0) { fit_fill(dev, x, y, width, height); } else { fit_copy(dev, sdata, sourcex, sraster, id, x, y, width, height); } draster = bitmap_raster(width * depth); max_height = max_rop_bitmap / draster; if (max_height == 0) max_height = 1; block_height = min(height, max_height); gs_make_mem_device(&mdev, mdproto, mem, -1, dev); gx_device_retain((gx_device *)&mdev, true); /* prevent freeing */ mdev.width = width; mdev.height = block_height; mdev.bitmap_memory = mem; mdev.color_info = dev->color_info; code = (*dev_proc(&mdev, open_device))((gx_device *)&mdev); if (code < 0) return code; if (rop3_uses_D(gs_transparent_rop(lop))) { row = gs_alloc_bytes(mem, draster * block_height, "copy_rop row"); if (row == 0) { code = gs_note_error(gs_error_VMerror); goto out; } } rect.p.x = x; rect.q.x = x + width; for (py = y; py < y + height; py += block_height) { if (block_height > y + height - py) block_height = y + height - py; rect.p.y = py; rect.q.y = py + block_height; if (row /*uses_d*/) { gs_get_bits_params_t bit_params; bit_params.options = GB_COLORS_NATIVE | GB_ALPHA_NONE | GB_DEPTH_ALL | GB_PACKING_CHUNKY | GB_RETURN_ALL | GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_OFFSET_ANY | GB_RASTER_STANDARD; bit_params.data[0] = row; bit_params.x_offset = 0; code = (*dev_proc(dev, get_bits_rectangle)) (dev, &rect, &bit_params, NULL); if (code < 0) break; code = (*dev_proc(&mdev, copy_color)) ((gx_device *)&mdev, bit_params.data[0], bit_params.x_offset, draster, gx_no_bitmap_id, 0, 0, width, block_height); if (code < 0) return code; } code = (*dev_proc(&mdev, strip_copy_rop)) ((gx_device *)&mdev, sdata + (py - y) * sraster, sourcex, sraster, gx_no_bitmap_id, scolors, textures, tcolors, 0, 0, width, block_height, phase_x + x, phase_y + py, lop); if (code < 0) break; code = (*dev_proc(dev, copy_color)) (dev, scan_line_base(&mdev, 0), 0, draster, gx_no_bitmap_id, x, py, width, block_height); if (code < 0) break; } out: gs_free_object(mem, row, "copy_rop row"); (*dev_proc(&mdev, close_device))((gx_device *)&mdev); return code; }