Beispiel #1
0
static void
fnt_parse_cid_widths(pdc_core *pdc, fnt_font *font)
{
    static const char fn[] = "fnt_parse_cid_widths";
    int slot, slota, slotm;
    const char *chunk;
    char **strlist = NULL, **sstrlist = NULL, *str;
    int cid = 0, cidfirst, cidlast, width;
    int il, is, ns, nss = 0;
    int wformat = 2;

    /* search for font name */
    slotm = 100;
    for (slot = 0; slot < slotm; slot += FNT_CIDMETRIC_INCR)
    {
        if (!strcmp(fnt_cid_width_arrays[slot], font->name))
            break;
    }
    if (slot == slotm)
        return;

    /* we take the maximum */
    font->m.numwidths = fnt_get_maxcid(font->m.charcoll, -1) + 1;
    font->m.widths = (int *) pdc_malloc(pdc,
                                 font->m.numwidths * sizeof(int), fn);

    slota = slot + 1;                       /* skip font name  */
    slotm = slot + FNT_CIDMETRIC_INCR;
    for (slot = slota; slot < slotm; slot++)
    {
        chunk = fnt_cid_width_arrays[slot];

        ns = pdc_split_stringlist(pdc, chunk, " \n", 0, &strlist);
        for (is = 0; is < ns; is++)
        {
            str = strlist[is];

            /* check for next format 1 chunk */
            if (wformat == 2 && strchr(str, '['))
            {
                nss = pdc_split_stringlist(pdc, str, " [", 0, &sstrlist);
                str = sstrlist[0];
                pdc_str2integer(str, 0, &cidfirst);
                for (; cid < cidfirst; cid++)
                    font->m.widths[cid] = FNT_DEFAULT_CIDWIDTH;
                str = sstrlist[1];
                wformat = 1;
            }

            /* format 1:  cid [width_1 width_2 ... width_n] */
            if (wformat == 1)
            {
                il = (int) strlen(str) - 1;
                if (str[il] == ']')
                {
                    str[il] = 0;
                    wformat = 2;
                }

                pdc_str2integer(str, 0, &font->m.widths[cid]);
                cid++;

                if (nss)
                {
                    pdc_cleanup_stringlist(pdc, sstrlist);
                    nss = 0;
                }
            }
            else
            {
                /* format 2:  cid_first cid_last width */
                pdc_str2integer(str, 0, &cidfirst);
                is++;
                str = strlist[is];
                pdc_str2integer(str, 0, &cidlast);
                is++;
                str = strlist[is];
                pdc_str2integer(str, 0, &width);

                for (; cid < cidfirst; cid++)
                    font->m.widths[cid] = FNT_DEFAULT_CIDWIDTH;
                for (; cid <= cidlast; cid++)
                    font->m.widths[cid] = width;
            }
        }

        pdc_cleanup_stringlist(pdc, strlist);
    }

    for (; cid < font->m.numwidths; cid++)
        font->m.widths[cid] = FNT_DEFAULT_CIDWIDTH;

    if (pdc_logg_is_enabled(pdc, 5, trc_font))
    {
        for (cid = 0; cid < font->m.numwidths; cid++)
            pdc_logg(pdc, "\t\t\tCID width[%d]: %d\n",
                     cid, font->m.widths[cid]);
    }
}
Beispiel #2
0
/*
** Returns CMap slot and for standard CJK fonts: fontandle.
**
** pdc_invalidenc: predefined CMap not found
** pdc_cid or pdc_unicode: predefined CMap found
**
** *o_slot:
** >= 0:  standard font found
**  < 0:  |error code|
*/
pdc_bool
pdf_handle_cidfont(PDF *p, const char *fontname, const char *encoding,
                   pdc_encoding enc, pdf_font *font, int *o_slot,
                   pdc_encoding *newenc)
{
    const char *encapiname = encoding;
    fnt_cmap_info cmapinfo;
    const fnt_font_metric *fontmetric;
    pdc_bool isidentity = pdc_false;
    pdc_bool isstdfont = pdc_false;
    pdc_bool iscjkcp = pdc_false;
    int charcoll, slot;

    (void) enc;
    (void) iscjkcp;
    (void) encapiname;

    *o_slot = -1;
    *newenc = pdc_invalidenc;


    /*
     * Look whether font is already in the cache.
     * If font with same name and encoding is found,
     * returns its slot number.
     */

    for (slot = 0; slot < p->fonts_number; slot++)
    {
        if (p->fonts[slot].ft.enc == pdc_cid &&
            p->fonts[slot].opt.fontstyle == font->opt.fontstyle &&
            p->fonts[slot].opt.embedding == font->opt.embedding &&
            !strcmp(p->fonts[slot].apiname, fontname) &&
            !strcmp(p->fonts[slot].ft.cmapname, encoding))
        {
            *o_slot = slot;
            *newenc = pdc_cid;
            return pdc_true;
        }
    }

    /* Check the requested CMap */
    charcoll = fnt_get_predefined_cmap_info(encoding, &cmapinfo);
    if (charcoll == (int) cc_none)
        return pdc_true;

    pdc_logg_cond(p->pdc, 1, trc_font,
        "\tPredefined CMap \"%s\" found\n", encoding);

    /* Check whether this CMap is supported in the desired PDF version */
    if (cmapinfo.compatibility > p->compatibility)
    {
        pdc_set_errmsg(p->pdc, PDF_E_DOC_PDFVERSION,
            encoding, pdc_get_pdfversion(p->pdc, p->compatibility), 0, 0);
        return pdc_false;
    }

    /* For Unicode capable language wrappers only UCS2/UTF16 CMaps allowed */
    if (cmapinfo.codesize == 0 && p->pdc->unicaplang)
    {
        pdc_set_errmsg(p->pdc, PDF_E_FONT_NEEDUCS2, 0, 0, 0, 0);
        return pdc_false;
    }

    /* Check whether the font name is among the known Acrobat CJK fonts */
    charcoll = fnt_get_preinstalled_cidfont(fontname, &fontmetric);
    isidentity = cmapinfo.charcoll == (int) cc_identity;
    if (isidentity)
        cmapinfo.charcoll = abs(charcoll);

    /* known Acrobat CID font */
    if (charcoll != (int) cc_none)
    {
        pdc_logg_cond(p->pdc, 1, trc_font,
            "\tStandard CJK font \"%s\" found\n", fontname);

        /* Selected CMap and known standard font don't match */
        if ((cmapinfo.charcoll != abs(charcoll) ||
             (charcoll == (int) cc_japanese && cmapinfo.codesize == -2)))
        {
            pdc_set_errmsg(p->pdc, PDF_E_CJK_UNSUPP_CHARCOLL,
                           0, 0, 0, 0);
            return pdc_false;
        }
        isstdfont = pdc_true;


        /* Embedding not possible */
        if (font->opt.embedding)
        {
            pdc_set_errmsg(p->pdc, PDF_E_FONT_EMBEDCMAP, 0, 0, 0, 0);
            return pdc_false;
        }
    }
#ifdef WIN32
    else if (iscjkcp && !p->pdc->ptfrun)
    {
        return pdc_true;
    }
#endif


    /* embedding check */
    if (!pdf_check_font_embedding(p, font, fontname))
        return pdc_false;

    /* supplement number, number of codes = (maximal) number of CIDs */
    font->supplement = fnt_get_supplement(&cmapinfo, p->compatibility);
    if (isidentity)
        font->supplement = -1;
    font->ft.numcodes = fnt_get_maxcid(cmapinfo.charcoll, font->supplement) + 1;

    {
        font->passthrough = pdc_true;
        font->codesize = 0;
    }

    /* CMap and default settings */
    font->ft.vertical = cmapinfo.vertical;
    font->ft.cmapname = pdc_strdup(p->pdc, encoding);
    if (font->outcmapname == NULL)
        font->outcmapname = pdc_strdup(p->pdc, encoding);
    font->ft.enc = pdc_cid;
    font->iscidfont = pdc_true;

    /* Fill up the font struct */
    fnt_fill_font_metric(p->pdc, &font->ft, pdc_false, fontmetric);

    /* CID widths not available */
        font->widthsmissing = pdc_true;

    pdc_logg_cond(p->pdc, 1, trc_font,
        "\n\t%s CJK font: \"%s\"\n\tPredefined CMap: \"%s\"\n"
        "\tOrdering: \"%s\"\n\tSupplement: %d\n",
        font->ft.isstdfont ? "Adobe Standard" : "Custom", fontname, encoding,
        fnt_get_ordering_cid(font->ft.m.charcoll), font->supplement);

    *newenc = pdc_cid;

    return pdc_true;
}