Example #1
0
void
pdf_grow_pattern(PDF *p)
{
    static const char fn[] = "pdf_grow_pattern";
    int i;

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

    for (i = p->pattern_capacity; i < 2 * p->pattern_capacity; i++) {
	p->pattern[i].used_on_current_page = pdc_false;
	p->pattern[i].obj_id = PDC_BAD_ID;
    }

    p->pattern_capacity *= 2;
}
Example #2
0
void
pdc_freset(pdc_file *sfp, size_t size)
{
    static const char fn[] = "pdc_freset";

    if (sfp->wrmode && !sfp->fp)
    {
        if (size > (size_t) (sfp->limit - sfp->data))
        {
            sfp->data = (pdc_byte *) pdc_realloc(sfp->pdc, sfp->data, size, fn);
            sfp->limit = sfp->data + size;
        }

        sfp->pos = sfp->data;
        sfp->end = sfp->data;
    }
}
Example #3
0
size_t
pdc_fwrite(const void *ptr, size_t size, size_t nmemb, pdc_file *sfp)
{
    static const char fn[] = "pdc_fwrite";

    if (sfp->wrmode)
    {
        size_t poslen, nbytes = 0;

        if (sfp->fp)
        {
            size_t total = pdc__fwrite(ptr, size, nmemb, sfp->fp);

            if (total < size * nmemb)
            {
                pdc_set_fwrite_errmsg(sfp->pdc, sfp->filename);
                PDC_RETHROW(sfp->pdc);
            }

            return total;
        }

        nbytes = size * nmemb;
        if (sfp->pos + nbytes > sfp->limit)
        {
            poslen = (size_t) (sfp->pos - sfp->data);
            size = poslen + nbytes;

            sfp->data = (pdc_byte *) pdc_realloc(sfp->pdc, sfp->data, size, fn);
            sfp->pos = sfp->data + poslen;
            sfp->end = sfp->data + size;
            sfp->limit = sfp->end;
        }
        memcpy(sfp->pos, ptr, nbytes);
        sfp->pos += nbytes;
        if (sfp->pos > sfp->end)
            sfp->end = sfp->pos;
    }
    else
    {
        nmemb = 0;
    }

    return nmemb;
}
Example #4
0
/*
 * Returns the full specified path name in a new memory.
 * The full path name can be concatened by a path name,
 * file name and extension (incl. dot).
 */
