/* <bool> .pathbbox <llx> <lly> <urx> <ury> */ static int z1pathbbox(i_ctx_t *i_ctx_p) { os_ptr op = osp; gs_rect box; int code; check_type(*op, t_boolean); code = gs_upathbbox(igs, &box, op->value.boolval); if (code < 0) return code; push(3); make_real(op - 3, box.p.x); make_real(op - 2, box.p.y); make_real(op - 1, box.q.x); make_real(op, box.q.y); return 0; }
int make_upath(i_ctx_t *i_ctx_p, ref *rupath, gs_state *pgs, gx_path *ppath, bool with_ucache) { int size = (with_ucache ? 6 : 5); gs_path_enum penum; gs_rect bbox; int op; ref *next; int code; /* Compute the bounding box. */ if ((code = gs_upathbbox(pgs, &bbox, true)) < 0) { /* * Note: Adobe throws 'nocurrentpoint' error, but the PLRM does * not list this as a possible error from 'upath', so if we are * not in CPSI compatibility mode, we set a reasonable default * bbox instead. */ if (code != e_nocurrentpoint || gs_currentcpsimode(imemory)) return code; bbox.p.x = bbox.p.y = bbox.q.x = bbox.q.y = 0; } code = path_length_for_upath(ppath); if (code < 0) return code; size += code; if (size >= 65536) return_error(e_limitcheck); code = ialloc_ref_array(rupath, a_all | a_executable, size, "make_upath"); if (code < 0) return code; /* Construct the path. */ next = rupath->value.refs; if (with_ucache) { if ((code = name_enter_string(pgs->memory, "ucache", next)) < 0) return code; r_set_attrs(next, a_executable | l_new); ++next; } make_real_new(next, bbox.p.x); make_real_new(next + 1, bbox.p.y); make_real_new(next + 2, bbox.q.x); make_real_new(next + 3, bbox.q.y); next += 4; if ((code = name_enter_string(pgs->memory, "setbbox", next)) < 0) return code; r_set_attrs(next, a_executable | l_new); ++next; { gs_point pts[3]; /* Patch the path in the gstate to set up the enumerator. */ gx_path *save_path = pgs->path; pgs->path = ppath; gs_path_enum_copy_init(&penum, pgs, false); pgs->path = save_path; while ((op = gs_path_enum_next(&penum, pts)) != 0) { const char *opstr; switch (op) { case gs_pe_moveto: opstr = "moveto"; goto ml; case gs_pe_lineto: opstr = "lineto"; ml:make_real_new(next, pts[0].x); make_real_new(next + 1, pts[0].y); next += 2; break; case gs_pe_curveto: opstr = "curveto"; make_real_new(next, pts[0].x); make_real_new(next + 1, pts[0].y); make_real_new(next + 2, pts[1].x); make_real_new(next + 3, pts[1].y); make_real_new(next + 4, pts[2].x); make_real_new(next + 5, pts[2].y); next += 6; break; case gs_pe_closepath: opstr = "closepath"; break; default: return_error(e_unregistered); } if ((code = name_enter_string(pgs->memory, opstr, next)) < 0) return code; r_set_attrs(next, a_executable); ++next; } } return 0; }