diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2012-07-17 18:05:05 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2012-07-17 18:05:05 +0200 |
commit | 4091b7a357728aed033216baafed540b795bcf9e (patch) | |
tree | ad0cd73cc428bc8922d1eaa94663479c04192edb /draw/draw_glyph.c | |
parent | 2b857ab9878d5ca8acd862ae58dafa8d269bc502 (diff) | |
download | mupdf-4091b7a357728aed033216baafed540b795bcf9e.tar.xz |
Handle glyphs that are too large to render as pixmaps.
Diffstat (limited to 'draw/draw_glyph.c')
-rw-r--r-- | draw/draw_glyph.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/draw/draw_glyph.c b/draw/draw_glyph.c index cef9d7fa..e7e7f03a 100644 --- a/draw/draw_glyph.c +++ b/draw/draw_glyph.c @@ -1,6 +1,5 @@ #include "fitz-internal.h" -#define MAX_FONT_SIZE 1000 #define MAX_GLYPH_SIZE 256 #define MAX_CACHE_SIZE (1024*1024) @@ -96,29 +95,44 @@ fz_keep_glyph_cache(fz_context *ctx) } fz_pixmap * -fz_render_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *stroke) +fz_render_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *stroke, fz_bbox scissor) { if (font->ft_face) return fz_render_ft_stroked_glyph(ctx, font, gid, trm, ctm, stroke); - return fz_render_glyph(ctx, font, gid, trm, NULL); + return fz_render_glyph(ctx, font, gid, trm, NULL, scissor); } +/* + Render a glyph and return a bitmap. + If the glyph is too large to fit the cache we have two choices: + 1) Return NULL so the caller can draw the glyph using an outline. + Only supported for freetype fonts. + 2) Render a clipped glyph by using the scissor rectangle. + Only supported for type 3 fonts. + This must not be inserted into the cache. + */ fz_pixmap * -fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_colorspace *model) +fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_colorspace *model, fz_bbox scissor) { fz_glyph_cache *cache; fz_glyph_key key; fz_pixmap *val; float size = fz_matrix_expansion(ctm); + int do_cache; - cache = ctx->glyph_cache; - - if (size > MAX_FONT_SIZE) + if (size <= MAX_GLYPH_SIZE) { - /* TODO: this case should be handled by rendering glyph as a path fill */ - fz_warn(ctx, "font size too large (%g), not rendering glyph", size); - return NULL; + scissor = fz_infinite_bbox; + do_cache = 1; } + else + { + if (font->ft_face) + return NULL; + do_cache = 0; + } + + cache = ctx->glyph_cache; memset(&key, 0, sizeof key); key.font = font; @@ -131,6 +145,9 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_color key.f = (ctm.f - floorf(ctm.f)) * 256; key.aa = fz_aa_level(ctx); + ctm.e = floorf(ctm.e) + key.e / 256.0f; + ctm.f = floorf(ctm.f) + key.f / 256.0f; + fz_lock(ctx, FZ_LOCK_GLYPHCACHE); val = fz_hash_find(ctx, cache->hash, &key); if (val) @@ -140,9 +157,6 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_color return val; } - ctm.e = floorf(ctm.e) + key.e / 256.0f; - ctm.f = floorf(ctm.f) + key.f / 256.0f; - fz_try(ctx) { if (font->ft_face) @@ -161,7 +175,7 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_color * abandon ours, and use the one there already. */ fz_unlock(ctx, FZ_LOCK_GLYPHCACHE); - val = fz_render_t3_glyph(ctx, font, gid, ctm, model); + val = fz_render_t3_glyph(ctx, font, gid, ctm, model, scissor); fz_lock(ctx, FZ_LOCK_GLYPHCACHE); } else @@ -176,7 +190,7 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_color fz_rethrow(ctx); } - if (val) + if (val && do_cache) { if (val->w < MAX_GLYPH_SIZE && val->h < MAX_GLYPH_SIZE) { |