Ejemplo n.º 1
0
int
zchar_charstring_data(gs_font *font, const ref *pgref, gs_glyph_data_t *pgd)
{
    ref *pcstr;

    if (dict_find(&pfont_data(font)->CharStrings, pgref, &pcstr) <= 0)
        return_error(e_undefined);
    if (!r_has_type(pcstr, t_string)) {
        /*
         * The ADOBEPS4 Windows driver replaces the .notdef entry of
         * otherwise normal Type 1 fonts with the procedure
         *	{pop 0 0 setcharwidth}
         * To prevent this from making the font unembeddable in PDF files
         * (with our present font-writing code), we recognize this as a
         * special case and return a Type 1 CharString consisting of
         *	0 0 hsbw endchar
         */
        if (font->FontType == ft_encrypted &&
            charstring_is_notdef_proc(font->memory, pcstr)
            )
            return charstring_make_notdef(pgd, font);
        else
            return_error(e_typecheck);
    }
    gs_glyph_data_from_string(pgd, pcstr->value.const_bytes, r_size(pcstr),
                              NULL);
    return 0;
}
Ejemplo n.º 2
0
static int
charstring_make_notdef(gs_glyph_data_t *pgd, gs_font *font)
{
    gs_font_type1 *const pfont = (gs_font_type1 *)font;
    static const byte char_data[4] = {
        139,			/* 0 */
        139,			/* 0 */
        c1_hsbw,
        cx_endchar
    };
    uint len = max(pfont->data.lenIV, 0) + sizeof(char_data);
    byte *chars = gs_alloc_string(font->memory, len, "charstring_make_notdef");

    if (chars == 0)
        return_error(e_VMerror);
    gs_glyph_data_from_string(pgd, chars, len, font);
    if (pfont->data.lenIV < 0)
        memcpy(chars, char_data, sizeof(char_data));
    else {
        crypt_state state = crypt_charstring_seed;

        memcpy(chars + pfont->data.lenIV, char_data, sizeof(char_data));
        gs_type1_encrypt(chars, chars, len, &state);
    }
    return 0;
}
Ejemplo n.º 3
0
/* pcref points to a t_string ref. */
static int
type1_continue_dispatch(i_ctx_t *i_ctx_p, gs_type1exec_state *pcxs,
                        const ref * pcref, ref *pos, int num_args)
{
    int value;
    int code;
    gs_glyph_data_t cs_data;
    gs_glyph_data_t *pcsd;

    cs_data.memory = imemory;
    if (pcref == 0) {
        pcsd = 0;
    } else {
        gs_glyph_data_from_string(&cs_data, pcref->value.const_bytes,
                                  r_size(pcref), NULL);
        pcsd = &cs_data;
    }
    /*
     * Since OtherSubrs may push or pop values on the PostScript operand
     * stack, remove the arguments of .type1execchar before calling the
     * Type 1 interpreter, and put them back afterwards unless we're
     * about to execute an OtherSubr procedure.  Also, we must set up
     * the callback data for pushing OtherSubrs arguments.
     */
    pcxs->i_ctx_p = i_ctx_p;
    pcxs->num_args = num_args;
    memcpy(pcxs->save_args, osp - (num_args - 1), num_args * sizeof(ref));
    osp -= num_args;
    gs_type1_set_callback_data(&pcxs->cis, pcxs);
    code = pcxs->cis.pfont->data.interpret(&pcxs->cis, pcsd, &value);
    switch (code) {
        case type1_result_callothersubr: {
            /*
             * The Type 1 interpreter handles all known OtherSubrs,
             * so this must be an unknown one.
             */
            const font_data *pfdata = pfont_data(gs_currentfont(igs));

            code = array_get(imemory, &pfdata->u.type1.OtherSubrs, (long)value, pos);
            if (code >= 0)
                return type1_result_callothersubr;
        }
    }
    /* Put back the arguments removed above. */
    memcpy(osp + 1, pcxs->save_args, num_args * sizeof(ref));
    osp += num_args;
    return code;
}
Ejemplo n.º 4
0
/* Get bytes from GlyphData or DataSource. */
static int
cid0_read_bytes(gs_font_cid0 *pfont, ulong base, uint count, byte *buf,
                gs_glyph_data_t *pgd)
{
    const font_data *pfdata = pfont_data(pfont);
    byte *data = buf;
    gs_font *gdfont = 0;	/* pfont if newly allocated, 0 if not */
    int code = 0;

    /* Check for overflow. */
    if (base != (long)base || base > base + count)
        return_error(e_rangecheck);
    if (r_has_type(&pfdata->u.cid0.DataSource, t_null)) {
        /* Get the bytes from GlyphData (a string or array of strings). */
        const ref *pgdata = &pfdata->u.cid0.GlyphData;

        if (r_has_type(pgdata, t_string)) {  /* single string */
            uint size = r_size(pgdata);

            if (base >= size || count > size - base)
                return_error(e_rangecheck);
            data = pgdata->value.bytes + base;
        } else {		/* array of strings */
            /*
             * The algorithm is similar to the one in
             * string_array_access_proc in zfont42.c, but it also has to
             * deal with the case where the requested string crosses array
             * elements.
             */
            ulong skip = base;
            uint copied = 0;
            uint index = 0;
            ref rstr;
            uint size;

            for (;; skip -= size, ++index) {
                int code = array_get(pfont->memory, pgdata, index, &rstr);

                if (code < 0)
                    return code;
                if (!r_has_type(&rstr, t_string))
                    return_error(e_typecheck);
                size = r_size(&rstr);
                if (skip < size)
                    break;
            }
            size -= skip;
            if (count <= size) {
                data = rstr.value.bytes + skip;
            } else {		/* multiple strings needed */
                if (data == 0) {  /* no buffer provided */
                    data = gs_alloc_string(pfont->memory, count,
                                           "cid0_read_bytes");
                    if (data == 0)
                        return_error(e_VMerror);
                    gdfont = (gs_font *)pfont; /* newly allocated */
                }
                memcpy(data, rstr.value.bytes + skip, size);
                copied = size;
                while (copied < count) {
                    int code = array_get(pfont->memory, pgdata, ++index, &rstr);

                    if (code < 0)
                        goto err;
                    if (!r_has_type(&rstr, t_string)) {
                        code = gs_note_error(e_typecheck);
                        goto err;
                    }
                    size = r_size(&rstr);
                    if (size > count - copied)
                        size = count - copied;
                    memcpy(data + copied, rstr.value.bytes, size);
                    copied += size;
                }
            }
        }
    } else {
        /* Get the bytes from DataSource (a stream). */
        stream *s;
        uint nread;
        i_ctx_t *i_ctx_p = get_minst_from_memory(pfont->memory)->i_ctx_p;

        check_read_known_file(i_ctx_p, s, &pfdata->u.cid0.DataSource, return_error);
        if (sseek(s, base) < 0)
            return_error(e_ioerror);
        if (data == 0) {	/* no buffer provided */
            data = gs_alloc_string(pfont->memory, count, "cid0_read_bytes");
            if (data == 0)
                return_error(e_VMerror);
            gdfont = (gs_font *)pfont; /* newly allocated */
        }
        if (sgets(s, data, count, &nread) < 0 || nread != count) {
            code = gs_note_error(e_ioerror);
            goto err;
        }
    }
    gs_glyph_data_from_string(pgd, data, count, gdfont);
    return code;
 err:
    if (data != buf)
        gs_free_string(pfont->memory, data, count, "cid0_read_bytes");
    return code;
}