int gs_initclip(gs_state * pgs) { gs_fixed_rect box; int code = gx_default_clip_box(pgs, &box); if (code < 0) return code; return gx_clip_to_rectangle(pgs, &box); }
/* Set up a clipping path and device for insideness testing. */ static int in_path(os_ptr oppath, i_ctx_t *i_ctx_p, gx_device * phdev) { int code = gs_gsave(igs); int npop; double uxy[2]; if (code < 0) return code; code = num_params(oppath, 2, uxy); if (code >= 0) { /* Aperture is a single pixel. */ gs_point dxy; gs_fixed_rect fr; gs_transform(igs, uxy[0], uxy[1], &dxy); fr.p.x = fixed_floor(float2fixed(dxy.x)); fr.p.y = fixed_floor(float2fixed(dxy.y)); fr.q.x = fr.p.x + fixed_1; fr.q.y = fr.p.y + fixed_1; code = gx_clip_to_rectangle(igs, &fr); npop = 2; } else if (code == e_stackunderflow) { /* If 0 elements, definitely a stackunderflow; otherwise, */ /* only 1 number, also a stackunderflow. */ npop = code; } else { /* Aperture is a user path. */ /* We have to set the clipping path without disturbing */ /* the current path. */ gx_path *ipath = igs->path; gx_path save; gx_path_init_local(&save, imemory); gx_path_assign_preserve(&save, ipath); gs_newpath(igs); code = upath_append(oppath, i_ctx_p, false); if (code >= 0) code = gx_clip_to_path(igs); gx_path_assign_free(igs->path, &save); npop = 1; } if (code < 0) { gs_grestore(igs); return code; } /* Install the hit detection device. */ gx_set_device_color_1(igs); gx_device_init((gx_device *) phdev, (const gx_device *)&gs_hit_device, NULL, true); phdev->width = phdev->height = max_int; gx_device_fill_in_procs(phdev); gx_set_device_only(igs, phdev); return npop; }
/* This is very inefficient right now. */ int gx_clip_to_path(gs_state * pgs) { gs_fixed_rect bbox; int code; if ((code = gx_path_bbox(pgs->path, &bbox)) < 0 || (code = gx_clip_to_rectangle(pgs, &bbox)) < 0 || (code = gs_clip(pgs)) < 0 ) return code; note_set_clip_path(pgs); return 0; }
/* [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; }
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; }