Beispiel #1
0
pdc_bstr *
pdc_bs_new(pdc_core *pdc)
{
#ifndef	USE_POOL
    static const char fn[] = "pdc_bs_new";

    pdc_bstr *result = (pdc_bstr *) pdc_malloc(pdc, sizeof (pdc_bstr), fn);
#else
    pdc_bstr *result = (pdc_bstr *) pdc_mp_alloc(pdc->bstr_pool);
#endif

    pdc_bs_boot(pdc, result);
    return result;
} /* pdc_bs_new */
Beispiel #2
0
void *
pdc_malloc_tmp(
    pdc_core *          pdc,
    size_t              size,
    const char *        caller,
    void *              opaque,
    pdc_destructor      destr)
{
    void *memory = pdc_malloc(pdc, size, caller);

    pdc_insert_mem_tmp(pdc, memory, opaque, destr);

    return memory;
}
Beispiel #3
0
pdc_bool
pdc_init_output(
    void *opaque,
    pdc_output *out,
    const char *filename,
    FILE *fp,
    size_t (*writeproc)(pdc_output *out, void *data, size_t size),
    int compatibility)
{
    static const char *fn = "pdc_init_output";
    pdc_core *pdc = out->pdc;
    int i;

    out->lastobj = 0;

    if (out->file_offset == NULL) {
	out->file_offset_capacity = + ID_CHUNKSIZE;

	out->file_offset = (long *) pdc_malloc(pdc,
		sizeof(long) * out->file_offset_capacity, fn);
    }

    for (i = 1; i < out->file_offset_capacity; ++i)
	out->file_offset[i] = PDC_BAD_ID;

    out->compresslevel	= PDF_DEFAULT_COMPRESSION;
    out->compr_changed	= pdc_false;

    out->opaque		= opaque;

    memcpy(out->id[0], out->id[1], MD5_DIGEST_LENGTH);


    if (!pdc_init_stream(pdc, out, filename, fp, writeproc))
	return pdc_false;

    /* Write the document header */
    if (compatibility == PDC_1_5)
	pdc_puts(out, "%PDF-1.5\n");
    else if (compatibility == PDC_1_4)
	pdc_puts(out, "%PDF-1.4\n");
    else
	pdc_puts(out, "%PDF-1.3\n");

    /* binary magic number */
#define PDC_MAGIC_BINARY "\045\344\343\317\322\012"
    pdc_write(out, PDC_MAGIC_BINARY, sizeof(PDC_MAGIC_BINARY) - 1);

    return pdc_true;
}
Beispiel #4
0
pdc_bool
pdc_init_output(
    void *opaque,
    pdc_output *out,
    int compatibility,
    pdc_outctl *oc)
{
    static const char *fn = "pdc_init_output";
    pdc_core *pdc = out->pdc;
    int i;

    pdc_cleanup_output(out, pdc_false);

    out->opaque		= opaque;
    out->lastobj	= 0;
#if defined(MVS) || defined(MVS_TEST)
    out->blocksize	= oc->blocksize;
#endif

    if (out->file_offset == NULL) {
	out->file_offset_capacity = ID_CHUNKSIZE;

	out->file_offset = (pdc_off_t *) pdc_malloc(pdc,
		sizeof(pdc_off_t) * out->file_offset_capacity, fn);
    }

    for (i = 1; i < out->file_offset_capacity; ++i)
	out->file_offset[i] = PDC_BAD_ID;

    out->compresslevel	= PDF_DEFAULT_COMPRESSION;
    out->compr_changed	= pdc_false;
    out->flush = oc->flush;

    memcpy(out->id[0], out->id[1], MD5_DIGEST_LENGTH);


    if (!pdc_init_stream(pdc, out, oc->filename, oc->fp, oc->writeproc))
	return pdc_false;
    {
	/* Write the document header */
	pdc_printf(out, "%%PDF-%s\n", pdc_get_pdfversion(pdc, compatibility));

#define PDC_MAGIC_BINARY "\045\344\343\317\322\012"
	pdc_write(out, PDC_MAGIC_BINARY, sizeof(PDC_MAGIC_BINARY) - 1);
    }

    out->open = pdc_true;

    return pdc_true;
}
Beispiel #5
0
pdc_ustr *
pdc_us_new(pdc_core *pdc, const pdc_ucval *src, size_t len)
{
#ifndef	USE_POOL
    static const char fn[] = "pdc_us_new";

    pdc_ustr *result = (pdc_ustr *) pdc_malloc(pdc, sizeof (pdc_ustr), fn);
#else
    pdc_ustr *result = (pdc_ustr *) pdc_mp_alloc(pdc->ustr_pool);
#endif

    pdc_us_boot(pdc, result);
    pdc_us_write(result, src, len);
    return result;
} /* pdc_us_new */
Beispiel #6
0
void *
pdc_boot_output(pdc_core *pdc)
{
    static const char *fn = "pdc_boot_output";
    pdc_output *out;

    out = (pdc_output*)pdc_malloc(pdc, sizeof(pdc_output), fn);
    out->pdc = pdc;

    out->file_offset	= NULL;

    pdc_boot_stream(out);

    return (void *) out;
}
Beispiel #7
0
void
pdf_init_shadings(PDF *p)
{
    int i;

    p->shadings_number = 0;
    p->shadings_capacity = SHADINGS_CHUNKSIZE;

    p->shadings = (pdf_shading *) pdc_malloc(p->pdc,
	sizeof(pdf_shading) * p->shadings_capacity, "pdf_init_shadings");

    for (i = 0; i < p->shadings_capacity; i++) {
	p->shadings[i].used_on_current_page = pdc_false;
	p->shadings[i].obj_id = PDC_BAD_ID;
    }
}
Beispiel #8
0
void
pdf_init_extgstate(PDF *p)
{
    int i;

    p->extgstates_number = 0;
    p->extgstates_capacity = EXTGSTATE_CHUNKSIZE;

    p->extgstates = (pdf_extgstateresource *)
    pdc_malloc(p->pdc, sizeof(pdf_extgstateresource) * p->extgstates_capacity,
	    "pdf_init_extgstates");

    for (i = 0; i < p->extgstates_capacity; i++) {
	pdf_init_extgstateresource( &p->extgstates[i] );
    }
}
Beispiel #9
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;
}
Beispiel #10
0
char *
pdc_file_fullname_mem(pdc_core *pdc, const char *dirname, const char *basename)
{
    static const char fn[] = "pdc_file_fullname_mem";
    char *fullname;
    size_t len;

    len = strlen(basename);
    if (dirname && dirname[0])
        len += strlen(dirname);
    len += EXTRA_SPACE;
    fullname = (char *) pdc_malloc(pdc, len, fn);

    pdc_file_fullname(dirname, basename, fullname);

    return fullname;
}
Beispiel #11
0
void
pdf_init_pattern(PDF *p)
{
    static const char fn[] = "pdf_init_pattern";
    int i;

    p->pattern_number = 0;
    p->pattern_capacity = PATTERN_CHUNKSIZE;

    p->pattern = (pdf_pattern *) pdc_malloc(p->pdc,
	sizeof(pdf_pattern) * p->pattern_capacity, fn);

    for (i = 0; i < p->pattern_capacity; i++) {
	p->pattern[i].used_on_current_page = pdc_false;
	p->pattern[i].obj_id = PDC_BAD_ID;
    }
}
Beispiel #12
0
void
pdf_init_cstate(PDF *p)
{
    static const char fn[] = "pdf_init_cstate";
    pdf_cstate *cstate;

    if (!p->curr_ppt->cstate)
    {
	p->curr_ppt->cstate = (pdf_cstate *) pdc_malloc(p->pdc,
                                   PDF_MAX_SAVE_LEVEL * sizeof(pdf_cstate), fn);
    }

    cstate = &p->curr_ppt->cstate[p->curr_ppt->sl];

    cstate->fill.cs             = DeviceGray;
    cstate->fill.val.gray       = 0.0;

    cstate->stroke.cs           = DeviceGray;
    cstate->stroke.val.gray     = 0.0;
}
Beispiel #13
0
static void
pdc_tmlist_grow(pdc_core *pdc)
{
    static const char	fn[] = "pdc_tmlist_grow";
    pdc_tmpmem_list *tm_list = &pdc->pr->tm_list;
    static const int	chunksize = 20;

    if (tm_list->capacity == 0)
    {
	tm_list->capacity = chunksize;
	tm_list->tmpmem = (pdc_tmpmem *) pdc_malloc(pdc,
	    (size_t) (tm_list->capacity * sizeof (pdc_tmpmem)), fn);
    }
    else
    {
	tm_list->capacity += chunksize;
	tm_list->tmpmem = (pdc_tmpmem *) pdc_realloc(pdc, tm_list->tmpmem,
	    (size_t) (tm_list->capacity * sizeof (pdc_tmpmem)), fn);
    }
}
Beispiel #14
0
static void
pdf_init_t3font(PDF *p, pdf_t3font *t3font, int glyph_capacity)
{
    static char fn[] = "pdf_init_t3font";
    int i;

    /* statement order is critical for cleanup!
    */
    t3font->curr_glyph = 0;
    t3font->next_glyph = 0;
    t3font->capacity = glyph_capacity;
    t3font->glyphs = (pdf_t3glyph *)
        pdc_malloc(p->pdc, t3font->capacity * sizeof (pdf_t3glyph), fn);

    for (i = 0; i < t3font->capacity; i++)
        t3font->glyphs[i].name = NULL;

    t3font->charprocs_id = PDC_BAD_ID;
    t3font->pass = 0;

}
Beispiel #15
0
pdc_output *
pdc_boot_output(pdc_core *pdc)
{
    static const char *fn = "pdc_boot_output";
    pdc_output *out;

    out = (pdc_output*)pdc_malloc(pdc, sizeof(pdc_output), fn);
    out->pdc = pdc;

    out->file_offset	= NULL;

    /* curpos must be initialized here so that the check for empty
     * buffer in PDF_delete() also works in the degenerate case of
     * no output produced.
     */
    out->basepos = out->curpos = NULL;

    out->open = pdc_false;

    return out;
}
Beispiel #16
0
void
pdf_data_source_file_init(PDF *p, PDF_data_source *src)
{
    pdc_file *fp;

    src->buffer_length = FILE_BUFSIZE;
    src->buffer_start = (pdc_byte *)
	pdc_malloc(p->pdc, src->buffer_length, "pdf_data_source_file_init");

    fp = pdc_fsearch_fopen(p->pdc, (const char *) src->private_data, NULL,
                           "embedded ", PDC_FILE_BINARY);

    if (fp == NULL)
	pdc_error(p->pdc, -1, 0, 0, 0, 0);

    if (src->offset)
	pdc_fseek(fp, src->offset, SEEK_SET);

    src->private_data = (void *) fp;
    src->total = (long) 0;
}
Beispiel #17
0
static pdc_bool
pdf_read_pfb_segment(PDF *p, PDF_data_source *src, t1_private_data *t1, int i)
{
    static const char *fn = "pdf_read_pfb_segment";
    size_t length, len;

    length  = (size_t) (pdf_t1getc(t1) & 0xff);
    length |= (size_t) (pdf_t1getc(t1) & 0xff) << 8;
    length |= (size_t) (pdf_t1getc(t1) & 0xff) << 16;
    length |= (size_t) (pdf_t1getc(t1) & 0xff) << 24;

    pdc_logg_cond(p->pdc, 5, trc_font,
        " and length x%04X", length);

    if (src->buffer_start)
        pdc_free(p->pdc, (void *) src->buffer_start);
    src->buffer_start = (pdc_byte *) pdc_malloc(p->pdc, length, fn);

    if (t1->fontfile)
    {
        len = pdc_fread(src->buffer_start, 1, length, t1->fontfile);
    }
    else
    {
        len = length;
        if (t1->pos + len > t1->end)
            len = (unsigned int)(t1->end - t1->pos);
        memcpy(src->buffer_start, t1->pos, len);
        t1->pos += len;
    }

    t1->length[i] = len;
    src->next_byte = src->buffer_start;
    src->bytes_available = len;

    return (len != length) ? pdc_false : pdc_true;
}
Beispiel #18
0
pdf_dest *
pdf_init_destination(PDF *p)
{
    static const char fn[] = "pdf_init_destination";
    pdf_dest *dest = (pdf_dest *) pdc_malloc(p->pdc, sizeof(pdf_dest), fn);

    dest->type = fitwindow;
    dest->remote_page = 0;
    dest->pgnum = 0;
    dest->page = PDC_BAD_ID;
    dest->left = -1;
    dest->right = -1;
    dest->bottom = -1;
    dest->top = -1;
    dest->zoom = -1;
    dest->name = NULL;
    dest->color[0] = 0.0;
    dest->color[1] = 0.0;
    dest->color[2] = 0.0;
    dest->fontstyle = fnt_Normal;
    dest->filename = NULL;

    return dest;
}
Beispiel #19
0
/* Set Info dictionary entries */
void
pdf__set_info(PDF *p, const char *key, const char *value, int len)
{
    static const char fn[] = "pdf__set_info";
    char *key_buf, *val_buf;
    pdf_info *oldentry, *newentry;
    const char **kp;
    static const char *forbidden_keys[] =
    {
        "Producer",
        "CreationDate",
        "ModDate",
        "GTS_PDFXVersion",
        "GTS_PDFXConformance",
        "ISO_PDFEVersion"
    };

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

    len = pdc_check_text_length(p->pdc, &value, len, PDF_MAXSTRINGSIZE);

    for (kp = forbidden_keys;
        kp != sizeof(forbidden_keys) / sizeof(char *) + forbidden_keys;
        kp += 1)
    {
        if (!strcmp(*kp, key))
        {
            pdc_error(p->pdc, PDC_E_ILLARG_STRING, "key", key, 0, 0);
        }
    }

    /* converting key */
    key_buf = pdf_convert_name(p, key, 0, 0);

    /* convert text string */
    val_buf = pdf_convert_hypertext_depr(p, value, len);
    if (val_buf == NULL)
        pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "value", 0, 0, 0);

    /* special handling required for "Trapped" */
    if (!strcmp(key_buf, "Trapped"))
    {
        if (strcmp(val_buf, PDF_TRAPPED_TRUE) &&
            strcmp(val_buf, PDF_TRAPPED_FALSE) &&
            strcmp(val_buf, PDF_TRAPPED_UNKNOWN))
        {
            pdc_free(p->pdc, val_buf);
            pdc_free(p->pdc, key_buf);
            pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
        }
    }

    oldentry = pdf_have_infokey(p, key_buf);
    if (oldentry != NULL)
    {
        pdc_free(p->pdc, key_buf);
        pdc_free(p->pdc, oldentry->value);
        oldentry->value = val_buf;
    }
    else
    {
        newentry = (pdf_info *)
            pdc_malloc(p->pdc, sizeof(pdf_info), fn);
        newentry->key  = key_buf;
        newentry->value = val_buf;
        newentry->next = p->userinfo;

        /* ordering doesn't matter so we insert at the beginning */
        p->userinfo = newentry;
    }
}
Beispiel #20
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;
    }
}
Beispiel #21
0
int
pdf_add_colorspace(PDF *p, pdf_colorspace *cs, pdc_bool inuse)
{
    pdf_colorspace *cs_new;
    static const char fn[] = "pdf_add_colorspace";
    int slot;

    for (slot = 0; slot < p->colorspaces_number; slot++)
    {
	if (pdf_colorspace_equal(p, &p->colorspaces[slot], cs))
	{
	    if (inuse)
		p->colorspaces[slot].used_on_current_page = pdc_true;
	    return slot;
	}
    }

    slot = p->colorspaces_number;

    if (p->colorspaces_number >= p->colorspaces_capacity)
	pdf_grow_colorspaces(p);

    cs_new = &p->colorspaces[slot];

    cs_new->type = cs->type;

    /* don't allocate id for simple color spaces, since we don't write these */
    if (PDF_SIMPLE_COLORSPACE(cs)) {
	cs_new->obj_id = PDC_BAD_ID;
	cs_new->used_on_current_page = pdc_false;

    } else {
	cs_new->obj_id = pdc_alloc_id(p->out);
	cs_new->used_on_current_page = inuse;
    }

    switch (cs_new->type) {
	case DeviceGray:
	case DeviceRGB:
	case DeviceCMYK:
	break;


	case Indexed:
	{
	size_t palsize; 	/* palette size in bytes */

	palsize = cs->val.indexed.palette_size *
			    pdf_color_components(p, cs->val.indexed.base);

        cs_new->val.indexed.base = cs->val.indexed.base;
        cs_new->val.indexed.palette_size = cs->val.indexed.palette_size;
        cs_new->val.indexed.colormap_id = pdc_alloc_id(p->out);
        cs_new->val.indexed.colormap =
	    (pdf_colormap *) pdc_malloc(p->pdc, palsize, fn);
        memcpy(cs_new->val.indexed.colormap, cs->val.indexed.colormap, palsize);
        cs_new->val.indexed.colormap_done = pdc_false;
	break;

	case PatternCS:
        cs_new->val.pattern.base = cs->val.pattern.base;
	break;
	}


	default:
	    pdc_error(p->pdc, PDF_E_INT_BADCS, fn,
		pdc_errprintf(p->pdc, "%d", slot),
		pdc_errprintf(p->pdc, "%d", cs_new->type), 0);
    }

    p->colorspaces_number++;

    return slot;
} /* pdf_add_colorspace */
Beispiel #22
0
pdf_mbox *
pdf_parse_mbox_optlist(PDF *p, const char *optlist)
{
    static const char fn[] = "pdf_parse_mbox_optlist";
    pdc_resopt *resopts = NULL;
    pdf_mbox *mbox;
    char **strlist = NULL;
    pdc_scalar margin;
    int i, ns;

    resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_create_mbox_options,
                                   NULL, pdc_true);

    mbox = (pdf_mbox *) pdc_malloc(p->pdc, sizeof(pdf_mbox), fn);
    pdf_reclaim_mbox(mbox);

    if (pdc_get_optvalues("name", resopts, NULL, NULL))
        mbox->name = (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM);

    pdc_get_optvalues("boxheight", resopts, mbox->boxheight, NULL);
    if (pdc_get_optvalues("clipping", resopts, mbox->clipping, NULL))
    {
        for (i = 0; i < 4; i++)
            mbox->percentclipping[i] = pdc_is_lastopt_percent(resopts, i) ?
                                       pdc_true : pdc_false;
    }


    pdc_get_optvalues("innerbox", resopts, &mbox->innerbox, NULL);
    pdc_get_optvalues("openrect", resopts, &mbox->openrect, NULL);

    ns = pdc_get_optvalues("fillcolor", resopts, NULL, &strlist);
    if (ns)
        pdf_parse_coloropt(p, "fillcolor", strlist, ns, (int) color_max,
                           &mbox->fillcolor);

    pdf_init_coloropt(p, &mbox->strokecolor);
    ns = pdc_get_optvalues("strokecolor", resopts, NULL, &strlist);
    if (ns)
        pdf_parse_coloropt(p, "strokecolor", strlist, ns, (int) color_max,
                           &mbox->strokecolor);

    pdc_get_optvalues("borderwidth", resopts, &mbox->borderwidth, NULL);
    mbox->dashlength =
        pdc_get_optvalues("dasharray", resopts, mbox->dasharray, NULL);
    pdc_get_optvalues("dashphase", resopts, &mbox->dashphase, NULL);
    pdc_get_optvalues("linecap", resopts, &mbox->linecap, NULL);
    pdc_get_optvalues("linejoin", resopts, &mbox->linejoin, NULL);

    pdc_get_optvalues("drawleft", resopts, &mbox->drawleft, NULL);
    pdc_get_optvalues("drawbottom", resopts, &mbox->drawbottom, NULL);
    pdc_get_optvalues("drawright", resopts, &mbox->drawright, NULL);
    pdc_get_optvalues("drawtop", resopts, &mbox->drawtop, NULL);

    if (pdc_get_optvalues("margin", resopts, &margin, NULL))
    {
        mbox->offsetleft = margin;
        mbox->percentleft = pdc_is_lastopt_percent(resopts, 0);

        mbox->offsetbottom = margin;
        mbox->percentbottom = pdc_is_lastopt_percent(resopts, 0);

        mbox->offsetright = -margin;
        mbox->percentright = pdc_is_lastopt_percent(resopts, 0);

        mbox->offsettop = -margin;
        mbox->percenttop = pdc_is_lastopt_percent(resopts, 0);
    }

    if (pdc_get_optvalues("offsetleft", resopts, &mbox->offsetleft, NULL))
    {
        mbox->percentleft = pdc_is_lastopt_percent(resopts, 0);
    }
    if (pdc_get_optvalues("offsetbottom", resopts, &mbox->offsetbottom, NULL))
    {
        mbox->percentbottom = pdc_is_lastopt_percent(resopts, 0);
    }
    if (pdc_get_optvalues("offsetright", resopts, &mbox->offsetright, NULL))
    {
        mbox->percentright = pdc_is_lastopt_percent(resopts, 0);
    }
    if (pdc_get_optvalues("offsettop", resopts, &mbox->offsettop, NULL))
    {
        mbox->percenttop = pdc_is_lastopt_percent(resopts, 0);
    }

    pdc_cleanup_optionlist(p->pdc, resopts);

    return mbox;
}
Beispiel #23
0
int
pdc_read_textfile(pdc_core *pdc, pdc_file *sfp, int flags, char ***linelist)
{
    static const char fn[] = "pdc_read_textfile";
    char buf[PDC_BUFSIZE];
    char *content = NULL;
    char **strlist = NULL;
    int nlines = 0;
    pdc_off_t filelen;
    size_t len = 0, sumlen = 0, maxl = 0;
    pdc_bool tocont = pdc_false;
    int i, nbs, is = -1;

    /* get file length */
    filelen = pdc_file_size(sfp);
    if (filelen)
    {
        /* allocate content array */
        content = (char *) pdc_calloc(pdc, (size_t) filelen, fn);

        /* read loop */
        while (pdc_fgetline(buf, PDC_BUFSIZE, sfp) != NULL)
        {
            /* trim white spaces */
            if (tocont)
                pdc_strtrim(buf);
            else
                pdc_str2trim(buf);

            /* skip blank and comment lines */
            if (buf[0] == 0 || buf[0] == '%')
            {
                tocont = pdc_false;
                continue;
            }

            /* register new line */
            if (!tocont)
            {
                if (nlines)
                    pdc_logg_cond(pdc, 2, trc_filesearch,
                        "\t\tLine %d; \"%s\"\n", nlines, strlist[nlines - 1]);

                if (nlines >= (int) maxl)
                {
                    maxl += PDC_ARGV_CHUNKSIZE;
                    strlist = (strlist == NULL) ?
                            (char **)pdc_malloc(pdc, maxl * sizeof(char *), fn):
                            (char **)pdc_realloc(pdc, strlist, maxl *
                                                 sizeof(char *), fn);
                }

                is += sumlen + 1;
                strlist[nlines] = &content[is];
                nlines++;
                sumlen = 0;
            }

            /* process new line */
            nbs = 0;
            len = strlen(buf);
            for (i = 0; i < (int) len; i++)
            {
                /* backslash found */
                if (buf[i] == '\\')
                {
                    nbs++;
                }
                else
                {
                    /* comment sign found */
                    if (buf[i] == '%')
                    {
                        if (nbs % 2)
                        {
                            /* masked */
                            memmove(&buf[i-1], &buf[i], (size_t) (len-i));
                            len--;
                            buf[len] = 0;
                        }
                        else
                        {
                            buf[i] = 0;
                            len = strlen(buf);
                        }
                    }
                    nbs = 0;
                }
            }

            /* continuation line */
            tocont = (nbs % 2) ? pdc_true : pdc_false;
            if (tocont)
            {
                if (flags & PDC_FILE_KEEPLF)
                    buf[len - 1] = '\n';
                else
                    len--;
            }
            buf[len] = '\0';

            /* backslash substitution */
            if (flags & PDC_FILE_BSSUBST)
            {
                len = (size_t) pdc_subst_backslash(pdc, (pdc_byte *) buf,
                                          (int) len, NULL, pdc_bytes, pdc_true);
            }

            /* concatenate line */
            strcat(&content[is], buf);

            sumlen += len;
        }

        if (!strlist) pdc_free(pdc, content);
    }

    if (nlines)
        pdc_logg_cond(pdc, 2, trc_filesearch,
            "\t\tLine %d; \"%s\"\n", nlines, strlist[nlines - 1]);

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

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

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

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

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

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

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

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

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

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

        pdc_cleanup_stringlist(pdc, strlist);
    }

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

    if (pdc_logg_is_enabled(pdc, 5, trc_font))
    {
        for (cid = 0; cid < font->m.numwidths; cid++)
            pdc_logg(pdc, "\t\t\tCID width[%d]: %d\n",
                     cid, font->m.widths[cid]);
    }
}
Beispiel #25
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;
}
Beispiel #26
0
/* normalized file name according PDF specification */
void
pdc_put_pdffilename(pdc_output *out, const char *text, int len)
{
    static const char *fn = "pdc_put_pdffilename";
    char *ttext;

#if defined(WIN32) || defined(MAC)
    int i, j = 0, k = 0;
#endif

    if (!len)
        len = (int) strlen(text);

    ttext = (char *) pdc_malloc(out->pdc, (size_t) (len + 4), fn);
    strcpy(ttext, text);

#if defined(WIN32)

    /* absolute path name */
    if (strchr(ttext, PDF_COLON) != NULL || text[0] == PDF_BACKSLASH)
    {
        ttext[j] = PDF_SLASH;
        j++;
    }
    for (i = k; i < len; i++)
    {
        if (text[i] == PDF_BACKSLASH)
            ttext[j] = PDF_SLASH;
        else if (text[i] == PDF_COLON)
            continue;
        else
            ttext[j] = text[i];
        j++;
    }
    len = j;

#elif defined(MAC)

    /* absolute path name */
    if (text[0] != PDF_COLON)
    {
        ttext[j] = PDF_SLASH;
        j++;
    }
    else
    {
        k = 1;
    }
    for (i = k; i < len; i++)
    {
        if (text[i] == PDF_COLON)
            ttext[j] = PDF_SLASH;
        else
            ttext[j] = text[i];
        j++;
    }
    len = j;

#endif

    pdc_put_pdfstring(out, ttext, len);

    pdc_free(out->pdc, ttext);
}
Beispiel #27
0
static pdc_bool
pdc_init_stream(
    pdc_core *pdc,
    pdc_output *out,
    const char *filename,
    FILE *fp,
    size_t (*writeproc)(pdc_output *out, void *data, size_t size))
{
    static const char fn[] = "pdc_init_stream";

#if (defined(MAC) || defined(MACOSX)) && defined(PDF_FILETYPE_SUPPORTED)
#if !defined(TARGET_API_MAC_CARBON) || defined(__MWERKS__)
    FCBPBRec	fcbInfo;
    Str32	name;
#endif	/* TARGET_API_MAC_CARBON */
    FInfo	fInfo;
    FSSpec	fSpec;
#endif  /* (MAC || MACOSX) && PDF_FILETYPE_SUPPORTED */

    /*
     * This may be left over from the previous run. We deliberately
     * don't reuse the previous buffer in order to avoid potentially
     * unwanted growth of the allocated buffer due to a single large
     * document in a longer series of documents.
     */
    if (out->basepos)
	pdc_free(pdc, (void *) out->basepos);

    out->basepos	= (pdc_byte *) pdc_malloc(pdc, STREAM_BUFSIZE, fn);
    out->curpos		= out->basepos;
    out->maxpos		= out->basepos + STREAM_BUFSIZE;
    out->buf_incr	= STREAM_BUFSIZE;

    out->base_offset	= 0;
    out->compressing	= pdc_false;

#ifdef HAVE_LIBZ
    /* zlib sometimes reads uninitialized memory where it shouldn't... */
    memset(&out->z, 0, sizeof out->z);

    out->z.zalloc	= (alloc_func) pdc_zlib_alloc;
    out->z.zfree	= (free_func) pdc_free;
    out->z.opaque	= (voidpf) pdc;

    if (deflateInit(&out->z, pdc_get_compresslevel(out)) != Z_OK)
	pdc_error(pdc, PDC_E_IO_COMPRESS, "deflateInit", 0, 0, 0);

    out->compr_changed = pdc_false;
#endif

    /* Defaults */
    out->fp		= (FILE *) NULL;
    out->writeproc	= pdc_writeproc_file;

    if (fp)
    {
	out->fp	= fp;
    }
    else if (writeproc)
    {
	out->writeproc	= writeproc;		/* PDF_open_mem */
    }
    else if (filename == NULL || *filename == '\0')
    {
	/* PDF_open_file with in-core output */
	out->writeproc = NULL;
    }
    else
    {
	/* PDF_open_file with file output */
#if !((defined(MAC) || defined (MACOSX)) && defined(__MWERKS__))
	if (filename && !strcmp(filename, "-"))
        {
	    out->fp = stdout;
#if !defined(__MWERKS__) && (defined(WIN32) || defined(OS2))
#if !defined(__BORLANDC__) && !defined(OS2)
	    _setmode(_fileno(stdout), _O_BINARY);
#else
	    setmode(fileno(stdout), O_BINARY);
#endif /* !__BORLANDC__ && !OS2 */
#endif
	}
        else
        {
#endif /* !MAC */
            char fopenparams[200]; /* sufficient */

#if defined(MVS) || defined(MVS_TEST)
            if (out->fopenparams != (char *) 0)
            {
                strcpy(fopenparams, WRITEMODE);
                strcat(fopenparams, ",");
                strcat(fopenparams, out->fopenparams);
            }
            else if (out->recordsize <= 1)
            {
                strcpy(fopenparams, WRITEMODE_V);
            }
            else
            {
                strcpy(fopenparams, WRITEMODE);
            }
#else
            strcpy(fopenparams, WRITEMODE);
#endif

            out->fp = pdc_fopen_logg(out->pdc, filename, fopenparams);
	    if (out->fp == NULL)
		return pdc_false;

#if (defined(MAC) || defined(MACOSX)) && defined(PDF_FILETYPE_SUPPORTED)
            if (!pdc->ptfrun)
            {
                /* set the proper type and creator for the output file */
#if TARGET_API_MAC_CARBON && !defined(__MWERKS__)

                if (FSPathMakeFSSpec((const UInt8 *) filename, &fSpec) == noErr)
                {
                    FSpGetFInfo(&fSpec, &fInfo);
                    fInfo.fdType = 'PDF ';
                    fInfo.fdCreator = 'CARO';
                    FSpSetFInfo(&fSpec, &fInfo);
                }

#else

                memset(&fcbInfo, 0, sizeof(FCBPBRec));
                fcbInfo.ioRefNum = (short) out->fp->handle;
                fcbInfo.ioNamePtr = name;

                if (!PBGetFCBInfoSync(&fcbInfo) &&
                    FSMakeFSSpec(fcbInfo.ioFCBVRefNum, fcbInfo.ioFCBParID,
                    name, &fSpec) == noErr)
                {
                        FSpGetFInfo(&fSpec, &fInfo);
                        fInfo.fdType = 'PDF ';
                        fInfo.fdCreator = 'CARO';
                        FSpSetFInfo(&fSpec, &fInfo);
                }
#endif  /* !defined(TARGET_API_MAC_CARBON) || defined(__MWERKS__) */
            }
#endif	/* (MAC || MACOSX) && PDF_FILETYPE_SUPPORTED */

#if !((defined(MAC) || defined (MACOSX)) && defined(__MWERKS__))
	}
#endif /* !MAC */
    }

    return pdc_true;
}
Beispiel #28
0
/* wrapper for pdc_malloc for use in zlib */
static voidpf
pdc_zlib_alloc(voidpf pdc, uInt items, uInt size)
{
    return (voidpf) pdc_malloc((pdc_core *) pdc, items * size, "zlib");
}
Beispiel #29
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);
}
Beispiel #30
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;
}