static int zsizeimagebox(i_ctx_t *i_ctx_p) { os_ptr op = osp; const gx_device *dev = gs_currentdevice(igs); gs_rect srect, drect; gs_matrix mat; gs_int_rect rect; int w, h; int code; check_type(op[-4], t_integer); check_type(op[-3], t_integer); check_type(op[-2], t_integer); check_type(op[-1], t_integer); srect.p.x = op[-4].value.intval; srect.p.y = op[-3].value.intval; srect.q.x = srect.p.x + op[-2].value.intval; srect.q.y = srect.p.y + op[-1].value.intval; gs_currentmatrix(igs, &mat); gs_bbox_transform(&srect, &mat, &drect); /* * We want the dimensions of the image as a source, not a * destination, so we need to expand it rather than pixround. */ rect.p.x = (int)floor(drect.p.x); rect.p.y = (int)floor(drect.p.y); rect.q.x = (int)ceil(drect.q.x); rect.q.y = (int)ceil(drect.q.y); /* * Clip the rectangle to the device boundaries, since that's what * the NeXT implementation does. */ box_confine(&rect.p.x, &rect.q.x, dev->width); box_confine(&rect.p.y, &rect.q.y, dev->height); w = rect.q.x - rect.p.x; h = rect.q.y - rect.p.y; /* * The NeXT documentation doesn't specify very clearly what is * supposed to be in the matrix: the following produces results * that match testing on an actual NeXT system. */ mat.tx -= rect.p.x; mat.ty -= rect.p.y; code = write_matrix(op, &mat); if (code < 0) return code; make_int(op - 4, rect.p.x); make_int(op - 3, rect.p.y); make_int(op - 2, w); make_int(op - 1, h); return 0; }
RELOC_PTRS_END static int is_image_visible(const gs_image_common_t * pic, gs_state * pgs, gx_clip_path *pcpath) { /* HACK : We need the source image size here, but gs_image_common_t doesn't pass it. We would like to move Width, Height to gs_image_common, but gs_image2_t appears to have those fields of double type. */ if (pic->type->begin_typed_image == gx_begin_image1) { gs_image1_t *pim = (gs_image1_t *) pic; gs_rect image_rect = {{0, 0}, {0, 0}}; gs_rect device_rect; gs_int_rect device_int_rect; gs_matrix mat; int code; image_rect.q.x = pim->Width; image_rect.q.y = pim->Height; if (pic->ImageMatrix.xx == ctm_only(pgs).xx && pic->ImageMatrix.xy == ctm_only(pgs).xy && pic->ImageMatrix.yx == ctm_only(pgs).yx && pic->ImageMatrix.yy == ctm_only(pgs).yy) { /* Handle common special case separately to accept singular matrix */ mat.xx = mat.yy = 1.; mat.yx = mat.xy = 0.; mat.tx = ctm_only(pgs).tx - pic->ImageMatrix.tx; mat.ty = ctm_only(pgs).ty - pic->ImageMatrix.ty; } else { code = gs_matrix_invert(&pic->ImageMatrix, &mat); if (code < 0) return code; code = gs_matrix_multiply(&mat, &ctm_only(pgs), &mat); if (code < 0) return code; } code = gs_bbox_transform(&image_rect, &mat, &device_rect); if (code < 0) return code; device_int_rect.p.x = (int)floor(device_rect.p.x); device_int_rect.p.y = (int)floor(device_rect.p.y); device_int_rect.q.x = (int)ceil(device_rect.q.x); device_int_rect.q.y = (int)ceil(device_rect.q.y); if (!gx_cpath_rect_visible(pcpath, &device_int_rect)) return 0; } return 1; }
/* This is just a bridge to an old code. */ int gx_dc_pattern2_shade_bbox_transform2fixed(const gs_rect * rect, const gs_imager_state * pis, gs_fixed_rect * rfixed) { gs_rect dev_rect; int code = gs_bbox_transform(rect, &ctm_only(pis), &dev_rect); if (code >= 0) { rfixed->p.x = float2fixed(dev_rect.p.x); rfixed->p.y = float2fixed(dev_rect.p.y); rfixed->q.x = float2fixed(dev_rect.q.x); rfixed->q.y = float2fixed(dev_rect.q.y); } return code; }
/* Set the bounding box for the current path. */ int gs_setbbox(gs_state * pgs, double llx, double lly, double urx, double ury) { gs_rect ubox, dbox; gs_fixed_rect obox, bbox; gx_path *ppath = pgs->path; int code; if (llx > urx || lly > ury) return_error(gs_error_rangecheck); /* Transform box to device coordinates. */ ubox.p.x = llx; ubox.p.y = lly; ubox.q.x = urx; ubox.q.y = ury; if ((code = gs_bbox_transform(&ubox, &ctm_only(pgs), &dbox)) < 0) return code; /* Round the corners in opposite directions. */ /* Because we can't predict the magnitude of the dbox values, */ /* we add/subtract the slop after fixing. */ if (dbox.p.x < fixed2float(min_fixed + box_rounding_slop_fixed) || dbox.p.y < fixed2float(min_fixed + box_rounding_slop_fixed) || dbox.q.x >= fixed2float(max_fixed - box_rounding_slop_fixed + fixed_epsilon) || dbox.q.y >= fixed2float(max_fixed - box_rounding_slop_fixed + fixed_epsilon) ) return_error(gs_error_limitcheck); bbox.p.x = (fixed) floor(dbox.p.x * fixed_scale) - box_rounding_slop_fixed; bbox.p.y = (fixed) floor(dbox.p.y * fixed_scale) - box_rounding_slop_fixed; bbox.q.x = (fixed) ceil(dbox.q.x * fixed_scale) + box_rounding_slop_fixed; bbox.q.y = (fixed) ceil(dbox.q.y * fixed_scale) + box_rounding_slop_fixed; if (gx_path_bbox_set(ppath, &obox) >= 0) { /* Take the union of the bboxes. */ ppath->bbox.p.x = min(obox.p.x, bbox.p.x); ppath->bbox.p.y = min(obox.p.y, bbox.p.y); ppath->bbox.q.x = max(obox.q.x, bbox.q.x); ppath->bbox.q.y = max(obox.q.y, bbox.q.y); } else { /* empty path *//* Just set the bbox. */ ppath->bbox = bbox; } ppath->bbox_set = 1; return 0; }
/* Get the default clipping box. */ int gx_default_clip_box(const gs_state * pgs, gs_fixed_rect * pbox) { register gx_device *dev = gs_currentdevice(pgs); gs_rect bbox; gs_matrix imat; int code; if (dev->ImagingBBox_set) { /* Use the ImagingBBox, relative to default user space. */ gs_defaultmatrix(pgs, &imat); bbox.p.x = dev->ImagingBBox[0]; bbox.p.y = dev->ImagingBBox[1]; bbox.q.x = dev->ImagingBBox[2]; bbox.q.y = dev->ImagingBBox[3]; } else { /* Use the MediaSize indented by the HWMargins, */ /* relative to unrotated user space adjusted by */ /* the Margins. (We suspect this isn't quite right, */ /* but the whole issue of "margins" is such a mess that */ /* we don't think we can do any better.) */ (*dev_proc(dev, get_initial_matrix)) (dev, &imat); /* Adjust for the Margins. */ imat.tx += dev->Margins[0] * dev->HWResolution[0] / dev->MarginsHWResolution[0]; imat.ty += dev->Margins[1] * dev->HWResolution[1] / dev->MarginsHWResolution[1]; bbox.p.x = dev->HWMargins[0]; bbox.p.y = dev->HWMargins[1]; bbox.q.x = dev->MediaSize[0] - dev->HWMargins[2]; bbox.q.y = dev->MediaSize[1] - dev->HWMargins[3]; } code = gs_bbox_transform(&bbox, &imat, &bbox); if (code < 0) return code; /* Round the clipping box so that it doesn't get ceilinged. */ pbox->p.x = fixed_rounded(float2fixed(bbox.p.x)); pbox->p.y = fixed_rounded(float2fixed(bbox.p.y)); pbox->q.x = fixed_rounded(float2fixed(bbox.q.x)); pbox->q.y = fixed_rounded(float2fixed(bbox.q.y)); return 0; }
static int pdf_make_form_dict(gx_device_pdf * pdev, const gs_pdf14trans_params_t * pparams, const gs_imager_state * pis, const cos_dict_t *group_dict, cos_dict_t *form_dict) { cos_array_t *bbox_array; float bbox[4]; gs_rect bbox_rect; int code; code = gs_bbox_transform(&pparams->bbox, &ctm_only(pis), &bbox_rect); if (code < 0) return code; bbox[0] = bbox_rect.p.x; bbox[1] = bbox_rect.p.y; bbox[2] = bbox_rect.q.x; bbox[3] = bbox_rect.q.y; code = cos_dict_put_c_key_string(form_dict, "/Type", (const byte *)"/XObject", 8); if (code < 0) return code; code = cos_dict_put_c_key_string(form_dict, "/Subtype", (const byte *)"/Form", 5); if (code < 0) return code; code = cos_dict_put_c_key_int(form_dict, "/FormType", 1); if (code < 0) return code; code = cos_dict_put_c_key_string(form_dict, "/Matrix", (const byte *)"[1 0 0 1 0 0]", 13); if (code < 0) return code; bbox_array = cos_array_from_floats(pdev, bbox, 4, "pdf_begin_transparency_group"); if (bbox_array == NULL) return_error(gs_error_VMerror); code = cos_dict_put_c_key_object(form_dict, "/BBox", (cos_object_t *)bbox_array); if (code < 0) return code; return cos_dict_put_c_key_object(form_dict, "/Group", (cos_object_t *)group_dict); }
/* SC; */ int hpgl_SC(hpgl_args_t *pargs, hpgl_state_t *pgls) { hpgl_real_t xy[4]; int i; int type; hpgl_scaling_params_t scale_params; gs_point point, dev_pt, dev_anchor; scale_params = pgls->g.scaling_params; hpgl_call(hpgl_get_current_position(pgls, &point)); hpgl_call(gs_transform(pgls->pgs, point.x, point.y, &dev_pt)); hpgl_call(gs_transform(pgls->pgs, pgls->g.anchor_corner.x, pgls->g.anchor_corner.y, &dev_anchor)); for ( i = 0; i < 4 && hpgl_arg_real(pgls->memory, pargs, &xy[i]); ++i ) ; switch ( i ) { case 0: /* set defaults */ { /* a naked SC implies the soft clip window is bound to plotter units. */ gs_matrix umat; type = hpgl_scaling_none; hpgl_compute_user_units_to_plu_ctm(pgls, &umat); /* in-place */ hpgl_call(gs_bbox_transform(&pgls->g.soft_clip_window.rect, &umat, &pgls->g.soft_clip_window.rect)); pgls->g.soft_clip_window.isbound = true; break; } default: return e_Range; case 4: type = hpgl_scaling_anisotropic; hpgl_arg_c_int(pgls->memory, pargs, &type); switch ( type ) { case hpgl_scaling_anisotropic: /* 0 */ if ( xy[0] == xy[1] || xy[2] == xy[3] ) return e_Range; pxy: scale_params.pmin.x = xy[0]; scale_params.pmax.x = xy[1]; scale_params.pmin.y = xy[2]; scale_params.pmax.y = xy[3]; break; case hpgl_scaling_isotropic: /* 1 */ if ( xy[0] == xy[1] || xy[2] == xy[3] ) return e_Range; { hpgl_real_t left = 50, bottom = 50; if ( (hpgl_arg_c_real(pgls->memory, pargs, &left) && (left < 0 || left > 100 || !hpgl_arg_c_real(pgls->memory, pargs, &bottom) || bottom < 0 || bottom > 100)) ) return e_Range; scale_params.left = left; scale_params.bottom = bottom; } goto pxy; case hpgl_scaling_point_factor: /* 2 */ if ( xy[1] == 0 || xy[3] == 0 ) return e_Range; scale_params.pmin.x = xy[0]; scale_params.factor.x = xy[1]; scale_params.pmin.y = xy[2]; scale_params.factor.y = xy[3]; break; default: return e_Range; } } hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); pgls->g.scaling_params = scale_params; pgls->g.scaling_type = type; hpgl_call(hpgl_set_ctm(pgls)); hpgl_call(gs_itransform(pgls->pgs, dev_pt.x, dev_pt.y, &point)); hpgl_call(hpgl_set_current_position(pgls, &point)); hpgl_call(gs_itransform(pgls->pgs, dev_anchor.x, dev_anchor.y, &pgls->g.anchor_corner)); /* PCLTRM 23-7 (commands the update cr position) does not list SC but PCL updates the position */ hpgl_call(hpgl_update_carriage_return_pos(pgls)); return 0; }
int xps_high_level_pattern(xps_context_t *ctx) { gs_matrix m; gs_rect bbox; gs_fixed_rect clip_box; int code; gx_device_color *pdc = gs_currentdevicecolor_inline(ctx->pgs); const gs_client_pattern *ppat = gs_getpattern(&pdc->ccolor); gs_pattern1_instance_t *pinst = (gs_pattern1_instance_t *)gs_currentcolor(ctx->pgs)->pattern; code = gx_pattern_cache_add_dummy_entry((gs_imager_state *)ctx->pgs, pinst, ctx->pgs->device->color_info.depth); if (code < 0) return code; code = gs_gsave(ctx->pgs); if (code < 0) return code; dev_proc(ctx->pgs->device, get_initial_matrix)(ctx->pgs->device, &m); gs_setmatrix(ctx->pgs, &m); code = gs_bbox_transform(&ppat->BBox, &ctm_only(ctx->pgs), &bbox); if (code < 0) { gs_grestore(ctx->pgs); return code; } clip_box.p.x = float2fixed(bbox.p.x); clip_box.p.y = float2fixed(bbox.p.y); clip_box.q.x = float2fixed(bbox.q.x); clip_box.q.y = float2fixed(bbox.q.y); code = gx_clip_to_rectangle(ctx->pgs, &clip_box); if (code < 0) { gs_grestore(ctx->pgs); return code; } { pattern_accum_param_s param; param.pinst = (void *)pinst; param.graphics_state = (void *)ctx->pgs; param.pinst_id = pinst->id; code = (*dev_proc(ctx->pgs->device, dev_spec_op))((gx_device *)ctx->pgs->device, gxdso_pattern_start_accum, ¶m, sizeof(pattern_accum_param_s)); } if (code < 0) { gs_grestore(ctx->pgs); return code; } code = xps_paint_tiling_brush(&pdc->ccolor, ctx->pgs); if (code) { gs_grestore(ctx->pgs); return gs_rethrow(code, "high level pattern brush function failed"); } code = gs_grestore(ctx->pgs); if (code < 0) return code; { pattern_accum_param_s param; param.pinst = (void *)pinst; param.graphics_state = (void *)ctx->pgs; param.pinst_id = pinst->id; code = (*dev_proc(ctx->pgs->device, dev_spec_op))((gx_device *)ctx->pgs->device, gxdso_pattern_finish_accum, ¶m, sizeof(pattern_accum_param_s)); } return code; }