char *
pdc_file_concat(pdc_core *pdc, const char *dirname, const char *basename,
                const char *extension)
{
    static const char fn[] = "pdc_file_concat";
    char *pathname = pdc_file_fullname_mem(pdc, dirname, basename);
    size_t len = strlen(pathname) + 1;

    if (extension != NULL)
        len += strlen(extension);

    pathname = (char *) pdc_realloc(pdc, pathname, len, fn);

    if (extension != NULL)
        strcat(pathname, extension);

    return pathname;
}
Example #5
0
pdc_id
pdc_alloc_id(pdc_output *out)
{
    pdc_core *pdc = out->pdc;

    out->lastobj++;

    if (out->lastobj >= out->file_offset_capacity) {
	out->file_offset_capacity *= 2;
	out->file_offset = (long *) pdc_realloc(pdc, out->file_offset,
		    sizeof(long) * out->file_offset_capacity, "pdc_alloc_id");
    }

    /* only needed for verifying obj table in PDF_close() */
    out->file_offset[out->lastobj] = PDC_BAD_ID;

    return out->lastobj;
}
Example #6
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);
    }
}
Example #7
0
pdc_id
pdc_alloc_id(pdc_output *out)
{

    out->lastobj++;

    if (out->lastobj > PDF_MAXINDOBJS)
        pdc_error(out->pdc, PDC_E_INT_TOOMUCH_INDOBJS,
                  pdc_errprintf(out->pdc, "%d", PDF_MAXINDOBJS), 0, 0, 0);

    if (out->lastobj >= out->file_offset_capacity) {
	out->file_offset_capacity *= 2;
	out->file_offset = (pdc_off_t *)
	    pdc_realloc(out->pdc, out->file_offset,
		sizeof(pdc_off_t) * out->file_offset_capacity, "pdc_alloc_id");
    }

    /* only needed for verifying obj table in PDF_close() */
    out->file_offset[out->lastobj] = PDC_BAD_ID;

    return out->lastobj;
}
Example #8
0
static int
pdf_insert_bookmark(
    PDF *p,
    const char *hypertext,
    pdf_outline *outline,
    int jndex)
{
    static const char fn[] = "pdf_insert_bookmark";
    pdf_outline *root, *self;
    int parent;
    int self_idx;
    int pageno = pdf_current_page(p);

    /* allocation */
    if (p->outline_count == 0)
    {
        p->outline_capacity = OUTLINE_CHUNKSIZE;
        p->outlines = (pdf_outline *) pdc_calloc(p->pdc,
                          sizeof(pdf_outline) * p->outline_capacity, fn);

        /* populate the root outline object */
        root = &p->outlines[0];
        pdf_init_outline(p, root);
        root->obj_id = pdc_alloc_id(p->out);
        root->open = pdc_true;

        /* set the open mode show bookmarks if we have at least one,
         * and the client didn't already set his own open mode.
         */
        pdf_fix_openmode(p);
    }
    else if (p->outline_count + 1 >= p->outline_capacity)
    {
        p->outline_capacity *= 2;
        p->outlines = (pdf_outline *) pdc_realloc(p->pdc, p->outlines,
                          sizeof(pdf_outline) * p->outline_capacity, fn);
    }

    /* copy */
    self_idx = ++p->outline_count;
    self = &p->outlines[self_idx];
    memcpy(self, outline, sizeof(pdf_outline));

    self->obj_id = pdc_alloc_id(p->out);
    self->text = (char *) hypertext;
    self->page_id = pdf_get_page_id(p, 0);
    parent = self->parent;

    /* default destination */
    if (self->action == NULL && self->dest == NULL)
        self->dest = pdf_init_destination(p);

    /* no destination */
    if (self->dest != NULL &&
        self->dest->name != NULL && !strlen(self->dest->name))
    {
        pdf_cleanup_destination(p, self->dest);
        self->dest = NULL;
    }

    /* current page */
    if (self->dest)
    {
	/* this ugly code is for compatibility with the
	** obsolete "bookmarkdest" parameter.
	*/
        if (self->dest->pgnum == 0)
            self->dest->pgnum = pdf_current_page(p);

        if (self->dest->pgnum == 0)
	{
            self->dest->pgnum = 1;
	}
	else if (self->dest->page == PDC_BAD_ID)
	{
            self->dest->page = pdf_get_page_id(p, self->dest->pgnum);
	}
    }

    /* special case: empty list.
    */
    if (FIRST(parent) == 0)
    {
        if (jndex > 0)
	    pdc_error(p->pdc, PDC_E_OPT_ILLINTEGER, "index",
                pdc_errprintf(p->pdc, "%d", jndex), 0, 0);

        FIRST(parent) = LAST(parent) = self_idx;
	self->in_order = pdc_true;
    }
    else switch (jndex)
    {
	case -2:	/* insert "in order" */
	{
	    /* the "natural" case: append to the end if appropriate.
	    */
	    if (pageno >= search_backward(p, -1, LAST(parent)))
	    {
		self->prev = LAST(parent);
		NEXT(LAST(parent)) = self_idx;
		LAST(parent) = self_idx;
	    }
	    else
	    {
		int idx;
		int curr_pg = 1;
		int next_pg;

		for (idx = FIRST(parent); idx != 0; idx = NEXT(idx))
		{
		    if (!IN_ORDER(idx))
			continue;

		    next_pg = pdf_search_page_fwd(p, curr_pg, PAGE_ID(idx));

		    /* TODO: understand why this can happen.
		    */
		    if (next_pg < 1)
		    {
			idx = 0;
			break;
		    }

		    if (next_pg > pageno)
		    {
			self->next = idx;
			self->prev = PREV(idx);
			PREV(idx) = self_idx;

			if (self->prev == 0)
			    FIRST(parent) = self_idx;
			else
			    NEXT(self->prev) = self_idx;

			break;
		    }

		    curr_pg = next_pg;
		}

		/* if there are no "in order" bookmarks yet,
		** we simply append this one to the end.
		*/
		if (idx == 0)
		{
		    self->prev = LAST(parent);
		    NEXT(LAST(parent)) = self_idx;
		    LAST(parent) = self_idx;
		}
	    }

	    self->in_order = pdc_true;
	    break;
	}

	case -1:	/* append to the end */
	{
	    self->prev = LAST(parent);
	    NEXT(LAST(parent)) = self_idx;
	    LAST(parent) = self_idx;

	    self->in_order =
		(pageno >= search_backward(p, pageno, self->prev));
	    break;
	}

	case 0:		/* insert at the beginning */
	{
	    self->next = FIRST(parent);
	    PREV(FIRST(parent)) = self_idx;
	    FIRST(parent) = self_idx;

	    self->in_order =
		(pageno <= search_forward(p, pageno, self->next));
	    break;
	}

	default:	/* insert before [1..LAST] */
	{
	    int i;
	    int target = FIRST(parent);

            for (i = 0; i < jndex; ++i)
	    {
		if (target == LAST(parent))
		    pdc_error(p->pdc, PDC_E_OPT_ILLINTEGER, "index",
                        pdc_errprintf(p->pdc, "%d", jndex), 0, 0);

		target = NEXT(target);
	    }

	    self->next = target;
	    self->prev = PREV(target);
	    NEXT(self->prev) = PREV(self->next) = self_idx;

	    self->in_order =
		((pageno >= search_backward(p, pageno, self->prev)) &&
		(pageno <= search_forward(p, pageno, self->next)));
	    break;
	}
    } /* else switch */

    /* increase the number of open sub-entries for all relevant ancestors */
    do {
        COUNT(parent)++;
    } while (OPEN(parent) && (parent = PARENT(parent)) != 0);

    return (self_idx);          /* caller may use this as handle */
}
Example #9
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);
}
Example #10
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;
}
Example #11
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;
}
Example #12
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;
    }
}