diff options
-rw-r--r-- | include/mupdf/fitz/font.h | 6 | ||||
-rw-r--r-- | source/fitz/font.c | 40 |
2 files changed, 33 insertions, 13 deletions
diff --git a/include/mupdf/fitz/font.h b/include/mupdf/fitz/font.h index 1e053470..21794d59 100644 --- a/include/mupdf/fitz/font.h +++ b/include/mupdf/fitz/font.h @@ -52,11 +52,15 @@ struct fz_font_s fz_rect bbox; /* font bbox is used only for t3 fonts */ + int glyph_count; + /* per glyph bounding box cache */ int use_glyph_bbox; - int bbox_count; fz_rect *bbox_table; + /* cached glyph metrics */ + float *advance_table; + /* substitute metrics */ int width_count; short width_default; /* in 1000 units */ diff --git a/source/fitz/font.c b/source/fitz/font.c index 75aa62c9..6a1e9232 100644 --- a/source/fitz/font.c +++ b/source/fitz/font.c @@ -6,6 +6,7 @@ #include FT_STROKER_H #define MAX_BBOX_TABLE_SIZE 4096 +#define MAX_ADVANCE_TABLE_SIZE 4096 /* 20 degrees */ #define SHEAR 0.36397f @@ -52,7 +53,7 @@ fz_new_font(fz_context *ctx, const char *name, int use_glyph_bbox, int glyph_cou font->use_glyph_bbox = use_glyph_bbox; if (use_glyph_bbox && glyph_count <= MAX_BBOX_TABLE_SIZE) { - font->bbox_count = glyph_count; + font->glyph_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; @@ -61,7 +62,7 @@ fz_new_font(fz_context *ctx, const char *name, int use_glyph_bbox, int glyph_cou { if (use_glyph_bbox) fz_warn(ctx, "not building glyph bbox table for font '%s' with %d glyphs", font->name, glyph_count); - font->bbox_count = 0; + font->glyph_count = 0; font->bbox_table = NULL; } @@ -1046,7 +1047,7 @@ fz_prepare_t3_glyph(fz_context *ctx, fz_font *font, int gid, int nested_depth) if (dev->flags & FZ_DEVFLAG_BBOX_DEFINED) { assert(font->bbox_table != NULL); - assert(font->bbox_count > gid); + assert(font->glyph_count > gid); font->bbox_table[gid] = dev->d1_rect; fz_transform_rect(&font->bbox_table[gid], &font->t3matrix); } @@ -1247,7 +1248,7 @@ fz_print_font(fz_context *ctx, fz_output *out, fz_font *font) fz_rect * fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, fz_rect *rect) { - if (font->bbox_table && gid < font->bbox_count) + if (font->bbox_table && gid < font->glyph_count) { if (fz_is_infinite_rect(&font->bbox_table[gid])) { @@ -1279,7 +1280,7 @@ fz_outline_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *ctm) int fz_glyph_cacheable(fz_context *ctx, fz_font *font, int gid) { - if (!font->t3procs || !font->t3flags || gid < 0 || gid >= font->bbox_count) + if (!font->t3procs || !font->t3flags || gid < 0 || gid >= font->glyph_count) return 1; return (font->t3flags[gid] & FZ_DEVFLAG_UNCACHEABLE) == 0; } @@ -1290,13 +1291,6 @@ fz_advance_ft_glyph(fz_context *ctx, fz_font *font, int gid) FT_Fixed adv; int mask; - if (font->width_table) - { - if (gid < font->width_count) - return font->width_table[gid] / 1000.0f; - return font->width_default / 1000.0f; - } - mask = FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_IGNORE_TRANSFORM; /* if (font->wmode) mask |= FT_LOAD_VERTICAL_LAYOUT; */ @@ -1318,7 +1312,29 @@ float fz_advance_glyph(fz_context *ctx, fz_font *font, int gid) { if (font->ft_face) + { + if (font->width_table) + { + if (gid < font->width_count) + return font->width_table[gid] / 1000.0f; + return font->width_default / 1000.0f; + } + + if (gid >= 0 && gid < font->glyph_count && font->glyph_count < MAX_ADVANCE_TABLE_SIZE) + { + if (!font->advance_table) + { + int i; + font->advance_table = fz_malloc_array(ctx, font->glyph_count, sizeof(float)); + for (i = 0; i < font->glyph_count; ++i) + font->advance_table[i] = -1; + } + if (font->advance_table[gid] == -1) + font->advance_table[gid] = fz_advance_ft_glyph(ctx, font, gid); + return font->advance_table[gid]; + } return fz_advance_ft_glyph(ctx, font, gid); + } if (font->t3procs) return fz_advance_t3_glyph(ctx, font, gid); return 0; |