diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2012-01-11 22:08:28 +0100 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2012-01-11 22:08:28 +0100 |
commit | 96b8920028fe35eefd8ea63ef8ca3fca70997fe8 (patch) | |
tree | 73eaf2b64f645582850e7deba18033fc49c613a9 | |
parent | 177346693da57e72d1e6c01edbdf7ce75e010a3f (diff) | |
download | mupdf-96b8920028fe35eefd8ea63ef8ca3fca70997fe8.tar.xz |
Add glyph bbox cache.
-rw-r--r-- | fitz/fitz.h | 12 | ||||
-rw-r--r-- | fitz/res_font.c | 54 | ||||
-rw-r--r-- | fitz/res_text.c | 2 | ||||
-rw-r--r-- | pdf/pdf_font.c | 27 | ||||
-rw-r--r-- | xps/xps_glyphs.c | 2 |
5 files changed, 65 insertions, 32 deletions
diff --git a/fitz/fitz.h b/fitz/fitz.h index ddaa6fe3..889ba5e2 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -1044,8 +1044,14 @@ struct fz_font_s fz_rect bbox; /* font bbox is used only for t3 fonts */ + /* per glyph bounding box cache */ + int use_glyph_bbox; + int bbox_count; + fz_rect *bbox_table; + + /* substitute metrics */ int width_count; - int *width_table; /* substitute metrics */ + int *width_table; // in 1000 units }; void fz_new_font_context(fz_context *ctx); @@ -1053,8 +1059,8 @@ void fz_free_font_context(fz_context *ctx); fz_font *fz_new_type3_font(fz_context *ctx, char *name, fz_matrix matrix); -fz_font *fz_new_font_from_memory(fz_context *ctx, unsigned char *data, int len, int index); -fz_font *fz_new_font_from_file(fz_context *ctx, char *path, int index); +fz_font *fz_new_font_from_memory(fz_context *ctx, unsigned char *data, int len, int index, int use_glyph_bbox); +fz_font *fz_new_font_from_file(fz_context *ctx, char *path, int index, int use_glyph_bbox); fz_font *fz_keep_font(fz_font *font); void fz_drop_font(fz_context *ctx, fz_font *font); diff --git a/fitz/res_font.c b/fitz/res_font.c index b224e7ac..79faa004 100644 --- a/fitz/res_font.c +++ b/fitz/res_font.c @@ -4,12 +4,15 @@ #include FT_FREETYPE_H #include FT_STROKER_H +#define MAX_BBOX_TABLE_SIZE 4096 + static void fz_finalize_freetype(fz_context *ctx); static fz_font * -fz_new_font(fz_context *ctx, char *name) +fz_new_font(fz_context *ctx, char *name, int use_glyph_bbox, int glyph_count) { fz_font *font; + int i; font = fz_malloc_struct(ctx, fz_font); font->refs = 1; @@ -41,6 +44,22 @@ fz_new_font(fz_context *ctx, char *name) font->bbox.x1 = 1; font->bbox.y1 = 1; + font->use_glyph_bbox = use_glyph_bbox; + if (use_glyph_bbox && glyph_count <= MAX_BBOX_TABLE_SIZE) + { + font->bbox_count = glyph_count; + font->bbox_table = fz_malloc_array(ctx, glyph_count, sizeof(fz_rect)); + for (i = 0; i < glyph_count; i++) + font->bbox_table[i] = fz_infinite_rect; + } + else + { + if (use_glyph_bbox) + fz_warn(ctx, "not building glyph bbox table for font '%s' with %d glyphs", name, glyph_count); + font->bbox_count = 0; + font->bbox_table = NULL; + } + font->width_count = 0; font->width_table = NULL; @@ -199,7 +218,7 @@ fz_finalize_freetype(fz_context *ctx) } fz_font * -fz_new_font_from_file(fz_context *ctx, char *path, int index) +fz_new_font_from_file(fz_context *ctx, char *path, int index, int use_glyph_bbox) { FT_Face face; fz_font *font; @@ -214,7 +233,7 @@ fz_new_font_from_file(fz_context *ctx, char *path, int index) fz_throw(ctx, "freetype: cannot load font: %s", ft_error_string(fterr)); } - font = fz_new_font(ctx, face->family_name); + font = fz_new_font(ctx, face->family_name, use_glyph_bbox, face->num_glyphs); font->ft_face = face; font->bbox.x0 = (float) face->bbox.xMin / face->units_per_EM; font->bbox.y0 = (float) face->bbox.yMin / face->units_per_EM; @@ -225,7 +244,7 @@ fz_new_font_from_file(fz_context *ctx, char *path, int index) } fz_font * -fz_new_font_from_memory(fz_context *ctx, unsigned char *data, int len, int index) +fz_new_font_from_memory(fz_context *ctx, unsigned char *data, int len, int index, int use_glyph_bbox) { FT_Face face; fz_font *font; @@ -240,7 +259,7 @@ fz_new_font_from_memory(fz_context *ctx, unsigned char *data, int len, int index fz_throw(ctx, "freetype: cannot load font: %s", ft_error_string(fterr)); } - font = fz_new_font(ctx, face->family_name); + font = fz_new_font(ctx, face->family_name, use_glyph_bbox, face->num_glyphs); font->ft_face = face; font->bbox.x0 = (float) face->bbox.xMin / face->units_per_EM; font->bbox.y0 = (float) face->bbox.yMin / face->units_per_EM; @@ -514,7 +533,6 @@ fz_bound_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm) FT_Vector v; fz_rect bounds; - // TODO: stroke state // TODO: refactor loading into fz_load_ft_glyph // TODO: cache results @@ -576,7 +594,7 @@ fz_new_type3_font(fz_context *ctx, char *name, fz_matrix matrix) fz_font *font; int i; - font = fz_new_font(ctx, name); + font = fz_new_font(ctx, name, 1, 256); font->t3procs = fz_malloc_array(ctx, 256, sizeof(fz_buffer*)); font->t3widths = fz_malloc_array(ctx, 256, sizeof(float)); @@ -593,6 +611,7 @@ fz_new_type3_font(fz_context *ctx, char *name, fz_matrix matrix) static fz_rect fz_bound_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm) { + // TODO: run through bbox device here and set d0/d1 flags trm = fz_concat(font->t3matrix, trm); return fz_transform_rect(trm, font->bbox); } @@ -694,9 +713,20 @@ fz_debug_font(fz_font *font) fz_rect fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm) { - if (font->ft_face) - return fz_bound_ft_glyph(ctx, font, gid, trm); - if (font->t3procs) - return fz_bound_t3_glyph(ctx, font, gid, trm); - return fz_empty_rect; + if (font->bbox_table && gid < font->bbox_count) + { + if (fz_is_infinite_rect(font->bbox_table[gid])) + { + if (font->ft_face) + font->bbox_table[gid] = fz_bound_ft_glyph(ctx, font, gid, fz_identity); + else if (font->t3procs) + font->bbox_table[gid] = fz_bound_t3_glyph(ctx, font, gid, fz_identity); + else + font->bbox_table[gid] = fz_empty_rect; + } + return fz_transform_rect(trm, font->bbox_table[gid]); + } + + /* fall back to font bbox */ + return fz_transform_rect(trm, font->bbox); } diff --git a/fitz/res_text.c b/fitz/res_text.c index 79a07e86..cc43b261 100644 --- a/fitz/res_text.c +++ b/fitz/res_text.c @@ -63,6 +63,8 @@ fz_bound_text(fz_context *ctx, fz_text *text, fz_matrix ctm) if (text->len == 0) return fz_empty_rect; + // TODO: stroke state + tm = text->trm; tm.e = text->items[0].x; diff --git a/pdf/pdf_font.c b/pdf/pdf_font.c index 76d4632a..a04e6b56 100644 --- a/pdf/pdf_font.c +++ b/pdf/pdf_font.c @@ -180,7 +180,7 @@ pdf_load_builtin_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname) if (!data) fz_throw(ctx, "cannot find builtin font: '%s'", fontname); - fontdesc->font = fz_new_font_from_memory(ctx, data, len, 0); + fontdesc->font = fz_new_font_from_memory(ctx, data, len, 0, 1); /* RJW: "cannot load freetype font from memory" */ if (!strcmp(fontname, "Symbol") || !strcmp(fontname, "ZapfDingbats")) @@ -197,7 +197,7 @@ pdf_load_substitute_font(fz_context *ctx, pdf_font_desc *fontdesc, int mono, int if (!data) fz_throw(ctx, "cannot find substitute font"); - fontdesc->font = fz_new_font_from_memory(ctx, data, len, 0); + fontdesc->font = fz_new_font_from_memory(ctx, data, len, 0, 1); /* RJW: "cannot load freetype font from memory" */ fontdesc->font->ft_substitute = 1; @@ -215,7 +215,8 @@ pdf_load_substitute_cjk_font(fz_context *ctx, pdf_font_desc *fontdesc, int ros, if (!data) fz_throw(ctx, "cannot find builtin CJK font"); - fontdesc->font = fz_new_font_from_memory(ctx, data, len, 0); + /* a glyph bbox cache is too big for droid sans fallback (51k glyphs!) */ + fontdesc->font = fz_new_font_from_memory(ctx, data, len, 0, 0); /* RJW: "cannot load builtin CJK font" */ fontdesc->font->ft_substitute = 1; @@ -281,7 +282,7 @@ pdf_load_embedded_font(pdf_font_desc *fontdesc, pdf_xref *xref, fz_obj *stmref) fz_try(ctx) { - fontdesc->font = fz_new_font_from_memory(ctx, buf->data, buf->len, 0); + fontdesc->font = fz_new_font_from_memory(ctx, buf->data, buf->len, 0, 1); } fz_catch(ctx) { @@ -1031,10 +1032,12 @@ pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_xref *xref, fz_obj *dict, } } -static int -pdf_count_font_glyphs(fz_context *ctx, pdf_font_desc *fontdesc) +static void +pdf_make_width_table(fz_context *ctx, pdf_font_desc *fontdesc) { + fz_font *font = fontdesc->font; int i, k, n, cid, gid; + n = 0; for (i = 0; i < fontdesc->hmtx_len; i++) { @@ -1045,17 +1048,9 @@ pdf_count_font_glyphs(fz_context *ctx, pdf_font_desc *fontdesc) if (gid > n) n = gid; } - } - return n + 1; -} - -static void -pdf_make_width_table(fz_context *ctx, pdf_font_desc *fontdesc) -{ - fz_font *font = fontdesc->font; - int i, k, cid, gid; + }; - font->width_count = pdf_count_font_glyphs(ctx, fontdesc); + font->width_count = n + 1; font->width_table = fz_malloc_array(ctx, font->width_count, sizeof(int)); fontdesc->size += font->width_count * sizeof(int); diff --git a/xps/xps_glyphs.c b/xps/xps_glyphs.c index 51cdaa77..8b88c4d0 100644 --- a/xps/xps_glyphs.c +++ b/xps/xps_glyphs.c @@ -501,7 +501,7 @@ xps_parse_glyphs(xps_document *doc, fz_matrix ctm, fz_try(doc->ctx) { - font = fz_new_font_from_memory(doc->ctx, part->data, part->size, subfontid); + font = fz_new_font_from_memory(doc->ctx, part->data, part->size, subfontid, 1); } fz_catch(doc->ctx) { |