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; }
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; }
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; }