summaryrefslogtreecommitdiff
path: root/fitz
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-05-11 05:35:12 +0200
committerTor Andersson <tor@ghostscript.com>2010-05-11 05:35:12 +0200
commit40fbb05a738dfe1161b46f3fb15614327833cd34 (patch)
treecc7eb092204c55aab7d546e00e19efd3eb00ce05 /fitz
parente43e0c7a92fdff506ad846ad1769606549dc1b2b (diff)
downloadmupdf-40fbb05a738dfe1161b46f3fb15614327833cd34.tar.xz
Add a bbox extraction device.
Diffstat (limited to 'fitz')
-rw-r--r--fitz/base_rect.c27
-rw-r--r--fitz/dev_bbox.c95
-rw-r--r--fitz/fitz_base.h10
-rw-r--r--fitz/fitz_res.h2
4 files changed, 128 insertions, 6 deletions
diff --git a/fitz/base_rect.c b/fitz/base_rect.c
index bd5e2df8..70c0f469 100644
--- a/fitz/base_rect.c
+++ b/fitz/base_rect.c
@@ -1,9 +1,12 @@
#include "fitz.h"
-fz_rect fz_infiniterect = { 1, 1, -1, -1 };
-fz_rect fz_emptyrect = { 0, 0, 0, 0 };
+const fz_rect fz_infiniterect = { 1, 1, -1, -1 };
+const fz_rect fz_emptyrect = { 0, 0, 0, 0 };
+const fz_rect fz_unityrect = { 0, 0, 1, 1 };
-static fz_bbox empty = { 0, 0, 0, 0 };
+const fz_bbox fz_infinitebbox = { 1, 1, -1, -1 };
+const fz_bbox fz_emptybbox = { 0, 0, 0, 0 };
+const fz_bbox fz_unitybbox = { 0, 0, 1, 1 };
fz_bbox
fz_roundrect(fz_rect f)
@@ -22,10 +25,26 @@ fz_intersectbbox(fz_bbox a, fz_bbox b)
fz_bbox r;
if (fz_isinfiniterect(a)) return b;
if (fz_isinfiniterect(b)) return a;
+ if (fz_isemptyrect(a)) return fz_emptybbox;
+ if (fz_isemptyrect(b)) return fz_emptybbox;
r.x0 = MAX(a.x0, b.x0);
r.y0 = MAX(a.y0, b.y0);
r.x1 = MIN(a.x1, b.x1);
r.y1 = MIN(a.y1, b.y1);
- return (r.x1 < r.x0 || r.y1 < r.y0) ? empty : r;
+ return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_emptybbox : r;
}
+fz_bbox
+fz_unionbbox(fz_bbox a, fz_bbox b)
+{
+ fz_bbox r;
+ if (fz_isinfiniterect(a)) return a;
+ if (fz_isinfiniterect(b)) return b;
+ if (fz_isemptyrect(a)) return b;
+ if (fz_isemptyrect(b)) return a;
+ r.x0 = MIN(a.x0, b.x0);
+ r.y0 = MIN(a.y0, b.y0);
+ r.x1 = MAX(a.x1, b.x1);
+ r.y1 = MAX(a.y1, b.y1);
+ return r;
+}
diff --git a/fitz/dev_bbox.c b/fitz/dev_bbox.c
new file mode 100644
index 00000000..27943a98
--- /dev/null
+++ b/fitz/dev_bbox.c
@@ -0,0 +1,95 @@
+#include "fitz.h"
+
+/* TODO: add clip stack and use to intersect bboxes */
+
+typedef struct fz_bboxdevice_s fz_bboxdevice;
+
+struct fz_bboxdevice_s
+{
+ fz_bbox *bbox;
+};
+
+static void
+fz_bboxfillpath(void *user, fz_path *path, int evenodd, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
+{
+ fz_bboxdevice *bdev = user;
+ fz_bbox bbox = fz_roundrect(fz_boundpath(path, nil, ctm));
+ *bdev->bbox = fz_unionbbox(*bdev->bbox, bbox);
+}
+
+static void
+fz_bboxstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
+{
+ fz_bboxdevice *bdev = user;
+ fz_bbox bbox = fz_roundrect(fz_boundpath(path, stroke, ctm));
+ *bdev->bbox = fz_unionbbox(*bdev->bbox, bbox);
+}
+
+static void
+fz_bboxfilltext(void *user, fz_text *text, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
+{
+ fz_bboxdevice *bdev = user;
+ fz_bbox bbox = fz_roundrect(fz_boundtext(text, ctm));
+ *bdev->bbox = fz_unionbbox(*bdev->bbox, bbox);
+}
+
+static void
+fz_bboxstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
+{
+ fz_bboxdevice *bdev = user;
+ fz_bbox bbox = fz_roundrect(fz_boundtext(text, ctm));
+ *bdev->bbox = fz_unionbbox(*bdev->bbox, bbox);
+}
+
+static void
+fz_bboxfillshade(void *user, fz_shade *shade, fz_matrix ctm)
+{
+ fz_bboxdevice *bdev = user;
+ fz_bbox bbox = fz_roundrect(fz_boundshade(shade, ctm));
+ *bdev->bbox = fz_unionbbox(*bdev->bbox, bbox);
+}
+
+static void
+fz_bboxfillimage(void *user, fz_pixmap *image, fz_matrix ctm)
+{
+ fz_bboxdevice *bdev = user;
+ fz_bbox bbox = fz_roundrect(fz_transformrect(ctm, fz_unityrect));
+ *bdev->bbox = fz_unionbbox(*bdev->bbox, bbox);
+}
+
+static void
+fz_bboxfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
+{
+ fz_bboxfillimage(user, image, ctm);
+}
+
+static void
+fz_bboxfreeuser(void *user)
+{
+ fz_bboxdevice *bdev = user;
+ fz_free(bdev);
+}
+
+fz_device *
+fz_newbboxdevice(fz_bbox *bboxp)
+{
+ fz_bboxdevice *bdev = fz_malloc(sizeof(fz_bboxdevice));
+ bdev->bbox = bboxp;
+ *bdev->bbox = fz_emptybbox;
+
+ fz_device *dev = fz_newdevice(bdev);
+ dev->freeuser = fz_bboxfreeuser;
+ dev->fillpath = fz_bboxfillpath;
+ dev->strokepath = fz_bboxstrokepath;
+ dev->filltext = fz_bboxfilltext;
+ dev->stroketext = fz_bboxstroketext;
+ dev->fillshade = fz_bboxfillshade;
+ dev->fillimage = fz_bboxfillimage;
+ dev->fillimagemask = fz_bboxfillimagemask;
+ return dev;
+}
diff --git a/fitz/fitz_base.h b/fitz/fitz_base.h
index 0048f489..40ae2c62 100644
--- a/fitz/fitz_base.h
+++ b/fitz/fitz_base.h
@@ -189,8 +189,13 @@ typedef struct fz_point_s fz_point;
typedef struct fz_rect_s fz_rect;
typedef struct fz_bbox_s fz_bbox;
-extern fz_rect fz_emptyrect;
-extern fz_rect fz_infiniterect;
+extern const fz_rect fz_unityrect;
+extern const fz_rect fz_emptyrect;
+extern const fz_rect fz_infiniterect;
+
+extern const fz_bbox fz_unitybbox;
+extern const fz_bbox fz_emptybbox;
+extern const fz_bbox fz_infinitebbox;
#define fz_isemptyrect(r) ((r).x0 == (r).x1)
#define fz_isinfiniterect(r) ((r).x0 > (r).x1)
@@ -235,6 +240,7 @@ float fz_matrixexpansion(fz_matrix m);
fz_bbox fz_roundrect(fz_rect r);
fz_bbox fz_intersectbbox(fz_bbox a, fz_bbox b);
+fz_bbox fz_unionbbox(fz_bbox a, fz_bbox b);
fz_point fz_transformpoint(fz_matrix m, fz_point p);
fz_rect fz_transformrect(fz_matrix m, fz_rect r);
diff --git a/fitz/fitz_res.h b/fitz/fitz_res.h
index b9305ac1..6b16b8a4 100644
--- a/fitz/fitz_res.h
+++ b/fitz/fitz_res.h
@@ -101,6 +101,8 @@ void fz_freedevice(fz_device *dev);
fz_device *fz_newtracedevice(void);
+fz_device *fz_newbboxdevice(fz_bbox *bboxp);
+
/* Text extraction device */
typedef struct fz_textspan_s fz_textspan;