/* Return 0 if OK, error code if not. */ int write_matrix_in(ref * op, const gs_matrix * pmat, gs_dual_memory_t *idmemory, gs_ref_memory_t *imem) { ref *aptr; const float *pel; int i; check_write_type(*op, t_array); if (r_size(op) != 6) return_error(e_rangecheck); aptr = op->value.refs; pel = (const float *)pmat; for (i = 5; i >= 0; i--, aptr++, pel++) { if (idmemory) { ref_save(op, aptr, "write_matrix"); make_real_new(aptr, *pel); } else { make_tav(aptr, t_real, imemory_new_mask(imem), realval, *pel); } } return 0; }
static int zgetpath(i_ctx_t *i_ctx_p) { os_ptr op = osp; int i, code, path_size, leaf_count; ref *main_ref, *operators[5]; push(1); path_size = code = path_length_for_upath(igs->path); if (code < 0) return code; leaf_count = (path_size + max_array_size - 1) / max_array_size; code = ialloc_ref_array(op, a_all, leaf_count, "zgetpath_master"); if (code < 0) return code; if (path_size == 0) return 0; if (dict_find_string(systemdict, "moveto", &operators[1]) <= 0 || dict_find_string(systemdict, "lineto", &operators[2]) <= 0 || dict_find_string(systemdict, "curveto", &operators[3]) <= 0 || dict_find_string(systemdict, "closepath", &operators[4]) <= 0) return_error(e_undefined); main_ref = op->value.refs; for (i = 0; i < leaf_count; i++) { int leaf_size = ( i == leaf_count - 1) ? path_size - i * max_array_size : max_array_size; code = ialloc_ref_array(&main_ref[i], a_all | a_executable, leaf_size, "zgetpath_leaf"); if (code < 0) return code; } { int pe, j, k; gs_path_enum penum; static const int oper_count[5] = { 0, 2, 2, 6, 0 }; gs_point pts[3]; const double *fts[6]; fts[0] = &pts[0].x; fts[1] = &pts[0].y; fts[2] = &pts[1].x; fts[3] = &pts[1].y; fts[4] = &pts[2].x; fts[5] = &pts[2].y; main_ref = op->value.refs; gs_path_enum_copy_init(&penum, igs, false); pe = gs_path_enum_next(&penum, pts); if (pe < 0) return pe; k = 0; for (i = 0; i < leaf_count; i++) { int leaf_size = ( i == leaf_count - 1) ? path_size - i * max_array_size : max_array_size; ref *leaf_ref = main_ref[i].value.refs; for (j = 0; j < leaf_size; j++) { if (k < oper_count[pe]) make_real_new(&leaf_ref[j], (float)*fts[k++]); else { k = 0; ref_assign(&leaf_ref[j], operators[pe]); pe = gs_path_enum_next(&penum, pts); if (pe <= 0) return pe; if (pe >= 5) return_error(e_unregistered); } } } } 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; }