summaryrefslogtreecommitdiff
path: root/draw
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-07-10 22:46:39 +0200
committerTor Andersson <tor@ghostscript.com>2010-07-10 22:46:39 +0200
commitf387dd1ec51d53b9439ef91894e56a4a163384d7 (patch)
tree716e938e0f2cc0d13f9d027495f1a647681922bf /draw
parent021329447f940512267171aa64c1288e45498c6e (diff)
downloadmupdf-f387dd1ec51d53b9439ef91894e56a4a163384d7.tar.xz
Clamp floats to representable numbers before converting to int. Clip lines against horizontal edges. Return empty bbox when the edge list is empty.
Diffstat (limited to 'draw')
-rw-r--r--draw/pathscan.c82
1 files changed, 63 insertions, 19 deletions
diff --git a/draw/pathscan.c b/draw/pathscan.c
index a667a33a..5833ed59 100644
--- a/draw/pathscan.c
+++ b/draw/pathscan.c
@@ -70,6 +70,8 @@ fz_bbox
fz_boundgel(fz_gel *gel)
{
fz_bbox bbox;
+ if (gel->len == 0)
+ return fz_emptybbox;
bbox.x0 = fz_idiv(gel->bbox.x0, HSCALE);
bbox.y0 = fz_idiv(gel->bbox.y0, VSCALE);
bbox.x1 = fz_idiv(gel->bbox.x1, HSCALE) + 1;
@@ -106,31 +108,14 @@ cliplerpx(int val, int m, int x0, int y0, int x1, int y1, int *out)
}
}
-void
-fz_insertgel(fz_gel *gel, float fx0, float fy0, float fx1, float fy1)
+static void
+fz_insertgelraw(fz_gel *gel, int x0, int y0, int x1, int y1)
{
fz_edge *edge;
int dx, dy;
int winding;
int width;
int tmp;
- int v;
- int d;
-
- int x0 = floorf(fx0 * HSCALE);
- int y0 = floorf(fy0 * VSCALE);
- int x1 = floorf(fx1 * HSCALE);
- int y1 = floorf(fy1 * VSCALE);
-
- d = cliplerpy(gel->clip.y0, 0, x0, y0, x1, y1, &v);
- if (d == OUTSIDE) return;
- if (d == LEAVE) { y1 = gel->clip.y0; x1 = v; }
- if (d == ENTER) { y0 = gel->clip.y0; x0 = v; }
-
- d = cliplerpy(gel->clip.y1, 1, x0, y0, x1, y1, &v);
- if (d == OUTSIDE) return;
- if (d == LEAVE) { y1 = gel->clip.y1; x1 = v; }
- if (d == ENTER) { y0 = gel->clip.y1; x0 = v; }
if (y0 == y1)
return;
@@ -189,6 +174,65 @@ fz_insertgel(fz_gel *gel, float fx0, float fy0, float fx1, float fy1)
}
void
+fz_insertgel(fz_gel *gel, float fx0, float fy0, float fx1, float fy1)
+{
+ int x0, y0, x1, y1;
+ int d, v;
+
+ fx0 = floorf(fx0 * HSCALE);
+ fx1 = floorf(fx1 * HSCALE);
+ fy0 = floorf(fy0 * VSCALE);
+ fy1 = floorf(fy1 * VSCALE);
+
+ x0 = CLAMP(fx0, BBOX_MIN, BBOX_MAX);
+ y0 = CLAMP(fy0, BBOX_MIN, BBOX_MAX);
+ x1 = CLAMP(fx1, BBOX_MIN, BBOX_MAX);
+ y1 = CLAMP(fy1, BBOX_MIN, BBOX_MAX);
+
+ d = cliplerpy(gel->clip.y0, 0, x0, y0, x1, y1, &v);
+ if (d == OUTSIDE) return;
+ if (d == LEAVE) { y1 = gel->clip.y0; x1 = v; }
+ if (d == ENTER) { y0 = gel->clip.y0; x0 = v; }
+
+ d = cliplerpy(gel->clip.y1, 1, x0, y0, x1, y1, &v);
+ if (d == OUTSIDE) return;
+ if (d == LEAVE) { y1 = gel->clip.y1; x1 = v; }
+ if (d == ENTER) { y0 = gel->clip.y1; x0 = v; }
+
+ d = cliplerpx(gel->clip.x0, 0, x0, y0, x1, y1, &v);
+ if (d == OUTSIDE) {
+ x0 = x1 = gel->clip.x0;
+ }
+ if (d == LEAVE) {
+ fz_insertgelraw(gel, gel->clip.x0, v, gel->clip.x0, y1);
+ x1 = gel->clip.x0;
+ y1 = v;
+ }
+ if (d == ENTER) {
+ fz_insertgelraw(gel, gel->clip.x0, y0, gel->clip.x0, v);
+ x0 = gel->clip.x0;
+ y0 = v;
+ }
+
+ d = cliplerpx(gel->clip.x1, 1, x0, y0, x1, y1, &v);
+ if (d == OUTSIDE) {
+ x0 = x1 = gel->clip.x1;
+ }
+ if (d == LEAVE) {
+ fz_insertgelraw(gel, gel->clip.x1, v, gel->clip.x1, y1);
+ x1 = gel->clip.x0;
+ y1 = v;
+ }
+ if (d == ENTER) {
+ fz_insertgelraw(gel, gel->clip.x1, y0, gel->clip.x1, v);
+ x0 = gel->clip.x1;
+ y0 = v;
+ }
+
+ fz_insertgelraw(gel, x0, y0, x1, y1);
+}
+
+void
fz_sortgel(fz_gel *gel)
{
fz_edge *a = gel->edges;