diff options
Diffstat (limited to 'source/fitz')
-rw-r--r-- | source/fitz/draw-edge.c | 45 | ||||
-rw-r--r-- | source/fitz/draw-imp.h | 1 | ||||
-rw-r--r-- | source/fitz/draw-path.c | 39 |
3 files changed, 84 insertions, 1 deletions
diff --git a/source/fitz/draw-edge.c b/source/fitz/draw-edge.c index a4c0d02e..4309b858 100644 --- a/source/fitz/draw-edge.c +++ b/source/fitz/draw-edge.c @@ -425,6 +425,51 @@ fz_insert_gel(fz_context *ctx, fz_gel *gel, float fx0, float fy0, float fx1, flo fz_insert_gel_raw(ctx, gel, x0, y0, x1, y1); } +void +fz_insert_gel_rect(fz_context *ctx, fz_gel *gel, float fx0, float fy0, float fx1, float fy1) +{ + int x0, y0, x1, y1; + fz_aa_context *ctxaa = ctx->aa; + + if (fx0 <= fx1) + { + fx0 = floorf(fx0 * fz_aa_hscale); + fx1 = ceilf(fx1 * fz_aa_hscale); + } + else + { + fx0 = ceilf(fx0 * fz_aa_hscale); + fx1 = floorf(fx1 * fz_aa_hscale); + } + if (fy0 <= fy1) + { + fy0 = floorf(fy0 * fz_aa_vscale); + fy1 = ceilf(fy1 * fz_aa_vscale); + } + else + { + fy0 = ceilf(fy0 * fz_aa_vscale); + fy1 = floorf(fy1 * fz_aa_vscale); + } + + fx0 = fz_clamp(fx0, gel->clip.x0, gel->clip.x1); + fx1 = fz_clamp(fx1, gel->clip.x0, gel->clip.x1); + fy0 = fz_clamp(fy0, gel->clip.y0, gel->clip.y1); + fy1 = fz_clamp(fy1, gel->clip.y0, gel->clip.y1); + + /* Call fz_clamp so that clamping is done in the float domain, THEN + * cast down to an int. Calling fz_clampi causes problems due to the + * implicit cast down from float to int of the first argument + * over/underflowing and flipping sign at extreme values. */ + x0 = (int)fz_clamp(fx0, BBOX_MIN * fz_aa_hscale, BBOX_MAX * fz_aa_hscale); + y0 = (int)fz_clamp(fy0, BBOX_MIN * fz_aa_vscale, BBOX_MAX * fz_aa_vscale); + x1 = (int)fz_clamp(fx1, BBOX_MIN * fz_aa_hscale, BBOX_MAX * fz_aa_hscale); + y1 = (int)fz_clamp(fy1, BBOX_MIN * fz_aa_vscale, BBOX_MAX * fz_aa_vscale); + + fz_insert_gel_raw(ctx, gel, x1, y0, x1, y1); + fz_insert_gel_raw(ctx, gel, x0, y1, x0, y0); +} + static int cmpedge(const void *va, const void *vb) { diff --git a/source/fitz/draw-imp.h b/source/fitz/draw-imp.h index ed457d34..3a1ddbd2 100644 --- a/source/fitz/draw-imp.h +++ b/source/fitz/draw-imp.h @@ -9,6 +9,7 @@ typedef struct fz_gel_s fz_gel; fz_gel *fz_new_gel(fz_context *ctx); void fz_insert_gel(fz_context *ctx, fz_gel *gel, float x0, float y0, float x1, float y1); +void fz_insert_gel_rect(fz_context *ctx, fz_gel *gel, float x0, float y0, float x1, float y1); void fz_reset_gel(fz_context *ctx, fz_gel *gel, const fz_irect *clip); void fz_sort_gel(fz_context *ctx, fz_gel *gel); fz_irect *fz_bound_gel(fz_context *ctx, const fz_gel *gel, fz_irect *bbox); diff --git a/source/fitz/draw-path.c b/source/fitz/draw-path.c index 2e751222..2c0caa50 100644 --- a/source/fitz/draw-path.c +++ b/source/fitz/draw-path.c @@ -168,13 +168,50 @@ flatten_close(fz_context *ctx, void *arg_) arg->c.y = arg->b.y; } +static void +flatten_rectto(fz_context *ctx, void *arg_, float x0, float y0, float x1, float y1) +{ + flatten_arg *arg = (flatten_arg *)arg_; + const fz_matrix *ctm = arg->ctm; + + flatten_moveto(ctx, arg_, x0, y0); + /* In the case where we have an axis aligned rectangle, do some + * horrid antidropout stuff. */ + if (ctm->b == 0 && ctm->c == 0) + { + float tx0 = ctm->a * x0 + ctm->e; + float ty0 = ctm->d * y0 + ctm->f; + float tx1 = ctm->a * x1 + ctm->e; + float ty1 = ctm->d * y1 + ctm->f; + fz_insert_gel_rect(ctx, arg->gel, tx0, ty0, tx1, ty1); + } + else if (ctm->a == 0 && ctm->d == 0) + { + float tx0 = ctm->c * y0 + ctm->e; + float ty0 = ctm->b * x0 + ctm->f; + float tx1 = ctm->c * y1 + ctm->e; + float ty1 = ctm->b * x1 + ctm->f; + fz_insert_gel_rect(ctx, arg->gel, tx0, ty1, tx1, ty0); + } + else + { + flatten_lineto(ctx, arg_, x1, y0); + flatten_lineto(ctx, arg_, x1, y1); + flatten_lineto(ctx, arg_, x0, y1); + flatten_close(ctx, arg_); + } +} + static const fz_path_processor flatten_proc = { flatten_moveto, flatten_lineto, flatten_curveto, flatten_close, - flatten_quadto + flatten_quadto, + NULL, + NULL, + flatten_rectto }; void |