summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fitz/fitz.h12
-rw-r--r--fitz/res_font.c54
-rw-r--r--fitz/res_text.c2
-rw-r--r--pdf/pdf_font.c27
-rw-r--r--xps/xps_glyphs.c2
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)
{