示例#1
0
static int
path_continue(i_ctx_t *i_ctx_p)
{
    gs_path_enum *penum = r_ptr(esp, gs_path_enum);
    gs_point ppts[3];
    int code;

    /* Make sure we have room on the o-stack for the worst case */
    /* before we enumerate the next path element. */
    check_ostack(6);		/* 3 points for curveto */
    code = gs_path_enum_next(penum, ppts);
    switch (code) {
	case 0:		/* all done */
	    esp -= 6;
	    path_cleanup(i_ctx_p);
	    return o_pop_estack;
	default:		/* error */
	    return code;
	case gs_pe_moveto:
	    esp[2] = esp[-4];	/* moveto proc */
	    pf_push(i_ctx_p, ppts, 1);
	    break;
	case gs_pe_lineto:
	    esp[2] = esp[-3];	/* lineto proc */
	    pf_push(i_ctx_p, ppts, 1);
	    break;
	case gs_pe_curveto:
	    esp[2] = esp[-2];	/* curveto proc */
	    pf_push(i_ctx_p, ppts, 3);
	    break;
	case gs_pe_closepath:
	    esp[2] = esp[-1];	/* closepath proc */
	    break;
    }
    push_op_estack(path_continue);
    ++esp;			/* include pushed procedure */
    return o_push_estack;
}
示例#2
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;
}
示例#3
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;
}