summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2011-07-29 19:11:53 +0100
committerRobin Watts <Robin.Watts@artifex.com>2011-08-01 14:11:53 +0100
commit5a46065a0df691a79b75f5e61e34e344afd5349a (patch)
tree3a4f175c73fbb945a4df3d1abcd822a5571641b5
parent684cd3ebbbeaffbf416a09aad6af2cb160cec6bb (diff)
downloadmupdf-5a46065a0df691a79b75f5e61e34e344afd5349a.tar.xz
Add support for colored Type3 glyphs (ones that use d0).
Detect the d0 or d1 operators by writing a bit to the new device flags word. This can then be checked by the Type3 code to create the appropriate backing pixmap. In order to know what the appropriate backing pixmap is, we pass an additional colorspace into the glyph rendering code.
-rw-r--r--draw/draw_device.c18
-rw-r--r--draw/draw_glyph.c6
-rw-r--r--fitz/dev_null.c1
-rw-r--r--fitz/fitz.h10
-rw-r--r--fitz/res_font.c29
-rw-r--r--pdf/pdf_interpret.c2
6 files changed, 52 insertions, 14 deletions
diff --git a/draw/draw_device.c b/draw/draw_device.c
index 52393081..22cdc720 100644
--- a/draw/draw_device.c
+++ b/draw/draw_device.c
@@ -426,12 +426,20 @@ fz_draw_fill_text(void *user, fz_text *text, fz_matrix ctm,
trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX);
trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX);
- glyph = fz_render_glyph(dev->cache, text->font, gid, trm);
+ glyph = fz_render_glyph(dev->cache, text->font, gid, trm, model);
if (glyph)
{
- draw_glyph(colorbv, dev->dest, glyph, x, y, dev->scissor);
- if (dev->shape)
- draw_glyph(&shapebv, dev->shape, glyph, x, y, dev->scissor);
+ if (glyph->n == 1)
+ {
+ draw_glyph(colorbv, dev->dest, glyph, x, y, dev->scissor);
+ if (dev->shape)
+ draw_glyph(&shapebv, dev->shape, glyph, x, y, dev->scissor);
+ }
+ else
+ {
+ fz_matrix ctm = {glyph->w, 0.0, 0.0, glyph->h, x, y};
+ fz_paint_image(dev->dest, dev->scissor, dev->shape, glyph, ctm, alpha * 255);
+ }
fz_drop_pixmap(glyph);
}
}
@@ -570,7 +578,7 @@ fz_draw_clip_text(void *user, fz_text *text, fz_matrix ctm, int accumulate)
trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX);
trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX);
- glyph = fz_render_glyph(dev->cache, text->font, gid, trm);
+ glyph = fz_render_glyph(dev->cache, text->font, gid, trm, model);
if (glyph)
{
draw_glyph(NULL, mask, glyph, x, y, bbox);
diff --git a/draw/draw_glyph.c b/draw/draw_glyph.c
index 383c0d68..95f3955d 100644
--- a/draw/draw_glyph.c
+++ b/draw/draw_glyph.c
@@ -68,11 +68,11 @@ fz_render_stroked_glyph(fz_glyph_cache *cache, fz_font *font, int gid, fz_matrix
{
if (font->ft_face)
return fz_render_ft_stroked_glyph(font, gid, trm, ctm, stroke);
- return fz_render_glyph(cache, font, gid, trm);
+ return fz_render_glyph(cache, font, gid, trm, NULL);
}
fz_pixmap *
-fz_render_glyph(fz_glyph_cache *cache, fz_font *font, int gid, fz_matrix ctm)
+fz_render_glyph(fz_glyph_cache *cache, fz_font *font, int gid, fz_matrix ctm, fz_colorspace *model)
{
fz_glyph_key key;
fz_pixmap *val;
@@ -108,7 +108,7 @@ fz_render_glyph(fz_glyph_cache *cache, fz_font *font, int gid, fz_matrix ctm)
}
else if (font->t3procs)
{
- val = fz_render_t3_glyph(font, gid, ctm);
+ val = fz_render_t3_glyph(font, gid, ctm, model);
}
else
{
diff --git a/fitz/dev_null.c b/fitz/dev_null.c
index 4d40ef73..508be7e0 100644
--- a/fitz/dev_null.c
+++ b/fitz/dev_null.c
@@ -6,6 +6,7 @@ fz_new_device(void *user)
fz_device *dev = fz_malloc(sizeof(fz_device));
memset(dev, 0, sizeof(fz_device));
dev->hints = 0;
+ dev->flags = 0;
dev->user = user;
return dev;
}
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 7fe8b297..cee62bc8 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -909,9 +909,9 @@ typedef struct fz_glyph_cache_s fz_glyph_cache;
fz_glyph_cache *fz_new_glyph_cache(void);
fz_pixmap *fz_render_ft_glyph(fz_font *font, int cid, fz_matrix trm);
-fz_pixmap *fz_render_t3_glyph(fz_font *font, int cid, fz_matrix trm);
+fz_pixmap *fz_render_t3_glyph(fz_font *font, int cid, fz_matrix trm, fz_colorspace *model);
fz_pixmap *fz_render_ft_stroked_glyph(fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *state);
-fz_pixmap *fz_render_glyph(fz_glyph_cache*, fz_font*, int, fz_matrix);
+fz_pixmap *fz_render_glyph(fz_glyph_cache*, fz_font*, int, fz_matrix, fz_colorspace *model);
fz_pixmap *fz_render_stroked_glyph(fz_glyph_cache*, fz_font*, int, fz_matrix, fz_matrix, fz_stroke_state *stroke);
void fz_free_glyph_cache(fz_glyph_cache *);
@@ -944,8 +944,13 @@ void fz_flatten_dash_path(fz_gel *gel, fz_path *path, fz_stroke_state *stroke, f
enum
{
+ /* Hints */
FZ_IGNORE_IMAGE = 1,
FZ_IGNORE_SHADE = 2,
+
+ /* Flags */
+ FZ_CHARPROC_MASK = 1,
+ FZ_CHARPROC_COLOR = 2,
};
typedef struct fz_device_s fz_device;
@@ -953,6 +958,7 @@ typedef struct fz_device_s fz_device;
struct fz_device_s
{
int hints;
+ int flags;
void *user;
void (*free_user)(void *);
diff --git a/fitz/res_font.c b/fitz/res_font.c
index e5027d5b..17646ea3 100644
--- a/fitz/res_font.c
+++ b/fitz/res_font.c
@@ -512,7 +512,7 @@ fz_new_type3_font(char *name, fz_matrix matrix)
}
fz_pixmap *
-fz_render_t3_glyph(fz_font *font, int gid, fz_matrix trm)
+fz_render_t3_glyph(fz_font *font, int gid, fz_matrix trm, fz_colorspace *model)
{
fz_error error;
fz_matrix ctm;
@@ -535,6 +535,22 @@ fz_render_t3_glyph(fz_font *font, int gid, fz_matrix trm)
error = font->t3run(font->t3xref, font->t3resources, contents, dev, ctm);
if (error)
fz_catch(error, "cannot draw type3 glyph");
+ if (dev->flags & FZ_CHARPROC_MASK)
+ {
+ if (dev->flags & FZ_CHARPROC_COLOR)
+ fz_warn("type3 glyph claims to be both masked and colored");
+ model = NULL;
+ }
+ else if (dev->flags & FZ_CHARPROC_COLOR)
+ {
+ if (model == NULL)
+ fz_warn("colored type3 glyph wanted in masked context");
+ }
+ else
+ {
+ fz_warn("type3 glyph doesn't specify masked or colored");
+ model = NULL; /* Treat as masked */
+ }
fz_free_device(dev);
bbox.x0--;
@@ -542,7 +558,7 @@ fz_render_t3_glyph(fz_font *font, int gid, fz_matrix trm)
bbox.x1++;
bbox.y1++;
- glyph = fz_new_pixmap_with_rect(fz_device_gray, bbox);
+ glyph = fz_new_pixmap_with_rect((model ? model : fz_device_gray), bbox);
fz_clear_pixmap(glyph);
cache = fz_new_glyph_cache();
@@ -553,8 +569,13 @@ fz_render_t3_glyph(fz_font *font, int gid, fz_matrix trm)
fz_free_device(dev);
fz_free_glyph_cache(cache);
- result = fz_alpha_from_gray(glyph, 0);
- fz_drop_pixmap(glyph);
+ if (model == NULL)
+ {
+ result = fz_alpha_from_gray(glyph, 0);
+ fz_drop_pixmap(glyph);
+ }
+ else
+ result = glyph;
return result;
}
diff --git a/pdf/pdf_interpret.c b/pdf/pdf_interpret.c
index 8dcd4f80..f10f6c83 100644
--- a/pdf/pdf_interpret.c
+++ b/pdf/pdf_interpret.c
@@ -1776,10 +1776,12 @@ static void pdf_run_d(pdf_csi *csi)
static void pdf_run_d0(pdf_csi *csi)
{
+ csi->dev->flags |= FZ_CHARPROC_COLOR;
}
static void pdf_run_d1(pdf_csi *csi)
{
+ csi->dev->flags |= FZ_CHARPROC_MASK;
}
static void pdf_run_f(pdf_csi *csi)