diff options
Diffstat (limited to 'src/pdflib/pdflib/p_font.c')
-rw-r--r-- | src/pdflib/pdflib/p_font.c | 200 |
1 files changed, 146 insertions, 54 deletions
diff --git a/src/pdflib/pdflib/p_font.c b/src/pdflib/pdflib/p_font.c index 5dfce77..4aec8a6 100644 --- a/src/pdflib/pdflib/p_font.c +++ b/src/pdflib/pdflib/p_font.c @@ -10,7 +10,7 @@ | | *---------------------------------------------------------------------------*/ -/* $Id: p_font.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ +/* $Id: p_font.c,v 1.2 2009/10/20 18:14:16 scuri Exp $ * * PDFlib font handling routines * @@ -132,6 +132,10 @@ pdf_init_font(PDF *p, pdf_font *font, pdf_font_options *fo) font->expectglyphs = pdc_false; font->iscidfont = pdc_false; + font->widths = NULL; + font->numwidths = 0; + font->konlydef = pdc_false; + } void @@ -182,6 +186,12 @@ pdf_cleanup_font(PDF *p, pdf_font *font) font->t3font = NULL; } + if (font->widths != NULL) + { + pdc_free(p->pdc, font->widths); + font->widths = NULL; + } + } void @@ -425,8 +435,9 @@ pdf_get_fontname_core(pdf_font *font, const char *fontname, pdc_bool checktimes) static pdc_bool pdf_get_metrics_core(PDF *p, pdf_font *font, const char *fontname, - pdc_encoding enc, pdc_bool checktimes) + const char *outfilename, pdc_encoding enc, pdc_bool checktimes) { + static const char fn[] = "pdf_get_metrics_core"; const char *fname = NULL; const fnt_font_metric *ftm; @@ -435,10 +446,16 @@ pdf_get_metrics_core(PDF *p, pdf_font *font, const char *fontname, { fontname = fname; font->opt.fontstyle = fnt_Normal; + + if (font->apiname != NULL) + { + pdc_free(p->pdc, font->apiname); + font->apiname = pdc_strdup_ext(p->pdc, fontname, 0, fn); + } } ftm = fnt_get_core_metric(fontname); - if (ftm != NULL) + if (ftm != NULL && (!font->opt.embedding || outfilename != NULL)) { pdc_logg_cond(p->pdc, 1, trc_font, "\tLoading metrics data for core font \"%s\":\n", fontname); @@ -813,6 +830,7 @@ pdf_init_font_options(PDF *p, pdf_font_options *fo) fo->xheight = 0; fo->linegap = 0; fo->auxiliary = pdc_false; + fo->dropcorewidths = pdc_false; } @@ -908,10 +926,12 @@ pdf_get_font_options(PDF *p, pdf_font_options *fo, pdc_resopt *resopts) if (pdc_get_optvalues("linegap", resopts, &fo->linegap, NULL)) fo->mask |= (1L << fo_linegap); + + pdc_get_optvalues("dropcorewidths", resopts, &fo->dropcorewidths, NULL); } int -pdf__load_font(PDF *p, const char *fontname, int inlen, +pdf__load_font(PDF *p, const char *fontname, int len, const char *encoding, const char *optlist) { int slot; @@ -920,14 +940,11 @@ pdf__load_font(PDF *p, const char *fontname, int inlen, if (encoding == NULL || *encoding == '\0') pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "encoding", 0, 0, 0); - if (fontname == NULL) - pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "fontname", 0, 0, 0); - /* initialize */ pdf_init_font_options(p, &fo); /* Converting fontname */ - fo.fontname = (char *) pdf_convert_name(p, fontname, inlen, + fo.fontname = (char *) pdf_convert_name(p, fontname, len, PDC_CONV_WITHBOM); if (fo.fontname == NULL || *fo.fontname == '\0') pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "fontname", 0, 0, 0); @@ -997,6 +1014,7 @@ pdf_check_font_embedding(PDF *p, pdf_font *font, const char *fontname) int pdf_load_font_internal(PDF *p, pdf_font_options *fo) { + pdc_bool logg1 = pdc_logg_is_enabled(p->pdc, 1, trc_font); pdc_bool logg2 = pdc_logg_is_enabled(p->pdc, 2, trc_font); const char *fontname; const char *encoding; @@ -1014,6 +1032,17 @@ pdf_load_font_internal(PDF *p, pdf_font_options *fo) pdc_bool retval = pdc_false; int slot = -1, i; + /* register and skip at sign '@' in font name */ + if (fo->fontname[0] == PDF_VERTICAL_SIGN || + (pdc_is_utf8_bytecode(fo->fontname) && + fo->fontname[3] == PDF_VERTICAL_SIGN)) + { + + i = (fo->fontname[0] == PDF_VERTICAL_SIGN) ? 1 : 4; + len = strlen(fo->fontname) + 1 - i; + memmove(&fo->fontname[i - 1], &fo->fontname[i], len); + } + /* host or UTF-8 encoded font name without BOM */ fontname_p = pdc_utf8_to_hostbytes(p->pdc, pdc_false, fo->fontname); if (fontname_p == NULL) @@ -1023,10 +1052,14 @@ pdf_load_font_internal(PDF *p, pdf_font_options *fo) else { fontname = pdc_utf8strprint(p->pdc, fontname_p); - pdc_free(p->pdc, fontname_p); + pdc_free_tmp(p->pdc, fontname_p); } fontname_p = NULL; + if (logg1) + pdc_logg(p->pdc, "\tCanonical font name: \"%s\"\n", + fontname); + /* font encoding */ encoding = fo->encoding; encoding_aux = encoding; @@ -1047,14 +1080,22 @@ pdf_load_font_internal(PDF *p, pdf_font_options *fo) /* UTF-8 font name with BOM */ font->ft.utf8name = pdc_strdup(p->pdc, fo->fontname); - pdc_logg_cond(p->pdc, 1, trc_font, "\tFont UTF-8 name: \"%s\"\n", - font->ft.utf8name); + if (logg1) + pdc_logg(p->pdc, "\tFont UTF-8 name: \"%s\"\n", + font->ft.utf8name); /* specified encoding name */ font->encapiname = pdc_strdup(p->pdc, encoding); /* search for a registered encoding */ enc = pdc_find_encoding(p->pdc, encoding); + + if (enc == pdc_unicode || enc == pdc_glyphid) + { + pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_UNICODE, 0, 0, 0, 0); + goto PDF_PREMATURE_EXIT; + } + if (enc == pdc_invalidenc || enc == pdc_unicode) { /* search for a predefined CMap and registered fonts */ @@ -1112,8 +1153,8 @@ pdf_load_font_internal(PDF *p, pdf_font_options *fo) * is found, make a copy in a new slot and attach the requested encoding. */ - pdc_logg_cond(p->pdc, 1, trc_font, - "\tFont will be searched in the PDFlib font cache\n"); + if (logg1) + pdc_logg(p->pdc, "\tFont will be searched in the PDFlib font cache\n"); for (slot = 0; slot < p->fonts_number; slot++) { if (p->fonts[slot].obj_id == PDC_BAD_ID && @@ -1233,8 +1274,8 @@ pdf_load_font_internal(PDF *p, pdf_font_options *fo) } slot = -1; - pdc_logg_cond(p->pdc, 1, trc_font, - "\tFont not found in the PDFlib font cache\n"); + if (logg1) + pdc_logg(p->pdc, "\tFont not found in the PDFlib font cache\n"); /* embedding check */ if (!pdf_check_font_embedding(p, font, fontname)) @@ -1269,18 +1310,11 @@ pdf_load_font_internal(PDF *p, pdf_font_options *fo) } mmparam[2] = '\0'; /* strip the parameter from the master name */ } - - /* Font for vertical writing mode */ fontname_p = mastername; - if (mastername[0] == '@') - { - font->ft.vertical = pdc_true; - fontname_p = &mastername[1]; - } /* protocol */ - pdc_logg_cond(p->pdc, 1, trc_font, - "\tPDFlib font name: \"%s\"\n", fontname_p); + if (logg1) + pdc_logg(p->pdc, "\tPDFlib font name: \"%s\"\n", fontname_p); /* Font file search hierarchy * - Check "FontOutline" resource entry and check TrueType font @@ -1293,6 +1327,14 @@ pdf_load_font_internal(PDF *p, pdf_font_options *fo) retval = pdc_false; while (1) { + if (font->opt.auxiliary) + { + /* only in-core fonts are possible */ + retval = pdf_get_metrics_core(p, font, fontname_p, "", enc, + pdc_false); + break; + } + #ifdef PDF_TRUETYPE_SUPPORTED /* Check specified TrueType file */ filename = pdc_find_resource(p->pdc, "FontOutline", fontname_p); @@ -1350,22 +1392,26 @@ pdf_load_font_internal(PDF *p, pdf_font_options *fo) - /* Check available in-core metrics */ - retval = pdf_get_metrics_core(p, font, fontname_p, enc, pdc_false); + /* Check available in-core metrics - will be skipped + * in the case of embedding and missing outline file + * to check the possibility of an host font in the next step. + */ + retval = pdf_get_metrics_core(p, font, fontname_p, outfilename, enc, + pdc_false); if (retval != pdc_undef) break; retval = pdc_false; /* Check available in-core metrics */ - retval = pdf_get_metrics_core(p, font, fontname_p, enc, pdc_true); + retval = pdf_get_metrics_core(p, font, fontname_p, "", enc, pdc_true); if (retval != pdc_undef) break; retval = pdc_false; /* Searching for a metric file */ - pdc_logg_cond(p->pdc, 1, trc_font, - "\tSearching for font metrics data file:\n"); + if (logg1) + pdc_logg(p->pdc, "\tSearching for font metrics data file:\n"); filename = testfilename; for (i = 0; i < 100; i++) @@ -1420,9 +1466,10 @@ pdf_load_font_internal(PDF *p, pdf_font_options *fo) { retval = pdc_false; - pdc_logg_cond(p->pdc, 1, trc_font, - "\tMetric data file for font \"%s\" not available\n", - fontname_p); + if (logg1) + pdc_logg(p->pdc, + "\tMetric data file for font \"%s\" not available\n", + fontname_p); pdc_set_errmsg(p->pdc, PDF_E_FONT_NOMETRICS, 0, 0, 0, 0); } @@ -1470,8 +1517,9 @@ pdf_load_font_internal(PDF *p, pdf_font_options *fo) else { /* Searching font outline file */ - pdc_logg_cond(p->pdc, 1, trc_font, - "\tSearching for font outline data file:\n"); + if (logg1) + pdc_logg(p->pdc, + "\tSearching for font outline data file:\n"); outfilename = testfilename; for (i = 0; i < 100; i++) @@ -1506,25 +1554,33 @@ pdf_load_font_internal(PDF *p, pdf_font_options *fo) if (retval == pdc_undef) { retval = pdc_false; - pdc_set_errmsg(p->pdc, PDF_E_FONT_NOOUTLINE, 0, 0, 0, 0); + if (font->ft.m.type == fnt_Type1 || + font->ft.m.type == fnt_MMType1) + pdc_set_errmsg(p->pdc, PDF_E_FONT_NOOUTLINE_PS, + 0, 0, 0, 0); + else + pdc_set_errmsg(p->pdc, PDF_E_FONT_NOOUTLINE_TT, + 0, 0, 0, 0); } } if (retval == pdc_false) { - pdc_logg_cond(p->pdc, 1, trc_font, - "\tOutline data file for font \"%s\" not found\n", - fontname_p); + if (logg1) + pdc_logg(p->pdc, + "\tOutline data file for font \"%s\" not found\n", + fontname_p); } else { if (!font->ft.img) font->filename = font->ft.filename; - pdc_logg_cond(p->pdc, 1, trc_font, - "\tFont outline data file \"%s\" available\n", - font->filename ? - font->filename : font->ft.imgname); + if (logg1) + pdc_logg(p->pdc, + "\tFont outline data file \"%s\" available\n", + font->filename ? + font->filename : font->ft.imgname); } } } @@ -1644,6 +1700,38 @@ pdf_transform_fontwidths(PDF *p, pdf_font *font, pdc_encodingvector *evto, memcpy(font->ft.code2gid, code2gid, 256 * sizeof(pdc_ushort)); } +void +pdf_prepare_fontwidths(PDF *p, pdf_font *font, int nusedgids) +{ + + (void) p; + (void) nusedgids; + + if (font->towinansi != pdc_invalidenc || font->widths != NULL || + (font->iscidfont && (font->ft.isstdfont || font->opt.monospace))) + { + return; + } + + /* exchange widths pointer */ + if (!font->iscidfont && font->ft.enc != pdc_unicode) + { + font->widths = font->ft.m.widths; + font->numwidths = font->ft.m.numwidths; + font->ft.m.widths = NULL; + font->ft.m.numwidths = 0; + return; + } + + /* already defined or no basic data */ + if (font->ft.m.widths == NULL && font->ft.m.ciw == NULL + ) + { + return; + } + +} + static void @@ -1746,6 +1834,7 @@ pdf_put_font(PDF *p, pdf_font *font) /* save font struct members */ pdc_encodingvector *ev = NULL; pdc_encoding font_encoding = font->ft.enc; + pdc_encoding font_towinansi = font->towinansi; int font_numcodes = font->ft.numcodes; int font_codesize = font->codesize; @@ -1889,8 +1978,12 @@ pdf_put_font(PDF *p, pdf_font *font) enc = font->towinansi; font->ft.enc = enc; + font->towinansi = pdc_invalidenc; } + /* preparation for font widths array */ + pdf_prepare_fontwidths(p, font, nusedgids); + /* /FontDescriptor, /FirstChar, /LastChar, /Widths */ switch (fonttype) { @@ -1912,8 +2005,11 @@ pdf_put_font(PDF *p, pdf_font *font) { fontdescriptor_id = pdc_alloc_id(p->out); pdc_objref(p->out, "/FontDescriptor", fontdescriptor_id); - } + /* bug #1036 */ + if (font->ft.isstdfont == pdc_true && font->opt.dropcorewidths) + break; + } /* determine missing width. * Only for embedded fonts because of a bug in Acrobat, @@ -1922,19 +2018,19 @@ pdf_put_font(PDF *p, pdf_font *font) if (font->opt.embedding) { if (fonttype != fnt_Type3) - defwidth = font->ft.m.widths[0]; + defwidth = font->widths[0]; { for (i = 1; i < 255; i++) { - if (font->ft.m.widths[i] != defwidth) + if (font->widths[i] != defwidth) break; } if (i > 1) firstchar = i; for (i = 255; i > 0; i--) { - if (i == firstchar || font->ft.m.widths[i] != defwidth) + if (i == firstchar || font->widths[i] != defwidth) break; } lastchar = i; @@ -1952,7 +2048,7 @@ pdf_put_font(PDF *p, pdf_font *font) for (i = firstchar; i <= lastchar; i++) { pdc_printf(p->out, "%d", - (int) (font->ft.m.widths[i] / a + .5)); + (int) (font->widths[i] / a + .5)); if (i < 255) pdc_printf(p->out, "%s", ((i + 1) % 16) ? " " : "\n"); } @@ -2376,6 +2472,7 @@ pdf_put_font(PDF *p, pdf_font *font) /* restore font struct members */ font->ft.enc = font_encoding; + font->towinansi = font_towinansi; font->ft.numcodes = font_numcodes; font->codesize = font_codesize; @@ -2451,7 +2548,6 @@ void pdf_write_page_fonts(PDF *p) { int i, total = 0; - int bias = p->curr_ppt->fn_bias; /* This doesn't really belong here, but all modules which write * font resources also need this, so we include it here. @@ -2466,7 +2562,7 @@ pdf_write_page_fonts(PDF *p) if (p->fonts[i].used_on_current_page == pdc_true) total++; - if (total > 0 || bias) + if (total > 0) { pdc_puts(p->out, "/Font"); pdc_begin_dict(p->out); /* font resource dict */ @@ -2478,12 +2574,11 @@ pdf_write_page_fonts(PDF *p) { if (p->fonts[i].used_on_current_page == pdc_true) { p->fonts[i].used_on_current_page = pdc_false; /* reset */ - pdc_printf(p->out, "/F%d", bias + i); + pdc_printf(p->out, "/F%d", i); pdc_objref(p->out, "", p->fonts[i].obj_id); } } - if (!bias) pdc_end_dict(p->out); /* font resource dict */ } } @@ -2508,6 +2603,3 @@ pdf_mark_page_font(PDF *p, int ft) { p->fonts[ft].used_on_current_page = pdc_true; } - - - |