/* Initialize an enumerator for a general image. penum->memory must be initialized in advance. */ int gs_image_enum_init(gs_image_enum * penum, gx_image_enum_common_t * pie, const gs_data_image_t * pim, gs_state *pgs) { pgs->device->sgr.stroke_stored = false; return gs_image_common_init(penum, pie, pim, (pgs->in_charpath ? NULL : gs_currentdevice_inline(pgs))); }
/* - .endform - */ static int zendform(i_ctx_t *i_ctx_p) { gx_device *cdev = gs_currentdevice_inline(igs); int code; code = dev_proc(cdev, dev_spec_op)(cdev, gxdso_form_end, 0, 0); return code; }
/* Release an alpha buffer. */ static int alpha_buffer_release(gs_state * pgs, bool newpath) { gx_device_memory *mdev = (gx_device_memory *) gs_currentdevice_inline(pgs); int code = (*dev_proc(mdev, close_device)) ((gx_device *) mdev); if (code >= 0) scale_paths(pgs, -mdev->log2_scale.x, -mdev->log2_scale.y, !(newpath && !gx_path_is_shared(pgs->path))); /* Reference counting will free mdev. */ gx_set_device_only(pgs, mdev->target); return code; }
static int alpha_buffer_init(gs_state * pgs, fixed extra_x, fixed extra_y, int alpha_bits, bool devn) { gx_device *dev = gs_currentdevice_inline(pgs); int log2_alpha_bits = ilog2(alpha_bits); gs_fixed_rect bbox; gs_int_rect ibox; uint width, raster, band_space; uint height; gs_log2_scale_point log2_scale; gs_memory_t *mem; gx_device_memory *mdev; log2_scale.x = log2_scale.y = log2_alpha_bits; gx_path_bbox(pgs->path, &bbox); ibox.p.x = fixed2int(bbox.p.x - extra_x) - 1; ibox.p.y = fixed2int(bbox.p.y - extra_y) - 1; ibox.q.x = fixed2int_ceiling(bbox.q.x + extra_x) + 1; ibox.q.y = fixed2int_ceiling(bbox.q.y + extra_y) + 1; width = (ibox.q.x - ibox.p.x) << log2_scale.x; raster = bitmap_raster(width); band_space = raster << log2_scale.y; height = (abuf_nominal / band_space) << log2_scale.y; if (height == 0) height = 1 << log2_scale.y; mem = pgs->memory; mdev = gs_alloc_struct(mem, gx_device_memory, &st_device_memory, "alpha_buffer_init"); if (mdev == 0) return 0; /* if no room, don't buffer */ /* We may have to update the marking parameters if we have a pdf14 device as our target. Need to do while dev is still active in pgs */ if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, NULL, 0) > 0) { gs_update_trans_marking_params(pgs); } gs_make_mem_abuf_device(mdev, mem, dev, &log2_scale, alpha_bits, ibox.p.x << log2_scale.x, devn); mdev->width = width; mdev->height = height; mdev->bitmap_memory = mem; if ((*dev_proc(mdev, open_device)) ((gx_device *) mdev) < 0) { /* No room for bits, punt. */ gs_free_object(mem, mdev, "alpha_buffer_init"); return 0; } gx_set_device_only(pgs, (gx_device *) mdev); scale_paths(pgs, log2_scale.x, log2_scale.y, true); return 1; }
/* * Determine the number of bits of alpha buffer for a stroke or fill. * We should do alpha buffering iff this value is >1. */ static int alpha_buffer_bits(gs_state * pgs) { gx_device *dev; if (!color_is_pure(pgs->dev_color)) return 0; dev = gs_currentdevice_inline(pgs); if (gs_device_is_abuf(dev)) { /* We're already writing into an alpha buffer. */ return 0; } return (*dev_proc(dev, get_alpha_bits)) (dev, (pgs->in_cachedevice ? go_text : go_graphics)); }
/* * <int> .repeatform - */ static int zrepeatform(i_ctx_t *i_ctx_p) { os_ptr op = osp; gx_device *cdev = gs_currentdevice_inline(igs); int code; gs_form_template_t tmplate; float BBox[4], Matrix[6]; check_type(*op, t_integer); code = read_matrix(imemory, op - 2, &tmplate.CTM); if (code < 0) return code; code = dict_floats_param(imemory, op - 1, "BBox", 4, BBox, NULL); if (code < 0) return code; if (code == 0) return_error(gs_error_undefined); tmplate.BBox.p.x = BBox[0]; tmplate.BBox.p.y = BBox[1]; code = dict_floats_param(imemory, op - 1, "Matrix", 6, Matrix, NULL); if (code < 0) return code; if (code == 0) return_error(gs_error_undefined); tmplate.form_matrix.xx = Matrix[0]; tmplate.form_matrix.xy = Matrix[1]; tmplate.form_matrix.yx = Matrix[2]; tmplate.form_matrix.yy = Matrix[3]; tmplate.form_matrix.tx = Matrix[4]; tmplate.form_matrix.ty = Matrix[5]; tmplate.pcpath = igs->clip_path; tmplate.FormID = op->value.intval; code = dev_proc(cdev, dev_spec_op)(cdev, gxdso_repeat_form, &tmplate, sizeof(gs_form_template_t)); pop(3); return code; }
int gs_defaultmatrix(const gs_state * pgs, gs_matrix * pmat) { gx_device *dev; if (pgs->ctm_default_set) { /* set after Install */ *pmat = pgs->ctm_default; return 1; } dev = gs_currentdevice_inline(pgs); gs_deviceinitialmatrix(dev, pmat); /* Add in the translation for the Margins. */ pmat->tx += dev->Margins[0] * dev->HWResolution[0] / dev->MarginsHWResolution[0]; pmat->ty += dev->Margins[1] * dev->HWResolution[1] / dev->MarginsHWResolution[1]; return 0; }
/* * - .get_form_id <int> */ static int zget_form_id(i_ctx_t *i_ctx_p) { os_ptr op = osp; gx_device *cdev = gs_currentdevice_inline(igs); int code, ID; code = dev_proc(cdev, dev_spec_op)(cdev, gxdso_get_form_ID, &ID, sizeof(int)); if (code < 0){ ID = -1; code = 0; } push(1); make_int(op, ID); return code; }
static int alpha_buffer_init(gs_state * pgs, fixed extra_x, fixed extra_y, int alpha_bits) { gx_device *dev = gs_currentdevice_inline(pgs); int log2_alpha_bits = ilog2(alpha_bits); gs_fixed_rect bbox; gs_int_rect ibox; uint width, raster, band_space; uint height; gs_log2_scale_point log2_scale; gs_memory_t *mem; gx_device_memory *mdev; log2_scale.x = log2_scale.y = log2_alpha_bits; gx_path_bbox(pgs->path, &bbox); ibox.p.x = fixed2int(bbox.p.x - extra_x) - 1; ibox.p.y = fixed2int(bbox.p.y - extra_y) - 1; ibox.q.x = fixed2int_ceiling(bbox.q.x + extra_x) + 1; ibox.q.y = fixed2int_ceiling(bbox.q.y + extra_y) + 1; width = (ibox.q.x - ibox.p.x) << log2_scale.x; raster = bitmap_raster(width); band_space = raster << log2_scale.y; height = (abuf_nominal / band_space) << log2_scale.y; if (height == 0) height = 1 << log2_scale.y; mem = pgs->memory; mdev = gs_alloc_struct(mem, gx_device_memory, &st_device_memory, "alpha_buffer_init"); if (mdev == 0) return 0; /* if no room, don't buffer */ gs_make_mem_abuf_device(mdev, mem, dev, &log2_scale, alpha_bits, ibox.p.x << log2_scale.x); mdev->width = width; mdev->height = height; mdev->bitmap_memory = mem; if ((*dev_proc(mdev, open_device)) ((gx_device *) mdev) < 0) { /* No room for bits, punt. */ gs_free_object(mem, mdev, "alpha_buffer_init"); return 0; } gx_set_device_only(pgs, (gx_device *) mdev); scale_paths(pgs, log2_scale.x, log2_scale.y, true); return 1; }
/* [CTM before Form Matrix applied] <<Form dictionary>> .beginform - */ static int zbeginform(i_ctx_t *i_ctx_p) { os_ptr op = osp; gx_device *cdev = gs_currentdevice_inline(igs); int code; float BBox[4], Matrix[6]; gs_form_template_t tmplate; gs_point ll, ur; gs_fixed_rect box; check_type(*op, t_dictionary); check_dict_read(*op); code = read_matrix(imemory, op - 1, &tmplate.CTM); if (code < 0) return code; code = dict_floats_param(imemory, op, "BBox", 4, BBox, NULL); if (code < 0) return code; if (code == 0) return_error(gs_error_undefined); tmplate.FormID = -1; tmplate.BBox.p.x = BBox[0]; tmplate.BBox.p.y = BBox[1]; tmplate.BBox.q.x = BBox[2]; tmplate.BBox.q.y = BBox[3]; code = dict_floats_param(imemory, op, "Matrix", 6, Matrix, NULL); if (code < 0) return code; if (code == 0) return_error(gs_error_undefined); tmplate.form_matrix.xx = Matrix[0]; tmplate.form_matrix.xy = Matrix[1]; tmplate.form_matrix.yx = Matrix[2]; tmplate.form_matrix.yy = Matrix[3]; tmplate.form_matrix.tx = Matrix[4]; tmplate.form_matrix.ty = Matrix[5]; tmplate.pcpath = igs->clip_path; code = dev_proc(cdev, dev_spec_op)(cdev, gxdso_form_begin, &tmplate, 0); /* return value > 0 means the device sent us back a matrix * and wants the CTM set to that. */ if (code > 0) { gs_setmatrix(igs, &tmplate.CTM); gs_distance_transform(tmplate.BBox.p.x, tmplate.BBox.p.y, &tmplate.CTM, &ll); gs_distance_transform(tmplate.BBox.q.x, tmplate.BBox.q.y, &tmplate.CTM, &ur); /* A form can legitimately have negative co-ordinates in paths * because it can be translated. But we always clip paths to the * page which (clearly) can't have negative co-ordinates. NB this * wouldn't be a problem if we didn't reset the CTM, but that would * break the form capture. * So here we temporarily set the clip to permit negative values, * fortunately this works..... */ /* We choose to permit negative values of the same magnitude as the * positive ones. */ box.p.x = float2fixed(ll.x); box.p.y = float2fixed(ll.y); box.q.x = float2fixed(ur.x); box.q.y = float2fixed(ur.y); if (box.p.x < 0) { if(box.p.x * -1 > box.q.x) box.q.x = box.p.x * -1; } else { if (fabs(ur.x) > fabs(ll.x)) box.p.x = box.q.x * -1; else { box.p.x = float2fixed(ll.x * -1); box.q.x = float2fixed(ll.x); } } if (box.p.y < 0) { if(box.p.y * -1 > box.q.y) box.q.y = box.p.y * -1; } else { if (fabs(ur.y) > fabs(ll.y)) box.p.y = box.q.y * -1; else { box.p.y = float2fixed(ll.y * -1); box.q.y = float2fixed(ll.y); } } /* This gets undone when we grestore after the form is executed */ code = gx_clip_to_rectangle(igs, &box); } pop(2); return code; }