summaryrefslogtreecommitdiff
path: root/draw/draw_glyph.c
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2012-07-17 18:05:05 +0200
committerTor Andersson <tor.andersson@artifex.com>2012-07-17 18:05:05 +0200
commit4091b7a357728aed033216baafed540b795bcf9e (patch)
treead0cd73cc428bc8922d1eaa94663479c04192edb /draw/draw_glyph.c
parent2b857ab9878d5ca8acd862ae58dafa8d269bc502 (diff)
downloadmupdf-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.c44
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)
{