diff options
author | Robin Watts <robin.watts@artifex.com> | 2017-06-15 17:57:28 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2017-06-22 14:59:43 +0100 |
commit | 2764ef8c0fd10d16a41842e8834efb1bd17e65d8 (patch) | |
tree | c1811c37e5314d59754e82a467ca88c775e7cd16 /source | |
parent | dd58ea5e2ff7e6b61cc5a5b6fd950fb62e92b8be (diff) | |
download | mupdf-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.
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/draw-device.c | 58 | ||||
-rw-r--r-- | source/fitz/draw-edge.c | 20 | ||||
-rw-r--r-- | source/fitz/draw-glyph.c | 26 | ||||
-rw-r--r-- | source/fitz/draw-imp.h | 80 | ||||
-rw-r--r-- | source/fitz/draw-rasterize.c | 180 | ||||
-rw-r--r-- | source/fitz/font.c | 21 | ||||
-rw-r--r-- | source/fitz/glyph-cache-imp.h | 14 |
7 files changed, 279 insertions, 120 deletions
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 |