diff options
author | Robin Watts <robin.watts@artifex.com> | 2013-08-28 15:18:37 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2013-09-02 11:40:13 +0100 |
commit | da277059b37380d57028ff79a636f4d725c96e8f (patch) | |
tree | 21140720e22a819b863a64160fca6a4dec2be714 /source/fitz/draw-device.c | |
parent | 2b2c67836932b1dada7f7f28e42fe4ed06c4e4ed (diff) | |
download | mupdf-da277059b37380d57028ff79a636f4d725c96e8f.tar.xz |
Be smarter when quantising sub pixel positions for glyphs.
For large glyphs, sub pixel positioning is supremely unimportant.
Even for smaller glyphs, we don't need 5*5 possible sub pixel
positions. Base the degree of sub pixel quantisation on the size
of the glyphs.
This should result in better cache use.
We push all the glyph sub positioning logic into fz_render_glyph
(and fz_render_stroked_glyph). This simplifies the calling code.
We also tweak fz_render_glyph so that it updates the transform it
is called with to reflect the sub pixel positioning. This solves
various problems: Firstly, we can round positions both up and down
to achieve a smaller net displacement (e.g. (0.99, 0.99) can go
to (1,1) rather than (0.75, 0.75) if we have a subpixel position
resolution of 1/4 pixels).
Secondly, glyphs that are drawn from outlines will have exactly the
same subpixel changes applied. This is unlikely to be noticable, but
it does mean that baselines should avoid having any shifts in them.
Finally, it enables us to avoid lots of unnecessary copying of
matrices, hopefully reducing overhead.
Diffstat (limited to 'source/fitz/draw-device.c')
-rw-r--r-- | source/fitz/draw-device.c | 86 |
1 files changed, 21 insertions, 65 deletions
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index 1cb76ae8..79886405 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -1,10 +1,6 @@ #include "mupdf/fitz.h" #include "draw-imp.h" -#define QUANT(x,a) (((int)((x) * (a))) / (a)) -#define HSUBPIX 5.0 -#define VSUBPIX 5.0 - #define STACK_SIZE 96 /* Enable the following to attempt to support knockout and/or isolated @@ -523,12 +519,11 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, unsigned char colorbv[FZ_MAX_COLORS + 1]; unsigned char shapebv; float colorfv[FZ_MAX_COLORS]; - fz_matrix tm, trm, trunc_trm; + fz_matrix tm, trm; fz_glyph *glyph; - int i, x, y, gid; + int i, gid; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; - fz_irect scissor; if (state->blendmode & FZ_BLEND_KNOCKOUT) state = fz_knockout_begin(dev); @@ -550,22 +545,13 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, tm.e = text->items[i].x; tm.f = text->items[i].y; fz_concat(&trm, &tm, ctm); - x = floorf(trm.e); - y = floorf(trm.f); - - trunc_trm = trm; - trunc_trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX); - trunc_trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX); - scissor.x0 = state->scissor.x0 - x; - scissor.y0 = state->scissor.y0 - y; - scissor.x1 = state->scissor.x1 - x; - scissor.y1 = state->scissor.y1 - y; - - glyph = fz_render_glyph(dev->ctx, text->font, gid, &trunc_trm, model, scissor); + glyph = fz_render_glyph(dev->ctx, text->font, gid, &trm, model, &state->scissor); if (glyph) { fz_pixmap *pixmap = glyph->pixmap; + int x = (int)trm.e; + int y = (int)trm.f; if (pixmap == NULL || pixmap->n == 1) { draw_glyph(colorbv, state->dest, glyph, x, y, &state->scissor); @@ -606,12 +592,11 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, fz_draw_device *dev = devp->user; unsigned char colorbv[FZ_MAX_COLORS + 1]; float colorfv[FZ_MAX_COLORS]; - fz_matrix tm, trm, trunc_trm; + fz_matrix tm, trm; fz_glyph *glyph; - int i, x, y, gid; + int i, gid; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; - fz_irect scissor; if (state->blendmode & FZ_BLEND_KNOCKOUT) state = fz_knockout_begin(dev); @@ -632,21 +617,12 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, tm.e = text->items[i].x; tm.f = text->items[i].y; fz_concat(&trm, &tm, ctm); - x = floorf(trm.e); - y = floorf(trm.f); - - trunc_trm = trm; - trunc_trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX); - trunc_trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX); - scissor.x0 = state->scissor.x0 - x; - scissor.y0 = state->scissor.y0 - y; - scissor.x1 = state->scissor.x1 - x; - scissor.y1 = state->scissor.y1 - y; - - glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, &trunc_trm, ctm, stroke, scissor); + glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, &trm, ctm, stroke, &state->scissor); if (glyph) { + int x = (int)trm.e; + int y = (int)trm.f; draw_glyph(colorbv, state->dest, glyph, x, y, &state->scissor); if (state->shape) draw_glyph(colorbv, state->shape, glyph, x, y, &state->scissor); @@ -678,9 +654,9 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu fz_context *ctx = dev->ctx; fz_irect bbox; fz_pixmap *mask, *dest, *shape; - fz_matrix tm, trm, trunc_trm; + fz_matrix tm, trm; fz_glyph *glyph; - int i, x, y, gid; + int i, gid; fz_draw_state *state; fz_colorspace *model; @@ -742,8 +718,6 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu for (i = 0; i < text->len; i++) { - fz_irect scissor; - gid = text->items[i].gid; if (gid < 0) continue; @@ -751,20 +725,12 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu tm.e = text->items[i].x; tm.f = text->items[i].y; fz_concat(&trm, &tm, ctm); - x = floorf(trm.e); - y = floorf(trm.f); - - trunc_trm = trm; - trunc_trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX); - trunc_trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX); - scissor.x0 = bbox.x0 - x; - scissor.y0 = bbox.y0 - y; - scissor.x1 = bbox.x1 - x; - scissor.y1 = bbox.y1 - y; - - glyph = fz_render_glyph(dev->ctx, text->font, gid, &trunc_trm, model, scissor); + + glyph = fz_render_glyph(dev->ctx, text->font, gid, &trm, model, &state->scissor); if (glyph) { + int x = (int)trm.e; + int y = (int)trm.f; draw_glyph(NULL, mask, glyph, x, y, &bbox); if (state[1].shape) draw_glyph(NULL, state[1].shape, glyph, x, y, &bbox); @@ -820,9 +786,9 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke fz_context *ctx = dev->ctx; fz_irect bbox; fz_pixmap *mask, *dest, *shape; - fz_matrix tm, trm, trunc_trm; + fz_matrix tm, trm; fz_glyph *glyph; - int i, x, y, gid; + int i, gid; fz_draw_state *state = push_stack(dev); fz_colorspace *model = state->dest->colorspace; fz_rect rect; @@ -857,7 +823,6 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke for (i = 0; i < text->len; i++) { - fz_irect scissor; gid = text->items[i].gid; if (gid < 0) continue; @@ -865,21 +830,12 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke tm.e = text->items[i].x; tm.f = text->items[i].y; fz_concat(&trm, &tm, ctm); - x = floorf(trm.e); - y = floorf(trm.f); - - trunc_trm = trm; - trunc_trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX); - trunc_trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX); - - scissor.x0 = bbox.x0 - x; - scissor.y0 = bbox.y0 - y; - scissor.x1 = bbox.x1 - x; - scissor.y1 = bbox.y1 - y; - glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, &trunc_trm, ctm, stroke, scissor); + glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, &trm, ctm, stroke, &state->scissor); if (glyph) { + int x = (int)trm.e; + int y = (int)trm.f; draw_glyph(NULL, mask, glyph, x, y, &bbox); if (shape) draw_glyph(NULL, shape, glyph, x, y, &bbox); |