Пример #1
0
int
build_gs_FDArray_font(i_ctx_t *i_ctx_p, ref *op,
                      gs_font_base **ppfont,
                      font_type ftype, gs_memory_type_ptr_t pstype,
                      const build_proc_refs * pbuild)
{
    gs_font_base *pfont;
    font_data *pdata;
    int code = build_gs_outline_font(i_ctx_p, op, &pfont, ftype, pstype,
                                     pbuild, bf_options_none,
                                     build_FDArray_sub_font);
    static const double bbox[4] = { 0, 0, 0, 0 };
    gs_uid uid;

    if (code < 0)
        return code;
    pdata = pfont_data(pfont);
    /* Fill in members normally set by build_gs_primitive_font. */
    make_null(&pdata->CharStrings);
    /* Fill in members normally set by build_gs_simple_font. */
    uid_set_invalid(&uid);
    init_gs_simple_font(pfont, bbox, &uid);
    pfont->encoding_index = ENCODING_INDEX_UNKNOWN;
    pfont->nearest_encoding_index = ENCODING_INDEX_UNKNOWN;
    /* Fill in members normally set by build_gs_font. */
    pfont->key_name = pfont->font_name;
    *ppfont = pfont;
    return 0;
}
Пример #2
0
/* The caller guarantees that *op is a dictionary. */
int
build_gs_primitive_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_base ** ppfont,
                        font_type ftype, gs_memory_type_ptr_t pstype,
                        const build_proc_refs * pbuild,
                        build_font_options_t options)
{
    ref *pcharstrings = 0;
    ref CharStrings;
    gs_font_base *pfont;
    font_data *pdata;
    int code;

    if (dict_find_string(op, "CharStrings", &pcharstrings) <= 0) {
        if (!(options & bf_CharStrings_optional))
            return_error(e_invalidfont);
    } else {
        ref *ignore;

        if (!r_has_type(pcharstrings, t_dictionary))
            return_error(e_invalidfont);
        if ((options & bf_notdef_required) != 0 &&
            dict_find_string(pcharstrings, ".notdef", &ignore) <= 0
            )
            return_error(e_invalidfont);
        /*
         * Since build_gs_simple_font may resize the dictionary and cause
         * pointers to become invalid, save CharStrings.
         */
        CharStrings = *pcharstrings;
    }
    code = build_gs_outline_font(i_ctx_p, op, ppfont, ftype, pstype, pbuild,
                                 options, build_gs_simple_font);
    if (code != 0)
        return code;
    pfont = *ppfont;
    pdata = pfont_data(pfont);
    if (pcharstrings)
        ref_assign(&pdata->CharStrings, &CharStrings);
    else
        make_null(&pdata->CharStrings);
    /* Check that the UniqueIDs match.  This is part of the */
    /* Adobe protection scheme, but we may as well emulate it. */
    if (uid_is_valid(&pfont->UID) &&
        !dict_check_uid_param(op, &pfont->UID)
        )
        uid_set_invalid(&pfont->UID);
    if (uid_is_valid(&pfont->UID)) {
        const gs_font *pfont0 = (const gs_font *)pfont;

        code = gs_font_find_similar(ifont_dir, &pfont0,
                       font_with_same_UID_and_another_metrics);
        if (code < 0)
            return code; /* Must not happen. */
        if (code)
            uid_set_invalid(&pfont->UID);
    }
    return 0;
}
Пример #3
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;
}