Esempio n. 1
0
/*
 * We have collected all of the sample data.  Create a type 0 function stucture.
 */
static int
sampled_data_finish(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_sampled_data_enum *penum = senum;
    /* Build a type 0 function using the given parameters */
    gs_function_Sd_params_t * params =
        (gs_function_Sd_params_t *)&penum->pfn->params;
    gs_function_t * pfn;
    ref cref;			/* closure */
    int code = gs_function_Sd_init(&pfn, params, imemory);

    if (code < 0)
        return code;

    code = ialloc_ref_array(&cref, a_executable | a_execute, 2,
                            "sampled_data_finish(cref)");
    if (code < 0)
        return code;

    make_istruct_new(cref.value.refs, a_executable | a_execute, pfn);
    make_oper_new(cref.value.refs + 1, 0, zexecfunction);
    ref_assign(op, &cref);

    esp -= estack_storage;
    ifree_object(penum->pfn, "sampled_data_finish(pfn)");
    ifree_object(penum, "sampled_data_finish(enum)");
    return o_pop_estack;
}
Esempio n. 2
0
/* The caller guarantees that *op is a dictionary. */
int
build_gs_sub_font(i_ctx_t *i_ctx_p, const ref *op, gs_font **ppfont,
                  font_type ftype, gs_memory_type_ptr_t pstype,
                  const build_proc_refs * pbuild, const ref *pencoding,
                  ref *fid_op)
{
    gs_matrix mat, omat;
    ref fname;			/* t_string */
    gs_font *pfont;
    font_data *pdata;
    /*
     * Make sure that we allocate the font data
     * in the same VM as the font dictionary.
     */
    uint space = ialloc_space(idmemory);
    int code = sub_font_params(imemory, op, &mat, &omat, &fname);

    if (code < 0)
        return code;
    ialloc_set_space(idmemory, r_space(op));
    pfont = gs_font_alloc(imemory, pstype, &gs_font_procs_default, NULL,
                          "buildfont(font)");
    pdata = ialloc_struct(font_data, &st_font_data,
                          "buildfont(data)");
    if (pfont == 0 || pdata == 0)
        code = gs_note_error(e_VMerror);
    else if (fid_op)
        code = add_FID(i_ctx_p, fid_op, pfont, iimemory);
    if (code < 0) {
        ifree_object(pdata, "buildfont(data)");
        ifree_object(pfont, "buildfont(font)");
        ialloc_set_space(idmemory, space);
        return code;
    }
    refset_null((ref *) pdata, sizeof(font_data) / sizeof(ref));
    ref_assign_new(&pdata->dict, op);
    ref_assign_new(&pdata->BuildChar, &pbuild->BuildChar);
    ref_assign_new(&pdata->BuildGlyph, &pbuild->BuildGlyph);
    if (pencoding)
        ref_assign_new(&pdata->Encoding, pencoding);
    pfont->client_data = pdata;
    pfont->FontType = ftype;
    pfont->FontMatrix = mat;
    pfont->orig_FontMatrix = omat;
    pfont->BitmapWidths = false;
    pfont->ExactSize = fbit_use_bitmaps;
    pfont->InBetweenSize = fbit_use_outlines;
    pfont->TransformedChar = fbit_use_outlines;
    pfont->WMode = 0;
    pfont->procs.encode_char = zfont_encode_char;
    pfont->procs.glyph_name = zfont_glyph_name;
    ialloc_set_space(idmemory, space);
    copy_font_name(&pfont->font_name, &fname);
    *ppfont = pfont;
    return 0;
}
Esempio n. 3
0
static int
zpathforall(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_path_enum *penum;
    int code;

    check_proc(op[-3]);
    check_proc(op[-2]);
    check_proc(op[-1]);
    check_proc(*op);
    check_estack(8);
    if ((penum = gs_path_enum_alloc(imemory, "pathforall")) == 0)
	return_error(e_VMerror);
    code = gs_path_enum_init(penum, igs);
    if (code < 0) {
	ifree_object(penum, "path_cleanup");
	return code;
    }
    /* Push a mark, the four procedures, and the path enumerator. */
    push_mark_estack(es_for, path_cleanup);	/* iterator */
    memcpy(esp + 1, op - 3, 4 * sizeof(ref));	/* 4 procs */
    esp += 5;
    make_istruct(esp, 0, penum);
    push_op_estack(path_continue);
    pop(4);
    op -= 4;
    return o_push_estack;
}
Esempio n. 4
0
/* <cx> <cy> <char> <string> widthshow - */
static int
zwidthshow(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_text_enum_t *penum;
    double cxy[2];
    int code;

    if ((code = op_show_setup(i_ctx_p, op)) != 0 )
	return code;
    check_type(op[-1], t_integer);
    if (gs_currentfont(igs)->FontType == ft_composite) {
        if ((gs_char) (op[-1].value.intval) != op[-1].value.intval)
	    return_error(e_rangecheck);
    } else {
        if (op[-1].value.intval < 0 || op[-1].value.intval > 255)
	    return_error(e_rangecheck); /* per PLRM and CET 13-26 */
    }
    if ((code = num_params(op - 2, 2, cxy)) < 0 )
        return code;
    if ((code = gs_widthshow_begin(igs, cxy[0], cxy[1],
				   (gs_char) op[-1].value.intval,
				   op->value.bytes, r_size(op),
				   imemory, &penum)) < 0)
	return code;
    *(op_proc_t *)&penum->enum_client_data = zwidthshow;
    if ((code = op_show_finish_setup(i_ctx_p, penum, 4, finish_show)) < 0) {
	ifree_object(penum, "op_show_enum_setup");
	return code;
    }
    return op_show_continue_pop(i_ctx_p, 4);
}
Esempio n. 5
0
/* <proc> <string> kshow - */
static int
zkshow(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_text_enum_t *penum;
    int code;

    check_read_type(*op, t_string);
    check_proc(op[-1]);
    /*
     * Per PLRM Section xx.x, kshow is illegal if the current font is a
     * composite font.  The graphics library does not have this limitation,
     * so we check for it here.
     */
    if (gs_currentfont(igs)->FontType == ft_composite)
	return_error(e_invalidfont);
    if ((code = op_show_setup(i_ctx_p, op)) != 0 ||
	(code = gs_kshow_begin(igs, op->value.bytes, r_size(op),
			       imemory, &penum)) < 0)
	return code;
    *(op_proc_t *)&penum->enum_client_data = zkshow;
    if ((code = op_show_finish_setup(i_ctx_p, penum, 2, finish_show)) < 0) {
	ifree_object(penum, "op_show_enum_setup");
	return code;
    }
    sslot = op[-1];		/* save kerning proc */
    return op_show_continue_pop(i_ctx_p, 2);
}
Esempio n. 6
0
/* <pattern> <matrix> <shading> .buildshadingpattern <pattern> <instance> */
static int
zbuildshadingpattern(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op2 = op - 2;
    gs_matrix mat;
    gs_pattern2_template_t templat;
    int_pattern *pdata;
    gs_client_color cc_instance;
    int code;

    check_type(*op2, t_dictionary);
    check_dict_read(*op2);
    gs_pattern2_init(&templat);
    if ((code = read_matrix(imemory, op - 1, &mat)) < 0 ||
        (code = dict_uid_param(op2, &templat.uid, 1, imemory, i_ctx_p)) != 1 ||
        (code = shading_param(op, &templat.Shading)) < 0 ||
        (code = int_pattern_alloc(&pdata, op2, imemory)) < 0
        )
        return_error((code < 0 ? code : gs_error_rangecheck));
    templat.client_data = pdata;
    code = gs_make_pattern(&cc_instance,
                           (const gs_pattern_template_t *)&templat,
                           &mat, igs, imemory);
    if (code < 0) {
        ifree_object(pdata, "int_pattern");
        return code;
    }
    make_istruct(op - 1, a_readonly, cc_instance.pattern);
    pop(1);
    return code;
}
Esempio n. 7
0
/* Clean up after a pathforall */
static int
path_cleanup(i_ctx_t *i_ctx_p)
{
    gs_path_enum *penum = r_ptr(esp + 6, gs_path_enum);

    gs_path_enum_cleanup(penum);
    ifree_object(penum, "path_cleanup");
    return 0;
}
Esempio n. 8
0
/* End a compositing operation. */
static void
end_composite(i_ctx_t *i_ctx_p, alpha_composite_state_t * pcp)
{
    /* Close and free the compositor and the compositing object. */
    if (pcp->cdev != pcp->orig_dev) {
        gs_closedevice(pcp->cdev);	/* also frees the device */
        gs_setdevice_no_init(igs, pcp->orig_dev);
    }
    ifree_object(pcp->pcte, "end_composite(gs_composite_t)");
}
Esempio n. 9
0
/* Common code for token reading + execution. */
static int
tokenexec_continue(i_ctx_t *i_ctx_p, scanner_state * pstate, bool save)
{
    os_ptr op;
    int code;
    /* Note that scan_token may change osp! */
    pop(1);
again:
    check_estack(1);
    code = scan_token(i_ctx_p, (ref *) (esp + 1), pstate);
    op = osp;
    switch (code) {
	case 0:
	    if (r_is_proc(esp + 1)) {	/* Treat procedure as a literal. */
		push(1);
		ref_assign(op, esp + 1);
		code = 0;
		break;
	    }
	    /* falls through */
	case scan_BOS:
	    ++esp;
	    code = o_push_estack;
	    break;
	case scan_EOF:		/* no tokens */
	    code = 0;
	    break;
	case scan_Refill:	/* need more data */
	    code = scan_handle_refill(i_ctx_p, pstate, save,
				      ztokenexec_continue);
	    switch (code) {
		case 0:	/* state is not copied to the heap */
		    goto again;
		case o_push_estack:
		    return code;
	    }
	    break;		/* error */
	case scan_Comment:
	case scan_DSC_Comment:
	    return ztoken_handle_comment(i_ctx_p, pstate, esp + 1, code,
					 save, true, ztokenexec_continue);
	default:		/* error */
	    scanner_error_object(i_ctx_p, pstate, &i_ctx_p->error_object);
	    break;
    }
    if (!save) {		/* Deallocate the scanner state record. */
	ifree_object(pstate, "token_continue");
    }
    return code;
}
Esempio n. 10
0
/* <charname> .glyphwidth <wx> <wy> */
static int
zglyphwidth(i_ctx_t *i_ctx_p)
{
    gs_glyph glyph;
    gs_text_enum_t *penum;
    int code;

    if ((code = glyph_show_setup(i_ctx_p, &glyph)) != 0 ||
        (code = gs_glyphwidth_begin(igs, glyph, imemory, &penum)) < 0)
        return code;
    if ((code = op_show_finish_setup(i_ctx_p, penum, 1, finish_stringwidth)) < 0) {
        ifree_object(penum, "zglyphwidth");
        return code;
    }
    return op_show_continue_pop(i_ctx_p, 1);
}
Esempio n. 11
0
/* <charname> glyphshow - */
static int
zglyphshow(i_ctx_t *i_ctx_p)
{
    gs_glyph glyph;
    gs_text_enum_t *penum;
    int code;

    if ((code = glyph_show_setup(i_ctx_p, &glyph)) != 0 ||
        (code = gs_glyphshow_begin(igs, glyph, imemory_local, &penum)) < 0)
        return code;
    *(op_proc_t *)&penum->enum_client_data = zglyphshow;
    if ((code = op_show_finish_setup(i_ctx_p, penum, 1, NULL)) < 0) {
        ifree_object(penum, "zglyphshow");
        return code;
    }
    return op_show_continue_pop(i_ctx_p, 1);
}
Esempio n. 12
0
/* Common code for token reading. */
static int
token_continue(i_ctx_t *i_ctx_p, scanner_state * pstate, bool save)
{
    os_ptr op = osp;
    int code;
    ref token;

    /* Note that gs_scan_token may change osp! */
    pop(1);                     /* remove the file or scanner state */
again:
    code = gs_scan_token(i_ctx_p, &token, pstate);
    op = osp;
    switch (code) {
        default:                /* error */
            if (code > 0)       /* comment, not possible */
                code = gs_note_error(e_syntaxerror);
            gs_scanner_error_object(i_ctx_p, pstate, &i_ctx_p->error_object);
            break;
        case scan_BOS:
            code = 0;
        case 0:         /* read a token */
            push(2);
            ref_assign(op - 1, &token);
            make_true(op);
            break;
        case scan_EOF:          /* no tokens */
            push(1);
            make_false(op);
            code = 0;
            break;
        case scan_Refill:       /* need more data */
            code = gs_scan_handle_refill(i_ctx_p, pstate, save,
                                      ztoken_continue);
            switch (code) {
                case 0: /* state is not copied to the heap */
                    goto again;
                case o_push_estack:
                    return code;
            }
            break;              /* error */
    }
    if (code <= 0 && !save) {   /* Deallocate the scanner state record. */
        ifree_object(pstate, "token_continue");
    }
    return code;
}
Esempio n. 13
0
/* <string> show - */
static int
zshow(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_text_enum_t *penum;
    int code = op_show_setup(i_ctx_p, op);

    if (code != 0 ||
	(code = gs_show_begin(igs, op->value.bytes, r_size(op), imemory, &penum)) < 0)
	return code;
    *(op_proc_t *)&penum->enum_client_data = zshow;
    if ((code = op_show_finish_setup(i_ctx_p, penum, 1, finish_show)) < 0) {
	ifree_object(penum, "op_show_enum_setup");
	return code;
    }
    return op_show_continue_pop(i_ctx_p, 1);
}
Esempio n. 14
0
/* <save> .forgetsave - */
static int
zforgetsave(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    alloc_save_t *asave;
    vm_save_t *vmsave;
    int code = restore_check_operand(op, &asave, idmemory);

    if (code < 0)
        return 0;
    vmsave = alloc_save_client_data(asave);
    /* Reset l_new in all stack entries if the new save level is zero. */
    restore_fix_stack(&o_stack, asave, false);
    restore_fix_stack(&e_stack, asave, false);
    restore_fix_stack(&d_stack, asave, false);
    /*
     * Forget the gsaves, by deleting the bottom gstate on
     * the current stack and the top one on the saved stack and then
     * concatenating the stacks together.
     */
    {
        gs_state *pgs = igs;
        gs_state *last;

        while (gs_state_saved(last = gs_state_saved(pgs)) != 0)
            pgs = last;
        gs_state_swap_saved(last, vmsave->gsave);
        gs_grestore(last);
        gs_grestore(last);
    }
    /* Forget the save in the memory manager. */
    code = alloc_forget_save_in(idmemory, asave);
    if (code < 0)
        return code;
    {
        uint space = icurrent_space;

        ialloc_set_space(idmemory, avm_local);
        /* See above for why we clear the gsave pointer here. */
        vmsave->gsave = 0;
        ifree_object(vmsave, "zrestore");
        ialloc_set_space(idmemory, space);
    }
    pop(1);
    return 0;
}
Esempio n. 15
0
/* <ax> <ay> <string> ashow - */
static int
zashow(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_text_enum_t *penum;
    double axy[2];
    int code = num_params(op - 1, 2, axy);

    if (code < 0 ||
	(code = op_show_setup(i_ctx_p, op)) != 0 ||
	(code = gs_ashow_begin(igs, axy[0], axy[1], op->value.bytes, r_size(op), imemory, &penum)) < 0)
	return code;
    *(op_proc_t *)&penum->enum_client_data = zashow;
    if ((code = op_show_finish_setup(i_ctx_p, penum, 3, finish_show)) < 0) {
	ifree_object(penum, "op_show_enum_setup");
	return code;
    }
    return op_show_continue_pop(i_ctx_p, 3);
}
Esempio n. 16
0
/* Common code for charpath and .charboxpath. */
static int
zchar_path(i_ctx_t *i_ctx_p, op_proc_t proc, 
	   int (*begin)(gs_state *, const byte *, uint,
			bool, gs_memory_t *, gs_text_enum_t **))
{
    os_ptr op = osp;
    gs_text_enum_t *penum;
    int code;

    check_type(*op, t_boolean);
    code = op_show_setup(i_ctx_p, op - 1);
    if (code != 0 ||
	(code = begin(igs, op[-1].value.bytes, r_size(op - 1),
		      op->value.boolval, imemory, &penum)) < 0)
	return code;
    *(op_proc_t *)&penum->enum_client_data = proc;
    if ((code = op_show_finish_setup(i_ctx_p, penum, 2, finish_show)) < 0) {
	ifree_object(penum, "op_show_enum_setup");
	return code;
    }
    return op_show_continue_pop(i_ctx_p, 2);
}
Esempio n. 17
0
/* - save <save> */
int
zsave(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint space = icurrent_space;
    vm_save_t *vmsave;
    ulong sid;
    int code;
    gs_state *prev;

    if (I_VALIDATE_BEFORE_SAVE)
        ivalidate_clean_spaces(i_ctx_p);
    ialloc_set_space(idmemory, avm_local);
    vmsave = ialloc_struct(vm_save_t, &st_vm_save, "zsave");
    ialloc_set_space(idmemory, space);
    if (vmsave == 0)
        return_error(e_VMerror);
    code = alloc_save_state(idmemory, vmsave, &sid);
    if (code < 0)
        return code;
    if (sid == 0) {
        ifree_object(vmsave, "zsave");
        return_error(e_VMerror);
    }
    if_debug2('u', "[u]vmsave 0x%lx, id = %lu\n",
              (ulong) vmsave, (ulong) sid);
    code = gs_gsave_for_save(igs, &prev);
    if (code < 0)
        return code;
    code = gs_gsave(igs);
    if (code < 0)
        return code;
    vmsave->gsave = prev;
    push(1);
    make_tav(op, t_save, 0, saveid, sid);
    if (I_VALIDATE_AFTER_SAVE)
        ivalidate_clean_spaces(i_ctx_p);
    return 0;
}
Esempio n. 18
0
/* - gstate <gstate> */
int
zgstate(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

    int code = gstate_check_space(i_ctx_p, istate, icurrent_space);
    igstate_obj *pigo;
    gs_state *pnew;
    int_gstate *isp;

    if (code < 0)
	return code;
    pigo = ialloc_struct(igstate_obj, &st_igstate_obj, "gstate");
    if (pigo == 0)
	return_error(e_VMerror);
    pnew = gs_state_copy(igs, imemory);
    if (pnew == 0) {
	ifree_object(pigo, "gstate");
	return_error(e_VMerror);
    }
    isp = gs_int_gstate(pnew);
    int_gstate_map_refs(isp, ref_mark_new);
    push(1);
    /*
     * Since igstate_obj isn't a ref, but only contains a ref, save won't
     * clear its l_new bit automatically, and restore won't set it
     * automatically; we have to make sure this ref is on the changes chain.
     */
    make_iastruct(op, a_all, pigo);
#if 0 /* Bug 689849 "gstate leaks memory" */ 
    make_null(&pigo->gstate);
    ref_save(op, &pigo->gstate, "gstate");
    make_istruct_new(&pigo->gstate, 0, pnew);
#else
    make_istruct(&pigo->gstate, 0, pnew);
#endif
    return 0;
}
Esempio n. 19
0
/* <string|name> <font_dict> .buildfont9 <string|name> <font> */
static int
zbuildfont9(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    build_proc_refs build;
    int code = build_proc_name_refs(imemory, &build, NULL, "%Type9BuildGlyph");
    gs_font_cid_data common;
    ref GlyphDirectory, GlyphData, DataSource;
    ref *prfda, cfnstr;
    ref *pCIDFontName, CIDFontName;
    gs_font_type1 **FDArray;
    uint FDArray_size;
    int FDBytes;
    uint CIDMapOffset;
    gs_font_base *pfont;
    gs_font_cid0 *pfcid;
    uint i;

    /*
     * If the CIDFont's data have been loaded into VM, GlyphData will be
     * a string or an array of strings; if they are loaded incrementally
     * from a file, GlyphData will be an integer, and DataSource will be
     * a (reusable) stream.
     */
    if (code < 0 ||
        (code = cid_font_data_param(op, &common, &GlyphDirectory)) < 0 ||
        (code = dict_find_string(op, "FDArray", &prfda)) < 0 ||
        (code = dict_find_string(op, "CIDFontName", &pCIDFontName)) <= 0 ||
        (code = dict_int_param(op, "FDBytes", 0, MAX_FDBytes, -1, &FDBytes)) < 0
        )
        return code;
    /*
     * Since build_gs_simple_font may resize the dictionary and cause
     * pointers to become invalid, save CIDFontName
     */
    CIDFontName = *pCIDFontName;
    if (r_has_type(&GlyphDirectory, t_null)) {
        /* Standard CIDFont, require GlyphData and CIDMapOffset. */
        ref *pGlyphData;

        if ((code = dict_find_string(op, "GlyphData", &pGlyphData)) < 0 ||
            (code = dict_uint_param(op, "CIDMapOffset", 0, max_uint - 1,
                                    max_uint, &CIDMapOffset)) < 0)
            return code;
        GlyphData = *pGlyphData;
        if (r_has_type(&GlyphData, t_integer)) {
            ref *pds;
            stream *ignore_s;

            if ((code = dict_find_string(op, "DataSource", &pds)) < 0)
                return code;
            check_read_file(i_ctx_p, ignore_s, pds);
            DataSource = *pds;
        } else {
            if (!r_has_type(&GlyphData, t_string) && !r_is_array(&GlyphData))
                return_error(e_typecheck);
            make_null(&DataSource);
        }
    } else {
        make_null(&GlyphData);
        make_null(&DataSource);
        CIDMapOffset = 0;
    }
    if (!r_is_array(prfda))
        return_error(e_invalidfont);
    FDArray_size = r_size(prfda);
    if (FDArray_size == 0)
        return_error(e_invalidfont);
    FDArray = ialloc_struct_array(FDArray_size, gs_font_type1 *,
                                  &st_gs_font_type1_ptr_element,
                                  "buildfont9(FDarray)");
    if (FDArray == 0)
        return_error(e_VMerror);
    memset(FDArray, 0, sizeof(gs_font_type1 *) * FDArray_size);
    for (i = 0; i < FDArray_size; ++i) {
        ref rfd;

        array_get(imemory, prfda, (long)i, &rfd);
        code = fd_array_element(i_ctx_p, &FDArray[i], &rfd);
        if (code < 0)
            goto fail;
    }
    code = build_gs_outline_font(i_ctx_p, op, &pfont, ft_CID_encrypted,
                                &st_gs_font_cid0, &build,
                                bf_Encoding_optional | bf_UniqueID_ignored,
                                build_gs_simple_font);
    if (code < 0)
        goto fail;
    if (code == 1) {
        /* The font already has a FID, don't need to build it again.
           Release FDArray and return normally.
           fixme: FDArray fonts are thrown for garbager.
           We're not safe to build them after
           build_gs_simple_font(..., &pfont, ...),
           because a failure in building them would throw
           an underbuilt font with unclear consequences.
         */
        ifree_object(FDArray, "buildfont9(FDarray)");
        return 0;
    }
    pfont->procs.enumerate_glyph = gs_font_cid0_enumerate_glyph;
    pfont->procs.glyph_outline = z9_glyph_outline;
    pfont->procs.glyph_info = z9_glyph_info;
    pfcid = (gs_font_cid0 *)pfont;
    pfcid->cidata.common = common;
    pfcid->cidata.CIDMapOffset = CIDMapOffset;
    pfcid->cidata.FDArray = FDArray;
    pfcid->cidata.FDArray_size = FDArray_size;
    pfcid->cidata.FDBytes = FDBytes;
    pfcid->cidata.glyph_data = z9_glyph_data;
    pfcid->cidata.proc_data = 0;	/* for GC */
    if (pfcid->font_name.size == 0) {
        get_font_name(imemory, &cfnstr, &CIDFontName);
        copy_font_name(&pfcid->font_name, &cfnstr);
    }
    ref_assign(&pfont_data(pfont)->u.cid0.GlyphDirectory, &GlyphDirectory);
    ref_assign(&pfont_data(pfont)->u.cid0.GlyphData, &GlyphData);
    ref_assign(&pfont_data(pfont)->u.cid0.DataSource, &DataSource);
    code = define_gs_font(i_ctx_p, (gs_font *)pfont);
    if (code >= 0)
       code = gs_notify_register(&pfont->notify_list, notify_remove_font_type9, pfont);
    if (code >= 0) {
        for (i = 0; i < FDArray_size; ++i) {
            FDArray[i]->dir = pfont->dir;
            FDArray[i]->data.parent = pfont;
        }
        return code;
    }
 fail:
    ifree_object(FDArray, "buildfont9(FDarray)");
    return code;
}
Esempio n. 20
0
/* <string> <numarray|numstring> xyshow - */
static int
moveshow(i_ctx_t *i_ctx_p, bool have_x, bool have_y)
{
    os_ptr op = osp;
    gs_text_enum_t *penum = NULL;
    int code = op_show_setup(i_ctx_p, op - 1);
    int format;
    uint i, size, widths_needed;
    float *values;
    bool CPSI_mode = gs_currentcpsimode(imemory);

    if (code != 0)
        return code;
    format = num_array_format(op);
    if (format < 0)
        return format;
    size = num_array_size(op, format);
    values = (float *)ialloc_byte_array(size, sizeof(float), "moveshow");
    if (values == 0)
        return_error(gs_error_VMerror);
    if (CPSI_mode)
        memset(values, 0, size * sizeof(values[0])); /* Safety. */
    if ((code = gs_xyshow_begin(igs, op[-1].value.bytes, r_size(op - 1),
                                (have_x ? values : (float *)0),
                                (have_y ? values : (float *)0),
                                size, imemory_local, &penum)) < 0) {
        ifree_object(values, "moveshow");
        if (penum)	/* if there was an error, the text_enum may not have been allocated */
            penum->text.x_widths = penum->text.y_widths = NULL;
        return code;
    }
    if (CPSI_mode) {
        /* CET 13-29.PS page 2 defines a longer width array
           then the text requires, and CPSI silently ignores extra elements.
           So we need to compute exact number of characters
           to know how many elements to load and type check. */
        code = gs_text_count_chars(igs, gs_get_text_params(penum), imemory);
        if (code < 0)
            return code;
        widths_needed = code;
        if (have_x && have_y)
            widths_needed <<= 1;
    } else
        widths_needed = size;
    for (i = 0; i < widths_needed; ++i) {
        ref value;

        switch (code = num_array_get(imemory, op, format, i, &value)) {
        case t_integer:
            values[i] = (float)value.value.intval; break;
        case t_real:
            values[i] = value.value.realval; break;
        case t_null:
            code = gs_note_error(gs_error_rangecheck);
            /* falls through */
        default:
            ifree_object(values, "moveshow");
        penum->text.x_widths = penum->text.y_widths = NULL;
            return code;
        }
    }
    if ((code = op_show_finish_setup(i_ctx_p, penum, 2, NULL)) < 0) {
        ifree_object(values, "moveshow");
        penum->text.x_widths = penum->text.y_widths = NULL;
        return code;
    }
    pop(2);
    return op_show_continue(i_ctx_p);
}
Esempio n. 21
0
int
zrestore(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    alloc_save_t *asave;
    bool last;
    vm_save_t *vmsave;
    int code = restore_check_operand(op, &asave, idmemory);

    if (code < 0)
        return code;
    if_debug2('u', "[u]vmrestore 0x%lx, id = %lu\n",
              (ulong) alloc_save_client_data(asave),
              (ulong) op->value.saveid);
    if (I_VALIDATE_BEFORE_RESTORE)
        ivalidate_clean_spaces(i_ctx_p);
    /* Check the contents of the stacks. */
    osp--;
    {
        int code;

        if ((code = restore_check_stack(i_ctx_p, &o_stack, asave, false)) < 0 ||
                (code = restore_check_stack(i_ctx_p, &e_stack, asave, true)) < 0 ||
                (code = restore_check_stack(i_ctx_p, &d_stack, asave, false)) < 0
           ) {
            osp++;
            return code;
        }
    }
    /* Reset l_new in all stack entries if the new save level is zero. */
    /* Also do some special fixing on the e-stack. */
    restore_fix_stack(&o_stack, asave, false);
    restore_fix_stack(&e_stack, asave, true);
    restore_fix_stack(&d_stack, asave, false);
    /* Iteratively restore the state of memory, */
    /* also doing a grestoreall at each step. */
    do {
        vmsave = alloc_save_client_data(alloc_save_current(idmemory));
        /* Restore the graphics state. */
        gs_grestoreall_for_restore(igs, vmsave->gsave);
        /*
         * If alloc_save_space decided to do a second save, the vmsave
         * object was allocated one save level less deep than the
         * current level, so ifree_object won't actually free it;
         * however, it points to a gsave object that definitely
         * *has* been freed.  In order not to trip up the garbage
         * collector, we clear the gsave pointer now.
         */
        vmsave->gsave = 0;
        /* Now it's safe to restore the state of memory. */
        code = alloc_restore_step_in(idmemory, asave);
        if (code < 0)
            return code;
        last = code;
    }
    while (!last);
    {
        uint space = icurrent_space;

        ialloc_set_space(idmemory, avm_local);
        ifree_object(vmsave, "zrestore");
        ialloc_set_space(idmemory, space);
    }
    dict_set_top();		/* reload dict stack cache */
    if (I_VALIDATE_AFTER_RESTORE)
        ivalidate_clean_spaces(i_ctx_p);
    /* If the i_ctx_p LockFilePermissions is true, but the userparams */
    /* we just restored is false, we need to make sure that we do not */
    /* cause an 'invalidaccess' in setuserparams. Temporarily set     */
    /* LockFilePermissions false until the gs_lev2.ps can do a        */
    /* setuserparams from the restored userparam dictionary.          */
    i_ctx_p->LockFilePermissions = false;
    return 0;
}
Esempio n. 22
0
/* <in1> ... <function_struct> %execfunction <out1> ... */
int
zexecfunction(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

        /*
         * Since this operator's name begins with %, the name is not defined
         * in systemdict.  The only place this operator can ever appear is
         * in the execute-only closure created by .buildfunction.
         * Therefore, in principle it is unnecessary to check the argument.
         * However, we do a little checking anyway just on general
         * principles.  Note that since the argument may be an instance of
         * any subclass of gs_function_t, we currently have no way to check
         * its type.
         */
    if (!r_is_struct(op) ||
        !r_has_masked_attrs(op, a_executable | a_execute, a_executable | a_all)
        )
        return_error(gs_error_typecheck);
    {
        gs_function_t *pfn = (gs_function_t *) op->value.pstruct;
        int m = pfn->params.m, n = pfn->params.n;
        int diff = n - (m + 1);

        if (diff > 0)
            check_ostack(diff);
        {
            float params[20];	/* arbitrary size, just to avoid allocs */
            float *in;
            float *out;
            int code = 0;

            if (m + n <= countof(params)) {
                in = params;
            } else {
                in = (float *)ialloc_byte_array(m + n, sizeof(float),
                                                "%execfunction(in/out)");
                if (in == 0)
                    code = gs_note_error(gs_error_VMerror);
            }
            out = in + m;
            if (code < 0 ||
                (code = float_params(op - 1, m, in)) < 0 ||
                (code = gs_function_evaluate(pfn, in, out)) < 0
                )
                DO_NOTHING;
            else {
                if (diff > 0)
                    push(diff);	/* can't fail */
                else if (diff < 0) {
                    pop(-diff);
                    op = osp;
                }
                code = make_floats(op + 1 - n, out, n);
            }
            if (in != params)
                ifree_object(in, "%execfunction(in)");
            return code;
        }
    }
}
Esempio n. 23
0
/*
 * Continuation procedure for processing sampled values.
 */
