Ejemplo n.º 1
0
/*
 * Get the additional parameters for a Type 2 font (or FontType 2 FDArray
 * entry in a CIDFontType 0 font), beyond those common to Type 1 and Type 2
 * fonts.
 */
int
type2_font_params(const_os_ptr op, charstring_font_refs_t *pfr,
		  gs_type1_data *pdata1)
{
    int code;
    float dwx, nwx;
    ref *temp;

    pdata1->interpret = gs_type2_interpret;
    pdata1->lenIV = DEFAULT_LENIV_2;
    pdata1->subroutineNumberBias = subr_bias(pfr->Subrs);
    /* Get information specific to Type 2 fonts. */
    if (dict_find_string(pfr->Private, "GlobalSubrs", &temp) > 0) {
	if (!r_is_array(temp))
	    return_error(e_typecheck);
        pfr->GlobalSubrs = temp;
    }
    pdata1->gsubrNumberBias = subr_bias(pfr->GlobalSubrs);
    if ((code = dict_uint_param(pfr->Private, "gsubrNumberBias",
				0, max_uint, pdata1->gsubrNumberBias,
				&pdata1->gsubrNumberBias)) < 0 ||
	(code = dict_float_param(pfr->Private, "defaultWidthX", 0.0,
				 &dwx)) < 0 ||
	(code = dict_float_param(pfr->Private, "nominalWidthX", 0.0,
				 &nwx)) < 0
	)
	return code;
    pdata1->defaultWidthX = float2fixed(dwx);
    pdata1->nominalWidthX = float2fixed(nwx);
    {
	ref *pirs;

	if (dict_find_string(pfr->Private, "initialRandomSeed", &pirs) <= 0)
	    pdata1->initialRandomSeed = 0;
	else if (!r_has_type(pirs, t_integer))
	    return_error(e_typecheck);
	else
	    pdata1->initialRandomSeed = pirs->value.intval;
    }
    return 0;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
/* <source> <dict> eexecDecode/filter <file> */
static int
zexD(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    stream_exD_state state;
    int code;

    (*s_exD_template.set_defaults)((stream_state *)&state);
    if (r_has_type(op, t_dictionary)) {
        uint cstate;
        bool is_eexec;

        check_dict_read(*op);
        if ((code = dict_uint_param(op, "seed", 0, 0xffff, 0x10000,
                                    &cstate)) < 0 ||
            (code = dict_int_param(op, "lenIV", 0, max_int, 4,
                                   &state.lenIV)) < 0 ||
            (code = dict_bool_param(op, "eexec", false,
                                   &is_eexec)) < 0 ||
            (code = dict_bool_param(op, "keep_spaces", false,
                                   &state.keep_spaces)) < 0
            )
            return code;
        state.cstate = cstate;
        state.binary = (is_eexec ? -1 : 1);
        code = 1;
    } else {
        state.binary = 1;
        code = eexec_param(op, &state.cstate);
    }
    if (code < 0)
        return code;
    /*
     * If we're reading a .PFB file, let the filter know about it,
     * so it can read recklessly to the end of the binary section.
     */
    if (r_has_type(op - 1, t_file)) {
        stream *s = (op - 1)->value.pfile;

        if (s->state != 0 && s->state->templat == &s_PFBD_template) {
            stream_PFBD_state *pss = (stream_PFBD_state *)s->state;

            state.pfb_state = pss;
            /*
             * If we're reading the binary section of a PFB stream,
             * avoid the conversion from binary to hex and back again.
             */
            if (pss->record_type == 2) {
                /*
                 * The PFB decoder may have converted some data to hex
                 * already.  Convert it back if necessary.
                 */
                if (pss->binary_to_hex && sbufavailable(s) > 0) {
                    state.binary = 0;	/* start as hex */
                    state.hex_left = sbufavailable(s);
                } else {
                    state.binary = 1;
                }
                pss->binary_to_hex = 0;
            }
        }
    }
    return filter_read(i_ctx_p, code, &s_exD_template, (stream_state *)&state, 0);
}