diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2016-02-24 17:06:00 +0100 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2016-02-29 15:56:45 +0100 |
commit | 2b65dae7e2ae091c03ffe0811aa4e60457a4cd84 (patch) | |
tree | 57593ffc1d970bf67608e5137df3630ed154b31e | |
parent | 63c0874392c5159e251514db48891500e9854c5d (diff) | |
download | mupdf-2b65dae7e2ae091c03ffe0811aa4e60457a4cd84.tar.xz |
Pass fz_font to pdf_add_xxx_font_res instead of a fz_buffer.
Make sure all fz_fonts have a ft_buffer available.
-rw-r--r-- | include/mupdf/fitz/buffer.h | 6 | ||||
-rw-r--r-- | include/mupdf/fitz/font.h | 5 | ||||
-rw-r--r-- | include/mupdf/pdf/font.h | 4 | ||||
-rw-r--r-- | source/fitz/buffer.c | 21 | ||||
-rw-r--r-- | source/fitz/font.c | 71 | ||||
-rw-r--r-- | source/pdf/pdf-device.c | 12 | ||||
-rw-r--r-- | source/pdf/pdf-font.c | 63 | ||||
-rw-r--r-- | source/tools/pdfcreate.c | 5 |
8 files changed, 102 insertions, 85 deletions
diff --git a/include/mupdf/fitz/buffer.h b/include/mupdf/fitz/buffer.h index 64096ca4..6f0e812f 100644 --- a/include/mupdf/fitz/buffer.h +++ b/include/mupdf/fitz/buffer.h @@ -44,6 +44,7 @@ struct fz_buffer_s unsigned char *data; int cap, len; int unused_bits; + int shared; }; /* @@ -72,6 +73,11 @@ fz_buffer *fz_new_buffer(fz_context *ctx, int capacity); fz_buffer *fz_new_buffer_from_data(fz_context *ctx, unsigned char *data, int size); /* + fz_new_buffer_from_shared_data: Like fz_new_buffer, but does not take ownership. +*/ +fz_buffer *fz_new_buffer_from_shared_data(fz_context *ctx, unsigned char *data, int size); + +/* fz_resize_buffer: Ensure that a buffer has a given capacity, truncating data if required. diff --git a/include/mupdf/fitz/font.h b/include/mupdf/fitz/font.h index ea992112..c16afd45 100644 --- a/include/mupdf/fitz/font.h +++ b/include/mupdf/fitz/font.h @@ -28,6 +28,7 @@ struct fz_font_s { int refs; char name[32]; + fz_buffer *buffer; char is_mono; char is_serif; @@ -42,10 +43,6 @@ struct fz_font_s int fake_italic; /* ... synthesize italic */ int force_hinting; /* ... force hinting for DynaLab fonts */ - /* origin of font data */ - fz_buffer *ft_buffer; - char *ft_filepath; /* kept for downstream consumers (such as SumatraPDF) */ - fz_matrix t3matrix; void *t3resources; fz_buffer **t3procs; /* has 256 entries if used */ diff --git a/include/mupdf/pdf/font.h b/include/mupdf/pdf/font.h index 40a1a3e5..73b25d2f 100644 --- a/include/mupdf/pdf/font.h +++ b/include/mupdf/pdf/font.h @@ -122,8 +122,8 @@ float pdf_text_stride(fz_context *ctx, pdf_font_desc *fontdesc, float fontsize, void pdf_run_glyph(fz_context *ctx, pdf_document *doc, pdf_obj *resources, fz_buffer *contents, fz_device *dev, const fz_matrix *ctm, void *gstate, int nestedDepth); -pdf_obj *pdf_add_simple_font_res(fz_context *ctx, pdf_document *doc, fz_buffer *buffer); -pdf_obj *pdf_add_cid_font_res(fz_context *ctx, pdf_document *doc, fz_buffer *buffer, fz_font *font); +pdf_obj *pdf_add_simple_font_res(fz_context *ctx, pdf_document *doc, fz_font *font); +pdf_obj *pdf_add_cid_font_res(fz_context *ctx, pdf_document *doc, fz_font *font); int pdf_font_writing_supported(fz_font *font); diff --git a/source/fitz/buffer.c b/source/fitz/buffer.c index 86947df0..d1609ef1 100644 --- a/source/fitz/buffer.c +++ b/source/fitz/buffer.c @@ -41,6 +41,22 @@ fz_new_buffer_from_data(fz_context *ctx, unsigned char *data, int size) } fz_buffer * +fz_new_buffer_from_shared_data(fz_context *ctx, unsigned char *data, int size) +{ + fz_buffer *b; + + b = fz_malloc_struct(ctx, fz_buffer); + b->refs = 1; + b->data = data; + b->cap = size; + b->len = size; + b->unused_bits = 0; + b->shared = 1; + + return b; +} + +fz_buffer * fz_keep_buffer(fz_context *ctx, fz_buffer *buf) { if (buf) @@ -55,7 +71,8 @@ fz_drop_buffer(fz_context *ctx, fz_buffer *buf) return; if (--buf->refs == 0) { - fz_free(ctx, buf->data); + if (!buf->shared) + fz_free(ctx, buf->data); fz_free(ctx, buf); } } @@ -63,6 +80,8 @@ fz_drop_buffer(fz_context *ctx, fz_buffer *buf) void fz_resize_buffer(fz_context *ctx, fz_buffer *buf, int size) { + if (buf->shared) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot resize a buffer with shared storage"); buf->data = fz_resize_array(ctx, buf->data, size, 1); buf->cap = size; if (buf->len > buf->cap) diff --git a/source/fitz/font.c b/source/fitz/font.c index db07e890..1bac6efc 100644 --- a/source/fitz/font.c +++ b/source/fitz/font.c @@ -37,9 +37,6 @@ fz_new_font(fz_context *ctx, const char *name, int use_glyph_bbox, int glyph_cou font->fake_italic = 0; font->force_hinting = 0; - font->ft_buffer = NULL; - font->ft_filepath = NULL; - font->t3matrix = fz_identity; font->t3resources = NULL; font->t3procs = NULL; @@ -149,8 +146,7 @@ fz_drop_font(fz_context *ctx, fz_font *font) for (i = 0; i < 256; ++i) fz_free(ctx, font->encoding_cache[i]); - fz_drop_buffer(ctx, font->ft_buffer); - fz_free(ctx, font->ft_filepath); + fz_drop_buffer(ctx, font->buffer); fz_free(ctx, font->bbox_table); fz_free(ctx, font->width_table); fz_free(ctx, font->advance_cache); @@ -419,40 +415,7 @@ fz_drop_freetype(fz_context *ctx) } fz_font * -fz_new_font_from_file(fz_context *ctx, const char *name, const char *path, int index, int use_glyph_bbox) -{ - FT_Face face; - fz_font *font; - int fterr; - - fz_keep_freetype(ctx); - - fz_lock(ctx, FZ_LOCK_FREETYPE); - fterr = FT_New_Face(ctx->font->ftlib, path, index, &face); - fz_unlock(ctx, FZ_LOCK_FREETYPE); - if (fterr) - { - fz_drop_freetype(ctx); - fz_throw(ctx, FZ_ERROR_GENERIC, "freetype: cannot load font: %s", ft_error_string(fterr)); - } - - if (!name) - name = face->family_name; - - font = fz_new_font(ctx, name, use_glyph_bbox, face->num_glyphs); - font->ft_face = face; - fz_set_font_bbox(ctx, font, - (float) face->bbox.xMin / face->units_per_EM, - (float) face->bbox.yMin / face->units_per_EM, - (float) face->bbox.xMax / face->units_per_EM, - (float) face->bbox.yMax / face->units_per_EM); - font->ft_filepath = fz_strdup(ctx, path); - - return font; -} - -fz_font * -fz_new_font_from_memory(fz_context *ctx, const char *name, unsigned char *data, int len, int index, int use_glyph_bbox) +fz_new_font_from_buffer(fz_context *ctx, const char *name, fz_buffer *buffer, int index, int use_glyph_bbox) { FT_Face face; TT_OS2 *os2; @@ -462,7 +425,7 @@ fz_new_font_from_memory(fz_context *ctx, const char *name, unsigned char *data, fz_keep_freetype(ctx); fz_lock(ctx, FZ_LOCK_FREETYPE); - fterr = FT_New_Memory_Face(ctx->font->ftlib, data, len, index, &face); + fterr = FT_New_Memory_Face(ctx->font->ftlib, buffer->data, buffer->len, index, &face); fz_unlock(ctx, FZ_LOCK_FREETYPE); if (fterr) { @@ -490,14 +453,36 @@ fz_new_font_from_memory(fz_context *ctx, const char *name, unsigned char *data, if (os2) font->is_serif = !(os2->sFamilyClass & 2048); /* Class 8 is sans-serif */ + font->buffer = fz_keep_buffer(ctx, buffer); + return font; } fz_font * -fz_new_font_from_buffer(fz_context *ctx, const char *name, fz_buffer *buffer, int index, int use_glyph_bbox) +fz_new_font_from_memory(fz_context *ctx, const char *name, unsigned char *data, int len, int index, int use_glyph_bbox) +{ + fz_buffer *buffer = fz_new_buffer_from_shared_data(ctx, data, len); + fz_font *font; + fz_try(ctx) + font = fz_new_font_from_buffer(ctx, name, buffer, index, use_glyph_bbox); + fz_always(ctx) + fz_drop_buffer(ctx, buffer); + fz_catch(ctx) + fz_rethrow(ctx); + return font; +} + +fz_font * +fz_new_font_from_file(fz_context *ctx, const char *name, const char *path, int index, int use_glyph_bbox) { - fz_font *font = fz_new_font_from_memory(ctx, name, buffer->data, buffer->len, index, use_glyph_bbox); - font->ft_buffer = fz_keep_buffer(ctx, buffer); /* remember buffer so we can drop it when we free the font */ + fz_buffer *buffer = fz_read_file(ctx, path); + fz_font *font; + fz_try(ctx) + font = fz_new_font_from_buffer(ctx, name, buffer, index, use_glyph_bbox); + fz_always(ctx) + fz_drop_buffer(ctx, buffer); + fz_catch(ctx) + fz_rethrow(ctx); return font; } diff --git a/source/pdf/pdf-device.c b/source/pdf/pdf-device.c index 29bfdbf8..e7215eaa 100644 --- a/source/pdf/pdf-device.c +++ b/source/pdf/pdf-device.c @@ -400,13 +400,13 @@ pdf_dev_font(fz_context *ctx, pdf_device *pdev, fz_font *font, float size) if (font->ft_substitute) fz_throw(ctx, FZ_ERROR_GENERIC, "pdf device does not support substitute metrics"); - if (font->ft_buffer != NULL && !pdf_font_writing_supported(font)) + if (font->buffer != NULL && !pdf_font_writing_supported(font)) fz_throw(ctx, FZ_ERROR_GENERIC, "pdf device does not support font types found in this file"); - if (font->ft_buffer != NULL) + if (font->buffer != NULL) { /* This will add it to the xref if needed */ - fres = pdf_add_cid_font_res(ctx, doc, font->ft_buffer, font); + fres = pdf_add_cid_font_res(ctx, doc, font); fz_buffer_printf(ctx, gs->buf, "/F%d %f Tf\n", pdf_to_num(ctx, fres), size); /* Possibly add to page resources */ @@ -575,9 +575,9 @@ pdf_dev_text_span(fz_context *ctx, pdf_device *pdev, fz_text_span *span, float s } fz_buffer_printf(ctx, gs->buf, "<"); - if (span->font->ft_buffer == NULL) + if (span->font->buffer == NULL) { - /* A standard 14 type font */ + /* A type3 font */ for (/* i from its current value */; i < j; i++) { fz_buffer_printf(ctx, gs->buf, "%02x", span->items[i].ucs); @@ -585,7 +585,7 @@ pdf_dev_text_span(fz_context *ctx, pdf_device *pdev, fz_text_span *span, float s } else { - /* Non-standard font. Saved as Type0 Identity-H */ + /* Saved as Type0 Identity-H */ for (/* i from its current value */; i < j; i++) { fz_buffer_printf(ctx, gs->buf, "%04x", span->items[i].gid); diff --git a/source/pdf/pdf-font.c b/source/pdf/pdf-font.c index 8fc01f0d..fdb716ba 100644 --- a/source/pdf/pdf-font.c +++ b/source/pdf/pdf-font.c @@ -1367,7 +1367,7 @@ float pdf_text_stride(fz_context *ctx, pdf_font_desc *fontdesc, float fontsize, return x; } -/* Populate font description. According to spec, required for Latin fonts are +/* Populate font description. According to spec, required for Latin fonts are * FontName, Flags, FontBBox, ItalicAngle, Ascent, Descent, CapHeight (Latin), * StemV */ static void @@ -1390,7 +1390,7 @@ pdf_fontdesc_init(fz_context *ctx, pdf_font_desc *fontdesc) fontdesc->italic_angle = 0; /* 0 for now */ /* Get the cap height and stem thickness from capital O. Obviously an - .* issue if this is not a latin font */ + * issue if this is not a latin font */ fterr = FT_Load_Char(fontdesc->font->ft_face, 'O', FT_LOAD_NO_HINTING | FT_LOAD_IGNORE_TRANSFORM); if (fterr) @@ -1429,7 +1429,7 @@ pdf_fontdesc_init(fz_context *ctx, pdf_font_desc *fontdesc) } count -= 1; fontdesc->stem_v = width * (float)count / (float)face->glyph->bitmap.width; - fontdesc->flags = PDF_FD_NONSYMBOLIC; /* ToDo: FixMe. Set non-symbolic always for now */ + fontdesc->flags = PDF_FD_NONSYMBOLIC; /* ToDo: FixMe. Set non-symbolic always for now */ } static void ft_width_for_simple_table(fz_context *ctx, pdf_font_desc *fontdesc, @@ -1634,7 +1634,7 @@ pdf_add_cid_font_widths_entry(fz_context *ctx, pdf_document *doc, pdf_obj *fwobj switch (state) { case FW_SAME: - /* Add three entries. First cid, last cid and width */ + /* Add three entries. First cid, last cid and width */ pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, first_code)); pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, prev_code)); pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, prev_size)); @@ -1668,7 +1668,7 @@ pdf_add_cid_font_widths_entry(fz_context *ctx, pdf_document *doc, pdf_obj *fwobj } } -/* ToDo: Ignore the default sized characters */ +/* ToDo: Ignore the default sized characters */ static pdf_obj* pdf_add_cid_font_widths(fz_context *ctx, pdf_document *doc, pdf_font_desc *fontdesc, fz_font *source_font) { @@ -1803,7 +1803,7 @@ pdf_add_cid_font_widths(fz_context *ctx, pdf_document *doc, pdf_font_desc *fontd } else { - /* Non conscecutive code. Restart */ + /* Non conscecutive code. Restart */ if (state == FW_RUN) { pdf_array_push_drop(ctx, run_obj, pdf_new_int(ctx, doc, prev_size)); @@ -1838,7 +1838,7 @@ pdf_add_cid_font_widths(fz_context *ctx, pdf_document *doc, pdf_font_desc *fontd /* Descendant font construction used for CID font creation from ttf or Adobe type1 */ static pdf_obj* -pdf_add_descendant_font(fz_context *ctx, pdf_document *doc, fz_buffer *buffer, pdf_font_desc *fontdesc, fz_font *source_font) +pdf_add_descendant_font(fz_context *ctx, pdf_document *doc, pdf_font_desc *fontdesc) { pdf_obj *fobj = NULL; pdf_obj *fref = NULL; @@ -1848,7 +1848,8 @@ pdf_add_descendant_font(fz_context *ctx, pdf_document *doc, fz_buffer *buffer, p pdf_obj *fw = NULL; const char *ps_name; - FT_Face face = fontdesc->font->ft_face; + fz_font *font = fontdesc->font; + FT_Face face = font->ft_face; fz_var(fobj); fz_var(fref); @@ -1859,23 +1860,23 @@ pdf_add_descendant_font(fz_context *ctx, pdf_document *doc, fz_buffer *buffer, p fz_try(ctx) { /* refs */ - fstr_ref = pdf_add_font_file(ctx, doc, buffer); + fstr_ref = pdf_add_font_file(ctx, doc, fontdesc->font->buffer); fdes_ref = pdf_add_font_descriptor(ctx, doc, fontdesc, fstr_ref); fsys_ref = pdf_add_cid_system_info(ctx, doc); /* We may have a cid font already with width info in source font and no * cmap in the ft face */ - fw = pdf_add_cid_font_widths(ctx, doc, fontdesc, source_font); + fw = pdf_add_cid_font_widths(ctx, doc, fontdesc, font); /* And now the font */ fobj = pdf_new_dict(ctx, doc, 3); pdf_dict_put_drop(ctx, fobj, PDF_NAME_Type, PDF_NAME_Font); - pdf_dict_put_drop(ctx, fobj, PDF_NAME_BaseFont, pdf_new_name(ctx, doc, fontdesc->font->name)); + pdf_dict_put_drop(ctx, fobj, PDF_NAME_BaseFont, pdf_new_name(ctx, doc, font->name)); pdf_dict_put_drop(ctx, fobj, PDF_NAME_FontDescriptor, fdes_ref); if (fw != NULL) pdf_dict_put_drop(ctx, fobj, PDF_NAME_W, fw); - if (source_font != NULL && source_font->width_table != NULL) - pdf_dict_put_drop(ctx, fobj, PDF_NAME_DW, pdf_new_int(ctx, doc, source_font->width_default)); + if (font->width_table != NULL) + pdf_dict_put_drop(ctx, fobj, PDF_NAME_DW, pdf_new_int(ctx, doc, font->width_default)); if ((ps_name = FT_Get_Postscript_Name(face)) != NULL) pdf_dict_put_drop(ctx, fobj, PDF_NAME_BaseFont, pdf_new_string(ctx, doc, ps_name, strlen(ps_name))); switch (ft_kind(face)) @@ -2119,11 +2120,10 @@ pdf_add_cid_to_unicode(fz_context *ctx, pdf_document *doc, pdf_font_desc *fontde /* Creates CID font with Identity-H CMap and a ToUnicode CMap that is created by * using the TTF cmap table "backwards" to go from the GID to a Unicode value. - * If this is coming from a source file, we have source_font so that we can - * possibly get any width information that may have been embedded in the PDF - * W name tag (or W2 if vertical text) */ + * We can possibly get width information that may have been embedded in + * the PDF /W array (or W2 if vertical text) */ pdf_obj * -pdf_add_cid_font_res(fz_context *ctx, pdf_document *doc, fz_buffer *buffer, fz_font *source_font) +pdf_add_cid_font_res(fz_context *ctx, pdf_document *doc, fz_font *font) { pdf_obj *fobj = NULL; pdf_obj *fref = NULL; @@ -2131,11 +2131,11 @@ pdf_add_cid_font_res(fz_context *ctx, pdf_document *doc, fz_buffer *buffer, fz_f pdf_obj *obj_tounicode_ref = NULL; pdf_obj *obj_array = NULL; pdf_font_desc *fontdesc = NULL; - fz_font *font = NULL; FT_Face face; FT_Error fterr; int has_lock = 0; unsigned char digest[16]; + fz_buffer *buffer; fz_var(fobj); fz_var(fref); @@ -2146,16 +2146,20 @@ pdf_add_cid_font_res(fz_context *ctx, pdf_document *doc, fz_buffer *buffer, fz_f fz_var(obj_array); fz_var(has_lock); + if (font->t3procs) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot create font resource for Type3 font"); + + buffer = font->buffer; + fz_try(ctx) { /* Before we add this font as a resource check if the same font - * already exists in our resources for this doc. If yes, then + * already exists in our resources for this doc. If yes, then * hand back that reference */ - fref = pdf_find_resource(ctx, doc, doc->resources->font, buffer, digest); + fref = pdf_find_resource(ctx, doc, doc->resources->font, font->buffer, digest); if (fref == NULL) { /* Set up desc, width, and font file */ - font = fz_new_font_from_memory(ctx, NULL, buffer->data, buffer->len, 0, 1); fontdesc = pdf_new_font_desc(ctx); fontdesc->font = font; face = font->ft_face; @@ -2169,7 +2173,7 @@ pdf_add_cid_font_res(fz_context *ctx, pdf_document *doc, fz_buffer *buffer, fz_f has_lock = 0; /* Get the descendant font and the tounicode references */ - obj_desc_ref = pdf_add_descendant_font(ctx, doc, buffer, fontdesc, source_font); + obj_desc_ref = pdf_add_descendant_font(ctx, doc, fontdesc); obj_tounicode_ref = pdf_add_cid_to_unicode(ctx, doc, fontdesc); /* And now the font */ @@ -2211,7 +2215,7 @@ pdf_add_cid_font_res(fz_context *ctx, pdf_document *doc, fz_buffer *buffer, fz_f /* Creates simple font */ pdf_obj * -pdf_add_simple_font_res(fz_context *ctx, pdf_document *doc, fz_buffer *buffer) +pdf_add_simple_font_res(fz_context *ctx, pdf_document *doc, fz_font *font) { pdf_obj *fobj = NULL; pdf_obj *fref = NULL; @@ -2219,7 +2223,6 @@ pdf_add_simple_font_res(fz_context *ctx, pdf_document *doc, fz_buffer *buffer) pdf_obj *fdes_ref = NULL; pdf_obj *fwidth_ref = NULL; pdf_font_desc *fontdesc; - fz_font *font; FT_Face face; FT_Error fterr; const char *ps_name; @@ -2236,19 +2239,23 @@ pdf_add_simple_font_res(fz_context *ctx, pdf_document *doc, fz_buffer *buffer) fz_var(font); fz_var(has_lock); + if (font->t3procs) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot create font resource for Type3 font"); + fz_try(ctx) { /* Before we add this font as a resource check if the same font - * already exists in our resources for this doc. If yes, then + * already exists in our resources for this doc. If yes, then * hand back that reference */ - fref = pdf_find_resource(ctx, doc, doc->resources->font, buffer, digest); + fref = pdf_find_resource(ctx, doc, doc->resources->font, font->buffer, digest); if (fref == NULL) { /* Set up desc, width, and font file */ fobj = pdf_new_dict(ctx, doc, 3); - font = fz_new_font_from_memory(ctx, NULL, buffer->data, buffer->len, 0, 1); + // XXX bad idea font->width_count = 256; font->width_table = fz_calloc(ctx, font->width_count, sizeof(int)); + // XXX fontdesc = pdf_new_font_desc(ctx); fontdesc->font = font; face = font->ft_face; @@ -2263,7 +2270,7 @@ pdf_add_simple_font_res(fz_context *ctx, pdf_document *doc, fz_buffer *buffer) has_lock = 0; /* refs */ - fstr_ref = pdf_add_font_file(ctx, doc, buffer); + fstr_ref = pdf_add_font_file(ctx, doc, font->buffer); fdes_ref = pdf_add_font_descriptor(ctx, doc, fontdesc, fstr_ref); fwidth_ref = pdf_add_simple_font_widths(ctx, doc, fontdesc); diff --git a/source/tools/pdfcreate.c b/source/tools/pdfcreate.c index e36e0e68..70d0aa42 100644 --- a/source/tools/pdfcreate.c +++ b/source/tools/pdfcreate.c @@ -371,9 +371,12 @@ static int create_pdf(fz_context *ctx, char *output, resources fonts[], int num_ pch = strchr(content.fonts[k].name, ':'); if (pch != NULL) { + fz_font *font; im_font_buff = fz_read_file(ctx, &(pch[1])); - font_res = pdf_add_simple_font_res(ctx, pdf, im_font_buff); + font = fz_new_font_from_buffer(ctx, NULL, im_font_buff, 0, 0); + font_res = pdf_add_simple_font_res(ctx, pdf, font); fz_drop_buffer(ctx, im_font_buff); + fz_drop_font(ctx, font); im_font_buff = NULL; /* Look through our font page resources and update the indirect |