/* This is the Level 2 >> operator. */ static int zdicttomark(i_ctx_t *i_ctx_p) { uint count2 = ref_stack_counttomark(&o_stack); ref rdict; int code; uint idx; if (count2 == 0) return_error(e_unmatchedmark); count2--; if ((count2 & 1) != 0) return_error(e_rangecheck); code = dict_create(count2 >> 1, &rdict); if (code < 0) return code; /* << /a 1 /a 2 >> => << /a 1 >>, i.e., */ /* we must enter the keys in top-to-bottom order. */ for (idx = 0; idx < count2; idx += 2) { code = idict_put(&rdict, ref_stack_index(&o_stack, idx + 1), ref_stack_index(&o_stack, idx)); if (code < 0) { /* There's no way to free the dictionary -- too bad. */ return code; } } ref_stack_pop(&o_stack, count2); ref_assign(osp, &rdict); return code; }
/* the TransformPQR procedure. -mark- ... v -> v */ static int cie_post_exec_tpqr(i_ctx_t *i_ctx_p) { os_ptr op = osp; uint count = ref_stack_counttomark(&o_stack); ref vref; if (count < 2) return_error(e_unmatchedmark); vref = *op; ref_stack_pop(&o_stack, count - 1); *osp = vref; return 0; }
int stack_param_list_read(stack_param_list * plist, ref_stack_t * pstack, uint skip, const ref * ppolicies, bool require_all, gs_ref_memory_t *imem) { iparam_list *const iplist = (iparam_list *) plist; uint count = ref_stack_counttomark(pstack); if (count == 0) return_error(e_unmatchedmark); count -= skip + 1; if (count & 1) return_error(e_rangecheck); plist->u.r.read = stack_param_read; plist->enumerate = stack_param_enumerate; plist->pstack = pstack; plist->skip = skip; return ref_param_read_init(iplist, count >> 1, ppolicies, require_all, imem); }
/* Note that .putdeviceparams clears the current pagedevice. */ static int zputdeviceparams(i_ctx_t *i_ctx_p) { uint count = ref_stack_counttomark(&o_stack); ref *prequire_all; ref *ppolicy; ref *pdev; gx_device *dev; stack_param_list list; int code; int old_width, old_height; int i, dest; if (count == 0) return_error(e_unmatchedmark); prequire_all = ref_stack_index(&o_stack, count); ppolicy = ref_stack_index(&o_stack, count + 1); pdev = ref_stack_index(&o_stack, count + 2); if (pdev == 0) return_error(e_stackunderflow); check_type_only(*prequire_all, t_boolean); check_write_type_only(*pdev, t_device); dev = pdev->value.pdevice; code = stack_param_list_read(&list, &o_stack, 0, ppolicy, prequire_all->value.boolval, iimemory); if (code < 0) return code; old_width = dev->width; old_height = dev->height; code = gs_putdeviceparams(dev, (gs_param_list *) & list); /* Check for names that were undefined or caused errors. */ for (dest = count - 2, i = 0; i < count >> 1; i++) if (list.results[i] < 0) { *ref_stack_index(&o_stack, dest) = *ref_stack_index(&o_stack, count - (i << 1) - 2); gs_errorname(i_ctx_p, list.results[i], ref_stack_index(&o_stack, dest - 1)); dest -= 2; } iparam_list_release(&list); if (code < 0) { /* There were errors reported. */ ref_stack_pop(&o_stack, dest + 1); return 0; } if (code > 0 || (code == 0 && (dev->width != old_width || dev->height != old_height))) { /* * The device was open and is now closed, or its dimensions have * changed. If it was the current device, call setdevice to * reinstall it and erase the page. */ /****** DOESN'T FIND ALL THE GSTATES THAT REFERENCE THE DEVICE. ******/ if (gs_currentdevice(igs) == dev) { bool was_open = dev->is_open; code = gs_setdevice_no_erase(igs, dev); /* If the device wasn't closed, setdevice won't erase the page. */ if (was_open && code >= 0) code = 1; } } if (code < 0) return code; ref_stack_pop(&o_stack, count + 1); make_bool(osp, code); clear_pagedevice(istate); return 0; }
/* <mark> <x0> <y0> ... <xn> <yn> .pdfinkpath - */ static int zpdfinkpath(i_ctx_t *i_ctx_p) { os_ptr optr, op = osp; uint count = ref_stack_counttomark(&o_stack); uint i, ocount; int code; double x0, y0, x1, y1, x2, y2, x3, y3, xc1, yc1, xc2, yc2, xc3, yc3; double len1, len2, len3, k1, k2, xm1, ym1, xm2, ym2; double ctrl1_x, ctrl1_y, ctrl2_x, ctrl2_y; const double smooth_value = 1; /* from 0..1 range */ if (count == 0) return_error(e_unmatchedmark); if ((count & 1) == 0 || count < 3) return_error(e_rangecheck); ocount = count - 1; optr = op - ocount + 1; if ((code = real_param(optr, &x1)) < 0) return code; if ((code = real_param(optr + 1, &y1)) < 0) return code; if ((code = gs_moveto(igs, x1, y1)) < 0) return code; if (ocount == 2) goto pop; if ((code = real_param(optr + 2, &x2)) < 0) return code; if ((code = real_param(optr + 3, &y2)) < 0) return code; if (ocount == 4) { if((code = gs_lineto(igs, x2, y2)) < 0) return code; goto pop; } x0 = 2*x1 - x2; y0 = 2*y1 - y2; for (i = 4; i <= ocount; i += 2) { if (i < ocount) { if ((code = real_param(optr + i, &x3)) < 0) return code; if ((code = real_param(optr + i + 1, &y3)) < 0) return code; } else { x3 = 2*x2 - x1; y3 = 2*y2 - y1; } xc1 = (x0 + x1) / 2.0; yc1 = (y0 + y1) / 2.0; xc2 = (x1 + x2) / 2.0; yc2 = (y1 + y2) / 2.0; xc3 = (x2 + x3) / 2.0; yc3 = (y2 + y3) / 2.0; len1 = hypot(x1 - x0, y1 - y0); len2 = hypot(x2 - x1, y2 - y1); len3 = hypot(x3 - x2, y3 - y2); k1 = len1 / (len1 + len2); k2 = len2 / (len2 + len3); xm1 = xc1 + (xc2 - xc1) * k1; ym1 = yc1 + (yc2 - yc1) * k1; xm2 = xc2 + (xc3 - xc2) * k2; ym2 = yc2 + (yc3 - yc2) * k2; ctrl1_x = xm1 + (xc2 - xm1) * smooth_value + x1 - xm1; ctrl1_y = ym1 + (yc2 - ym1) * smooth_value + y1 - ym1; ctrl2_x = xm2 + (xc2 - xm2) * smooth_value + x2 - xm2; ctrl2_y = ym2 + (yc2 - ym2) * smooth_value + y2 - ym2; code = gs_curveto(igs, ctrl1_x, ctrl1_y, ctrl2_x, ctrl2_y, x2, y2); if (code < 0) return code; x0 = x1, x1 = x2, x2 = x3; y0 = y1, y1 = y2, y2 = y3; } pop: ref_stack_pop(&o_stack, count); return 0; }