예제 #1
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;
}
예제 #2
0
파일: p_afm.c 프로젝트: xharbour/core
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;
}
예제 #3
0
static int
PFA_data_fill(PDF *p, PDF_data_source *src)
{
    static const char *fn = "PFA_data_fill";
    pdc_bool logg6 = pdc_logg_is_enabled(p->pdc, 6, trc_font);
#ifndef PDFLIB_EBCDIC
    static const char HexToBin['F' - '0' + 1] = {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
        0, 10, 11, 12, 13, 14, 15
    };
#else
#endif
    char *s, *c;
    int i;
    int len;
    t1_private_data *t1;
    pdf_t1portion t1portion;

    t1 = (t1_private_data *) src->private_data;

    if (t1->portion == t1_eof)
        return pdc_false;

    if (src->buffer_start == NULL)
    {
        src->buffer_start = (pdc_byte *)
                                pdc_malloc(p->pdc, PDC_BUFSIZE + 1, fn);
        src->buffer_length = PDC_BUFSIZE;
    }

    if (logg6)
        pdc_logg(p->pdc, "\t\t\tdata fill: portion=%s\n",
                 pdc_get_keyword(t1->portion, pdf_t1portion_keylist));

    s = pdc_fgetline((char *) src->buffer_start, PDC_BUFSIZE, t1->fontfile);
    if (s == NULL)
        return pdc_false;

    /* set unix line end */
    len = (int) strlen(s);
    s[len] = '\n';
    len++;
    s[len] = 0;

    /* check for line of zeros: set t1_zero flag if found */
    if (*s == '0')
    {
        for (i = 0; s[i] == '0'; i++)
        {
            /* */ ;
        }
        if (s[i] == '\n')
        {
            t1->portion = t1_zeros;

            if (logg6)
                pdc_logg(p->pdc, "\t\t\tlinefeed detected: set portion %s\n",
                         pdc_get_keyword(t1->portion,
                                         pdf_t1portion_keylist));
        }
    }

    /* check whether font data portion follows: set t1_encrypted flag later */
    t1portion = t1->portion;
    if (t1->portion != t1_encrypted &&
        !strncmp((const char *)s, PDF_CURRENTFILE, strlen(PDF_CURRENTFILE)))
    {
        t1portion = t1_encrypted;

        if (logg6)
            pdc_logg(p->pdc, "\t\t\t\"%s\" detected\n", PDF_CURRENTFILE);
    }

    src->next_byte = src->buffer_start;

    switch (t1->portion)
    {
        case t1_ascii:
        {
            t1->length[1] += (size_t) len;
            src->bytes_available = (size_t) len;
        }
        break;

        case t1_encrypted:
        {
            src->bytes_available = 0;

            /* Convert to upper case for safe binary conversion */
            for (c = s; *c != '\n'; c++)
            {
                *c = (char) pdc_toupper(*c);
            }

            /* convert ASCII to binary in-place */
            for (i = 0; s[i] != '\n'; i += 2)
            {
                if ((!pdc_isxdigit(s[i]) && !pdc_isspace(s[i])) ||
                    (!pdc_isxdigit(s[i+1]) && !pdc_isspace(s[i+1])))
                {
                    pdc_fclose(t1->fontfile);
                    pdc_error(p->pdc, PDF_E_FONT_CORRUPT_PFA, 0, 0, 0, 0);
                }
                s[i/2] = (char) (16*HexToBin[s[i]-'0'] + HexToBin[s[i+1]-'0']);

                src->bytes_available++;
            }
            t1->length[2] += src->bytes_available;
        }
        break;

        case t1_zeros:
        {
            t1->length[3] += (size_t) len;
            src->bytes_available = (size_t) len;
        }
        break;

        default:
        break;
    }

    t1->portion = t1portion;

    if (logg6)
        pdc_logg(p->pdc, "\t\t\tset portion %s\n",
                 pdc_get_keyword(t1->portion, pdf_t1portion_keylist));
    return pdc_true;
}