summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/fitz/draw-edge.c45
-rw-r--r--source/fitz/draw-imp.h1
-rw-r--r--source/fitz/draw-path.c39
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