static int
sampled_data_continue(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_sampled_data_enum *penum = senum;
    gs_function_Sd_params_t * params =
            (gs_function_Sd_params_t *)&penum->pfn->params;
    int i, j, num_out = params->n;
    int code = 0;
    byte * data_ptr;
    double sampled_data_value_max = (double)((1 << params->BitsPerSample) - 1);
    int bps = bits2bytes(params->BitsPerSample), stack_depth_adjust = 0;

    /*
     * Check to make sure that the procedure produced the correct number of
     * values.  If not, move the stack back to where it belongs and abort
     */
    if (num_out + O_STACK_PAD + penum->o_stack_depth != ref_stack_count(&o_stack)) {
        stack_depth_adjust = ref_stack_count(&o_stack) - penum->o_stack_depth;

        if (stack_depth_adjust < 0) {
            /*
             * If we get to here then there were major problems.  The function
             * removed too many items off of the stack.  We had placed extra
             * (unused) stack stack space to allow for this but the function
             * exceeded even that.  Data on the stack may have been lost.
             * The only thing that we can do is move the stack pointer back and
             * hope.  (We have not seen real Postscript files that have this
             * problem.)
             */
            push(-stack_depth_adjust);
            ifree_object(penum->pfn, "sampled_data_continue(pfn)");
            ifree_object(penum, "sampled_data_continue((enum)");
            return_error(e_undefinedresult);
        }
    }

    /* Save data from the given function */
    data_ptr = cube_ptr_from_index(params, penum->indexes);
    for (i=0; i < num_out; i++) {
        ulong cv;
        double value;
        double rmin = params->Range[2 * i];
        double rmax = params->Range[2 * i + 1];

        code = real_param(op + i - num_out + 1, &value);
        if (code < 0)
            return code;
        if (value < rmin)
            value = rmin;
        else if (value > rmax)
            value = rmax;
        value = (value - rmin) / (rmax - rmin);		/* Convert to 0 to 1.0 */
        cv = (int) (value * sampled_data_value_max + 0.5);
        for (j = 0; j < bps; j++)
            data_ptr[bps * i + j] = (byte)(cv >> ((bps - 1 - j) * 8));	/* MSB first */
    }
    pop(num_out);		    /* Move op to base of result values */

    /* Check if we are done collecting data. */

    if (increment_cube_indexes(params, penum->indexes)) {
        if (stack_depth_adjust == 0)
            pop(O_STACK_PAD);	    /* Remove spare stack space */
        else
            pop(stack_depth_adjust - num_out);
        /* Execute the closing procedure, if given */
        code = 0;
        if (esp_finish_proc != 0)
            code = esp_finish_proc(i_ctx_p);

        return code;
    } else {
        if (stack_depth_adjust) {
            stack_depth_adjust -= num_out;
            push(O_STACK_PAD - stack_depth_adjust);
            for (i=0;i<O_STACK_PAD - stack_depth_adjust;i++)
                make_null(op - i);
        }
    }

    /* Now get the data for the next location */

    return sampled_data_sample(i_ctx_p);
}
Esempio n. 24
0
/* Common setup for encoding and decoding filters */
static int
bhc_setup(os_ptr op, stream_BHC_state * pbhcs)
{
    int code;
    int num_counts;
    int data[max_hc_length + 1 + 256 + max_zero_run + 1];
    uint dsize;
    int i;
    uint num_values, accum;
    ushort *counts;
    ushort *values;

    check_type(*op, t_dictionary);
    check_dict_read(*op);
    if ((code = dict_bool_param(op, "FirstBitLowOrder", false,
                                &pbhcs->FirstBitLowOrder)) < 0 ||
        (code = dict_int_param(op, "MaxCodeLength", 1, max_hc_length,
                               max_hc_length, &num_counts)) < 0 ||
        (code = dict_bool_param(op, "EndOfData", true,
                                &pbhcs->EndOfData)) < 0 ||
        (code = dict_uint_param(op, "EncodeZeroRuns", 2, 256,
                                256, &pbhcs->EncodeZeroRuns)) < 0 ||
    /* Note: the code returned from the following call */
    /* is actually the number of elements in the array. */
        (code = dict_int_array_param(imemory, op, "Tables", countof(data),
                                     data)) <= 0
        )
        return (code < 0 ? code : gs_note_error(e_rangecheck));
    dsize = code;
    if (dsize <= num_counts + 2)
        return_error(e_rangecheck);
    for (i = 0, num_values = 0, accum = 0; i <= num_counts;
         i++, accum <<= 1
        ) {
        int count = data[i];

        if (count < 0)
            return_error(e_rangecheck);
        num_values += count;
        accum += count;
    }
    if (dsize != num_counts + 1 + num_values ||
        accum != 1 << (num_counts + 1) ||
        pbhcs->EncodeZeroRuns >
        (pbhcs->EndOfData ? num_values - 1 : num_values)
        )
        return_error(e_rangecheck);
    for (; i < num_counts + 1 + num_values; i++) {
        int value = data[i];

        if (value < 0 || value >= num_values)
            return_error(e_rangecheck);
    }
    pbhcs->definition.counts = counts =
        (ushort *) ialloc_byte_array(num_counts + 1, sizeof(ushort),
                                     "bhc_setup(counts)");
    pbhcs->definition.values = values =
        (ushort *) ialloc_byte_array(num_values, sizeof(ushort),
                                     "bhc_setup(values)");
    if (counts == 0 || values == 0) {
        ifree_object(values, "bhc_setup(values)");
        ifree_object(counts, "bhc_setup(counts)");
        return_error(e_VMerror);
    }
    for (i = 0; i <= num_counts; i++)
        counts[i] = data[i];
    pbhcs->definition.counts = counts;
    pbhcs->definition.num_counts = num_counts;
    for (i = 0; i < num_values; i++)
        values[i] = data[i + num_counts + 1];
    pbhcs->definition.values = values;
    pbhcs->definition.num_values = num_values;
    return 0;
}