Esempio n. 1
0
int
pdf__add_bookmark(PDF *p, const char *text, int len, int parent, int open)
{
    static const char *fn = "pdf__add_bookmark";
    pdf_outline self;
    pdf_dest *dest = (pdf_dest *) p->bookmark_dest;
    char *hypertext = NULL;
    int acthdl;
    int retval = 0;

    len = pdc_check_text_length(p->pdc, &text, len, PDF_MAXSTRINGSIZE);
    if (!len)
        pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "text", 0, 0, 0);

    pdf_init_outline(p, &self);

    if (parent != 0)
        pdf_check_handle(p, parent, pdc_bookmarkhandle);
    self.parent = parent;
    self.open = open;

    /* creating a Launch action - defined via bookmarkdest */
    if (dest->filename)
    {
        char *actoptlist;

        actoptlist = (char *)
            pdc_malloc(p->pdc, strlen(dest->filename) + 80, fn);
        pdc_sprintf(p->pdc, pdc_false, actoptlist, "filename {%s} ",
                    dest->filename);
        acthdl = pdf__create_action(p, "Launch", actoptlist);
        if (acthdl != -1)
        {
            if (p->pdc->hastobepos) acthdl++;
            pdc_sprintf(p->pdc, pdc_false, actoptlist, "activate %d", acthdl);
            self.action = pdc_strdup(p->pdc, actoptlist);
        }

        pdc_free(p->pdc, actoptlist);
    }
    else
    {
        self.dest = pdf_init_destination(p);
        *self.dest = *dest;
        if (dest->name)
            self.dest->name = pdc_strdup(p->pdc, dest->name);
    }

    memcpy(self.textcolor, dest->color, 3 * sizeof(pdc_scalar));
    self.fontstyle = dest->fontstyle;

    hypertext = pdf_convert_hypertext_depr(p, text, len);
    if (hypertext)
        retval = pdf_insert_bookmark(p, hypertext, &self, -1);

    return retval;
}
Esempio n. 2
0
pdc_bool
pdf_get_metrics_afm(
    PDF *p,
    pdf_font *font,
    const char *fontname,
    pdc_encoding enc,
    const char *filename,
    pdc_bool requested)
{
    static const char fn[] = "pdf_get_metrics_afm";
    char fullname[PDC_FILENAMELEN];
    pdc_file *afmfile;

    /* open AFM file */
    afmfile = pdc_fsearch_fopen(p->pdc, filename, fullname, "AFM ",
                                PDC_FILE_TEXT);
    if (afmfile == NULL)
        return pdc_check_fopen_errmsg(p->pdc, requested);

    pdc_logg_cond(p->pdc, 1, trc_font,
        "\tLoading AFM metric fontfile \"%s\":\n", fullname);

    /* parse AFM file */
    if (pdf_parse_afm(p, afmfile, font, fontname, fullname) == pdc_false)
        return pdc_false;

    /* members not fount */
    if (font->ft.m.type == fnt_unknownType)
        font->ft.m.type = fnt_Type1;
    if (font->ft.name == NULL)
    {
        font->ft.name = pdc_strdup(p->pdc, fontname);
        font->ft.m.name = pdc_strdup(p->pdc, fontname);
    }

    /* save full filename */
    font->metricfilename = pdc_strdup_ext(p->pdc, fullname, 0, fn);

    /* process metric data */
    font->ft.enc = enc;
    if (pdf_process_metrics_data(p, font, fontname) == pdc_false)
        return pdc_false;

    if (!pdf_make_fontflag(p, font))
        return pdc_false;

    return pdc_true;
}
Esempio n. 3
0
void
pdf__create_pvf(PDF *p, const char *filename, int reserved,
                const void *data, size_t size, const char *optlist)
{
    static const char fn[] = "pdf__create_pvf";
    pdc_bool iscopy = pdc_false;
    pdf_virtfile  *vfile, *lastvfile = NULL;
    pdc_resopt *results;

    (void) reserved;

    /* Parse optlist */
    results = pdc_parse_optionlist(p->pdc, optlist, pdf_create_pvf_options,
                                   NULL, pdc_true);
    pdc_get_optvalues(p->pdc, "copy", results, &iscopy, NULL);
    pdc_cleanup_optionlist(p->pdc, results);

    /* Find virtual file in file system */
    vfile = pdf_find_pvf(p, filename, &lastvfile);

    /* Name already exists */
    if (vfile != NULL)
        pdc_error(p->pdc, PDC_E_PVF_NAMEEXISTS, filename, 0, 0, 0);

    /* New virtual file */
    vfile = (pdf_virtfile *) pdc_calloc(p->pdc, sizeof(pdf_virtfile), fn);
    if (lastvfile)
        lastvfile->next = vfile;
    else
        p->filesystem = vfile;

    /* Fill up file struct */
    vfile->name = pdc_strdup(p->pdc, filename);
    if (iscopy == pdc_true)
    {
        vfile->data = (const void *) pdc_malloc(p->pdc, size, fn);
        memcpy((void *) vfile->data, data, size);
    }
    else
    {
        vfile->data = data;
    }
    vfile->size = size;
    vfile->iscopy = iscopy;
    vfile->lockcount = 0;
    vfile->next = NULL;
}
Esempio n. 4
0
/* returns font handle,
** or -1 if no font found,
** or -2 in case of an error.
*/
int
pdf_handle_cidfont(PDF *p, const char *fontname, const char *encoding)
{
    pdc_font *font = &p->fonts[p->fonts_number];
    int slot, cmap, metric;

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

    for (slot = 0; slot < p->fonts_number; slot++) {
        if (p->fonts[slot].encoding == pdc_cid &&
            p->fonts[slot].style == font->style &&
            !strcmp(p->fonts[slot].name, fontname) &&
            !strcmp(p->fonts[slot].cmapname, encoding))
            return slot;
    }

    /* Check the requested CMap */
    for (cmap = 0; cmap < NUMBER_OF_CMAPS; cmap++)
        if (!strcmp(cmaps[cmap].name, encoding))
            break;

    /* Unknown CMap */
    if (cmap == NUMBER_OF_CMAPS)
        return -1;

    /* Check whether this CMap is supported in the desired PDF version */
    if (cmaps[cmap].compatibility > p->compatibility)
    {
	pdc_set_errmsg(p->pdc, PDF_E_DOC_PDFVERSION,
	    encoding, pdc_errprintf(p->pdc, "%d.%d",
	    p->compatibility/10, p->compatibility % 10), 0, 0);

        if (font->verbose)
            pdc_error(p->pdc, -1, 0, 0, 0, 0);

        return -2;
    }

    /* Check whether the font name is among the known CID fonts */
    for (metric = 0; metric < SIZEOF_CID_METRICS; metric++) {
        if (!strcmp(pdf_cid_metrics[metric].name, fontname))
            break;
    }

    /* Unknown font */
    if (metric == SIZEOF_CID_METRICS)
    {
	pdc_set_errmsg(p->pdc, PDF_E_CJK_NOSTANDARD, fontname, 0, 0, 0);

        if (font->verbose)
            pdc_error(p->pdc, -1, 0, 0, 0, 0);

        return -2;
    }

    /* Selected CMap and font don't match */
    if (cmaps[cmap].charcoll != cc_identity &&
        cmaps[cmap].charcoll != pdf_cid_metrics[metric].charcoll)
    {
	pdc_set_errmsg(p->pdc, PDF_E_FONT_BADENC, fontname, encoding, 0, 0);

        if (font->verbose)
            pdc_error(p->pdc, -1, 0, 0, 0, 0);

        return -2;
    }

    /* For Unicode capable language wrappers only UCS2 CMaps allowed */
    if (cmaps[cmap].codesize == 0 && p->textformat == pdc_auto2)
    {
	pdc_set_errmsg(p->pdc, PDF_E_FONT_NEEDUCS2, encoding, fontname, 0, 0);

        if (font->verbose)
            pdc_error(p->pdc, -1, 0, 0, 0, 0);

        return -2;
    }

    p->fonts_number++;

    /* Code size of CMap */
    font->codeSize = 0;
    font->numOfCodes = 0;

    /* Fill up the font struct */
    pdc_fill_font_metric(p->pdc, font, &pdf_cid_metrics[metric]);

    /* Now everything is fine; fill the remaining entries */
    font->encoding = pdc_cid;
    font->cmapname = pdc_strdup(p->pdc, encoding);
    font->ttname = pdc_strdup(p->pdc, fontname);
    font->apiname = pdc_strdup(p->pdc, fontname);
    font->obj_id = pdc_alloc_id(p->out);
    font->embedding = pdc_false;
    font->kerning = pdc_false;
    font->subsetting = pdc_false;
    font->autocidfont = pdc_false;
    font->unicodemap = pdc_false;
    font->autosubsetting = pdc_false;

    /* return valid font descriptor */
    return slot;
}
Esempio n. 5
0
pdc_resopt *
pdc_parse_optionlist(pdc_core *pdc, const char *optlist,
                     const pdc_defopt *defopt,
                     const pdc_clientdata *clientdata, pdc_bool verbose)
{
    static const char *fn = "pdc_parse_optionlist";
    pdc_bool logg5 = pdc_logg_is_enabled(pdc, 5, trc_optlist);
    const char *stemp1 = NULL, *stemp2 = NULL, *stemp3 = NULL, *s1, *s2;
    char **items = NULL, *keyword = NULL;
    char **values = NULL, *value = NULL, **strings = NULL;
    int i, j, k, nd, is, iss, it, iv, icoord;
    int numdef, nitems = 0, nvalues, ncoords = 0, errcode = 0;
    void *resval;
    double dz, maxval;
    int retval, iz;
    pdc_sint32 lz = 0;
    pdc_uint32 ulz = 0;
    size_t len;
    const pdc_defopt *dopt = NULL;
    pdc_resopt *resopt = NULL;
    pdc_bool ignore = pdc_false;
    pdc_bool boolval = pdc_false;
    pdc_bool tocheck = pdc_false;
    pdc_bool issorted = pdc_true;
    pdc_bool ishandle = pdc_true;
    pdc_bool isutf8 = pdc_false;

    pdc_logg_cond(pdc, 1, trc_optlist, "\n\tOption list: \"%T\"\n",
                      optlist ? optlist : "", 0);

    /* split option list */
    if (optlist != NULL)
    {
        nitems = pdc_split_stringlist(pdc, optlist, PDC_OPT_LISTSEPS,
                                      PDC_SPLIT_ISOPTLIST, &items);
        isutf8 = pdc_is_utf8_bytecode(optlist);
    }
    if (nitems < 0)
    {
        keyword = (char *) optlist;
        errcode = PDC_E_OPT_NOTBAL;
        goto PDC_OPT_SYNTAXERROR;
    }

    /* initialize result list */
    for (numdef = 0; defopt[numdef].name != NULL; numdef++)
    {
	/* */ ;
    }

    /* allocate temporary memory for option parser result struct */
    resopt = (pdc_resopt *) pdc_calloc_tmp(pdc, numdef * sizeof(pdc_resopt),
                                    fn, pdc, pdc_cleanup_optionlist_tmp);
    for (i = 0; i < numdef; i++)
    {
        resopt[i].numdef = numdef;
        resopt[i].defopt = &defopt[i];

        if (defopt[i].flags & PDC_OPT_IGNOREIF1 ||
            defopt[i].flags & PDC_OPT_IGNOREIF2 ||
            defopt[i].flags & PDC_OPT_REQUIRIF1 ||
            defopt[i].flags & PDC_OPT_REQUIRIF2 ||
            defopt[i].flags & PDC_OPT_REQUIRED)
            tocheck = pdc_true;

        if (i && issorted)
            issorted = (strcmp(defopt[i-1].name, defopt[i].name) <= 0) ?
                       pdc_true : pdc_false;
    }

    /* loop over all option list elements */
    for (is = 0; is < nitems; is++)
    {
        pdc_bool isequal = pdc_false;

        /* search keyword */
        boolval = pdc_undef;
        keyword = items[is];
        for (it = 0; it < numdef; it++)
        {
            s1 = keyword;
            s2 = defopt[it].name;

            /* if (!pdc_stricmp(keyword, defopt[it].name))
             *     isequal = pdc_true;
             */
            for (; *s1; ++s1, ++s2)
            {
                if (pdc_tolower(*s1) != pdc_tolower(*s2))
                    break;
            }
            if (pdc_tolower(*s1) == pdc_tolower(*s2))
                isequal = pdc_true;

            /* special handling for booleans */
            if (defopt[it].type == pdc_booleanlist)
            {
                if (isequal ||
                    (keyword[1] != 0 &&
                     !pdc_stricmp(&keyword[2], defopt[it].name)))
                {
                    iss = is + 1;
                    if (iss == nitems ||
                        (pdc_stricmp(items[iss], "true") &&
                         pdc_stricmp(items[iss], "false")))
                    {
                        i = pdc_strincmp(defopt[it].name, "no", 2) ? 0 : 2;
                        if (!pdc_strincmp(&keyword[i], "no", 2))
                        {
                            boolval = pdc_false;
                            break;
                        }
                        else if (isequal)
                        {
                            boolval = pdc_true;
                            break;
                        }
                    }
                }
            }

            if (isequal)
                break;
        }

        if (logg5)
            pdc_logg(pdc, "\t\t\toption \"%s\" specified: ", keyword);

        if (it == numdef)
        {
            errcode = PDC_E_OPT_UNKNOWNKEY;
            goto PDC_OPT_SYNTAXERROR;
        }

        /* initialize */
        dopt = &defopt[it];
        ignore = pdc_false;
        nvalues = 1;
        values = NULL;
        ishandle = pdc_true;

        /* compatibility */
        if (clientdata && clientdata->compatibility)
        {
            int compatibility = clientdata->compatibility;

            for (iv = PDC_1_3; iv <= PDC_X_X_LAST; iv++)
            {
                if (logg5 && (dopt->flags & (1L<<iv)))
                    pdc_logg(pdc, "(compatibility >= %s) ",
                             pdc_get_pdfversion(pdc, iv));

                if ((dopt->flags & (1L<<iv)) && compatibility < iv)
                {
                    if (logg5)
                        pdc_logg(pdc, "\n");
                    stemp2 = pdc_get_pdfversion(pdc, compatibility);
                    errcode = PDC_E_OPT_VERSION;
                    goto PDC_OPT_SYNTAXERROR;
                }
            }
        }

        /* not supported */
        if (dopt->flags & PDC_OPT_UNSUPP)
        {
            if (logg5)
                pdc_logg(pdc, "(unsupported)\n");

            keyword = (char *) dopt->name;
            errcode = PDC_E_OPT_UNSUPP;
            goto PDC_OPT_SYNTAXERROR;
        }

        /* parse values */
        if (boolval == pdc_undef)
        {
            is++;
            if (is == nitems)
            {
                errcode = PDC_E_OPT_NOVALUES;
                goto PDC_OPT_SYNTAXERROR;
            }
            if (!ignore)
            {
                if (dopt->type == pdc_stringlist &&
                    pdc_is_utf8_bytecode(items[is]))
                    resopt[it].flags |= PDC_OPT_ISUTF8;

                if (dopt->type != pdc_stringlist || dopt->maxnum > 1)
                    nvalues = pdc_split_stringlist(pdc, items[is],
                                    (dopt->flags & PDC_OPT_SUBOPTLIST) ?
                                    PDC_OPT_LISTSEPS : NULL,
                                    PDC_SPLIT_ISOPTLIST, &values);

                if (dopt->flags & PDC_OPT_DUPORIGVAL)
                    resopt[it].origval = pdc_strdup(pdc, items[is]);
            }
        }

        /* ignore */
        if (ignore) continue;

        /* number of values check */
        if (nvalues < dopt->minnum)
        {
            stemp2 = pdc_errprintf(pdc, "%d", dopt->minnum);
            errcode = PDC_E_OPT_TOOFEWVALUES;
            goto PDC_OPT_SYNTAXERROR;
        }
        else if (nvalues > dopt->maxnum)
        {
            stemp2 = pdc_errprintf(pdc, "%d", dopt->maxnum);
            errcode = PDC_E_OPT_TOOMANYVALUES;
            goto PDC_OPT_SYNTAXERROR;
        }

        /* number of values must be even */
        if (dopt->flags & PDC_OPT_EVENNUM && (nvalues % 2))
        {
            errcode = PDC_E_OPT_ODDNUM;
            goto PDC_OPT_SYNTAXERROR;
        }

        /* number of values must be odd */
        if (dopt->flags & PDC_OPT_ODDNUM && !(nvalues % 2))
        {
            errcode = PDC_E_OPT_EVENNUM;
            goto PDC_OPT_SYNTAXERROR;
        }

        /* deprecated option since PDFlib 7 */
        if (dopt->flags & PDC_OPT_PDFLIB_7)
        {
            pdc_logg_cond(pdc, 2, trc_api,
                  "[Option \"%s\" is deprecated since PDFlib 7]\n",
                  keyword);
        }

        /* option already exists */
        if (resopt[it].num)
        {
            pdc_delete_optvalue(pdc, &resopt[it]);
        }

        /* no values */
        if (!nvalues ) continue;

        /* maximal value */
        switch (dopt->type)
        {
            case pdc_3ddatahandle:
            maxval = clientdata->max3ddata;
            break;

            case pdc_3dviewhandle:
            maxval = clientdata->max3dview;
            break;

            case pdc_actionhandle:
            maxval = clientdata->maxaction;
            break;

            case pdc_bookmarkhandle:
            maxval = clientdata->maxbookmark;
            break;

            case pdc_colorhandle:
            maxval = clientdata->maxcolor;
            break;

            case pdc_documenthandle:
            maxval = clientdata->maxdocument;
            break;

            case pdc_fonthandle:
            maxval = clientdata->maxfont;
            break;

            case pdc_gstatehandle:
            maxval = clientdata->maxgstate;
            break;

            case pdc_iccprofilehandle:
            maxval = clientdata->maxiccprofile;
            break;

            case pdc_imagehandle:
            maxval = clientdata->maximage;
            break;

	    case pdc_layerhandle:
            maxval = clientdata->maxlayer;
            break;

            case pdc_pagehandle:
            maxval = clientdata->maxpage;
            break;

            case pdc_patternhandle:
            maxval = clientdata->maxpattern;
            break;

            case pdc_shadinghandle:
            maxval = clientdata->maxshading;
            break;

            case pdc_tablehandle:
            maxval = clientdata->maxtable;
            break;

            case pdc_templatehandle:
            maxval = clientdata->maxtemplate;
            break;

            case pdc_textflowhandle:
            maxval = clientdata->maxtextflow;
            break;

            case pdc_stringhandle:
            maxval = clientdata->maxstring;
            break;

            case pdc_polylinelist:
            ncoords = 0;

            default:
            maxval = dopt->maxval;
            ishandle = pdc_false;
            break;
        }

        /* allocate value array */
        resopt[it].val = pdc_calloc(pdc,
                            (size_t) (nvalues * pdc_typesizes[dopt->type]), fn);
        resopt[it].num = nvalues;
        resopt[it].currind = it;

        if (dopt->flags & PDC_OPT_PERCENT)
            memset(resopt[it].pcbits, 0, PDC_PCBITS_SIZE);

        if (logg5)
            pdc_logg(pdc, "{");

        /* analyze type */
        resval = resopt[it].val;
        for (iv = 0; iv < nvalues; iv++)
        {
            errcode = 0;
            if (dopt->maxnum > 1 && nvalues)
                value = values[iv];
            else
                value = items[is];
            if (logg5)
                pdc_logg(pdc, "%s{%T}", iv ? " " : "", value, 0);
            switch (dopt->type)
            {
                /* boolean list */
                case pdc_booleanlist:
                if (boolval == pdc_true || !pdc_stricmp(value, "true"))
                {
                    *(pdc_bool *) resval = pdc_true;
                }
                else if (boolval == pdc_false || !pdc_stricmp(value, "false"))
                {
                    *(pdc_bool *) resval = pdc_false;
                }
                else
                {
                    errcode = PDC_E_OPT_ILLBOOLEAN;
                }
                break;

                /* string list */
                case pdc_stringlist:
                if (dopt->flags & PDC_OPT_NOSPACES)
                {
                    if (pdc_split_stringlist(pdc, value, NULL, 0, &strings) > 1)
                        errcode = PDC_E_OPT_ILLSPACES;
                    pdc_cleanup_stringlist(pdc, strings);
                }
                if (!errcode)
                {
                    len = strlen(value);
                    dz = (double) len;
                    if (dz < dopt->minval)
                    {
                        stemp3 = pdc_errprintf(pdc, "%d", (int) dopt->minval);
                        errcode = PDC_E_OPT_TOOSHORTSTR;
                    }
                    else if (dz > maxval)
                    {
                        stemp3 = pdc_errprintf(pdc, "%d", (int) maxval);
                        errcode = PDC_E_OPT_TOOLONGSTR;
                    }

                    if (dopt->flags & PDC_OPT_CONVUTF8)
                    {
                        int flags = PDC_CONV_EBCDIC | PDC_CONV_WITHBOM;

                        if (isutf8 || (resopt[it].flags & PDC_OPT_ISUTF8))
                            flags |= PDC_CONV_ISUTF8;

                        *((char **) resval) =
                            pdc_convert_name(pdc, value, 0, flags);
                    }
                    else
                    {
                        *((char **) resval) = pdc_strdup(pdc, value);
                    }
                }
                break;

                /* keyword list */
                case pdc_keywordlist:
                if (dopt->flags & PDC_OPT_CASESENS)
                    iz = pdc_get_keycode(value, dopt->keylist);
                else
                    iz = pdc_get_keycode_ci(value, dopt->keylist);
                if (iz == PDC_KEY_NOTFOUND)
                {
                    errcode = PDC_E_OPT_ILLKEYWORD;
                }
                else
                {
                    *(int *) resval = iz;
                }
                break;

                /* character list */
                case pdc_unicharlist:
                iz = pdc_string2unicode(pdc, value, dopt->flags, dopt->keylist,
                                        pdc_false);
                if (iz < 0)
                {
                    errcode = PDC_E_OPT_ILLCHAR;
                    break;
                }
                dz = iz;
                if (dz < dopt->minval)
                {
                    stemp3 = pdc_errprintf(pdc, "%g", dopt->minval);
                    errcode = PDC_E_OPT_TOOSMALLVAL;
                }
                else if (dz > maxval)
                {
                    stemp3 = pdc_errprintf(pdc, "%g", maxval);
                    errcode = PDC_E_OPT_TOOBIGVAL;
                }
                *(int *) resval = iz;
                break;

                /* string list */
                case pdc_polylinelist:
                {
                    int np = pdc_split_stringlist(pdc, value, NULL, 0,
                                                  &strings);
                    pdc_polyline *pl = (pdc_polyline *) resval;

                    pl->np = np / 2;
                    pl->p = NULL;

                    /* number of coordinates must be even */
                    if (np % 2)
                    {
                        errcode = PDC_E_OPT_ODDNUM;
                        np = 0;
                    }

                    /* polyline must be a box */
                    else if ((dopt->flags & PDC_OPT_ISBOX) && np != 4)
                    {
                        errcode = PDC_E_OPT_ILLBOX;
                        np = 0;
                    }

                    /* polyline will be closed */
                    else if ((dopt->flags & PDC_OPT_CLOSEPOLY) && np <= 4)
                    {
                        errcode = PDC_E_OPT_ILLPOLYLINE;
                        np = 0;
                    }

                    /* polyline not empty */
                    if (np)
                    {
                        if (dopt->flags & PDC_OPT_CLOSEPOLY)
                            pl->np += 1;
                        pl->p = (pdc_vector *) pdc_malloc(pdc,
                                        pl->np * sizeof(pdc_vector), fn);

                        iz = PDC_KEY_NOTFOUND;
                        j = 0;
                        icoord = ncoords;
                        for (i = 0; i < np; i++)
                        {
                            char *sk = strings[i];

                            if (dopt->keylist)
                            {
                                /* optional keyword list */
                                if (dopt->flags & PDC_OPT_CASESENS)
                                    iz = pdc_get_keycode(sk, dopt->keylist);
                                else
                                    iz = pdc_get_keycode_ci(sk, dopt->keylist);
                            }
                            if (iz == PDC_KEY_NOTFOUND)
                            {
                                /* percentage */
                                if (dopt->flags & PDC_OPT_PERCENT)
                                {
                                    k = (int) strlen(sk) - 1;
                                    if (sk[k] == '%')
                                    {
                                        sk[k] = 0;
                                        if (ncoords < PDC_MAX_PERCENTS)
                                        {
                                            pdc_setbit(resopt[it].pcbits,
                                                       ncoords);
                                        }
                                        else
                                        {
                                            errcode = PDC_E_OPT_TOOMANYPERCVALS;
                                        }
                                    }
                                }

                                retval = pdc_str2double(sk, &dz);
                                if (!retval)
                                {
                                    errcode = PDC_E_OPT_ILLNUMBER;
                                }
                                else if (pdc_getbit(resopt[it].pcbits, ncoords))
                                {
                                    if (dopt->flags & PDC_OPT_PERCRANGE)
                                    {
                                        if (dz < 0)
                                            errcode = PDC_E_OPT_TOOSMALLPERCVAL;
                                        if (dz > 100)
                                            errcode = PDC_E_OPT_TOOBIGPERCVAL;
                                    }
                                    dz /= 100.0;
                                }
                            }
                            else
                            {
                                dz = (double) iz;
                            }

                            if (!(i % 2))
                            {
                                pl->p[j].x = dz;
                            }
                            else
                            {
                                pl->p[j].y = dz;
                                j++;
                            }
                            ncoords++;
                        }

                        if (dopt->flags & PDC_OPT_CLOSEPOLY)
                        {
                            pl->p[pl->np - 1] = pl->p[0];
                            if (pdc_getbit(resopt[it].pcbits, icoord))
                                pdc_setbit(resopt[it].pcbits, ncoords);
                            ncoords++;
                            if (pdc_getbit(resopt[it].pcbits, icoord + 1))
                                pdc_setbit(resopt[it].pcbits, ncoords);
                            ncoords++;
                        }
                    }
                    pdc_cleanup_stringlist(pdc, strings);
                }
                break;

                /* number list */
                case pdc_3ddatahandle:
                case pdc_3dviewhandle:
                case pdc_actionhandle:
                case pdc_bookmarkhandle:
                case pdc_colorhandle:
                case pdc_documenthandle:
                case pdc_fonthandle:
                case pdc_gstatehandle:
                case pdc_iccprofilehandle:
                case pdc_imagehandle:
                case pdc_layerhandle:
                case pdc_pagehandle:
                case pdc_patternhandle:
                case pdc_shadinghandle:
                case pdc_tablehandle:
                case pdc_templatehandle:
                case pdc_textflowhandle:
                case pdc_integerlist:
                case pdc_floatlist:
                case pdc_doublelist:
                case pdc_scalarlist:

                if (dopt->keylist &&
                    (!(dopt->flags & PDC_OPT_KEYLIST1) || !iv))
                {
                    /* optional keyword and/or allowed integer list */
                    if (dopt->flags & PDC_OPT_CASESENS)
                        iz = pdc_get_keycode(value, dopt->keylist);
                    else
                        iz = pdc_get_keycode_ci(value, dopt->keylist);
                    if (iz == PDC_KEY_NOTFOUND)
                    {
                        if (dopt->flags & PDC_OPT_INTLIST)
                        {
                            errcode = PDC_E_OPT_ILLINTEGER;
                            break;
                        }
                    }
                    else
                    {
                        switch (dopt->type)
                        {
                            default:
                            case pdc_integerlist:
                            *(int *) resval = iz;
                            break;

                            case pdc_floatlist:
                            *(float *) resval = (float) iz;
                            break;

                            case pdc_doublelist:
                            *(double *) resval = (double) iz;
                            break;

                            case pdc_scalarlist:
                            *(pdc_scalar *) resval = (pdc_scalar) iz;
                            break;
                        }
                        break;
                    }
                }

                /* percentage */
                if (dopt->flags & PDC_OPT_PERCENT)
                {
                    i = (int) strlen(value) - 1;
                    if (value[i] == '%')
                    {
                        value[i] = 0;
                        if (iv < PDC_MAX_PERCENTS)
                        {
                            pdc_setbit(resopt[it].pcbits, iv);
                        }
                        else
                        {
                            errcode = PDC_E_OPT_TOOMANYPERCVALS;
                        }
                    }
                }

                case pdc_stringhandle:

                if (dopt->type == pdc_floatlist ||
                    dopt->type == pdc_doublelist ||
                    dopt->type == pdc_scalarlist)
                {
                    retval = pdc_str2double(value, &dz);
                }
                else
                {
                    if (dopt->minval >= 0)
                    {
                        retval = pdc_str2integer(value, PDC_INT_UNSIGNED, &ulz);
                        dz = ulz;
                    }
                    else
                    {
                        retval = pdc_str2integer(value, 0, &lz);
                        dz = lz;
                    }

                    if (retval && ishandle && pdc->hastobepos &&
                        dopt->type != pdc_bookmarkhandle &&
                        dopt->type != pdc_stringhandle)
                    {
                        dz -= 1;
                        lz = (pdc_sint32) dz;
                        ulz = (pdc_uint32) dz;
                    }
                }
                if (!retval)
                {
                    errcode = PDC_E_OPT_ILLNUMBER;
                }
                else
                {
                    if (pdc_getbit(resopt[it].pcbits, iv))
                    {
                        if (dopt->flags & PDC_OPT_PERCRANGE)
                        {
                            if (dz < 0)
                                errcode = PDC_E_OPT_TOOSMALLPERCVAL;
                            if (dz > 100)
                                errcode = PDC_E_OPT_TOOBIGPERCVAL;
                        }
                        dz /= 100.0;
                    }

                    if (errcode == 0)
                    {
                        if (dz < dopt->minval)
                        {
                            if (ishandle)
                            {
                                stemp3 = pdc_get_keyword(dopt->type,
                                                         pdc_handletypes);
                                errcode = PDC_E_OPT_ILLHANDLE;
                            }
                            else
                            {
                                stemp3 = pdc_errprintf(pdc, "%g", dopt->minval);
                                errcode = PDC_E_OPT_TOOSMALLVAL;
                            }
                        }
                        else if (dz > maxval)
                        {
                            if (ishandle)
                            {
                                stemp3 = pdc_get_keyword(dopt->type,
                                                         pdc_handletypes);
                                errcode = PDC_E_OPT_ILLHANDLE;
                            }
                            else
                            {
                                stemp3 = pdc_errprintf(pdc, "%g", maxval);
                                errcode = PDC_E_OPT_TOOBIGVAL;
                            }
                        }
                        else if (dopt->flags & PDC_OPT_NOZERO &&
                                 fabs(dz) < PDC_FLOAT_PREC)
                        {
                            errcode = PDC_E_OPT_ZEROVAL;
                        }
                        else if (dopt->type == pdc_scalarlist)
                        {
                            *(pdc_scalar *) resval = dz;
                        }
                        else if (dopt->type == pdc_doublelist)
                        {
                            *(double *) resval = dz;
                        }
                        else if (dopt->type == pdc_floatlist)
                        {
                            *(float *) resval = (float) dz;
                        }
                        else
                        {
                            if (dopt->minval >= 0)
                                *(pdc_uint32 *) resval = ulz;
                            else
                                *(pdc_sint32 *) resval = lz;
                        }
                    }
                }
                break;
            }

            if (errcode)
            {
                stemp2 = pdc_errprintf(pdc, "%.*s", PDC_ERR_MAXSTRLEN, value);
                goto PDC_OPT_SYNTAXERROR;
            }

            /* increment value pointer */
            resval = (void *) ((char *)(resval) + pdc_typesizes[dopt->type]);
        }
        pdc_cleanup_stringlist(pdc, values);
        values = NULL;

        if (logg5)
            pdc_logg(pdc, "}\n");

        /* build OR bit pattern */
        if (dopt->flags & PDC_OPT_BUILDOR && nvalues > 1)
        {
            int *bcode = (int *) resopt[it].val;
            for (iv = 1; iv < nvalues; iv++)
            {
                bcode[0] |= bcode[iv];
            }
            resopt[it].num = 1;
        }
    }
    pdc_cleanup_stringlist(pdc, items);
    items = NULL;

    /* required and to be ignored options */
    for (is = 0; tocheck && is < numdef; is++)
    {
        /* to be ignored option */
        if (resopt[is].num)
        {
            nd = 0;
            if (defopt[is].flags & PDC_OPT_IGNOREIF1) nd = 1;
            if (defopt[is].flags & PDC_OPT_IGNOREIF2) nd = 2;
            for (it = is - 1; it >= is - nd && it >= 0; it--)
            {
                if (resopt[it].num)
                {
                    pdc_delete_optvalue(pdc, &resopt[is]);
                    if (verbose)
                        pdc_warning(pdc, PDC_E_OPT_IGNORE, defopt[is].name,
                                    defopt[it].name, 0, 0);
                }
            }
        }

        /* required option */
        if (!resopt[is].num &&
            ((defopt[is].flags & PDC_OPT_REQUIRED) ||
             (defopt[is].flags & PDC_OPT_REQUIRIF1 && resopt[is-1].num) ||
             (defopt[is].flags & PDC_OPT_REQUIRIF2 &&
              (resopt[is-1].num || resopt[is-2].num))))
        {
            keyword = (char *) defopt[is].name;
            errcode = PDC_E_OPT_NOTFOUND;
            goto PDC_OPT_SYNTAXERROR;
        }
    }

    /* is no sorted */
    if (!issorted)
    {
        qsort((void *)resopt, (size_t) numdef, sizeof(pdc_resopt),
              pdc_optname_compare);
    }

    /* global UTF-8 check after sort */
    if (isutf8)
        resopt[0].isutf8 = pdc_true;

    /* index of last got option */
    resopt[0].lastind = -1;

    /* protocol */
    if (pdc_logg_is_enabled(pdc, 1, trc_optlist))
    {
        for (is = 0; is < numdef; is++)
        {
            if (resopt[is].num)
                pdc_logg(pdc, "\tOption \"%s\": %d value%s found\n",
                         resopt[is].defopt->name, resopt[is].num,
                         resopt[is].num == 1 ? "" : "s");
            else if (logg5)
                pdc_logg(pdc, "\t\t\toption \"%s\" not specified\n",
                         resopt[is].defopt->name);
            for (iv = 0; iv < resopt[is].num; iv++)
            {
                switch (resopt[is].defopt->type)
                {
                    case pdc_booleanlist:
                    case pdc_keywordlist:
                    case pdc_integerlist:
                    case pdc_3ddatahandle:
                    case pdc_3dviewhandle:
                    case pdc_actionhandle:
                    case pdc_bookmarkhandle:
                    case pdc_colorhandle:
                    case pdc_documenthandle:
                    case pdc_fonthandle:
                    case pdc_gstatehandle:
                    case pdc_iccprofilehandle:
                    case pdc_imagehandle:
                    case pdc_layerhandle:
                    case pdc_pagehandle:
                    case pdc_patternhandle:
                    case pdc_shadinghandle:
                    case pdc_tablehandle:
                    case pdc_templatehandle:
                    case pdc_textflowhandle:
                    case pdc_stringhandle:
                    pdc_logg(pdc, "\tValue %d: %d\n",
                             iv + 1, *((int *) resopt[is].val + iv));
                    break;

                    case pdc_stringlist:
                    pdc_logg(pdc, "\tValue %d: \"%T\"\n",
                             iv + 1, *((char **) resopt[is].val + iv), 0);
                    break;

                    case pdc_floatlist:
                    pdc_logg(pdc, "\tValue %d: %f\n",
                             iv + 1, *((float *) resopt[is].val + iv));
                    break;

                    case pdc_doublelist:
                    pdc_logg(pdc, "\tValue %d: %f\n",
                             iv + 1, *((double *) resopt[is].val + iv));
                    break;

                    case pdc_scalarlist:
                    pdc_logg(pdc, "\tValue %d: %f\n",
                             iv + 1, *((pdc_scalar *) resopt[is].val + iv));
                    break;

                    case pdc_unicharlist:
                    pdc_logg(pdc, "\tValue %d: %d\n",
                             iv + 1, *((int *) resopt[is].val + iv));
                    break;

                    case pdc_polylinelist:
                    pdc_logg(pdc, "\t\t#%d: ", iv + 1);
                    {
                        pdc_polyline *pl = (pdc_polyline *) resopt[is].val + iv;

                        for (j = 0; j < pl->np; j++)
                            pdc_logg(pdc, "%f,%f  ", pl->p[j].x, pl->p[j].y);
                        pdc_logg(pdc, "\n");
                    }
                    break;
                }
            }
        }
    }

    return resopt;

    PDC_OPT_SYNTAXERROR:
    stemp1 = pdc_errprintf(pdc, "%.*s", PDC_ERR_MAXSTRLEN, keyword);
    pdc_cleanup_stringlist(pdc, items);
    pdc_cleanup_stringlist(pdc, values);

    pdc_set_errmsg(pdc, errcode, stemp1, stemp2, stemp3, 0);
    if (verbose)
        pdc_error(pdc, -1, 0, 0, 0, 0);

    return NULL;
}
Esempio n. 6
0
void
pdf__set_parameter(PDF *p, const char *key, const char *value)
{
    pdc_pagebox usebox = pdc_pbox_none;
    pdc_text_format textformat = pdc_auto;
    char optlist[PDC_GEN_BUFSIZE];
    pdf_ppt *ppt;
    int i, k;

    i = pdf_get_index(p, key, pdc_true);

    if (value == NULL) value = "";

    ppt = p->curr_ppt;

    switch (i)
    {
        case PDF_PARAMETER_PDIUSEBOX:
        case PDF_PARAMETER_VIEWAREA:
        case PDF_PARAMETER_VIEWCLIP:
        case PDF_PARAMETER_PRINTAREA:
        case PDF_PARAMETER_PRINTCLIP:
            k = pdc_get_keycode_ci(value, pdf_usebox_keylist);
            if (k == PDC_KEY_NOTFOUND)
                pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
            usebox = (pdc_pagebox) k;
            pdc_sprintf(p->pdc, pdc_false, optlist, "%s %s", key, value);
            break;

        case PDF_PARAMETER_TEXTFORMAT:
        case PDF_PARAMETER_HYPERTEXTFORMAT:
            k = pdc_get_keycode_ci(value, pdf_textformat_keylist);
            if (k == PDC_KEY_NOTFOUND)
                pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
            textformat = (pdc_text_format) k;
            break;
    }

    switch (i)
    {
        case PDF_PARAMETER_SEARCHPATH:
        case PDF_PARAMETER_FONTAFM:
	case PDF_PARAMETER_FONTPFM:
        case PDF_PARAMETER_FONTOUTLINE:
        case PDF_PARAMETER_HOSTFONT:
        case PDF_PARAMETER_ENCODING:
        case PDF_PARAMETER_ICCPROFILE:
        case PDF_PARAMETER_STANDARDOUTPUTINTENT:
	{
            pdf_add_pdflib_resource(p, key, value);
            break;
        }

	case PDF_PARAMETER_DEBUG:
	{
	    const unsigned char *c;

	    for (c = (const unsigned char *) value; *c; c++)
		p->debug[(int) *c] = 1;
	    break;
	}

	case PDF_PARAMETER_NODEBUG:
	{
	    const unsigned char *c;

	    for (c = (const unsigned char *) value; *c; c++)
                p->debug[(int) *c] = 0;
	    break;
	}

        case PDF_PARAMETER_BINDING:
            if (!p->pdc->binding)
                p->pdc->binding = pdc_strdup(p->pdc, value);
            break;

        case PDF_PARAMETER_OBJORIENT:
            p->pdc->objorient = pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_HASTOBEPOS:
            p->pdc->hastobepos = pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_PTFRUN:
            p->pdc->ptfrun = pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_SMOKERUN:
            p->pdc->smokerun = pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_UNICAPLANG:
            p->pdc->unicaplang = pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_ERRORPOLICY:
            k = pdc_get_keycode_ci(value, pdf_errpol_keylist);
            if (k == PDC_KEY_NOTFOUND)
                pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
            p->errorpolicy = (pdf_errpol) k;
            break;

	case PDF_PARAMETER_UNDERLINE:
            pdf_set_tstate(p, (double) pdf_bool_value(p, key, value),
                           to_underline);
	    break;

	case PDF_PARAMETER_OVERLINE:
            pdf_set_tstate(p, (double) pdf_bool_value(p, key, value),
                           to_overline);
	    break;

	case PDF_PARAMETER_STRIKEOUT:
            pdf_set_tstate(p, (double) pdf_bool_value(p, key, value),
                           to_strikeout);
	    break;

        case PDF_PARAMETER_KERNING:
            pdc_warning(p->pdc, PDF_E_UNSUPP_KERNING, 0, 0, 0, 0);
            break;

        case PDF_PARAMETER_FAKEBOLD:
            pdf_set_tstate(p, (double) pdf_bool_value(p, key, value),
                           to_fakebold);
            break;


        case PDF_PARAMETER_RESOURCEFILE:
            pdc_set_resourcefile(p->pdc, value);
            break;

        case PDF_PARAMETER_RENDERINGINTENT:
            k = pdc_get_keycode_ci(value, pdf_renderingintent_pdfkeylist);
            if (k == PDC_KEY_NOTFOUND)
                pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
            p->rendintent = (pdf_renderingintent) k;
            break;

        case PDF_PARAMETER_PRESERVEOLDPANTONENAMES:
            p->preserveoldpantonenames = pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_SPOTCOLORLOOKUP:
            p->spotcolorlookup = pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_PDISTRICT:
            p->pdi_strict = pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_TOPDOWN:
            if (pdf_bool_value(p, key, value))
                p->ydirection = -1.0;
            else
                p->ydirection = 1.0;
            break;

        case PDF_PARAMETER_USERCOORDINATES:
            p->usercoordinates = pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_USEHYPERTEXTENCODING:
            p->usehyptxtenc = pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_TEXTFORMAT:
            pdf_check_textformat(p, textformat);
            p->textformat = textformat;
            if (p->curr_ppt)
                pdf_set_tstate(p, (double) textformat, to_textformat);
            break;

        case PDF_PARAMETER_HYPERTEXTFORMAT:
            pdf_check_hypertextformat(p, textformat);
            p->hypertextformat = textformat;
            break;

        case PDF_PARAMETER_HYPERTEXTENCODING:
        {
            p->hypertextencoding =
                pdf_get_hypertextencoding(p, value, &p->hypertextcodepage,
                                          pdc_true);
            pdf_check_hypertextencoding(p, p->hypertextencoding);
            break;
        }

        case PDF_PARAMETER_CHARREF:
            pdc_warning(p->pdc, PDF_E_UNSUPP_CHARREF, 0, 0, 0, 0);
            break;

        case PDF_PARAMETER_ESCAPESEQUENCE:
            pdc_warning(p->pdc, PDF_E_UNSUPP_ESCAPESEQU, 0, 0, 0, 0);
            break;

        case PDF_PARAMETER_HONORLANG:
            pdc_warning(p->pdc, PDF_E_UNSUPP_HONORLANG, 0, 0, 0, 0);
            break;

        case PDF_PARAMETER_GLYPHCHECK:
            pdc_warning(p->pdc, PDF_E_UNSUPP_GLYPHCHECK, 0, 0, 0, 0);
            break;

        case PDF_PARAMETER_FILLRULE:
            k = pdc_get_keycode_ci(value, pdf_fillrule_keylist);
            if (k == PDC_KEY_NOTFOUND)
                pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
            ppt->fillrule = (pdf_fillrule) k;
            break;

        case PDF_PARAMETER_LOGGING:
            pdc_set_logg_options(p->pdc, value);
            break;

        case PDF_PARAMETER_LOGMSG:
            pdc_logg_cond(p->pdc, 1, trc_user, value);
            break;

        case PDF_PARAMETER_TRACEMSG:
            /* do nothing -- client-supplied string will show up
             * in the log file
             */
            break;

        case PDF_PARAMETER_NODEMOSTAMP:
            break;

        case PDF_PARAMETER_SERIAL:
        case PDF_PARAMETER_LICENCE:
        case PDF_PARAMETER_LICENSE:
            break;

        case PDF_PARAMETER_LICENCEFILE:
        case PDF_PARAMETER_LICENSEFILE:
            break;

        case PDF_PARAMETER_AUTOSPACE:
            pdc_warning(p->pdc, PDF_E_UNSUPP_TAGGED, 0, 0, 0, 0);
            break;

/*****************************************************************************/
/**                   deprecated historical parameters                      **/
/*****************************************************************************/

        case PDF_PARAMETER_OPENWARNING:
            p->debug[(int) 'o'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_FONTWARNING:
            p->debug[(int) 'F'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_ICCWARNING:
            p->debug[(int) 'I'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_IMAGEWARNING:
            p->debug[(int) 'i'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_PDIWARNING:
            p->debug[(int) 'p'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_HONORICCPROFILE:
            p->debug[(int) 'e'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_GLYPHWARNING:
            p->debug[(int) 'g'] = (char) pdf_bool_value(p, key, value);
            if (p->curr_ppt)
                pdf_set_tstate(p, (double) pdf_bool_value(p, key, value),
                               to_glyphwarning);
            break;

        case PDF_PARAMETER_TRACE:
        {
            pdc_bool bv = pdf_bool_value(p, key, value);
            if (bv)
                pdc_set_logg_options(p->pdc, "");
            else
                pdc_set_logg_options(p->pdc, "disable");
            break;
        }

        case PDF_PARAMETER_TRACEFILE:
            pdc_sprintf(p->pdc, pdc_false, optlist, "filename %s", value);
            pdc_set_logg_options(p->pdc, optlist);
            break;

        case PDF_PARAMETER_WARNING:
            break;

	case PDF_PARAMETER_MASTERPASSWORD:
	    pdc_warning(p->pdc, PDF_E_UNSUPP_CRYPT, 0, 0, 0, 0);
            break;

	case PDF_PARAMETER_USERPASSWORD:
            pdc_warning(p->pdc, PDF_E_UNSUPP_CRYPT, 0, 0, 0, 0);
            break;

	case PDF_PARAMETER_PERMISSIONS:
            pdc_warning(p->pdc, PDF_E_UNSUPP_CRYPT, 0, 0, 0, 0);
            break;

	case PDF_PARAMETER_COMPATIBILITY:
            pdf_set_compatibility(p, value);
	    break;

        case PDF_PARAMETER_FLUSH:
            pdf_set_flush(p, value);
            break;

	case PDF_PARAMETER_PDFX:
	    pdc_warning(p->pdc, PDF_E_UNSUPP_PDFX, 0, 0, 0, 0);
	    break;

	case PDF_PARAMETER_HIDETOOLBAR:
        case PDF_PARAMETER_HIDEMENUBAR:
        case PDF_PARAMETER_HIDEWINDOWUI:
        case PDF_PARAMETER_FITWINDOW:
        case PDF_PARAMETER_CENTERWINDOW:
        case PDF_PARAMETER_DISPLAYDOCTITLE:
	    if (pdf_bool_value(p, key, value))
                pdf_set_viewerpreference(p, key);
	    break;

	case PDF_PARAMETER_NONFULLSCREENPAGEMODE:
            if (!pdc_stricmp(value, "useoutlines"))
                pdf_set_viewerpreference(p, "nonfullscreenpagemode bookmarks");
            else if (!pdc_stricmp(value, "usethumbs"))
                pdf_set_viewerpreference(p, "nonfullscreenpagemode thumbnails");
            else if (!pdc_stricmp(value, "usenone"))
                pdf_set_viewerpreference(p, "nonfullscreenpagemode none");
	    else
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
	    break;

	case PDF_PARAMETER_DIRECTION:
            if (!pdc_stricmp(value, "r2l"))
                pdf_set_viewerpreference(p, "direction r2l");
            else if (!pdc_stricmp(value, "l2r"))
                pdf_set_viewerpreference(p, "direction l2r");
	    else
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
	    break;

	case PDF_PARAMETER_VIEWAREA:
        case PDF_PARAMETER_VIEWCLIP:
        case PDF_PARAMETER_PRINTAREA:
        case PDF_PARAMETER_PRINTCLIP:
            pdf_set_viewerpreference(p, optlist);
	    break;

	case PDF_PARAMETER_OPENACTION:
            pdf_set_openaction(p, value);
	    break;

	case PDF_PARAMETER_OPENMODE:
            pdf_set_openmode(p, value);
	    break;

	case PDF_PARAMETER_BOOKMARKDEST:
	    pdf_cleanup_destination(p, p->bookmark_dest);
            p->bookmark_dest =
                pdf_parse_destination_optlist(p, value, 0, pdf_bookmark);
	    break;

        case PDF_PARAMETER_INHERITGSTATE:
	    (void) pdf_bool_value(p, key, value);
	    break;

	case PDF_PARAMETER_TRANSITION:
	    pdf_set_transition(p, value);
	    break;

	case PDF_PARAMETER_BASE:
            pdf_set_uri(p, value);
	    break;

	case PDF_PARAMETER_LAUNCHLINK_PARAMETERS:
	    if (p->launchlink_parameters) {
		pdc_free(p->pdc, p->launchlink_parameters);
		p->launchlink_parameters = NULL;
	    }
	    p->launchlink_parameters = pdc_strdup(p->pdc, value);
	    break;

	case PDF_PARAMETER_LAUNCHLINK_OPERATION:
	    if (p->launchlink_operation) {
		pdc_free(p->pdc, p->launchlink_operation);
		p->launchlink_operation = NULL;
	    }
	    p->launchlink_operation = pdc_strdup(p->pdc, value);
	    break;

	case PDF_PARAMETER_LAUNCHLINK_DEFAULTDIR:
	    if (p->launchlink_defaultdir) {
		pdc_free(p->pdc, p->launchlink_defaultdir);
		p->launchlink_defaultdir = NULL;
	    }
	    p->launchlink_defaultdir = pdc_strdup(p->pdc, value);
	    break;

        case PDF_PARAMETER_PDIUSEBOX:
            p->pdi_usebox = usebox;
            break;

        case PDF_PARAMETER_AUTOSUBSETTING:
        case PDF_PARAMETER_AUTOCIDFONT:
        case PDF_PARAMETER_UNICODEMAP:
            pdc_warning(p->pdc, PDF_E_UNSUPP_UNICODE, 0, 0, 0, 0);
            break;

	default:
	    pdc_error(p->pdc, PDC_E_PAR_UNKNOWNKEY, key, 0, 0, 0);
	    break;
    } /* switch */
} /* pdf__set_parameter */
Esempio n. 7
0
void
pdf__begin_glyph(
    PDF *p,
    const char *glyphname,
    pdc_scalar wx,
    pdc_scalar llx, pdc_scalar lly, pdc_scalar urx, pdc_scalar ury)
{
    static const char fn[] = "pdf__begin_glyph";
    pdf_font *font;
    pdf_t3font *t3font;
    pdf_t3glyph *glyph = NULL;
    pdc_scalar tbc;
    int ig;

    if (glyphname == NULL || *glyphname == '\0')
        pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "glyphname", 0, 0, 0);

    font = &p->fonts[p->t3slot];
    t3font = font->t3font;

    /* error message prefix */
    pdc_push_errmsg(p->pdc, PDF_E_T3_FONT_PREFIX, font->apiname, 0, 0, 0);

    for (ig = 0; ig < t3font->next_glyph; ig++)
    {
        glyph = &t3font->glyphs[ig];
        if (!pdc_strcmp(glyph->name, glyphname))
        {
            if (t3font->pass == glyph->pass)
                pdc_error(p->pdc, PDF_E_T3_GLYPH, glyphname, 0, 0, 0);
            else
                break;
        }
    }

    /* new glyph */
    if (ig == t3font->next_glyph)
    {
        if (t3font->pass == 2)
            pdc_error(p->pdc, PDF_E_T3_UNKOWNGLYPH, glyphname, 0, 0, 0);

        pdc_check_number(p->pdc, "wx", wx);
        pdc_check_number(p->pdc, "llx", llx);
        pdc_check_number(p->pdc, "lly", lly);
        pdc_check_number(p->pdc, "urx", urx);
        pdc_check_number(p->pdc, "ury", ury);

        if (t3font->colorized == pdc_true &&
            (llx != 0 || lly != 0 ||
             urx != 0 || ury != 0))
            pdc_error(p->pdc, PDF_E_T3_BADBBOX, 0, 0, 0, 0);


        if (urx < llx)
        {
            tbc = llx;
            llx = urx;
            urx = tbc;
        }

        if (ury < lly)
        {
            tbc = lly;
            lly = ury;
            ury = tbc;
        }

        if (ig == t3font->capacity)
        {
            t3font->capacity *= 2;
            t3font->glyphs = (pdf_t3glyph *) pdc_realloc(p->pdc, t3font->glyphs,
                t3font->capacity * sizeof (pdf_t3glyph), fn);
        }

        glyph = &t3font->glyphs[ig];
        glyph->charproc_id = PDC_BAD_ID;
        glyph->name = pdc_strdup(p->pdc, glyphname);
        glyph->wx = wx;
        glyph->llx = llx;
        glyph->lly = lly;
        glyph->urx = urx;
        glyph->ury = ury;

        /* see comment in p_font.c for explanation */
        glyph->width = 1000 * wx * font->ft.matrix.a;

        /* if the strdup above fails, cleanup won't touch this slot. */
        t3font->next_glyph++;
    }
    glyph->pass = t3font->pass;
    t3font->curr_glyph = ig;

    pdc_logg_cond(p->pdc, 1, trc_font,
        "\tBegin of Type3 font glyph \"%s\"\n", glyphname);

    if (t3font->pass != 1)
    {
            if (t3font->pass == 2)
                pdc_logg_cond(p->pdc, 2, trc_font,
                              "\t\tglyph [%d] was used in text\n", ig);

            glyph->charproc_id = pdc_begin_obj(p->out, PDC_NEW_ID);
            pdc_begin_dict(p->out);

            p->length_id = pdc_alloc_id(p->out);
            pdc_objref(p->out, "/Length", p->length_id);

            if (pdc_get_compresslevel(p->out))
                pdc_puts(p->out, "/Filter/FlateDecode\n");

            pdc_end_dict(p->out);

            pdc_begin_pdfstream(p->out);

            if (t3font->colorized == pdc_true)
                pdc_printf(p->out, "%f 0 d0\n", glyph->wx);
            else
            {
                pdc_printf(p->out, "%f 0 %f %f %f %f d1\n",
                    glyph->wx, glyph->llx, glyph->lly, glyph->urx, glyph->ury);

                /* adjust the font's bounding box */
                if (glyph->llx < font->ft.bbox.llx)
                    font->ft.bbox.llx = glyph->llx;
                if (glyph->lly < font->ft.bbox.lly)
                    font->ft.bbox.lly = glyph->lly;
                if (glyph->urx > font->ft.bbox.urx)
                    font->ft.bbox.urx = glyph->urx;
                if (glyph->ury > font->ft.bbox.ury)
                    font->ft.bbox.ury = glyph->ury;
            }

            /* we must initialize the text, graphics and color state
             * otherwise the user get unpredictable appearance of a
             * glyph because of optimizing outputting graphics properties.
             * Following statements were inserted due to bug #719
             */
            pdf_init_tstate(p);
            pdf_init_gstate(p);
            pdf_init_cstate(p);

            PDF_SET_STATE(p, pdf_state_glyph);
    }
    else
    {
        PDF_SET_STATE(p, pdf_state_glyphmetrics);
    }

    pdc_pop_errmsg(p->pdc);

    if (!p->pdc->smokerun)
        pdc_logg_cond(p->pdc, 1, trc_api, "[Begin glyph %d]\n", ig);
}
Esempio n. 8
0
void
pdf__begin_font(
    PDF *p,
    const char *fontname, int len,
    pdc_scalar a, pdc_scalar b, pdc_scalar c, pdc_scalar d,
    pdc_scalar e, pdc_scalar f,
    const char *optlist)
{
    static const char fn[] = "pdf__begin_font";
    pdc_resopt *results;
    pdf_font tmpfont, *font;
    pdf_font_options fo;
    pdc_scalar det;
    pdc_clientdata cdata;
    int colorized = pdc_false;
    int metricsonly = pdc_false;
    int slot;

    if (fontname == NULL)
        pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "fontname", 0, 0, 0);

    /* Converting fontname */
    fontname = pdf_convert_name(p, fontname, len,
                                PDC_CONV_WITHBOM | PDC_CONV_TMPALLOC);
    if (fontname == NULL || *fontname == '\0')
        pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "fontname", 0, 0, 0);

    pdc_logg_cond(p->pdc, 1, trc_font,
        "\tBegin of Type3 font \"%s\"\n", fontname);

    /* error message prefix */
    pdc_push_errmsg(p->pdc, PDF_E_T3_FONT_PREFIX, fontname, 0, 0, 0);

    /* look for an already existing font */
    for (slot = 0; slot < p->fonts_number; slot++)
    {
        if (!pdc_strcmp(p->fonts[slot].apiname, fontname))
        {
            if (p->fonts[slot].t3font->pass == 1)
            {
                pdc_logg_cond(p->pdc, 1, trc_font,
                    "\tType3 font [%d] with metric definition found\n", slot);

                PDF_CHECK_STATE(p, pdf_state_document);

                p->fonts[slot].t3font->pass = 2;
                p->t3slot = slot;

                pdc_pop_errmsg(p->pdc);

                pdf_pg_suspend(p);
                PDF_SET_STATE(p, pdf_state_font);
                return;
            }

            pdc_error(p->pdc, PDF_E_T3_FONTEXISTS, 0, 0, 0, 0);
        }
    }

    pdc_check_number(p->pdc, "a", a);
    pdc_check_number(p->pdc, "b", b);
    pdc_check_number(p->pdc, "c", c);
    pdc_check_number(p->pdc, "d", d);
    pdc_check_number(p->pdc, "e", e);
    pdc_check_number(p->pdc, "f", f);

    det = a*d - b*c;

    if (det == 0)
        pdc_error(p->pdc, PDC_E_ILLARG_MATRIX,
            pdc_errprintf(p->pdc, "%f %f %f %f %f %f", a, b, c, d, e, f),
            0, 0, 0);

    /* parsing optlist */
    pdf_set_clientdata(p, &cdata);
    results = pdc_parse_optionlist(p->pdc, optlist, pdf_begin_font_options,
                                   &cdata, pdc_true);

    pdc_get_optvalues("colorized", results, &colorized, NULL);
    pdc_get_optvalues("widthsonly", results, &metricsonly, NULL);


    pdc_cleanup_optionlist(p->pdc, results);

    /* initialize font struct */
    font = &tmpfont;
    pdf_init_font_options(p, &fo);
    pdf_init_font(p, font, &fo);

    /*
     * We store the new font in a font slot marked with "invalidenc" encoding.
     * When the font is used for the first time we modify the encoding.
     * Later uses will make a copy if the encoding is different.
     */

    /* API font name */
    font->apiname = pdc_strdup(p->pdc, fontname);

    font->ft.m.type = fnt_Type3;
    font->hasoriginal = pdc_true;

    font->ft.matrix.a = a;
    font->ft.matrix.b = b;
    font->ft.matrix.c = c;
    font->ft.matrix.d = d;
    font->ft.matrix.e = e;
    font->ft.matrix.f = f;

    font->t3font = (pdf_t3font*) pdc_malloc(p->pdc, sizeof(pdf_t3font), fn);
    pdf_init_t3font(p, font->t3font, T3GLYPHS_CHUNKSIZE);

    font->t3font->colorized = colorized;


    /* the resource id is needed until the font dict is written */
    font->t3font->res_id = pdc_alloc_id(p->out);

    /* Now everything is fine, insert Type3 font with invalid encoding */
    slot = pdf_insert_font(p, font);

    /*
     * We must store a pointer to the current font because its glyph
     * definitions may use other fonts and we would be unable to find
     * "our" current font again. This pointer lives throughout the
     * font definition, and will be reset in PDF_end_font() below.
     */
    p->t3slot = slot;

    if (metricsonly)
    {
        font->t3font->pass = 1;
        pdc_logg_cond(p->pdc, 2, trc_font,
                          "\t\tonly for metric definition\n");
    }
    else
    {
        pdf_pg_suspend(p);
    }

    pdc_pop_errmsg(p->pdc);

    PDF_SET_STATE(p, pdf_state_font);

    if (!p->pdc->smokerun)
        pdc_logg_cond(p->pdc, 1, trc_api, "[Begin font %d]\n", p->t3slot);
}
Esempio n. 9
0
pdc_bool
pdf_t1open_fontfile(PDF *p, pdf_font *font, const char *filename,
                    PDF_data_source *t1src, pdc_bool requested)
{
    static const char *fn = "pdf_t1open_fontfile";
    t1_private_data  *t1 = NULL;
    pdc_file *fp = NULL;
    const char *stemp = NULL;
    pdc_byte magic[PFA_TESTBYTE];
    char fullname[PDC_FILENAMELEN];
    int fflags = PDC_FILE_BINARY;
    pdc_bool ispfb = pdc_true;

    if (filename)
    {
        pdc_bool retval = pdc_true;
        pdc_bool fnamegiven = (strcmp(filename, FNT_MISSING_FILENAME) == 0) ?
                              pdc_false : pdc_true;
        (void) retval;

        if (fnamegiven)
        {
            fp = pdc_fsearch_fopen(p->pdc, filename, fullname,
                                   "PostScript Type1 ", fflags);
            if (fp == NULL)
            {
                if (t1src)
                    PDC_RETHROW(p->pdc);
                return pdc_check_fopen_errmsg(p->pdc, requested);
            }

            pdc_logg_cond(p->pdc, 1, trc_font,
                "\tLoading PostScript Type1 fontfile \"%s\":\n", fullname);
        }

    }

    if (fp)
    {
        pdc_fread(magic, 1, PFA_TESTBYTE, fp);
        stemp = filename;
    }
    else if (font->ft.img)
    {
        strncpy((char *) magic, (const char *)font->ft.img, PFA_TESTBYTE);
        stemp = font->ft.name;
    }

    /* try to identify PFA files */
    if (magic[0] != PFB_MARKER)
    {
        char startsequ[PFA_TESTBYTE + 1];

        strcpy(startsequ, FNT_PFA_STARTSEQU);

        if (strncmp((const char *) magic, startsequ, PFA_TESTBYTE))
        {
            if (fp)
                pdc_fclose(fp);
            pdc_set_errmsg(p->pdc, PDF_E_T1_NOFONT, stemp, 0, 0, 0);
            if (t1src)
                PDC_RETHROW(p->pdc);
            return pdc_false;
        }
        ispfb = pdc_false;
    }

    pdc_logg_cond(p->pdc, 1, trc_font,
        "\tPostScript Type1 font of format \"%s\" detected\n",
        ispfb ? "PFB" : "PFA");

    if (t1src)
    {
        t1src->private_data = (unsigned char *)
                pdc_malloc(p->pdc, sizeof(t1_private_data), fn);
        t1 = (t1_private_data *) t1src->private_data;

        if (filename)
        {
            pdc_fclose(fp);
            if (ispfb)
            {
                t1->fontfile =
                    pdc_fsearch_fopen(p->pdc, fullname, NULL, "PFB ", fflags);
            }
            else
            {
                t1->fontfile =
                    pdc_fsearch_fopen(p->pdc, fullname, NULL, "PFA ",
                                      PDC_FILE_TEXT);
            }

            if (t1->fontfile == NULL)
                PDC_RETHROW(p->pdc);
        }
        else if (font->ft.img)
        {
            /* only for virtual PFB files */
            t1->fontfile = NULL;
            t1->img = font->ft.img;
            t1->pos = font->ft.img;
            t1->end = font->ft.img + font->ft.filelen;
        }

        t1src->init = t1data_init;
        t1src->fill = ispfb ? PFB_data_fill : PFA_data_fill;
        t1src->terminate = t1data_terminate;
    }
    else if (fp != NULL)
    {
        if (pdc_file_isvirtual(fp) == pdc_true)
        {
            if (ispfb)
                font->ft.img =
                    (pdc_byte *) pdc_freadall(fp, &font->ft.filelen, NULL);
            font->ft.imgname = pdc_strdup(p->pdc, fullname);
            pdc_lock_pvf(p->pdc, font->ft.imgname);
        }
        font->ft.filename = pdc_strdup(p->pdc, fullname);
        pdc_fclose(fp);
    }

    return pdc_true;
}
Esempio n. 10
0
pdc_bool
pdf_get_metrics_tt(PDF *p, pdf_font *font, const char *fontname,
                   pdc_encoding enc, const char *filename)
{
    pdc_bool logg1 = pdc_logg_is_enabled(p->pdc, 1, trc_font);
    pdc_bool logg2 = pdc_logg_is_enabled(p->pdc, 2, trc_font);
    int filesize = 0;
    double kbfilesize = 0;
    int foundglyphs, flags = 0;
    tt_file *ttf;
    pdc_bool retval;
    pdc_encoding enc_req;
    pdc_encodingvector *ev = NULL;
    pdc_bool isotf;
    int errcode = 0;

    (void) logg2;

    /*
     * Initialisation
     */
    ttf = fnt_new_tt(p->pdc, &font->ft);
    ttf->filename = filename;
    ttf->fontname = fontname;
    ttf->verbose = font->verbose;
    ttf->incore = pdc_true;
    ttf->monospace = font->opt.monospace;
    filesize = font->ft.filelen;
    kbfilesize = filesize / 1024.0;

    /*
     * Read font file
     */
    retval = fnt_read_tt(ttf);
    if (retval == pdc_false)
        goto PDF_TRUETYPE_ERROR2;

    /*
     * Font type
     */
    if (ttf->tab_CFF_)
    {
        isotf = pdc_true;
        font->ft.m.type = fnt_Type1C;
	font->cff_offset = (long) ttf->tab_CFF_->offset;
	font->cff_length = ttf->tab_CFF_->length;
    }
    else
    {
        isotf = pdc_false;
        font->ft.m.type = fnt_TrueType;
        TT_IOCHECK(ttf, tt_tag2idx(ttf, fnt_str_glyf) != -1);
        TT_IOCHECK(ttf, tt_tag2idx(ttf, fnt_str_loca) != -1);
    }

    /* Number of Glyphs */
    if (ttf->numGlyphs <= 1)
    {
        errcode = FNT_E_TT_NOGLYFDESC;
        goto PDF_TRUETYPE_ERROR1;
    }


    /*
     * Encoding
     */
    if (isotf)
    {
        /* OpenType font with CFF table */
        if (ttf->charcoll != cc_none)
        {
            /* CID font */
            if (font->ft.m.charcoll != cc_none)
            {
                if (!ttf->regisadobe)
                {
                    errcode = PDF_E_CJK_UNSUPP_REGISTRY;
                    goto PDF_TRUETYPE_ERROR1;
                }

                if (font->ft.m.charcoll != ttf->charcoll)
                {
                    errcode = PDF_E_CJK_UNSUPP_CHARCOLL;
                    goto PDF_TRUETYPE_ERROR1;
                }


                if (font->outcmapname != NULL)
                    enc = pdc_cid;

                if (logg1)
                    pdc_logg(p->pdc, "\tCID font ordering: \"%s\"\n",
                             fnt_get_ordering_cid(ttf->charcoll));
            }
            else if (enc == pdc_unicode || enc == pdc_glyphid)
            {
                font->ft.m.charcoll = ttf->charcoll;
                font->supplement = ttf->supplement;
            }
            else
            {
                errcode = PDF_E_FONT_ONLY_CMAP;
                goto PDF_TRUETYPE_ERROR1;
            }
        }
        else if (font->ft.m.charcoll != cc_none)
        {
            /* SID font */
            errcode = PDF_E_FONT_UNSUPP_CMAP;
            goto PDF_TRUETYPE_ERROR1;
        }
    }
    else
    {
        if (font->ft.m.charcoll != cc_none)
        {
            int i;
            pdc_bool iscjk = pdc_false;

            for (i = 0; i < PDC_NUMCHARCOLL; i++)
            {
                if (ttf->tab_OS_2->charcolls[i])
                    iscjk = pdc_true;

                if (ttf->tab_OS_2->charcolls[i] == font->ft.m.charcoll)
                    break;
            }
            if (i == PDC_NUMCHARCOLL)
            {
                if (iscjk)
                {
                    /* CJK font */
                    errcode = PDF_E_CJK_UNSUPP_CHARCOLL;
                    goto PDF_TRUETYPE_ERROR1;
                }
                else
                {
                    /* no CJK font */
                    errcode = PDF_E_FONT_UNSUPP_CMAP;
                    goto PDF_TRUETYPE_ERROR1;
                }
            }
            else
            {
                if (font->outcmapname != NULL)
                {
                    ttf->charcoll = font->ft.m.charcoll;
                    enc = pdc_cid;
                }
            }
        }
    }

    /* encoding vector */
    enc_req = fnt_get_tt_encoding_key(ttf, enc);
    if (enc_req == pdc_invalidenc)
    {
        errcode = FNT_E_TT_BADCMAP;
        goto PDF_TRUETYPE_ERROR1;
    }
    else if (enc_req != enc)
    {
        if (strcmp(font->encapiname, "auto"))
        {
            pdc_warning(p->pdc, PDF_E_FONT_FORCEENC,
                        pdf_get_encoding_name(p, enc_req, NULL),
                        0, 0, 0);
        }
        enc = enc_req;
    }
    if (enc >= 0)
        ev = pdc_get_encoding_vector(p->pdc, enc);
    font->ft.enc = enc;
    font->ft.issymbfont = ttf->issymbol;
    font->hasnomac = !ttf->tab_cmap || !ttf->tab_cmap->mac;


    /* builtin encoding */
    if (enc == pdc_builtin)
    {
        if (font->ft.issymbfont == pdc_false)
        {
            errcode = PDF_E_FONT_BADENC;
            goto PDF_TRUETYPE_ERROR1;
        }
        else
        {
            /* encoding vector for builtin */
            ev = pdf_create_font_encoding(p, enc, font, fontname, pdc_true);
            font->symenc = font->ft.enc;
        }
    }

    {
        /* optimizing PDF output */
        if (enc == pdc_ebcdic ||
            enc == pdc_ebcdic_37 ||
            enc == pdc_ebcdic_winansi)
            font->towinansi = pdc_winansi;

    }

    /* /FontName in FontDescriptor */
    font->ft.m.name = pdc_strdup(p->pdc, ttf->tab_name->englishname4);

    /* /BaseFont name */
    font->ft.name = pdc_strdup(p->pdc, ttf->tab_name->englishname6);


#define PDF_RESTRICTED_TT_EMBEDDING	0x02
    /* check embedding flags */
    if ((font->opt.embedding) && ttf->tab_OS_2 &&
	ttf->tab_OS_2->fsType == PDF_RESTRICTED_TT_EMBEDDING)
    {
        errcode = FNT_E_TT_EMBED;
        goto PDF_TRUETYPE_ERROR1;
    }


    if (logg1)
    {
        pdc_logg(p->pdc,
            "\tFull font name: \"%s\"\n"
            "\tPostScript font name: \"%s\"\n"
            "\tFont embedding: %s\n"
            "\tVertical font: %s\n",
            font->ft.name, font->ft.m.name,
            PDC_BOOLSTR(font->opt.embedding),
            PDC_BOOLSTR(font->ft.vertical));

        if (ttf->tab_name->producer != NULL)
            pdc_logg(p->pdc, "\tFont producer: \"%s\"\n",
                     ttf->tab_name->producer);

        pdc_logg(p->pdc, "\tNumber of Glyphs: %d\n", ttf->numGlyphs);
    }

    /* Save font values */
    fnt_set_tt_fontvalues(ttf);

    /* Flags for creating font arrays */
    flags = TT_FONT_code2gid | TT_FONT_m_widths;



    /* Create font mapping and width arrays */
    foundglyphs = fnt_set_tt_fontarrays(ttf, flags);

   /***********************************/
    if (font->symenc != pdc_invalidenc)
        font->ft.enc = pdc_builtin;
   /***********************************/

    if (!foundglyphs)
    {
        errcode = PDF_E_FONT_BADENC;
        goto PDF_TRUETYPE_ERROR1;
    }


    fnt_delete_tt(ttf);

    if (!pdf_make_fontflag(p, font))
        return pdc_false;

    return pdc_true;

    PDF_TRUETYPE_ERROR1:
    pdc_set_errmsg(p->pdc, errcode, 0, 0, 0, 0);

    PDF_TRUETYPE_ERROR2:
    fnt_delete_tt(ttf);

    return pdc_false;
}
Esempio n. 11
0
static pdc_bool
pdf_parse_afm(
    PDF *p,
    pdc_file *fp,
    pdf_font *font,
    const char *fontname,
    const char *filename)
{
    static const char fn[] = "pdf_parse_afm";
    fnt_font_metric *ftm = &font->ft.m;
    const char *afmtype = NULL;
    char **wordlist = NULL, *keyword, *arg1;
    char line[AFM_LINEBUF];
    int i, cmp, lo, hi, nwords, nglyphs = 0, nline = 0;
    int tablen = ((sizeof keyStrings) / (sizeof (char *)));
    pdc_sint32 iz;
    double dz;
    pdc_scalar charwidth = -1;
    pdf_afmkey keynumber;
    fnt_glyphwidth *glw;
    pdc_bool toskip = pdc_false;
    pdc_bool is_zadbfont = !strcmp(fontname, "ZapfDingbats");

    /* all new glyph names of AGL 2.0 are missing */
    font->missingglyphs = 0xFFFFFFFF;

    /* read loop. because of Mac files we use pdc_fgetline */
    while (pdc_fgetline(line, AFM_LINEBUF, fp) != NULL)
    {
        /* split line */
        nline++;
        nwords = pdc_split_stringlist(p->pdc, line, AFM_SEPARATORS, 0,
                                      &wordlist);
        if (!nwords) continue;
        keyword = wordlist[0];

        /* find keynumber */
        lo = 0;
        hi = tablen;
        keynumber = NOPE;
        while (lo < hi)
        {
            i = (lo + hi) / 2;
            cmp = strcmp(keyword, keyStrings[i]);

            if (cmp == 0)
            {
                keynumber = (pdf_afmkey) i;
                break;
            }

            if (cmp < 0)
                hi = i;
            else
                lo = i + 1;
        }

        /* unkown key */
        if (keynumber == NOPE)
        {
            pdc_warning(p->pdc, PDF_E_T1_AFMBADKEY, keyword, filename, 0,0);
            goto PDF_PARSECONTD;
        }
        if (keynumber == ENDDIRECTION)
            toskip = pdc_false;

        if (nwords == 1 || toskip == pdc_true)
            goto PDF_PARSECONTD;

        /* key switch */
        arg1 = wordlist[1];
        switch (keynumber)
        {
            case STARTDIRECTION:
            if (pdc_str2integer(arg1, 0, &iz) != pdc_true)
                goto PDF_SYNTAXERROR;
            if (iz)
                toskip = pdc_true;
            break;

            case STARTCOMPFONTMETRICS:
            afmtype = "ACFM";
            goto PDF_SYNTAXERROR;

            case STARTMASTERFONTMETRICS:
            afmtype = "AMFM";
            goto PDF_SYNTAXERROR;

            case ISCIDFONT:
            afmtype = "CID font";
            if (!strcmp(arg1, "true"))
                goto PDF_SYNTAXERROR;
            break;

            case FONTNAME:
            font->ft.name = pdc_strdup(p->pdc, arg1);
            ftm->name = pdc_strdup(p->pdc, arg1);
            pdc_logg_cond(p->pdc, 1, trc_font,
                "\tPostScript font name: \"%s\"\n", ftm->name);
            break;

            /* Recognize Multiple Master fonts by last part of name */
            case FAMILYNAME:
            if (!strcmp(wordlist[nwords-1], "MM"))
                ftm->type = fnt_MMType1;
            else
                ftm->type = fnt_Type1;
            break;

            /* Default: FontSpecific */
            case ENCODINGSCHEME:
            if (!pdc_stricmp(arg1, "StandardEncoding") ||
                !pdc_stricmp(arg1, "AdobeStandardEncoding"))
                font->ft.issymbfont = pdc_false;
            break;

            case STDHW:
            if (pdc_str2double(arg1, &dz) != pdc_true)
                goto PDF_SYNTAXERROR;
            ftm->StdHW = (int) dz;
            break;

            case STDVW:
            if (pdc_str2double(arg1, &dz) != pdc_true)
                goto PDF_SYNTAXERROR;
            ftm->StdVW = (int) dz;
            break;

            case WEIGHT:
            font->ft.weight = fnt_check_weight(fnt_weightname2weight(arg1));
            break;

            case ISFIXEDPITCH:
            if (!pdc_stricmp(arg1, "false"))
                ftm->isFixedPitch = pdc_false;
            else
                ftm->isFixedPitch = pdc_true;
            break;

            /* New AFM 4.1 keyword "CharWidth" implies fixed pitch */
            case CHARWIDTH:
            if (pdc_str2double(arg1, &dz) != pdc_true)
                goto PDF_SYNTAXERROR;
            charwidth = dz;
            ftm->isFixedPitch = pdc_true;
            break;

            case ITALICANGLE:
            {
                if (pdc_str2double(arg1, &dz) != pdc_true)
                    goto PDF_SYNTAXERROR;
                ftm->italicAngle = dz;
            }
            break;

            case UNDERLINEPOSITION:
            if (pdc_str2double(arg1, &dz) != pdc_true)
                goto PDF_SYNTAXERROR;
            ftm->underlinePosition = (int) dz;
            break;

            case UNDERLINETHICKNESS:
            if (pdc_str2double(arg1, &dz) != pdc_true)
                goto PDF_SYNTAXERROR;
            ftm->underlineThickness = (int) dz;
            break;

            case FONTBBOX:
            {
                if (nwords != 5)
                    goto PDF_SYNTAXERROR;
                for (i = 1; i < nwords; i++)
                {
                    if (pdc_str2double(wordlist[i], &dz) != pdc_true)
                        goto PDF_SYNTAXERROR;
                    if (i == 1)
                        ftm->llx = dz;
                    else if (i == 2)
                        ftm->lly = dz;
                    else if (i == 3)
                        ftm->urx = dz;
                    else if (i == 4)
                        ftm->ury = dz;
                }
            }
            break;

            case CAPHEIGHT:
            if (pdc_str2double(arg1, &dz) != pdc_true)
                goto PDF_SYNTAXERROR;
            ftm->capHeight = (int) dz;
            break;

            case XHEIGHT:
            if (pdc_str2double(arg1, &dz) != pdc_true)
                goto PDF_SYNTAXERROR;
            ftm->xHeight = (int) dz;
            break;

            case DESCENDER:
            if (pdc_str2double(arg1, &dz) != pdc_true)
                goto PDF_SYNTAXERROR;
            ftm->descender = (int) dz;
            break;

            case ASCENDER:
            if (pdc_str2double(arg1, &dz) != pdc_true)
                goto PDF_SYNTAXERROR;
            ftm->ascender = (int) dz;
            break;

            /* Character widths */

            case STARTCHARMETRICS:
            if (pdc_str2integer(arg1, PDC_INT_UNSIGNED, (pdc_sint32 *) &nglyphs)
                != pdc_true || nglyphs <= 0)
                goto PDF_SYNTAXERROR;
            ftm->glw = (fnt_glyphwidth *) pdc_calloc(p->pdc,
                            (size_t) nglyphs * sizeof(fnt_glyphwidth), fn);
            break;

            /* Character code */
            case CODE:
            case CODEHEX:
            if (!nglyphs || !ftm->glw)
                goto PDF_SYNTAXERROR;
            if (font->ft.numglyphs >= nglyphs)
            {
                nglyphs++;
                ftm->glw = (fnt_glyphwidth *) pdc_realloc(p->pdc, ftm->glw,
                                (size_t) nglyphs * sizeof(fnt_glyphwidth), fn);
            }
            glw = &ftm->glw[font->ft.numglyphs];
            if (keynumber == CODE)
            {
                if (pdc_str2integer(arg1, 0, &iz) != pdc_true)
                    goto PDF_SYNTAXERROR;
            }
            else
            {
                if (pdc_str2integer(arg1, PDC_INT_HEXADEC, &iz) != pdc_true)
                    goto PDF_SYNTAXERROR;
            }
            glw->code = (pdc_short) iz;
            glw->unicode = 0;
            glw->width = (pdc_ushort)
                (font->opt.monospace ? font->opt.monospace : charwidth);
            font->ft.numglyphs++;

            /* Character width and name */
            for (i = 2; i < nwords; i++)
            {
                if (!strcmp(wordlist[i], "WX") ||
                    !strcmp(wordlist[i], "W0X") ||
                    !strcmp(wordlist[i], "W"))
                {
                    i++;
                    if (i == nwords)
                        goto PDF_SYNTAXERROR;
                    if (pdc_str2double(wordlist[i], &dz) != pdc_true)
                        goto PDF_SYNTAXERROR;
                    glw->width = (pdc_ushort)
                         (font->opt.monospace ? font->opt.monospace : dz);
                }

                if (!strcmp(wordlist[i], "N"))
                {
                    i++;
                    if (i == nwords)
                        goto PDF_SYNTAXERROR;

                    /* Unicode value by means of AGL,
                     * internal and private table
                     */
                    glw->unicode = is_zadbfont ?
                         (pdc_ushort) pdc_zadb2unicode(wordlist[i]):
                         pdc_insert_glyphname(p->pdc, wordlist[i]);
                    pdc_delete_missingglyph_bit(glw->unicode,
                                                &font->missingglyphs);

                }
            }
            break;


            default:
            break;
        }

        PDF_PARSECONTD:
        pdc_cleanup_stringlist(p->pdc, wordlist);
        wordlist = NULL;

        if (keynumber == ENDFONTMETRICS)
            break;
    }

    /* necessary font struct members */
    if (font->ft.name == NULL || ftm->glw == NULL)
        goto PDF_SYNTAXERROR;

    pdc_fclose(fp);

    ftm->numglwidths = font->ft.numglyphs;
    return pdc_true;

    PDF_SYNTAXERROR:
    pdc_fclose(fp);
    pdc_cleanup_stringlist(p->pdc, wordlist);

    if (afmtype)
        pdc_set_errmsg(p->pdc, PDF_E_T1_UNSUPP_FORMAT, afmtype, 0, 0, 0);
    else
        pdc_set_errmsg(p->pdc, PDC_E_IO_ILLSYNTAX, "AFM ", filename,
                       pdc_errprintf(p->pdc, "%d", nline), 0);
    return pdc_false;
}
Esempio n. 12
0
PDFLIB_API void PDFLIB_CALL
PDF_set_parameter(PDF *p, const char *key, const char *value)
{
    static const char fn[] = "PDF_set_parameter";
    pdc_usebox usebox = use_none;
    pdc_text_format textformat = pdc_auto;
    int i, k;

    if (key == NULL || !*key)
	pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "key", 0, 0, 0);

    i = get_index(key);

    if (!pdf_enter_api(p, fn, (pdf_state) pdf_state_all,
	"(p[%p], \"%s\", \"%s\")\n", (void *) p, key, value))
	return;

    if (i == -1)
	pdc_error(p->pdc, PDC_E_PAR_UNKNOWNKEY, key, 0, 0, 0);

    if ((p->state_stack[p->state_sp] & parms[i].set_scope) == 0)
	pdc_error(p->pdc, PDF_E_DOC_SCOPE_SET, key, pdf_current_scope(p), 0, 0);

    if (value == NULL)
	pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "value", 0, 0, 0);

    switch (i)
    {
        case PDF_PARAMETER_PDIUSEBOX:
        case PDF_PARAMETER_VIEWAREA:
        case PDF_PARAMETER_VIEWCLIP:
        case PDF_PARAMETER_PRINTAREA:
        case PDF_PARAMETER_PRINTCLIP:
            k = pdc_get_keycode(value, pdf_usebox_keylist);
            if (k == PDC_KEY_NOTFOUND)
                pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
            usebox = (pdc_usebox) k;
            break;

        case PDF_PARAMETER_TEXTFORMAT:
        case PDF_PARAMETER_HYPERTEXTFORMAT:
            k = pdc_get_keycode(value, pdf_textformat_keylist);
            if (k == PDC_KEY_NOTFOUND)
                pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
            textformat = (pdc_text_format) k;
            break;
    }

    switch (i)
    {
        case PDF_PARAMETER_SEARCHPATH:
        case PDF_PARAMETER_FONTAFM:
	case PDF_PARAMETER_FONTPFM:
        case PDF_PARAMETER_FONTOUTLINE:
        case PDF_PARAMETER_HOSTFONT:
        case PDF_PARAMETER_ENCODING:
        case PDF_PARAMETER_ICCPROFILE:
        case PDF_PARAMETER_STANDARDOUTPUTINTENT:
	{
            pdf_add_resource(p, key, value);
            break;
        }

	case PDF_PARAMETER_FLUSH:
	    if (p->binding != NULL && strcmp(p->binding, "C++"))
		break;

	    if (!strcmp(value, "none"))
		p->flush = pdf_flush_none;
	    else if (!strcmp(value, "page"))
                p->flush = (pdf_flush_state) (p->flush | pdf_flush_page);
	    else if (!strcmp(value, "content"))
                p->flush = (pdf_flush_state) (p->flush | pdf_flush_content);
	    else if (!strcmp(value, "heavy"))
                p->flush = (pdf_flush_state) (p->flush | pdf_flush_heavy);
	    else
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);

	    break;

	case PDF_PARAMETER_DEBUG:
	{
	    const unsigned char *c;

	    for (c = (const unsigned char *) value; *c; c++) {
		p->debug[(int) *c] = 1;

		if (*c == 't') {
		    pdc_set_trace(p->pdc, "PDFlib " PDFLIB_VERSIONSTRING);
		}
	    }
	    break;
	}

	case PDF_PARAMETER_NODEBUG:
	{
	    const unsigned char *c;

	    for (c = (const unsigned char *) value; *c; c++) {
		if (*c == 't')
		    pdc_set_trace(p->pdc, NULL);

		p->debug[(int) *c] = 0;
	    }
	    break;
	}

        case PDF_PARAMETER_BINDING:
            if (!p->binding)
                p->binding = pdc_strdup(p->pdc, value);
            break;

        case PDF_PARAMETER_HASTOBEPOS:
            p->hastobepos = pdf_bool_value(p, key, value);
            break;

	case PDF_PARAMETER_UNDERLINE:
	    p->underline = pdf_bool_value(p, key, value);
	    break;

	case PDF_PARAMETER_OVERLINE:
	    p->overline = pdf_bool_value(p, key, value);
	    break;

	case PDF_PARAMETER_STRIKEOUT:
	    p->strikeout = pdf_bool_value(p, key, value);
	    break;

        case PDF_PARAMETER_KERNING:
            pdc_warning(p->pdc, PDF_E_UNSUPP_KERNING, 0, 0, 0, 0);
            break;

        case PDF_PARAMETER_AUTOSUBSETTING:
            pdc_warning(p->pdc, PDF_E_UNSUPP_SUBSET, 0, 0, 0, 0);
            break;

        case PDF_PARAMETER_AUTOCIDFONT:
            pdc_warning(p->pdc, PDF_E_UNSUPP_UNICODE, 0, 0, 0, 0);
            break;

        case PDF_PARAMETER_UNICODEMAP:
            pdc_warning(p->pdc, PDF_E_UNSUPP_UNICODE, 0, 0, 0, 0);
            break;

	case PDF_PARAMETER_MASTERPASSWORD:
	    pdc_warning(p->pdc, PDF_E_UNSUPP_CRYPT, 0, 0, 0, 0);
	    break;

	case PDF_PARAMETER_USERPASSWORD:
            pdc_warning(p->pdc, PDF_E_UNSUPP_CRYPT, 0, 0, 0, 0);
	    break;

	case PDF_PARAMETER_PERMISSIONS:
            pdc_warning(p->pdc, PDF_E_UNSUPP_CRYPT, 0, 0, 0, 0);
	    break;

	case PDF_PARAMETER_COMPATIBILITY:

	    if (!strcmp(value, "1.3"))
		p->compatibility = PDC_1_3;
	    else if (!strcmp(value, "1.4"))
		p->compatibility = PDC_1_4;
	    else if (!strcmp(value, "1.5"))
		p->compatibility = PDC_1_5;
	    else
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
	    break;

	case PDF_PARAMETER_PDFX:
	    pdc_warning(p->pdc, PDF_E_UNSUPP_PDFX, 0, 0, 0, 0);

	    break;


        case PDF_PARAMETER_RESOURCEFILE:
            if (p->resourcefilename)
            {
                pdc_free(p->pdc, p->resourcefilename);
                p->resourcefilename = NULL;
            }
            p->resourcefilename = pdc_strdup(p->pdc, value);
            p->resfilepending = pdc_true;
            break;

	case PDF_PARAMETER_PREFIX:
            if (p->prefix)
            {
                pdc_free(p->pdc, p->prefix);
                p->prefix = NULL;
            }
            /* because of downward compatibility */
            p->prefix = pdc_strdup(p->pdc, &value[value[0] == '/' ? 1 : 0]);
	    break;

	case PDF_PARAMETER_WARNING:
	    pdc_set_warnings(p->pdc, pdf_bool_value(p, key, value));
	    break;

        case PDF_PARAMETER_OPENWARNING:
            p->debug['o'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_FONTWARNING:
            p->debug['F'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_ICCWARNING:
            p->debug['I'] = (char) pdf_bool_value(p, key, value);
            break;

	case PDF_PARAMETER_IMAGEWARNING:
	    p->debug['i'] = (char) pdf_bool_value(p, key, value);
	    break;

        case PDF_PARAMETER_PDIWARNING:
            p->debug['p'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_HONORICCPROFILE:
            p->debug['e'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_GLYPHWARNING:
            p->debug['g'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_RENDERINGINTENT:
            k = pdc_get_keycode(value, gs_renderingintents);
            if (k == PDC_KEY_NOTFOUND)
                pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
            p->rendintent = (pdf_renderingintent) k;
            break;

        case PDF_PARAMETER_PRESERVEOLDPANTONENAMES:
            p->preserveoldpantonenames = pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_SPOTCOLORLOOKUP:
            p->spotcolorlookup = pdf_bool_value(p, key, value);
            break;

	case PDF_PARAMETER_INHERITGSTATE:
	    p->inheritgs = pdf_bool_value(p, key, value);
	    break;

	case PDF_PARAMETER_PDISTRICT:
	    p->pdi_strict = pdf_bool_value(p, key, value);
	    break;

	case PDF_PARAMETER_PDIUSEBOX:
            p->pdi_usebox = usebox;
            break;

	case PDF_PARAMETER_PASSTHROUGH:
	    p->debug['P'] = (char) !pdf_bool_value(p, key, value);
	    break;

	case PDF_PARAMETER_HIDETOOLBAR:
	    if (pdf_bool_value(p, key, value))
		p->ViewerPreferences.flags |= HideToolbar;
	    break;

	case PDF_PARAMETER_HIDEMENUBAR:
	    if (pdf_bool_value(p, key, value))
		p->ViewerPreferences.flags |= HideMenubar;
	    break;

	case PDF_PARAMETER_HIDEWINDOWUI:
	    if (pdf_bool_value(p, key, value))
		p->ViewerPreferences.flags |= HideWindowUI;
	    break;

	case PDF_PARAMETER_FITWINDOW:
	    if (pdf_bool_value(p, key, value))
		p->ViewerPreferences.flags |= FitWindow;
	    break;

	case PDF_PARAMETER_CENTERWINDOW:
	    if (pdf_bool_value(p, key, value))
		p->ViewerPreferences.flags |= CenterWindow;
	    break;

	case PDF_PARAMETER_DISPLAYDOCTITLE:
	    if (pdf_bool_value(p, key, value))
		p->ViewerPreferences.flags |= DisplayDocTitle;
	    break;

	case PDF_PARAMETER_NONFULLSCREENPAGEMODE:
	    if (!strcmp(value, "useoutlines")) {
		p->ViewerPreferences.flags |= NonFullScreenPageModeOutlines;
		p->ViewerPreferences.flags &= ~NonFullScreenPageModeThumbs;
	    } else if (!strcmp(value, "usethumbs")) {
		p->ViewerPreferences.flags &= ~NonFullScreenPageModeOutlines;
		p->ViewerPreferences.flags |= NonFullScreenPageModeThumbs;
	    } else if (!strcmp(value, "usenone")) {
		p->ViewerPreferences.flags &= ~NonFullScreenPageModeOutlines;
		p->ViewerPreferences.flags &= ~NonFullScreenPageModeThumbs;
	    } else {
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
	    }

	    break;

	case PDF_PARAMETER_DIRECTION:
	    if (!strcmp(value, "r2l")) {
		p->ViewerPreferences.flags |= DirectionR2L;
	    } else if (!strcmp(value, "l2r")) {
		p->ViewerPreferences.flags &= ~DirectionR2L;
	    } else {
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
	    }
	    break;

	case PDF_PARAMETER_VIEWAREA:
            p->ViewerPreferences.ViewArea = usebox;
	    break;

	case PDF_PARAMETER_VIEWCLIP:
            p->ViewerPreferences.ViewClip = usebox;
            break;

	case PDF_PARAMETER_PRINTAREA:
            p->ViewerPreferences.PrintArea = usebox;
            break;

	case PDF_PARAMETER_PRINTCLIP:
            p->ViewerPreferences.PrintClip = usebox;
            break;

        case PDF_PARAMETER_TOPDOWN:
            if (pdf_bool_value(p, key, value))
                p->ydirection = (float) -1.0;
            else
                p->ydirection = (float) 1.0;
            break;

        case PDF_PARAMETER_USERCOORDINATES:
            p->usercoordinates = pdf_bool_value(p, key, value);
            break;

	case PDF_PARAMETER_OPENACTION:
	    pdf_cleanup_destination(p, &p->open_action);

	    pdf_parse_destination_optlist(p,
                value, &p->open_action, 1, pdf_openaction);
	    break;

	case PDF_PARAMETER_OPENMODE:
	    if (!strcmp(value, "none")) {
		p->open_mode = open_none;
	    } else if (!strcmp(value, "bookmarks")) {
		p->open_mode = open_bookmarks;
	    } else if (!strcmp(value, "thumbnails")) {
		p->open_mode = open_thumbnails;
	    } else if (!strcmp(value, "fullscreen")) {
		p->open_mode = open_fullscreen;
	    } else {
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
	    }
	    break;

	case PDF_PARAMETER_BOOKMARKDEST:
	    pdf_cleanup_destination(p, &p->bookmark_dest);

	    pdf_parse_destination_optlist(p,
                value, &p->bookmark_dest, 0, pdf_bookmark);
	    break;

	case PDF_PARAMETER_FILLRULE:
	    if (!strcmp(value, "winding")) {
		p->fillrule = pdf_fill_winding;
	    } else if (!strcmp(value, "evenodd")) {
		p->fillrule = pdf_fill_evenodd;
	    } else {
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
	    }
	    break;

        case PDF_PARAMETER_TEXTFORMAT:
            p->textformat = textformat;
            break;

        case PDF_PARAMETER_HYPERTEXTFORMAT:
            p->hypertextformat = textformat;
            break;

        case PDF_PARAMETER_HYPERTEXTENCODING:
        {
            pdc_encoding enc;

            if (!*value)
            {
                enc = pdc_unicode;
            }
            else
            {
                enc = pdf_find_encoding(p, (const char *) value);
                if (enc == pdc_invalidenc)
                    enc = pdf_insert_encoding(p, (const char *) value);
                if (enc < 0 && enc != pdc_unicode)
                    pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
            }
            p->hypertextencoding = enc;
            break;
        }

	/* deprecated */
	case PDF_PARAMETER_NATIVEUNICODE:
	    (void) pdf_bool_value(p, key, value);
	    break;

	case PDF_PARAMETER_TRANSITION:
	    pdf_set_transition(p, value);
	    break;

	case PDF_PARAMETER_BASE:
	    if (p->base) {
		pdc_free(p->pdc, p->base);
		p->base = NULL;
	    }

	    p->base = pdc_strdup(p->pdc, value);
	    break;

	case PDF_PARAMETER_LAUNCHLINK_PARAMETERS:
	    if (p->launchlink_parameters) {
		pdc_free(p->pdc, p->launchlink_parameters);
		p->launchlink_parameters = NULL;
	    }
	    p->launchlink_parameters = pdc_strdup(p->pdc, value);
	    break;

	case PDF_PARAMETER_LAUNCHLINK_OPERATION:
	    if (p->launchlink_operation) {
		pdc_free(p->pdc, p->launchlink_operation);
		p->launchlink_operation = NULL;
	    }
	    p->launchlink_operation = pdc_strdup(p->pdc, value);
	    break;

	case PDF_PARAMETER_LAUNCHLINK_DEFAULTDIR:
	    if (p->launchlink_defaultdir) {
		pdc_free(p->pdc, p->launchlink_defaultdir);
		p->launchlink_defaultdir = NULL;
	    }
	    p->launchlink_defaultdir = pdc_strdup(p->pdc, value);
	    break;

	case PDF_PARAMETER_TRACE:
	    if (pdf_bool_value(p, key, value)) {
		p->debug['t'] = 1;
		pdc_set_trace(p->pdc, "PDFlib " PDFLIB_VERSIONSTRING);
	    } else {
		pdc_set_trace(p->pdc, NULL);
		p->debug['t'] = 0;
	    }
	    break;

	case PDF_PARAMETER_TRACEFILE:
	    pdc_set_tracefile(p->pdc, value);
	    break;

	case PDF_PARAMETER_TRACEMSG:
	    /* do nothing -- client-supplied string will show up in the trace */
	    break;

	case PDF_PARAMETER_SERIAL:
	case PDF_PARAMETER_LICENSE:
	    break;

	case PDF_PARAMETER_LICENSEFILE:
	    break;

	default:
	    pdc_error(p->pdc, PDC_E_PAR_UNKNOWNKEY, key, 0, 0, 0);
	    break;
    } /* switch */
} /* PDF_set_parameter */
Esempio n. 13
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;
}
Esempio n. 14
0
static void
pdf_read_resourcefile(PDF *p, const char *filename)
{
    pdc_file   *fp = NULL;
    char      **linelist;
    char       *line;
    char       *category = NULL;
    char       *uprfilename = NULL;
#if defined(AS400) || defined(WIN32)
#define BUFSIZE 2048
    char        buffer[BUFSIZE];
#ifdef WIN32
    char        regkey[128];
    HKEY        hKey = NULL;
    DWORD       size, lType;
#endif
#endif
    int         il, nlines = 0, nextcat, begin;

#ifdef WIN32

/* don't add patchlevel's to registry searchpath */
#define stringiz1(x)	#x
#define stringiz(x)	stringiz1(x)

#define PDFLIBKEY  "Software\\PDFlib\\PDFlib\\"

    strcpy(regkey, PDFLIBKEY);
    strcat(regkey, PDFLIB_VERSIONSTRING);

    /* process registry entries */
    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, regkey, 0L,
        (REGSAM) KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
    {
        size = BUFSIZE - 2;
        if (RegQueryValueExA(hKey, "SearchPath", (LPDWORD) NULL,
                             &lType, (LPBYTE) buffer, &size)
            == ERROR_SUCCESS && *buffer)
        {
            char **pathlist;
            int ip, np;

            np = pdc_split_stringlist(p->pdc, buffer,
                                      ";", &pathlist);
            for (ip = 0; ip < np; ip++)
                pdf_add_resource(p, "SearchPath", pathlist[ip]);
            pdc_cleanup_stringlist(p->pdc, pathlist);
        }

        size = BUFSIZE - 2;
        if (RegQueryValueExA(hKey, "prefix", (LPDWORD) NULL,
                             &lType, (LPBYTE) buffer, &size)
            == ERROR_SUCCESS && *buffer)
        {
            /* '/' because of downward compatibility */
            if (p->prefix)
            {
                pdc_free(p->pdc, p->prefix);
                p->prefix = NULL;
            }
            p->prefix = pdc_strdup(p->pdc,
                            &buffer[buffer[0] == '/' ? 1 : 0]);
        }

        RegCloseKey(hKey);
    }
#endif  /* WIN32 */

#ifdef AS400
    strcpy (buffer, "/pdflib/");
    strcat (buffer, PDFLIB_VERSIONSTRING);
    il = (int) strlen(buffer);
    strcat (buffer, "/fonts");
    pdf_add_resource(p, "SearchPath", buffer);
    strcpy(&buffer[il], "/bind/data");
    pdf_add_resource(p, "SearchPath", buffer);
#endif  /* AS400 */

    /* searching for name of upr file */
    uprfilename = (char *)filename;
    if (!uprfilename || *uprfilename == '\0')
    {
        /* user-supplied upr file */
        uprfilename = pdc_getenv(RESOURCEFILE);
        if (!uprfilename || *uprfilename == '\0')
        {
            uprfilename = DEFAULTRESOURCEFILE;

            /* user-supplied upr file */
            fp = pdf_fopen(p, uprfilename, NULL, 0);
            if (fp == NULL)
            {
                uprfilename = NULL;
#ifdef WIN32
                /* process registry entries */
                if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, regkey, 0L,
                    (REGSAM) KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
                {
                    size = BUFSIZE - 2;
                    if (RegQueryValueExA(hKey, "resourcefile", (LPDWORD) NULL,
                                         &lType, (LPBYTE) buffer, &size)
                        == ERROR_SUCCESS && *buffer)
                    {
                        uprfilename = buffer;
                    }

                    RegCloseKey(hKey);
                }
#endif  /* WIN32 */
            }
        }

        if (!uprfilename || *uprfilename == '\0')
            return;

        if (p->resourcefilename)
        {
            pdc_free(p->pdc, p->resourcefilename);
            p->resourcefilename = NULL;
        }
        p->resourcefilename = pdc_strdup(p->pdc, uprfilename);
    }

    /* read upr file */
    if ((fp == NULL) && ((fp = pdf_fopen(p, uprfilename, "UPR ", 0)) == NULL))
	pdc_error(p->pdc, -1, 0, 0, 0, 0);

    nlines = pdc_read_textfile(p->pdc, fp, &linelist);
    pdc_fclose(fp);

    if (!nlines) return;

    /* Lines loop */
    begin = 1;
    nextcat = 0;
    for (il = 0; il < nlines; il++)
    {
        line = linelist[il];

        /* Next category */
        if (line[0] == '.' && strlen(line) == 1)
        {
            begin = 0;
            nextcat = 1;
            continue;
        }

        /* Skip category list */
        if (begin) continue;

        /* Prefiex or category expected */
        if (nextcat)
        {
            /* Directory prefix */
            if (line[0] == '/')
            {
                if (p->prefix)
                {
                    pdc_free(p->pdc, p->prefix);
                    p->prefix = NULL;
                }
                p->prefix = pdc_strdup(p->pdc, &line[1]);
                continue;
            }

            /* Ressource Category */
            category = line;
            nextcat = 0;
            continue;
        }

        /* Add resource */
        pdf_add_resource(p, category, line);
    }

    pdc_cleanup_stringlist(p->pdc, linelist);
}
Esempio n. 15
0
void
pdf_add_resource(PDF *p, const char *category, const char *resource)
{
    static const char fn[] = "pdf_add_resource";
    pdf_rescategory rescat;
    pdf_category *cat, *lastcat = NULL;
    pdf_res *res, *lastres = NULL;
    char          *name;
    char          *value;
    char          *prefix = NULL;
    size_t        len;
    int           k, absolut;

    /* We no longer raise an error but silently ignore unknown categories */
    k = pdc_get_keycode(category, pdf_rescategories);
    if (k == PDC_KEY_NOTFOUND)
        return;
    rescat = (pdf_rescategory) k;

    /* Read resource configuration file if it is pending */
    if (p->resfilepending)
    {
        p->resfilepending = pdc_false;
        pdf_read_resourcefile(p, p->resourcefilename);
    }

    /* Find start of this category's resource list, if the category exists */
    for (cat = p->resources; cat != (pdf_category *) NULL; cat = cat->next)
    {
        lastcat = cat;
        if (!strcmp(cat->category, category))
            break;
    }
    if (cat == NULL)
    {
        cat = (pdf_category *) pdc_malloc(p->pdc, sizeof(pdf_category), fn);
        cat->category = pdc_strdup(p->pdc, category);
        cat->kids = NULL;
        cat->next = NULL;

        if (lastcat)
            lastcat->next = cat;
        else
            p->resources = cat;
    }

    /* Determine name and value of resource */
    absolut = 0;
    len = strlen(resource);
    value = strchr(resource, '=');
    if (value)
    {
        len = (size_t) (value - resource);
        value++;
        if (*value == '=')
        {
            absolut = 1;
            value++;
        }

        /* file name is assumed */
        if (value[0] != '\0' && value[0] == '.' && value[1] == '/')
        {
            value += 2;
        }
    }

    /* Copy resource name */
    name = (char *) pdc_malloc(p->pdc, len + 1, fn);
    strncpy(name, resource, len);
    name[len] = 0;
    pdc_strtrim(name);

    /* Find resource name in resource list */
    for (res = cat->kids; res != (pdf_res *) NULL; res = res->next)
    {
        if (!strcmp(res->name, name))
            break;
        lastres = res;
    }

    /* New resource */
    if (res)
    {
        pdc_free(p->pdc, name);
    }
    else
    {
        res = (pdf_res *) pdc_calloc(p->pdc, sizeof(pdf_res), fn);
        if (lastres)
            lastres->next = res;
        else
            cat->kids = res;
        res->prev = lastres;
        res->name = name;
    }

    /* New value */
    if (res->value)
        pdc_free(p->pdc, res->value);
    res->value = NULL;
    if (!value)
    {
        value = "";
    }
    else if (!absolut && p->prefix)
    {
        /* Directory prefix */
        prefix = p->prefix;
        if (prefix[0] != '\0' && prefix[0] == '.' && prefix[1] == '/')
            prefix += 2;
        if (prefix)
        {
            len = strlen(prefix) + strlen(value) + 6;
            res->value = (char *) pdc_malloc(p->pdc, len, fn);
            pdc_file_fullname(prefix, value, res->value);
        }
    }
    if (!res->value)
    {
        res->value = pdc_strdup(p->pdc, value);
        pdc_str2trim(res->value);
    }

#undef PDF_TEST_RESOURCE
#ifdef PDF_TEST_RESOURCE
    printf("%s.%s: '%s'\n", category, res->name, res->value);
#endif

    switch (rescat)
    {
        case pdf_FontOutline:
        case pdf_FontAFM:
        case pdf_FontPFM:
        case pdf_HostFont:
        case pdf_Encoding:
        case pdf_ICCProfile:
        if (!strlen(res->name) || !strlen(res->value))
            pdc_error(p->pdc, PDF_E_RES_BADRES, resource, category, 0, 0);
        break;

        default:
        break;
    }
}
Esempio n. 16
0
/*
 * Fill font metric struct from core metric struct
 */
void
fnt_fill_font_metric(pdc_core *pdc, fnt_font *font, pdc_bool kerning,
                     const fnt_font_metric *metric)
{
    static const char fn[] = "fnt_fill_font_metric";

    (void) kerning;

    /* Fill font metric struct. Font struct must be initialized */
    font->m = *metric;
    font->m.charcoll = abs(font->m.charcoll);
    font->m.name = pdc_strdup(pdc, metric->name);
    font->name = pdc_strdup(pdc, metric->name);

    /* Fill glyph widths array (double mapping Unicode <-> code <-> width) */
    if (font->m.numglwidths)
    {
        font->m.glw = (fnt_glyphwidth *) pdc_calloc(pdc,
                          metric->numglwidths * sizeof(fnt_glyphwidth), fn);
        memcpy(font->m.glw, metric->glw,
               metric->numglwidths * sizeof(fnt_glyphwidth));
    }

    /* Fill glyph width array (mapping Unicode interval <-> width) */
    if (metric->numinters)
    {
        /* We must convert */
        if (font->m.type == fnt_Type1)
        {
            int i, j, iw, iwe;
            pdc_ushort uv;

            for (i = 0; i < metric->numinters; i++)
            {
                if (i && metric->ciw[i-1].width != 0)
                    font->m.numglwidths += metric->ciw[i].startcode -
                                           metric->ciw[i-1].startcode;
            }
            font->m.glw = (fnt_glyphwidth *) pdc_calloc(pdc,
                              font->m.numglwidths * sizeof(fnt_glyphwidth), fn);

            j = 0;
            iw = 0;
            for (i = 0; i < metric->numinters; i++)
            {
                if (i && metric->ciw[j].width != 0)
                {
                    uv = metric->ciw[j].startcode;
                    iwe = iw + metric->ciw[i].startcode - uv;
                    for (; iw < iwe; iw++)
                    {
                        font->m.glw[iw].unicode = uv;
                        font->m.glw[iw].width = metric->ciw[j].width;
                        uv++;
                    }
                }
                j = i;
            }
            font->m.numinters = 0;
            font->m.ciw = NULL;
        }
        else
        {
            font->m.ciw = (fnt_interwidth *) pdc_calloc(pdc,
                                font->m.numinters * sizeof(fnt_interwidth), fn);
            memcpy(font->m.ciw, metric->ciw,
                   metric->numinters * sizeof(fnt_interwidth));
        }
    }

#ifdef PDF_CJKFONTWIDTHS_SUPPORTED
    /* Fill glyph width array (mapping CID -> width) */
    if (font->m.type == fnt_CIDFontType0)
        fnt_parse_cid_widths(pdc, font);
#endif /* PDF_CJKFONTWIDTHS_SUPPORTED */

    /* Number of glyphs */
    if (font->m.type == fnt_Type1)
        font->numglyphs = font->m.numglwidths;


    /* font weight */
    font->weight = fnt_stemv2weight(font->m.StdVW);

    /* standard Adobe font */
    font->isstdfont = pdc_true;

    /* symbol font */
    if (!(font->m.flags & FNT_SYMBOL))
        font->issymbfont = pdc_false;
}
Esempio n. 17
0
void
pdf__begin_glyph(
    PDF *p,
    const char *glyphname,
    float wx, float llx, float lly, float urx, float ury)
{
    static const char fn[] = "pdf__begin_glyph";
    pdc_t3font *t3font;
    pdc_t3glyph *glyph;
    int i;

    t3font = p->t3font;

    if (t3font->colorized == pdc_true &&
        (llx != (float) 0 || lly != (float) 0 ||
         urx != (float) 0 || ury != (float) 0))
        pdc_error(p->pdc, PDF_E_T3_BADBBOX, t3font->fontname, 0, 0, 0);

    PDF_SET_STATE(p, pdf_state_glyph);

    for (i = 0; i < t3font->next_glyph; ++i) {
        if (!strcmp(t3font->glyphs[i].name, glyphname)) {
            pdc_error(p->pdc, PDF_E_T3_GLYPH, glyphname,
                      t3font->fontname, 0, 0);
        }
    }

    if (t3font->next_glyph == t3font->capacity) {
        t3font->capacity *= 2;
        t3font->glyphs = (pdc_t3glyph *) pdc_realloc(p->pdc, t3font->glyphs,
            t3font->capacity * sizeof (pdc_t3glyph), fn);
    }

    glyph               = &t3font->glyphs[t3font->next_glyph];
    glyph->charproc_id  = pdc_begin_obj(p->out, PDC_NEW_ID);
    glyph->name         = pdc_strdup(p->pdc, glyphname);

    /* see comment in p_font.c for explanation */
    glyph->width        = 1000 * wx * t3font->matrix.a;

    /* if the strdup above fails, cleanup won't touch this slot. */
    ++t3font->next_glyph;

    p->contents = c_page;
                                                /* glyph description */
    pdc_begin_dict(p->out);                     /* glyph description dict */

    p->length_id = pdc_alloc_id(p->out);
    pdc_printf(p->out, "/Length %ld 0 R\n", p->length_id);

    if (pdc_get_compresslevel(p->out))
        pdc_puts(p->out, "/Filter/FlateDecode\n");

    pdc_end_dict(p->out);                       /* glyph description dict */

    pdc_begin_pdfstream(p->out);                /* glyph description stream */

    p->next_content++;

    if (t3font->colorized == pdc_true)
        pdc_printf(p->out, "%f 0 d0\n", wx);
    else {
        pdc_printf(p->out, "%f 0 %f %f %f %f d1\n", wx, llx, lly, urx, ury);

        /* adjust the font's bounding box */
        if (llx < t3font->bbox.llx)
            t3font->bbox.llx = llx;
        if (lly < t3font->bbox.lly)
            t3font->bbox.lly = lly;
        if (urx > t3font->bbox.urx)
            t3font->bbox.urx = urx;
        if (ury > t3font->bbox.ury)
            t3font->bbox.ury = ury;
    }
}
Esempio n. 18
0
static pdc_bool
pdf_parse_pfm(PDF *p, pdc_file *fp, pdf_font *font)
{
    static const char fn[] = "pdf_parse_pfm";
    fnt_font_metric *ftm = &font->ft.m;
    size_t length;
    pdc_byte *pfm;
    pdc_bool ismem;
    int i, dfFirstChar, dfLastChar, default_width;
    unsigned long dfExtentTable;

    /* read whole file and close it */
    pfm = (pdc_byte *) pdc_freadall(fp, &length, &ismem);
    pdc_fclose(fp);

    /* check whether this is really a valid PostScript PFM file */
    if (pfm == NULL ||
	(header_dfVersion != 0x100 && header_dfVersion != 0x200) ||
	dfDevice > length ||
	strncmp((const char *) pfm + dfDevice, PDF_STRING_PostScript, 10) ||
	ext_dfDriverInfo > length)
    {
	if (!ismem)
	    pdc_free(p->pdc, pfm);
        return pdc_false;
    }

    /* fetch relevant data from the PFM */
    ftm->type = fnt_Type1;

    font->ft.name = pdc_strdup(p->pdc, (const char *)pfm + ext_dfDriverInfo);
    ftm->name = pdc_strdup(p->pdc, font->ft.name);

    pdc_logg_cond(p->pdc, 1, trc_font,
        "\tPostScript font name: \"%s\"\n", ftm->name);

    switch (header_dfPitchAndFamily & 0xF0)
    {
	case PDF_ROMAN:
            ftm->flags |= FNT_SERIF;
	    break;
	case PDF_MODERN:
	    /* Has to be ignored, contrary to MS's specs */
	    break;
	case PDF_SCRIPT:
            ftm->flags |= FNT_SCRIPT;
	    break;
	case PDF_DECORATIVE:
	    /* the dfCharSet flag lies in this case... */
	    header_dfCharSet = PFM_SYMBOL_CHARSET;
	    break;
	case PDF_SWISS:
	case PDF_DONTCARE:
	default:
	    break;
    }

    /* temporarily */
    font->ft.enc = (pdc_encoding) header_dfCharSet;

    dfFirstChar = header_dfFirstChar;
    dfLastChar = header_dfLastChar;
    dfExtentTable = ext_dfExtentTable;

    /*
     * Some rare PFMs do not contain any ExtentTable if the fixed pitch flag
     * is set. Use the dfMaxWidth entry for all glyphs in this case.
     * If the user forced the font to be monospaced we use this value instead.
     */
    if ((!(header_dfPitchAndFamily & PDF_FIXED_PITCH) && dfExtentTable == 0) ||
        font->opt.monospace)
    {
        ftm->isFixedPitch = pdc_true;
        default_width = font->opt.monospace ? font->opt.monospace :
				(int) header_dfMaxWidth;
    }
    else
    {
	/* default values -- don't take the width of the default character */
        default_width = FNT_DEFAULT_WIDTH;
    }

    font->ft.numcodes = 256;
    ftm->numwidths = font->ft.numcodes;
    ftm->widths = (int *) pdc_calloc(p->pdc, ftm->numwidths * sizeof(int), fn);
    for (i = 0; i < font->ft.numcodes; i++)
        ftm->widths[i] = default_width;

    if (!ftm->isFixedPitch)
    {
	if (ext_dfExtentTable == 0 ||
	    ext_dfExtentTable + 2 * (header_dfLastChar-header_dfFirstChar) + 1 >
		length)
        {
	    if (!ismem)
		pdc_free(p->pdc, pfm);
	    return pdc_false;
	}

	for (i = dfFirstChar; i <= dfLastChar; i++)
            ftm->widths[i] =
                          (int) PFM_WORD(dfExtentTable + 2 * (i - dfFirstChar));
	/*
         * Check whether the font is actually opt.monospaced
	 * (the fixed pitch flag is not necessarily set)
	 */
        default_width = ftm->widths[dfFirstChar];

	for (i = dfFirstChar+1; i <= dfLastChar; i++)
            if (default_width != ftm->widths[i])
		break;

	if (i == dfLastChar + 1)
            ftm->isFixedPitch = pdc_true;
    }

    font->ft.weight = fnt_check_weight(header_dfWeight);
    ftm->defwidth = default_width;
    ftm->italicAngle = (header_dfItalic ? etmSlant/(10.0) : 0.0);
    ftm->capHeight = etmCapHeight;
    ftm->xHeight = etmXHeight;
    ftm->descender = -etmLowerCaseDescent;
    ftm->ascender = (int) header_dfAscent;

    ftm->underlinePosition = -etmUnderlineOffset;
    ftm->underlineThickness = etmUnderlineWidth;

    ftm->urx = header_dfMaxWidth;


    if (!ismem)
        pdc_free(p->pdc, pfm);

    return pdc_true;
}
Esempio n. 19
0
pdc_bool
pdf_handle_t3font(PDF *p, const char *fontname, pdc_encoding enc,
                  pdf_font *font, int *slot)
{
    static const char fn[] = "pdf_handle_t3font";
    const char *encname;
    char *fname;
    size_t namlen;
    pdf_font *deffont = &p->fonts[*slot];
    pdc_encodingvector *ev = pdc_get_encoding_vector(p->pdc, enc);
    fnt_font_metric *ftm = &font->ft.m;
    size_t nalloc;
    int code, gid;
    pdc_bool newinst = pdc_false;

    /* font name incl. encoding name */
    encname = pdc_get_user_encoding(p->pdc, enc);
    namlen = strlen(fontname) + strlen(encname) + 2;
    fname = (char *) pdc_malloc(p->pdc, namlen, fn);
    pdc_sprintf(p->pdc, pdc_false, fname, "%s.%s", fontname, encname);

    /* we have to copy the available font.
     * otherwise the original font will be changed
     */
    newinst = deffont->ft.enc != pdc_invalidenc;

    pdc_logg_cond(p->pdc, 1, trc_font,
        "\n\tType3 font \"%s\" with %d glyphs found\n",
        fontname, deffont->t3font->next_glyph);

    if (newinst)
    {
        pdc_logg_cond(p->pdc, 1, trc_font,
            "\tInstance with specified encoding will be created\n");

    }

    /* copy data from available font (see pdf__begin_font()) */
    font->ft.m.type = fnt_Type3;
    font->ft.matrix = deffont->ft.matrix;
    font->ft.bbox = deffont->ft.bbox;
    font->t3font = deffont->t3font;
    font->ft.numglyphs = deffont->t3font->next_glyph;
    nalloc = (size_t) font->ft.numglyphs;

    ftm->name = fname;
    font->ft.name = pdc_strdup(p->pdc, fname);
    font->ft.enc = enc;
    font->ft.issymbfont = pdc_false;
    font->opt.embedding = pdc_true;

    if (enc >= pdc_winansi)
    {
        font->codesize = 1;
        font->ft.numcodes = 256;
        font->lastcode = -1;

        ftm->widths = (int *) pdc_calloc(p->pdc,
                                  (size_t) font->ft.numcodes * sizeof(int), fn);
        ftm->numwidths = font->ft.numcodes;
    }

    font->ft.code2gid = (pdc_ushort *) pdc_calloc(p->pdc,
                           (size_t) font->ft.numcodes * sizeof(pdc_ushort), fn);

    font->ft.gid2code = (pdc_ushort *) pdc_calloc(p->pdc,
                                          nalloc * sizeof (pdc_ushort), fn);

    /* fill up font arrays */
    for (gid = 0; gid < font->ft.numglyphs; gid++)
    {
        const char *str = NULL, *glyphname = font->t3font->glyphs[gid].name;

        if (enc >= pdc_winansi)
        {
            /* search for code */
            for (code = 0; code < font->ft.numcodes; code++)
            {
                if (ev->chars[code] != NULL)
                    str = ev->chars[code];
                else if (ev->codes[code])
                    str = pdc_unicode2glyphname(p->pdc, ev->codes[code]);

                if (str != NULL && !pdc_strcmp(glyphname, str))
                    break;
            }

            /* code found */
            if (code < font->ft.numcodes)
            {
                font->ft.code2gid[code] = gid;
                font->ft.gid2code[gid] = code;

                if (!gid)
                    font->gid0code = code;

                if (font->opt.monospace)
                    ftm->widths[code] = font->opt.monospace;
                else
                    ftm->widths[code] =
                          (int) (font->t3font->glyphs[gid].width + 0.5);
            }
        }
    }


    pdf_type3_protocol(p, font, ev);

    /* font flags */
    if (!pdf_make_fontflag(p, font))
        return pdc_false;

    if (newinst)
    {
        *slot = -1;
    }
    else
    {
        if (deffont->apiname != NULL)
            pdc_free(p->pdc, deffont->apiname);
        *deffont = *font;
        deffont->hasoriginal = pdc_true;
    }

    return pdc_true;
}
Esempio n. 20
0
void
pdf__begin_font(
    PDF *p,
    const char *fontname,
    float a, float b, float c, float d, float e, float f,
    const char *optlist)
{
    static const char fn[] = "pdf__begin_font";
    pdc_resopt *results;
    pdc_font *font;
    float det;
    int colorized = pdc_false;
    int slot;

    /* parsing optlist */
    results = pdc_parse_optionlist(p->pdc, optlist, pdf_begin_font_options,
                                   NULL, pdc_true);
    pdc_get_optvalues(p->pdc, "colorized", results, &colorized, NULL);
    pdc_cleanup_optionlist(p->pdc, results);

    det = a*d - b*c;

    if (det == 0)
        pdc_error(p->pdc, PDC_E_ILLARG_MATRIX,
            pdc_errprintf(p->pdc, "%f %f %f %f %f %f", a, b, c, d, e, f),
            0, 0, 0);

    /* look for an already existing font */
    for (slot = 0; slot < p->fonts_number; slot++)
    {
        if (!strcmp(p->fonts[slot].apiname, fontname))
        {
            pdc_error(p->pdc, PDF_E_T3_FONTEXISTS, fontname, 0, 0, 0);
        }
    }

    PDF_SET_STATE(p, pdf_state_font);

    pdf_init_tstate(p);
    pdf_init_gstate(p);
    pdf_init_cstate(p);

    /* slot for new font struct */
    slot = pdf_init_newfont(p);
    font = &p->fonts[slot];
    p->fonts_number++;

    /*
     * We store the new font in a font slot marked with "invalidenc" encoding.
     * When the font is used for the first time we modify the encoding.
     * Later uses will make a copy if the encoding is different.
     */

    font->type          = pdc_Type3;
    font->obj_id        = pdc_alloc_id(p->out);

    font->name          = NULL;
    font->apiname       = pdc_strdup(p->pdc, fontname);
    font->encoding      = pdc_invalidenc;  /* initially there is no encoding */
    font->widths        = (int *) pdc_calloc(p->pdc,
                                 font->numOfCodes * sizeof(int), fn);

    font->t3font = (pdc_t3font*) pdc_malloc(p->pdc, sizeof(pdc_t3font), fn);
    pdf_init_t3font_struct(p, font->t3font, T3GLYPHS_CHUNKSIZE);

    font->t3font->fontname      = pdc_strdup(p->pdc, fontname);
    font->t3font->colorized     = colorized;

    /* the resource id is needed until the font dict is written */
    font->t3font->res_id        = pdc_alloc_id(p->out);

    font->t3font->matrix.a      = a;
    font->t3font->matrix.b      = b;
    font->t3font->matrix.c      = c;
    font->t3font->matrix.d      = d;
    font->t3font->matrix.e      = e;
    font->t3font->matrix.f      = f;

    /* We won't receive glyph bounding box values for colorized true,
     * so we use the font matrix to get an approximation instead.
     *
     * Writing the font matrix should be optional according to the
     * PDF reference, but we must write it in order to work around a
     * display bug in Acrobat.
     */
    if (font->t3font->colorized == pdc_true) {
        font->t3font->bbox.llx = 0;
        font->t3font->bbox.lly = 0;
        font->t3font->bbox.urx = (d-b)/det;
        font->t3font->bbox.ury = (a-c)/det;
    }

    /*
     * We must store a pointer to the current font because its glyph
     * definitions may use other fonts and we would be unable to find
     * "our" current font again. This pointer lives throughout the
     * font definition, and will be reset in PDF_end_font() below.
     */
    p->t3font = font->t3font;
}
Esempio n. 21
0
int
pdf_handle_t3font(PDF *p, const char *fontname, pdc_encoding enc, int oldslot)
{
    static const char fn[] = "pdf_handle_t3font";
    char *fname;
    int slot, i;
    unsigned int namlen;
    pdc_font *oldfont, *newfont;
    pdc_encodingvector *ev = p->encodings[enc].ev;

    oldfont = &p->fonts[oldslot];

    /* slot of new font struct - initialized in pdf__load_font */
    slot = p->fonts_number;
    newfont = &p->fonts[slot];

    /* font name incl. encoding name */
    namlen = strlen(fontname) + (int) strlen(ev->apiname) + 2;
    fname = (char *) pdc_malloc(p->pdc, namlen, fn);
    sprintf(fname, "%s.%s", fontname, ev->apiname);

    /*
     * This is a fresh font which has never been used.
     * Enter the new encoding, and we're done.
     */
    if (oldfont->encoding == pdc_invalidenc) {

        oldfont->encoding = enc;

        for (i = 0; i < oldfont->numOfCodes; i++) {
            oldfont->widths[i] =
                name2width(oldfont->t3font, ev->chars[i]);
            if (newfont->monospace && oldfont->widths[i])
                oldfont->widths[i] = newfont->monospace;
        }
        ev->flags |= PDC_ENC_USED;

        oldfont->name = fname;

        return oldslot;
    }

    p->fonts_number++;

    /* copy the complete font structure */
    memcpy(newfont, oldfont, sizeof(pdc_font));

    /* make copies of relevant strings to ensure correct cleanup */
    newfont->name = fname;
    newfont->apiname = pdc_strdup(p->pdc, fontname);

    /* modify relevant entries */
    newfont->used_on_current_page       = pdc_false;
    newfont->encoding                   = enc;
    newfont->obj_id                     = pdc_alloc_id(p->out);

    newfont->t3font = (pdc_t3font*)pdc_malloc(p->pdc, sizeof(pdc_t3font), fn);
    pdf_init_t3font_struct(p, newfont->t3font, oldfont->t3font->capacity);

    /* copy relevant entries of Type 3 structure */
    newfont->t3font->charprocs_id = oldfont->t3font->charprocs_id;
    newfont->t3font->res_id = oldfont->t3font->res_id;
    newfont->t3font->colorized = oldfont->t3font->colorized;
    memcpy(&newfont->t3font->matrix, &oldfont->t3font->matrix,
        sizeof(pdc_matrix));
    memcpy(&newfont->t3font->bbox, &oldfont->t3font->bbox,
        sizeof(pdc_rectangle));

    /* copy the glyph/width list from oldfont to newfont */
    newfont->t3font->next_glyph = oldfont->t3font->next_glyph;
    for (i = 0; i < newfont->t3font->next_glyph; ++i) {
        newfont->t3font->glyphs[i].width =
            oldfont->t3font->glyphs[i].width;
        newfont->t3font->glyphs[i].charproc_id =
            oldfont->t3font->glyphs[i].charproc_id;
        newfont->t3font->glyphs[i].name =
            pdc_strdup(p->pdc, oldfont->t3font->glyphs[i].name);
    }

    newfont->widths = (int *) pdc_calloc(p->pdc,
                                 newfont->numOfCodes * sizeof(int), fn);
    for (i = 0; i < newfont->numOfCodes; i++) {
        newfont->widths[i] =
            name2width(newfont->t3font, p->encodings[enc].ev->chars[i]);
        if (newfont->monospace && oldfont->widths[i])
            newfont->widths[i] = newfont->monospace;
    }
    p->encodings[enc].ev->flags |= PDC_ENC_USED;

    return slot;
}