summaryrefslogtreecommitdiff
path: root/source/fitz/draw-device.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2013-08-23 19:24:58 +0100
committerRobin Watts <robin.watts@artifex.com>2013-08-30 16:26:39 +0100
commit2b2c67836932b1dada7f7f28e42fe4ed06c4e4ed (patch)
treebed929cca0ac26018ffbc9c98cf177da63562536 /source/fitz/draw-device.c
parent8f248600b2834fb121db4990aa756c40da8ddd0e (diff)
downloadmupdf-2b2c67836932b1dada7f7f28e42fe4ed06c4e4ed.tar.xz
Use RLE coding scheme for glyph bitmaps.
Rather than generating fz_pixmaps for glyphs, we generate fz_glyphs. fz_glyphs can either contain a pixmap, or an RLEd representation (if it's a mask, and it's smaller). Should take less memory in the cache, and should be faster to plot.
Diffstat (limited to 'source/fitz/draw-device.c')
-rw-r--r--source/fitz/draw-device.c61
1 files changed, 37 insertions, 24 deletions
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c
index 00b95e75..1cb76ae8 100644
--- a/source/fitz/draw-device.c
+++ b/source/fitz/draw-device.c
@@ -467,15 +467,18 @@ fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, const fz_rect *rect, fz
}
}
+
static void
-draw_glyph(unsigned char *colorbv, fz_pixmap *dst, fz_pixmap *msk,
+draw_glyph(unsigned char *colorbv, fz_pixmap *dst, fz_glyph *glyph,
int xorig, int yorig, const fz_irect *scissor)
{
- unsigned char *dp, *mp;
+ unsigned char *dp;
fz_irect bbox, bbox2;
int x, y, w, h;
+ int skip_x, skip_y;
+ fz_pixmap *msk;
- fz_pixmap_bbox_no_ctx(msk, &bbox);
+ fz_glyph_bbox_no_ctx(glyph, &bbox);
fz_translate_irect(&bbox, xorig, yorig);
fz_intersect_irect(&bbox, scissor); /* scissor < dst */
@@ -487,19 +490,28 @@ draw_glyph(unsigned char *colorbv, fz_pixmap *dst, fz_pixmap *msk,
w = bbox.x1 - bbox.x0;
h = bbox.y1 - bbox.y0;
- mp = msk->samples + (unsigned int)((y - msk->y - yorig) * msk->w + (x - msk->x - xorig));
- dp = dst->samples + (unsigned int)(((y - dst->y) * dst->w + (x - dst->x)) * dst->n);
+ skip_x = x - glyph->x - xorig;
+ skip_y = y - glyph->y - yorig;
- assert(msk->n == 1);
+ dp = dst->samples + (unsigned int)(((y - dst->y) * dst->w + (x - dst->x)) * dst->n);
- while (h--)
+ msk = glyph->pixmap;
+ if (msk == NULL)
{
- if (dst->colorspace)
- fz_paint_span_with_color(dp, mp, dst->n, w, colorbv);
- else
- fz_paint_span(dp, mp, 1, w, 255);
- dp += dst->w * dst->n;
- mp += msk->w;
+ fz_paint_glyph(colorbv, dst, dp, glyph, w, h, skip_x, skip_y);
+ }
+ else
+ {
+ unsigned char *mp = msk->samples + skip_y * msk->w + skip_x;
+ while (h--)
+ {
+ if (dst->colorspace)
+ fz_paint_span_with_color(dp, mp, dst->n, w, colorbv);
+ else
+ fz_paint_span(dp, mp, 1, w, 255);
+ dp += dst->w * dst->n;
+ mp += msk->w;
+ }
}
}
@@ -512,7 +524,7 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, const fz_matrix *ctm,
unsigned char shapebv;
float colorfv[FZ_MAX_COLORS];
fz_matrix tm, trm, trunc_trm;
- fz_pixmap *glyph;
+ fz_glyph *glyph;
int i, x, y, gid;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model = state->dest->colorspace;
@@ -553,7 +565,8 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, const fz_matrix *ctm,
glyph = fz_render_glyph(dev->ctx, text->font, gid, &trunc_trm, model, scissor);
if (glyph)
{
- if (glyph->n == 1)
+ fz_pixmap *pixmap = glyph->pixmap;
+ if (pixmap == NULL || pixmap->n == 1)
{
draw_glyph(colorbv, state->dest, glyph, x, y, &state->scissor);
if (state->shape)
@@ -561,10 +574,10 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, const fz_matrix *ctm,
}
else
{
- fz_matrix mat = {glyph->w, 0.0, 0.0, glyph->h, x + glyph->x, y + glyph->y};
- fz_paint_image(state->dest, &state->scissor, state->shape, glyph, &mat, alpha * 255);
+ fz_matrix mat = {pixmap->w, 0.0, 0.0, pixmap->h, x + pixmap->x, y + pixmap->y};
+ fz_paint_image(state->dest, &state->scissor, state->shape, pixmap, &mat, alpha * 255);
}
- fz_drop_pixmap(dev->ctx, glyph);
+ fz_drop_glyph(dev->ctx, glyph);
}
else
{
@@ -594,7 +607,7 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke,
unsigned char colorbv[FZ_MAX_COLORS + 1];
float colorfv[FZ_MAX_COLORS];
fz_matrix tm, trm, trunc_trm;
- fz_pixmap *glyph;
+ fz_glyph *glyph;
int i, x, y, gid;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model = state->dest->colorspace;
@@ -637,7 +650,7 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke,
draw_glyph(colorbv, state->dest, glyph, x, y, &state->scissor);
if (state->shape)
draw_glyph(colorbv, state->shape, glyph, x, y, &state->scissor);
- fz_drop_pixmap(dev->ctx, glyph);
+ fz_drop_glyph(dev->ctx, glyph);
}
else
{
@@ -666,7 +679,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu
fz_irect bbox;
fz_pixmap *mask, *dest, *shape;
fz_matrix tm, trm, trunc_trm;
- fz_pixmap *glyph;
+ fz_glyph *glyph;
int i, x, y, gid;
fz_draw_state *state;
fz_colorspace *model;
@@ -755,7 +768,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu
draw_glyph(NULL, mask, glyph, x, y, &bbox);
if (state[1].shape)
draw_glyph(NULL, state[1].shape, glyph, x, y, &bbox);
- fz_drop_pixmap(dev->ctx, glyph);
+ fz_drop_glyph(dev->ctx, glyph);
}
else
{
@@ -808,7 +821,7 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke
fz_irect bbox;
fz_pixmap *mask, *dest, *shape;
fz_matrix tm, trm, trunc_trm;
- fz_pixmap *glyph;
+ fz_glyph *glyph;
int i, x, y, gid;
fz_draw_state *state = push_stack(dev);
fz_colorspace *model = state->dest->colorspace;
@@ -870,7 +883,7 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke
draw_glyph(NULL, mask, glyph, x, y, &bbox);
if (shape)
draw_glyph(NULL, shape, glyph, x, y, &bbox);
- fz_drop_pixmap(dev->ctx, glyph);
+ fz_drop_glyph(dev->ctx, glyph);
}
else
{