summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2017-06-15 17:57:28 +0100
committerRobin Watts <robin.watts@artifex.com>2017-06-22 14:59:43 +0100
commit2764ef8c0fd10d16a41842e8834efb1bd17e65d8 (patch)
treec1811c37e5314d59754e82a467ca88c775e7cd16
parentdd58ea5e2ff7e6b61cc5a5b6fd950fb62e92b8be (diff)
downloadmupdf-2764ef8c0fd10d16a41842e8834efb1bd17e65d8.tar.xz
Move rasterizer/anti-alias choices into the draw device.
We still use the fz_context versions as the default, but these can be overridden with draw device options.
-rw-r--r--include/mupdf/fitz/device.h2
-rw-r--r--include/mupdf/fitz/glyph-cache.h2
-rw-r--r--platform/gl/gl-font.c2
-rw-r--r--source/fitz/draw-device.c58
-rw-r--r--source/fitz/draw-edge.c20
-rw-r--r--source/fitz/draw-glyph.c26
-rw-r--r--source/fitz/draw-imp.h80
-rw-r--r--source/fitz/draw-rasterize.c180
-rw-r--r--source/fitz/font.c21
-rw-r--r--source/fitz/glyph-cache-imp.h14
10 files changed, 283 insertions, 122 deletions
diff --git a/include/mupdf/fitz/device.h b/include/mupdf/fitz/device.h
index 2f7971c0..6d2c24c2 100644
--- a/include/mupdf/fitz/device.h
+++ b/include/mupdf/fitz/device.h
@@ -349,6 +349,8 @@ struct fz_draw_options_s
int height;
fz_colorspace *colorspace;
int alpha;
+ int graphics;
+ int text;
};
extern const char *fz_draw_options_usage;
diff --git a/include/mupdf/fitz/glyph-cache.h b/include/mupdf/fitz/glyph-cache.h
index 16fff19a..100986a8 100644
--- a/include/mupdf/fitz/glyph-cache.h
+++ b/include/mupdf/fitz/glyph-cache.h
@@ -7,7 +7,7 @@
#include "mupdf/fitz/pixmap.h"
void fz_purge_glyph_cache(fz_context *ctx);
-fz_pixmap *fz_render_glyph_pixmap(fz_context *ctx, fz_font*, int, fz_matrix *, const fz_irect *scissor);
+fz_pixmap *fz_render_glyph_pixmap(fz_context *ctx, fz_font*, int, fz_matrix *, const fz_irect *scissor, int aa);
void fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, const fz_matrix *trm, void *gstate, int nestedDepth);
void fz_prepare_t3_glyph(fz_context *ctx, fz_font *font, int gid, int nestedDepth);
void fz_dump_glyph_cache_stats(fz_context *ctx);
diff --git a/platform/gl/gl-font.c b/platform/gl/gl-font.c
index efbba42a..98bb62af 100644
--- a/platform/gl/gl-font.c
+++ b/platform/gl/gl-font.c
@@ -164,7 +164,7 @@ static struct glyph *lookup_glyph(fz_font *font, int gid, float *xp, float *yp)
glEnd();
- pixmap = fz_render_glyph_pixmap(ctx, font, gid, &subpix_trm, NULL);
+ pixmap = fz_render_glyph_pixmap(ctx, font, gid, &subpix_trm, NULL, 8);
w = pixmap->w;
h = pixmap->h;
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c
index b4cb88c2..e2579b9f 100644
--- a/source/fitz/draw-device.c
+++ b/source/fitz/draw-device.c
@@ -399,10 +399,10 @@ fz_draw_stroke_path(fz_context *ctx, fz_device *devp, const fz_path *path, const
float colorfv[FZ_MAX_COLORS];
fz_irect bbox;
int i, n;
- float aa_level = 2.0f/(fz_graphics_aa_level(ctx)+2);
+ float aa_level = 2.0f/(fz_rasterizer_graphics_aa_level(rast)+2);
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model = state->dest->colorspace;
- float mlw = fz_graphics_min_line_width(ctx);
+ float mlw = fz_rasterizer_graphics_min_line_width(rast);
if (colorspace == NULL && model != NULL)
@@ -542,8 +542,8 @@ fz_draw_clip_stroke_path(fz_context *ctx, fz_device *devp, const fz_path *path,
fz_irect bbox;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model;
- float aa_level = 2.0f/(fz_graphics_aa_level(ctx)+2);
- float mlw = fz_graphics_min_line_width(ctx);
+ float aa_level = 2.0f/(fz_rasterizer_graphics_aa_level(rast)+2);
+ float mlw = fz_rasterizer_graphics_min_line_width(rast);
fz_irect local_scissor;
fz_irect *scissor_ptr = &state->scissor;
@@ -693,6 +693,7 @@ fz_draw_fill_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f
int i, n;
fz_colorspace *colorspace = NULL;
fz_colorspace *prf = fz_proof_cs(ctx, devp);
+ fz_rasterizer *rast = dev->rast;
if (colorspace_in)
colorspace = fz_default_colorspace(ctx, dev->default_cs, colorspace_in);
@@ -736,7 +737,7 @@ fz_draw_fill_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f
tm.f = span->items[i].y;
fz_concat(&trm, &tm, &ctm);
- glyph = fz_render_glyph(ctx, span->font, gid, &trm, model, &state->scissor, state->dest->alpha);
+ glyph = fz_render_glyph(ctx, span->font, gid, &trm, model, &state->scissor, state->dest->alpha, fz_rasterizer_text_aa_level(rast));
if (glyph)
{
fz_pixmap *pixmap = glyph->pixmap;
@@ -791,6 +792,7 @@ fz_draw_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, const
int i, n;
fz_colorspace *colorspace = NULL;
fz_colorspace *prf = fz_proof_cs(ctx, devp);
+ int aa = fz_rasterizer_text_aa_level(dev->rast);
if (colorspace_in)
colorspace = fz_default_colorspace(ctx, dev->default_cs, colorspace_in);
@@ -833,7 +835,7 @@ fz_draw_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, const
tm.f = span->items[i].y;
fz_concat(&trm, &tm, &ctm);
- glyph = fz_render_stroked_glyph(ctx, span->font, gid, &trm, &ctm, stroke, &state->scissor);
+ glyph = fz_render_stroked_glyph(ctx, span->font, gid, &trm, &ctm, stroke, &state->scissor, aa);
if (glyph)
{
int x = (int)trm.e;
@@ -877,6 +879,7 @@ fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f
fz_colorspace *model;
fz_text_span *span;
fz_rect rect;
+ fz_rasterizer *rast = dev->rast;
state = push_stack(ctx, dev);
STACK_PUSHED("clip text");
@@ -939,7 +942,7 @@ fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f
tm.f = span->items[i].y;
fz_concat(&trm, &tm, &ctm);
- glyph = fz_render_glyph(ctx, span->font, gid, &trm, model, &state->scissor, state[1].dest->alpha);
+ glyph = fz_render_glyph(ctx, span->font, gid, &trm, model, &state->scissor, state[1].dest->alpha, fz_rasterizer_text_aa_level(rast));
if (glyph)
{
int x = (int)trm.e;
@@ -1005,6 +1008,7 @@ fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text,
fz_colorspace *model = state->dest->colorspace;
fz_text_span *span;
fz_rect rect;
+ int aa = fz_rasterizer_text_aa_level(dev->rast);
STACK_PUSHED("clip stroke text");
/* make the mask the exact size needed */
@@ -1061,7 +1065,7 @@ fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text,
tm.f = span->items[i].y;
fz_concat(&trm, &tm, &ctm);
- glyph = fz_render_stroked_glyph(ctx, span->font, gid, &trm, &ctm, stroke, &state->scissor);
+ glyph = fz_render_stroked_glyph(ctx, span->font, gid, &trm, &ctm, stroke, &state->scissor, aa);
if (glyph)
{
int x = (int)trm.e;
@@ -2386,7 +2390,7 @@ fz_draw_drop_device(fz_context *ctx, fz_device *devp)
}
fz_device *
-fz_new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest)
+new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest, const fz_aa_context *aa)
{
fz_draw_device *dev = fz_new_derived_device(ctx, fz_draw_device);
@@ -2437,7 +2441,7 @@ fz_new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest)
fz_try(ctx)
{
- dev->rast = fz_new_rasterizer(ctx);
+ dev->rast = fz_new_rasterizer(ctx, aa);
dev->cache_x = fz_new_scale_cache(ctx);
dev->cache_y = fz_new_scale_cache(ctx);
}
@@ -2451,6 +2455,12 @@ fz_new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest)
}
fz_device *
+fz_new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest)
+{
+ return new_draw_device(ctx, transform, dest, NULL);
+}
+
+fz_device *
fz_new_draw_device_with_bbox(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest, const fz_irect *clip)
{
fz_draw_device *dev = (fz_draw_device*)fz_new_draw_device(ctx, transform, dest);
@@ -2478,7 +2488,7 @@ fz_new_draw_device_type3(fz_context *ctx, const fz_matrix *transform, fz_pixmap
fz_irect *
fz_bound_path_accurate(fz_context *ctx, fz_irect *bbox, const fz_irect *scissor, const fz_path *path, const fz_stroke_state *stroke, const fz_matrix *ctm, float flatness, float linewidth)
{
- fz_rasterizer *rast = fz_new_rasterizer(ctx);
+ fz_rasterizer *rast = fz_new_rasterizer(ctx, NULL);
if (stroke)
(void)fz_flatten_stroke_path(ctx, rast, path, stroke, ctm, flatness, linewidth, scissor, bbox);
@@ -2499,8 +2509,24 @@ const char *fz_draw_options_usage =
"\theight=N: render pages to fit N pixels tall (ignore resolution option)\n"
"\tcolorspace=(gray|rgb|cmyk): render using specified colorspace\n"
"\talpha: render pages with alpha channel and transparent background\n"
+ "\tgraphics=(aaN|cop|app): set the rasterizer to use\n"
+ "\ttext=(aaN|cop|app): set the rasterizer to use for text\n"
+ "\t\taaN=antialias with N bits (0 to 8)\n"
+ "\t\tcop=center of pixel\n"
+ "\t\tapp=any part of pixel\n"
"\n";
+static int parse_aa_opts(const char *val)
+{
+ if (fz_option_eq(val, "cop"))
+ return 9;
+ if (fz_option_eq(val, "app"))
+ return 10;
+ if (val[0] == 'a' && val[1] == 'a' && val[2] >= '0' && val[2] <= '9')
+ return fz_clampi(fz_atoi(&val[2]), 0, 8);
+ return 8;
+}
+
fz_draw_options *
fz_parse_draw_options(fz_context *ctx, fz_draw_options *opts, const char *args)
{
@@ -2515,6 +2541,8 @@ fz_parse_draw_options(fz_context *ctx, fz_draw_options *opts, const char *args)
opts->height = 0;
opts->colorspace = fz_device_rgb(ctx);
opts->alpha = 0;
+ opts->graphics = fz_aa_level(ctx);
+ opts->text = fz_text_aa_level(ctx);
if (fz_has_option(ctx, args, "rotate", &val))
opts->rotate = fz_atoi(val);
@@ -2541,6 +2569,10 @@ fz_parse_draw_options(fz_context *ctx, fz_draw_options *opts, const char *args)
}
if (fz_has_option(ctx, args, "alpha", &val))
opts->alpha = fz_option_eq(val, "yes");
+ if (fz_has_option(ctx, args, "graphics", &val))
+ opts->text = opts->graphics = parse_aa_opts(val);
+ if (fz_has_option(ctx, args, "text", &val))
+ opts->text = parse_aa_opts(val);
/* Sanity check values */
if (opts->x_resolution <= 0) opts->x_resolution = 96;
@@ -2562,6 +2594,10 @@ fz_new_draw_device_with_options(fz_context *ctx, const fz_draw_options *opts, co
fz_irect ibounds;
fz_matrix transform;
fz_device *dev;
+ fz_aa_context aa = *ctx->aa;
+
+ fz_set_rasterizer_graphics_aa_level(ctx, &aa, opts->graphics);
+ fz_set_rasterizer_text_aa_level(ctx, &aa, opts->text);
fz_pre_rotate(fz_scale(&transform, x_zoom, y_zoom), opts->rotate);
bounds = *mediabox;
diff --git a/source/fitz/draw-edge.c b/source/fitz/draw-edge.c
index 9b417345..1700a4d9 100644
--- a/source/fitz/draw-edge.c
+++ b/source/fitz/draw-edge.c
@@ -149,8 +149,8 @@ fz_insert_gel(fz_context *ctx, fz_rasterizer *ras, float fx0, float fy0, float f
{
int x0, y0, x1, y1;
int d, v;
- const int hscale = fz_aa_hscale;
- const int vscale = fz_aa_vscale;
+ const int hscale = fz_rasterizer_aa_hscale(ras);
+ const int vscale = fz_rasterizer_aa_vscale(ras);
fx0 = floorf(fx0 * hscale);
fx1 = floorf(fx1 * hscale);
@@ -213,8 +213,8 @@ static void
fz_insert_gel_rect(fz_context *ctx, fz_rasterizer *ras, float fx0, float fy0, float fx1, float fy1)
{
int x0, y0, x1, y1;
- const int hscale = fz_aa_hscale;
- const int vscale = fz_aa_vscale;
+ const int hscale = fz_rasterizer_aa_hscale(ras);
+ const int vscale = fz_rasterizer_aa_vscale(ras);
if (fx0 <= fx1)
{
@@ -445,11 +445,11 @@ advance_active(fz_context *ctx, fz_gel *gel, int inc)
*/
static inline void
-add_span_aa(fz_context *ctx, int *list, int x0, int x1, int xofs, int h)
+add_span_aa(fz_context *ctx, fz_gel *gel, int *list, int x0, int x1, int xofs, int h)
{
int x0pix, x0sub;
int x1pix, x1sub;
- const int hscale = fz_aa_hscale;
+ const int hscale = fz_rasterizer_aa_hscale(&gel->super);
if (x0 == x1)
return;
@@ -493,7 +493,7 @@ non_zero_winding_aa(fz_context *ctx, fz_gel *gel, int *list, int xofs, int h)
if (!winding && (winding + gel->active[i]->ydir))
x = gel->active[i]->x;
if (winding && !(winding + gel->active[i]->ydir))
- add_span_aa(ctx, list, x, gel->active[i]->x, xofs, h);
+ add_span_aa(ctx, gel, list, x, gel->active[i]->x, xofs, h);
winding += gel->active[i]->ydir;
}
}
@@ -510,7 +510,7 @@ even_odd_aa(fz_context *ctx, fz_gel *gel, int *list, int xofs, int h)
if (!even)
x = gel->active[i]->x;
else
- add_span_aa(ctx, list, x, gel->active[i]->x, xofs, h);
+ add_span_aa(ctx, gel, list, x, gel->active[i]->x, xofs, h);
even = !even;
}
}
@@ -548,8 +548,8 @@ fz_scan_convert_aa(fz_context *ctx, fz_gel *gel, int eofill, const fz_irect *cli
int y, e;
int yd, yc;
int height, h0, rh;
- const int hscale = fz_aa_hscale;
- const int vscale = fz_aa_vscale;
+ const int hscale = fz_rasterizer_aa_hscale(&gel->super);
+ const int vscale = fz_rasterizer_aa_vscale(&gel->super);
int xmin = fz_idiv(gel->super.bbox.x0, hscale);
int xmax = fz_idiv_up(gel->super.bbox.x1, hscale);
diff --git a/source/fitz/draw-glyph.c b/source/fitz/draw-glyph.c
index 7a6b9126..49ca6661 100644
--- a/source/fitz/draw-glyph.c
+++ b/source/fitz/draw-glyph.c
@@ -177,7 +177,7 @@ fz_subpixel_adjust(fz_context *ctx, fz_matrix *ctm, fz_matrix *subpix_ctm, unsig
}
fz_glyph *
-fz_render_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *stroke, const fz_irect *scissor)
+fz_render_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *stroke, const fz_irect *scissor, int aa)
{
if (fz_font_ft_face(ctx, font))
{
@@ -187,13 +187,13 @@ fz_render_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *trm,
if (stroke->dash_len > 0)
return NULL;
(void)fz_subpixel_adjust(ctx, trm, &subpix_trm, &qe, &qf);
- return fz_render_ft_stroked_glyph(ctx, font, gid, &subpix_trm, ctm, stroke);
+ return fz_render_ft_stroked_glyph(ctx, font, gid, &subpix_trm, ctm, stroke, aa);
}
- return fz_render_glyph(ctx, font, gid, trm, NULL, scissor, 1);
+ return fz_render_glyph(ctx, font, gid, trm, NULL, scissor, 1, aa);
}
fz_pixmap *
-fz_render_stroked_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *stroke, const fz_irect *scissor)
+fz_render_stroked_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *stroke, const fz_irect *scissor, int aa)
{
if (fz_font_ft_face(ctx, font))
{
@@ -203,9 +203,9 @@ fz_render_stroked_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matri
if (stroke->dash_len > 0)
return NULL;
(void)fz_subpixel_adjust(ctx, trm, &subpix_trm, &qe, &qf);
- return fz_render_ft_stroked_glyph_pixmap(ctx, font, gid, &subpix_trm, ctm, stroke);
+ return fz_render_ft_stroked_glyph_pixmap(ctx, font, gid, &subpix_trm, ctm, stroke, aa);
}
- return fz_render_glyph_pixmap(ctx, font, gid, trm, scissor);
+ return fz_render_glyph_pixmap(ctx, font, gid, trm, scissor, aa);
}
static unsigned do_hash(unsigned char *s, int len)
@@ -245,7 +245,7 @@ move_to_front(fz_glyph_cache *cache, fz_glyph_cache_entry *entry)
}
fz_glyph *
-fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, fz_colorspace *model, const fz_irect *scissor, int alpha)
+fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, fz_colorspace *model, const fz_irect *scissor, int alpha, int aa)
{
fz_glyph_cache *cache;
fz_glyph_key key;
@@ -289,7 +289,7 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, fz_colo
key.b = subpix_ctm.b * 65536;
key.c = subpix_ctm.c * 65536;
key.d = subpix_ctm.d * 65536;
- key.aa = fz_text_aa_level(ctx);
+ key.aa = aa;
hash = do_hash((unsigned char *)&key, sizeof(key)) % GLYPH_HASH_LEN;
fz_lock(ctx, FZ_LOCK_GLYPHCACHE);
@@ -314,7 +314,7 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, fz_colo
{
if (is_ft_font)
{
- val = fz_render_ft_glyph(ctx, font, gid, &subpix_ctm, key.aa);
+ val = fz_render_ft_glyph(ctx, font, gid, &subpix_ctm, aa);
}
else if (fz_font_t3_procs(ctx, font))
{
@@ -329,7 +329,7 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, fz_colo
*/
fz_unlock(ctx, FZ_LOCK_GLYPHCACHE);
locked = 0;
- val = fz_render_t3_glyph(ctx, font, gid, &subpix_ctm, model, scissor);
+ val = fz_render_t3_glyph(ctx, font, gid, &subpix_ctm, model, scissor, aa);
fz_lock(ctx, FZ_LOCK_GLYPHCACHE);
locked = 1;
}
@@ -411,7 +411,7 @@ unlock_and_return_val:
}
fz_pixmap *
-fz_render_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, const fz_irect *scissor)
+fz_render_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, const fz_irect *scissor, int aa)
{
fz_pixmap *val;
unsigned char qe, qf;
@@ -433,11 +433,11 @@ fz_render_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm,
{
if (is_ft_font)
{
- val = fz_render_ft_glyph_pixmap(ctx, font, gid, &subpix_ctm, fz_text_aa_level(ctx));
+ val = fz_render_ft_glyph_pixmap(ctx, font, gid, &subpix_ctm, aa);
}
else if (fz_font_t3_procs(ctx, font))
{
- val = fz_render_t3_glyph_pixmap(ctx, font, gid, &subpix_ctm, NULL, scissor);
+ val = fz_render_t3_glyph_pixmap(ctx, font, gid, &subpix_ctm, NULL, scissor, aa);
}
else
{
diff --git a/source/fitz/draw-imp.h b/source/fitz/draw-imp.h
index 48d0c7f0..2d78a912 100644
--- a/source/fitz/draw-imp.h
+++ b/source/fitz/draw-imp.h
@@ -26,6 +26,10 @@ static inline int fz_idiv_up(int a, int b)
#define fz_aa_vscale 15
#define fz_aa_bits 8
#define fz_aa_text_bits 8
+#define fz_rasterizer_aa_hscale(ras) 17
+#define fz_rasterizer_aa_vscale(ras) 15
+#define fz_rasterizer_aa_bits(ras) 8
+#define fz_rasterizer_aa_text_bits(ras) 8
#elif AA_BITS > 4
#define AA_SCALE(s, x) ((x * 255) >> 6)
@@ -33,6 +37,10 @@ static inline int fz_idiv_up(int a, int b)
#define fz_aa_vscale 8
#define fz_aa_bits 6
#define fz_aa_text_bits 6
+#define fz_rasterizer_aa_hscale(ras) 8
+#define fz_rasterizer_aa_vscale(ras) 8
+#define fz_rasterizer_aa_bits(ras) 6
+#define fz_rasterizer_aa_text_bits(ras) 6
#elif AA_BITS > 2
#define AA_SCALE(s, x) (x * 17)
@@ -40,6 +48,11 @@ static inline int fz_idiv_up(int a, int b)
#define fz_aa_vscale 3
#define fz_aa_bits 4
#define fz_aa_text_bits 4
+#define fz_rasterizer_aa_hscale(ras) 5
+#define fz_rasterizer_aa_vscale(ras) 3
+#define fz_rasterizer_aa_bits(ras) 4
+#define fz_rasterizer_aa_text_bits(ras) 4
+
#elif AA_BITS > 0
#define AA_SCALE(s, x) ((x * 255) >> 2)
@@ -47,6 +60,10 @@ static inline int fz_idiv_up(int a, int b)
#define fz_aa_vscale 2
#define fz_aa_bits 2
#define fz_aa_text_bits 2
+#define fz_rasterizer_aa_hscale(ras) 2
+#define fz_rasterizer_aa_vscale(ras) 2
+#define fz_rasterizer_aa_bits(ras) 2
+#define fz_rasterizer_aa_text_bits(ras) 2
#else
#define AA_SCALE(s, x) (x * 255)
@@ -54,6 +71,10 @@ static inline int fz_idiv_up(int a, int b)
#define fz_aa_vscale 1
#define fz_aa_bits 0
#define fz_aa_text_bits 0
+#define fz_rasterizer_aa_hscale(ras) 1
+#define fz_rasterizer_aa_vscale(ras) 1
+#define fz_rasterizer_aa_bits(ras) 0
+#define fz_rasterizer_aa_text_bits(ras) 0
#endif
#else
@@ -64,6 +85,10 @@ static inline int fz_idiv_up(int a, int b)
#define fz_aa_scale (ctx->aa->scale)
#define fz_aa_bits (ctx->aa->bits)
#define fz_aa_text_bits (ctx->aa->text_bits)
+#define fz_rasterizer_aa_hscale(ras) ((ras)->aa.hscale)
+#define fz_rasterizer_aa_vscale(ras) ((ras)->aa.vscale)
+#define fz_rasterizer_aa_bits(ras) ((ras)->aa.bits)
+#define fz_rasterizer_aa_text_bits(ras) ((ras)->aa.text_bits)
#endif
@@ -115,6 +140,7 @@ typedef struct
struct fz_rasterizer_s
{
fz_rasterizer_fns fns;
+ fz_aa_context aa;
fz_irect clip; /* Specified clip rectangle */
fz_irect bbox; /* Measured bbox of path while stroking/filling */
};
@@ -182,8 +208,10 @@ struct fz_rasterizer_s
A single rasterizer instance can be used to scan convert many
things.
+
+ aa: The antialiasing settings to use (or NULL).
*/
-fz_rasterizer *fz_new_rasterizer(fz_context *ctx);
+fz_rasterizer *fz_new_rasterizer(fz_context *ctx, const fz_aa_context *aa);
/*
fz_drop_rasterizer: Dispose of a rasterizer once
@@ -314,6 +342,56 @@ void *fz_new_rasterizer_of_size(fz_context *ctx, int size, const fz_rasterizer_f
#define fz_new_derived_rasterizer(C,M,F) \
((M*)Memento_label(fz_new_rasterizer_of_size(C, sizeof(M), F), #M))
+/*
+ fz_rasterizer_text_aa_level: Get the number of bits of
+ antialiasing we are using for text in a given rasterizer.
+ Between 0 and 8.
+*/
+int fz_rasterizer_text_aa_level(fz_rasterizer *ras);
+
+/*
+ fz_set_rasterizer_text_aa_level: Set the number of bits of
+ antialiasing we should use for text in a given configuration.
+
+ bits: The number of bits of antialiasing to use (values are clamped
+ to within the 0 to 8 range).
+*/
+void fz_set_rasterizer_text_aa_level(fz_context *ctx, fz_aa_context *aa, int bits);
+
+/*
+ fz_rasterizer_graphics_aa_level: Get the number of bits of
+ antialiasing we are using for graphics in a given rasterizer.
+
+ Between 0 and 8.
+*/
+int fz_rasterizer_graphics_aa_level(fz_rasterizer *ras);
+
+/*
+ fz_set_rasterizer_graphics_aa_level: Set the number of bits of
+ antialiasing we should use for graphics in a given rasterizer.
+
+ bits: The number of bits of antialiasing to use (values are clamped
+ to within the 0 to 8 range).
+*/
+void fz_set_rasterizer_graphics_aa_level(fz_context *ctx, fz_aa_context *aa, int bits);
+
+/*
+ fz_rasterizer_graphics_min_line_width: Get the minimum line
+ width to be used for stroked lines in a given rasterizer.
+
+ min_line_width: The minimum line width to use (in pixels).
+*/
+float fz_rasterizer_graphics_min_line_width(fz_rasterizer *ras);
+
+/*
+ fz_set_rasterizer_graphics_min_line_width: Set the minimum line
+ width to be used for stroked lines in a given configuration.
+
+ min_line_width: The minimum line width to use (in pixels).
+*/
+void fz_set_rasterizer_graphics_min_line_width(fz_context *ctx, fz_aa_context *aa, float min_line_width);
+
+
fz_rasterizer *fz_new_gel(fz_context *ctx);
typedef enum
diff --git a/source/fitz/draw-rasterize.c b/source/fitz/draw-rasterize.c
index 2231801e..63a9d0b2 100644
--- a/source/fitz/draw-rasterize.c
+++ b/source/fitz/draw-rasterize.c
@@ -47,94 +47,117 @@ fz_text_aa_level(fz_context *ctx)
return fz_aa_text_bits;
}
-#ifndef AA_BITS
-static void
-set_gfx_level(fz_context *ctx, int level)
+int
+fz_rasterizer_graphics_aa_level(fz_rasterizer *ras)
+{
+ return fz_rasterizer_aa_bits(ras);
+}
+
+int
+fz_rasterizer_text_aa_level(fz_rasterizer *ras)
{
+ return fz_rasterizer_aa_text_bits(ras);
+}
+
+void
+fz_set_rasterizer_text_aa_level(fz_context *ctx, fz_aa_context *aa, int level)
+{
+#ifdef AA_BITS
+ if (level != fz_aa_bits)
+ {
+ if (fz_aa_bits == 10)
+ fz_warn(ctx, "Only the Any-part-of-a-pixel rasterizer was compiled in");
+ else if (fz_aa_bits == 9)
+ fz_warn(ctx, "Only the Centre-of-a-pixel rasterizer was compiled in");
+ else
+ fz_warn(ctx, "Only the %d bit anti-aliasing rasterizer was compiled in", fz_aa_bits);
+ }
+#else
+ if (level > 6)
+ aa->text_bits = 8;
+ else if (level > 4)
+ aa->text_bits = 6;
+ else if (level > 2)
+ aa->text_bits = 4;
+ else if (level > 0)
+ aa->text_bits = 2;
+ else
+ aa->text_bits = 0;
+#endif
+}
+
+void
+fz_set_rasterizer_graphics_aa_level(fz_context *ctx, fz_aa_context *aa, int level)
+{
+#ifdef AA_BITS
+ if (level != fz_aa_bits)
+ {
+ if (fz_aa_bits == 10)
+ fz_warn(ctx, "Only the Any-part-of-a-pixel rasterizer was compiled in");
+ else if (fz_aa_bits == 9)
+ fz_warn(ctx, "Only the Centre-of-a-pixel rasterizer was compiled in");
+ else
+ fz_warn(ctx, "Only the %d bit anti-aliasing rasterizer was compiled in", fz_aa_bits);
+ }
+#else
if (level == 9 || level == 10)
{
- fz_aa_hscale = 1;
- fz_aa_vscale = 1;
- fz_aa_bits = level;
+ aa->hscale = 1;
+ aa->vscale = 1;
+ aa->bits = level;
}
else if (level > 6)
{
- fz_aa_hscale = 17;
- fz_aa_vscale = 15;
- fz_aa_bits = 8;
+ aa->hscale = 17;
+ aa->vscale = 15;
+ aa->bits = 8;
}
else if (level > 4)
{
- fz_aa_hscale = 8;
- fz_aa_vscale = 8;
- fz_aa_bits = 6;
+ aa->hscale = 8;
+ aa->vscale = 8;
+ aa->bits = 6;
}
else if (level > 2)
{
- fz_aa_hscale = 5;
- fz_aa_vscale = 3;
- fz_aa_bits = 4;
+ aa->hscale = 5;
+ aa->vscale = 3;
+ aa->bits = 4;
}
else if (level > 0)
{
- fz_aa_hscale = 2;
- fz_aa_vscale = 2;
- fz_aa_bits = 2;
+ aa->hscale = 2;
+ aa->vscale = 2;
+ aa->bits = 2;
}
else
{
- fz_aa_hscale = 1;
- fz_aa_vscale = 1;
- fz_aa_bits = 0;
+ aa->hscale = 1;
+ aa->vscale = 1;
+ aa->bits = 0;
}
- fz_aa_scale = 0xFF00 / (fz_aa_hscale * fz_aa_vscale);
-}
-
-static void
-set_txt_level(fz_context *ctx, int level)
-{
- if (level > 6)
- fz_aa_text_bits = 8;
- else if (level > 4)
- fz_aa_text_bits = 6;
- else if (level > 2)
- fz_aa_text_bits = 4;
- else if (level > 0)
- fz_aa_text_bits = 2;
- else
- fz_aa_text_bits = 0;
+ aa->scale = 0xFF00 / (aa->hscale * aa->vscale);
+ fz_set_rasterizer_text_aa_level(ctx, aa, level);
+#endif
}
-#endif /* AA_BITS */
void
fz_set_aa_level(fz_context *ctx, int level)
{
-#ifdef AA_BITS
- fz_warn(ctx, "anti-aliasing was compiled with a fixed precision of %d bits", fz_aa_bits);
-#else
- set_gfx_level(ctx, level);
- set_txt_level(ctx, level);
-#endif
+ fz_set_rasterizer_graphics_aa_level(ctx, ctx->aa, level);
+ fz_set_rasterizer_text_aa_level(ctx, ctx->aa, level);
}
void
fz_set_text_aa_level(fz_context *ctx, int level)
{
-#ifdef AA_BITS
- fz_warn(ctx, "anti-aliasing was compiled with a fixed precision of %d bits", fz_aa_bits);
-#else
- set_txt_level(ctx, level);
-#endif
+ fz_set_rasterizer_text_aa_level(ctx, ctx->aa, level);
}
void
fz_set_graphics_aa_level(fz_context *ctx, int level)
{
-#ifdef AA_BITS
- fz_warn(ctx, "anti-aliasing was compiled with a fixed precision of %d bits", fz_aa_bits);
-#else
- set_gfx_level(ctx, level);
-#endif
+ fz_set_rasterizer_graphics_aa_level(ctx, ctx->aa, level);
}
void
@@ -155,11 +178,17 @@ fz_graphics_min_line_width(fz_context *ctx)
return ctx->aa->min_line_width;
}
+float
+fz_rasterizer_graphics_min_line_width(fz_rasterizer *ras)
+{
+ return ras->aa.min_line_width;
+}
+
fz_irect *
fz_bound_rasterizer(fz_context *ctx, const fz_rasterizer *rast, fz_irect *bbox)
{
- const int hscale = fz_aa_hscale;
- const int vscale = fz_aa_vscale;
+ const int hscale = fz_rasterizer_aa_hscale(rast);
+ const int vscale = fz_rasterizer_aa_vscale(rast);
if (rast->bbox.x1 < rast->bbox.x0 || rast->bbox.y1 < rast->bbox.y0)
{
@@ -177,8 +206,8 @@ fz_bound_rasterizer(fz_context *ctx, const fz_rasterizer *rast, fz_irect *bbox)
fz_rect *fz_scissor_rasterizer(fz_context *ctx, const fz_rasterizer *rast, fz_rect *r)
{
- const int hscale = fz_aa_hscale;
- const int vscale = fz_aa_vscale;
+ const int hscale = fz_rasterizer_aa_hscale(rast);
+ const int vscale = fz_rasterizer_aa_vscale(rast);
r->x0 = ((float)rast->clip.x0) / hscale;
r->y0 = ((float)rast->clip.y0) / vscale;
@@ -190,8 +219,8 @@ fz_rect *fz_scissor_rasterizer(fz_context *ctx, const fz_rasterizer *rast, fz_re
static fz_irect *fz_clip_rasterizer(fz_context *ctx, const fz_rasterizer *rast, fz_irect *r)
{
- const int hscale = fz_aa_hscale;
- const int vscale = fz_aa_vscale;
+ const int hscale = fz_rasterizer_aa_hscale(rast);
+ const int vscale = fz_rasterizer_aa_vscale(rast);
r->x0 = fz_idiv(rast->clip.x0, hscale);
r->y0 = fz_idiv(rast->clip.y0, vscale);
@@ -203,8 +232,8 @@ static fz_irect *fz_clip_rasterizer(fz_context *ctx, const fz_rasterizer *rast,
int fz_reset_rasterizer(fz_context *ctx, fz_rasterizer *rast, const fz_irect *clip)
{
- const int hscale = fz_aa_hscale;
- const int vscale = fz_aa_vscale;
+ const int hscale = fz_rasterizer_aa_hscale(rast);
+ const int vscale = fz_rasterizer_aa_vscale(rast);
if (fz_is_infinite_irect(clip))
{
@@ -239,14 +268,29 @@ void *fz_new_rasterizer_of_size(fz_context *ctx, int size, const fz_rasterizer_f
return rast;
}
-fz_rasterizer *fz_new_rasterizer(fz_context *ctx)
+fz_rasterizer *fz_new_rasterizer(fz_context *ctx, const fz_aa_context *aa)
{
- if (ctx->aa->bits == 10)
- return fz_new_edgebuffer(ctx, FZ_EDGEBUFFER_ANY_PART_OF_PIXEL);
- else if (ctx->aa->bits == 9)
- return fz_new_edgebuffer(ctx, FZ_EDGEBUFFER_CENTER_OF_PIXEL);
+ fz_rasterizer *r;
+ int bits;
+
+#ifdef AA_BITS
+ bits = AA_BITS;
+#else
+ if (aa == NULL)
+ aa = ctx->aa;
+ bits = aa->bits;
+#endif
+ if (bits == 10)
+ r = fz_new_edgebuffer(ctx, FZ_EDGEBUFFER_ANY_PART_OF_PIXEL);
+ else if (bits == 9)
+ r = fz_new_edgebuffer(ctx, FZ_EDGEBUFFER_CENTER_OF_PIXEL);
else
- return fz_new_gel(ctx);
+ r = fz_new_gel(ctx);
+#ifndef AA_BITS
+ r->aa = *aa;
+#endif
+
+ return r;
}
void fz_convert_rasterizer(fz_context *ctx, fz_rasterizer *r, int eofill, fz_pixmap *pix, unsigned char *colorbv)
diff --git a/source/fitz/font.c b/source/fitz/font.c
index 77041dd8..79b17458 100644
--- a/source/fitz/font.c
+++ b/source/fitz/font.c
@@ -2,6 +2,7 @@
#include "mupdf/ucdn.h"
#include "fitz-imp.h"
#include "font-imp.h"
+#include "draw-imp.h"
#include <ft2build.h>
#include "hb.h"
@@ -678,7 +679,7 @@ retry_unhinted:
FT_Outline_Translate(&face->glyph->outline, -strength * 32, -strength * 32);
}
- fterr = FT_Render_Glyph(face->glyph, fz_text_aa_level(ctx) > 0 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
+ fterr = FT_Render_Glyph(face->glyph, aa > 0 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
if (fterr)
{
fz_warn(ctx, "freetype render glyph (gid %d): %s", gid, ft_error_string(fterr));
@@ -746,7 +747,7 @@ fz_render_ft_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm
/* Takes the freetype lock, and returns with it held */
static FT_Glyph
-do_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *state)
+do_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *state, int aa)
{
FT_Face face = font->ft_face;
float expansion = fz_matrix_expansion(ctm);
@@ -829,7 +830,7 @@ do_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_mat
FT_Stroker_Done(stroker);
- fterr = FT_Glyph_To_Bitmap(&glyph, fz_text_aa_level(ctx) > 0 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
+ fterr = FT_Glyph_To_Bitmap(&glyph, aa > 0 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
if (fterr)
{
fz_warn(ctx, "FT_Glyph_To_Bitmap: %s", ft_error_string(fterr));
@@ -840,9 +841,9 @@ do_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_mat
}
fz_pixmap *
-fz_render_ft_stroked_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *state)
+fz_render_ft_stroked_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *state, int aa)
{
- FT_Glyph glyph = do_render_ft_stroked_glyph(ctx, font, gid, trm, ctm, state);
+ FT_Glyph glyph = do_render_ft_stroked_glyph(ctx, font, gid, trm, ctm, state, aa);
FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
fz_pixmap *pixmap;
@@ -870,9 +871,9 @@ fz_render_ft_stroked_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const
}
fz_glyph *
-fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *state)
+fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *state, int aa)
{
- FT_Glyph glyph = do_render_ft_stroked_glyph(ctx, font, gid, trm, ctm, state);
+ FT_Glyph glyph = do_render_ft_stroked_glyph(ctx, font, gid, trm, ctm, state, aa);
FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
fz_glyph *result;
@@ -1253,7 +1254,7 @@ fz_run_t3_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, f
}
fz_pixmap *
-fz_render_t3_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, fz_colorspace *model, const fz_irect *scissor)
+fz_render_t3_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, fz_colorspace *model, const fz_irect *scissor, int aa)
{
fz_display_list *list;
fz_rect bounds;
@@ -1333,9 +1334,9 @@ fz_render_t3_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const fz_matr
}
fz_glyph *
-fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, fz_colorspace *model, const fz_irect *scissor)
+fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, fz_colorspace *model, const fz_irect *scissor, int aa)
{
- fz_pixmap *pixmap = fz_render_t3_glyph_pixmap(ctx, font, gid, trm, model, scissor);
+ fz_pixmap *pixmap = fz_render_t3_glyph_pixmap(ctx, font, gid, trm, model, scissor, aa);
return fz_new_glyph_from_pixmap(ctx, pixmap);
}
diff --git a/source/fitz/glyph-cache-imp.h b/source/fitz/glyph-cache-imp.h
index f21cfbb1..f6226ae4 100644
--- a/source/fitz/glyph-cache-imp.h
+++ b/source/fitz/glyph-cache-imp.h
@@ -5,12 +5,12 @@ fz_path *fz_outline_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matr
fz_path *fz_outline_ft_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm);
fz_glyph *fz_render_ft_glyph(fz_context *ctx, fz_font *font, int cid, const fz_matrix *trm, int aa);
fz_pixmap *fz_render_ft_glyph_pixmap(fz_context *ctx, fz_font *font, int cid, const fz_matrix *trm, int aa);
-fz_glyph *fz_render_t3_glyph(fz_context *ctx, fz_font *font, int cid, const fz_matrix *trm, fz_colorspace *model, const fz_irect *scissor);
-fz_pixmap *fz_render_t3_glyph_pixmap(fz_context *ctx, fz_font *font, int cid, const fz_matrix *trm, fz_colorspace *model, const fz_irect *scissor);
-fz_glyph *fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *state);
-fz_pixmap *fz_render_ft_stroked_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *state);
-fz_glyph *fz_render_glyph(fz_context *ctx, fz_font*, int, fz_matrix *, fz_colorspace *model, const fz_irect *scissor, int alpha);
-fz_glyph *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix *, const fz_matrix *, const fz_stroke_state *stroke, const fz_irect *scissor);
-fz_pixmap *fz_render_stroked_glyph_pixmap(fz_context *ctx, fz_font*, int, fz_matrix *, const fz_matrix *, const fz_stroke_state *stroke, const fz_irect *scissor);
+fz_glyph *fz_render_t3_glyph(fz_context *ctx, fz_font *font, int cid, const fz_matrix *trm, fz_colorspace *model, const fz_irect *scissor, int aa);
+fz_pixmap *fz_render_t3_glyph_pixmap(fz_context *ctx, fz_font *font, int cid, const fz_matrix *trm, fz_colorspace *model, const fz_irect *scissor, int aa);
+fz_glyph *fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *state, int aa);
+fz_pixmap *fz_render_ft_stroked_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *state, int aa);
+fz_glyph *fz_render_glyph(fz_context *ctx, fz_font*, int gid, fz_matrix *, fz_colorspace *model, const fz_irect *scissor, int alpha, int aa);
+fz_glyph *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix *, const fz_matrix *, const fz_stroke_state *stroke, const fz_irect *scissor, int aa);
+fz_pixmap *fz_render_stroked_glyph_pixmap(fz_context *ctx, fz_font*, int, fz_matrix *, const fz_matrix *, const fz_stroke_state *stroke, const fz_irect *scissor, int aa);
#endif