summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2004-11-24 03:47:04 +0100
committerTor Andersson <tor@ghostscript.com>2004-11-24 03:47:04 +0100
commitb48de7618e25bc2cef9d9db4f9b49e1d546e438a (patch)
tree5f365a90a0bd355073e7d5d1f69e66d2f82b4446
parente092458f4403f1424d8fd1f5ec194880a05c3362 (diff)
downloadmupdf-b48de7618e25bc2cef9d9db4f9b49e1d546e438a.tar.xz
rewrite of render loop part 3
-rw-r--r--Jamfile2
-rw-r--r--TODO8
-rw-r--r--base/rect.c58
-rw-r--r--include/fitz/geometry.h8
-rw-r--r--include/fitz/pixmap.h5
-rw-r--r--include/fitz/render.h56
-rw-r--r--include/mupdf/rsrc.h1
-rw-r--r--mupdf/type3.c18
-rw-r--r--render/pixmap.c117
-rw-r--r--render/rastnone.c385
-rw-r--r--render/rastport.c448
-rw-r--r--render/render.c427
-rw-r--r--test/ximage.c7
-rw-r--r--tree/debug.c14
-rw-r--r--tree/node1.c2
-rw-r--r--tree/node2.c73
-rw-r--r--tree/path.c27
-rw-r--r--tree/text.c2
-rw-r--r--tree/tree.c2
19 files changed, 871 insertions, 789 deletions
diff --git a/Jamfile b/Jamfile
index 4a56f5a9..ebf69619 100644
--- a/Jamfile
+++ b/Jamfile
@@ -87,7 +87,7 @@ Library libfitz :
render/fill.c
render/stroke.c
render/scale.c
- render/rastnone.c
+ render/rastport.c
render/render.c
;
diff --git a/TODO b/TODO
index 7f95264b..bbe23a8e 100644
--- a/TODO
+++ b/TODO
@@ -16,7 +16,6 @@ shadings
rendering
- bbox culling (cache bbox in over node?)
- - image mask + color case
- merge gka optims
- optimize inner rendering loops
- optimize image load/decode/scale
@@ -27,7 +26,12 @@ parser
- resource dict generate fake ids
- try to clean up colorspace/material handling in interpreter
- annotations and destinations (for links and outline)
- - BPC 2, 4
+
+fz_optimizetree()
+ - remove rectangular clip nodes whose children fit
+ - remove white fills at beginning of page
+ - remove overs with only one child
+ - concatenate chained transforms
clean up
- make source ansi c89 / pedantic
diff --git a/base/rect.c b/base/rect.c
index 6df6749a..2efb11f7 100644
--- a/base/rect.c
+++ b/base/rect.c
@@ -1,38 +1,43 @@
#include <fitz.h>
-static fz_rect none = { { 0, 0}, {0, 0} };
-static fz_irect inone = { { 0, 0}, {0, 0} };
+fz_rect fz_infiniterect = { { 1, 1}, {-1, -1} };
+fz_rect fz_emptyrect = { { 0, 0}, {0, 0} };
-fz_rect
-fz_infiniterect(void)
+static fz_irect infinite = { { 1, 1}, {-1, -1} };
+static fz_irect empty = { { 0, 0}, {0, 0} };
+
+fz_irect
+fz_roundrect(fz_rect f)
{
- fz_rect r;
- r.min.x = 1;
- r.min.y = 1;
- r.max.x = -1;
- r.max.y = -1;
- return r;
+ fz_irect i;
+ i.min.x = fz_floor(f.min.x);
+ i.min.y = fz_floor(f.min.y);
+ i.max.x = fz_ceil(f.max.x);
+ i.max.y = fz_ceil(f.max.y);
+ return i;
}
fz_rect
fz_intersectrects(fz_rect a, fz_rect b)
{
fz_rect r;
- if (a.max.x < a.min.x)
- return (b.max.x < b.min.x) ? none : b;
+ if (fz_isinfiniterect(a)) return b;
+ if (fz_isinfiniterect(b)) return a;
r.min.x = MAX(a.min.x, b.min.x);
r.min.y = MAX(a.min.y, b.min.y);
r.max.x = MIN(a.max.x, b.max.x);
r.max.y = MIN(a.max.y, b.max.y);
- return (r.max.x < r.min.x || r.max.y < r.min.y) ? none : r;
+ return (r.max.x < r.min.x || r.max.y < r.min.y) ? fz_emptyrect : r;
}
fz_rect
fz_mergerects(fz_rect a, fz_rect b)
{
fz_rect r;
- if (a.max.x < a.min.x)
- return (b.max.x < b.min.x) ? none : b;
+ if (fz_isinfiniterect(a) || fz_isinfiniterect(b))
+ return fz_infiniterect;
+ if (fz_isemptyrect(a)) return b;
+ if (fz_isemptyrect(b)) return a;
r.min.x = MIN(a.min.x, b.min.x);
r.min.y = MIN(a.min.y, b.min.y);
r.max.x = MAX(a.max.x, b.max.x);
@@ -41,35 +46,26 @@ fz_mergerects(fz_rect a, fz_rect b)
}
fz_irect
-fz_roundrect(fz_rect f)
-{
- fz_irect i;
- i.min.x = fz_floor(f.min.x);
- i.min.y = fz_floor(f.min.y);
- i.max.x = fz_ceil(f.max.x);
- i.max.y = fz_ceil(f.max.y);
- return i;
-}
-
-fz_irect
fz_intersectirects(fz_irect a, fz_irect b)
{
fz_irect r;
- if (a.max.x < a.min.x)
- return (b.max.x < b.min.x) ? inone : b;
+ if (fz_isinfiniterect(a)) return b;
+ if (fz_isinfiniterect(b)) return a;
r.min.x = MAX(a.min.x, b.min.x);
r.min.y = MAX(a.min.y, b.min.y);
r.max.x = MIN(a.max.x, b.max.x);
r.max.y = MIN(a.max.y, b.max.y);
- return (r.max.x < r.min.x || r.max.y < r.min.y) ? inone : r;
+ return (r.max.x < r.min.x || r.max.y < r.min.y) ? empty : r;
}
fz_irect
fz_mergeirects(fz_irect a, fz_irect b)
{
fz_irect r;
- if (a.max.x < a.min.x)
- return (b.max.x < b.min.x) ? inone : b;
+ if (fz_isinfiniterect(a) || fz_isinfiniterect(b))
+ return infinite;
+ if (fz_isemptyrect(a)) return b;
+ if (fz_isemptyrect(b)) return a;
r.min.x = MIN(a.min.x, b.min.x);
r.min.y = MIN(a.min.y, b.min.y);
r.max.x = MAX(a.max.x, b.max.x);
diff --git a/include/fitz/geometry.h b/include/fitz/geometry.h
index 96977cc6..7d2adc98 100644
--- a/include/fitz/geometry.h
+++ b/include/fitz/geometry.h
@@ -4,6 +4,12 @@ typedef struct fz_rect_s fz_rect;
typedef struct fz_ipoint_s fz_ipoint;
typedef struct fz_irect_s fz_irect;
+extern fz_rect fz_emptyrect;
+extern fz_rect fz_infiniterect;
+
+#define fz_isemptyrect(r) ((r).min.x == (r).max.x)
+#define fz_isinfiniterect(r) ((r).min.x > (r).max.x)
+
/*
/ a b 0 \
| c d 0 |
@@ -38,8 +44,6 @@ struct fz_irect_s
void fz_invert3x3(float *dst, float *m);
-fz_rect fz_infiniterect(void);
-
fz_matrix fz_concat(fz_matrix one, fz_matrix two);
fz_matrix fz_identity(void);
fz_matrix fz_scale(float sx, float sy);
diff --git a/include/fitz/pixmap.h b/include/fitz/pixmap.h
index 6d0391fa..c369df84 100644
--- a/include/fitz/pixmap.h
+++ b/include/fitz/pixmap.h
@@ -15,12 +15,11 @@ struct fz_pixmap_s
fz_error *fz_newpixmapwithrect(fz_pixmap **mapp, fz_irect bbox, int n);
fz_error *fz_newpixmap(fz_pixmap **mapp, int x, int y, int w, int h, int n);
+fz_error *fz_newpixmapcopy(fz_pixmap **pixp, fz_pixmap *old);
+
void fz_debugpixmap(fz_pixmap *map);
void fz_clearpixmap(fz_pixmap *map);
void fz_droppixmap(fz_pixmap *map);
fz_error *fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom);
-void fz_blendover(fz_pixmap *src, fz_pixmap *dst);
-void fz_blendmask(fz_pixmap *dst, fz_pixmap *color, fz_pixmap *shape);
-
diff --git a/include/fitz/render.h b/include/fitz/render.h
index 807b6227..e2435382 100644
--- a/include/fitz/render.h
+++ b/include/fitz/render.h
@@ -2,39 +2,42 @@ typedef struct fz_renderer_s fz_renderer;
typedef struct fz_rastfuncs_s fz_rastfuncs;
#define FZ_BYTE unsigned char
-#define FZ_PID \
- FZ_BYTE *src, int w, int h, int nx, int ny, \
- FZ_BYTE *dst0, int dstw, \
- int u0, int v0, int fa, int fb, int fc, int fd
-#define FZ_PIM \
- FZ_BYTE *src, int w, int h, int nx, int ny, \
- FZ_BYTE *dst0, int dstw, \
- FZ_BYTE *msk0, int mskw, \
- int u0, int v0, int fa, int fb, int fc, int fd
+
+#define FZ_PSRC \
+ unsigned char *src, int srcw, int srch
+#define FZ_PDST \
+ unsigned char *dst0, int dstw
+#define FZ_PCTM \
+ int u0, int v0, int fa, int fb, int fc, int fd, int w0, int h
struct fz_rastfuncs_s
{
- void (*mask_g)(int, FZ_BYTE*, FZ_BYTE*);
- void (*mask_i1)(int, FZ_BYTE*, FZ_BYTE*);
- void (*mask_o1)(int, FZ_BYTE*, FZ_BYTE*);
- void (*mask_i1o1)(int, FZ_BYTE*, FZ_BYTE*, FZ_BYTE*);
- void (*mask_o4w3)(int, FZ_BYTE*, FZ_BYTE*, FZ_BYTE*);
- void (*mask_i1o4w3)(int, FZ_BYTE*, FZ_BYTE*, FZ_BYTE*, FZ_BYTE*);
+ void (*duff_NoN)(FZ_BYTE*,int,int,FZ_BYTE*,int,int,int);
+ void (*duff_NiMcN)(FZ_BYTE*,int,int,FZ_BYTE*,int,int,FZ_BYTE*,int,int,int);
+ void (*duff_NiMoN)(FZ_BYTE*,int,int,FZ_BYTE*,int,int,FZ_BYTE*,int,int,int);
+ void (*duff_1o1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+ void (*duff_4o4)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+ void (*duff_1i1c1)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+ void (*duff_4i1c4)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+ void (*duff_1i1o1)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+ void (*duff_4i1o4)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+
+ void (*msk_1c1)(FZ_BYTE*,FZ_BYTE*,int);
+ void (*msk_1o1)(FZ_BYTE*,FZ_BYTE*,int);
+ void (*msk_w3i1o4)(FZ_BYTE*,FZ_BYTE*,FZ_BYTE*,int);
- void (*img1_g)(FZ_PID);
- void (*img1_i1)(FZ_PID);
- void (*img1_o1)(FZ_PID);
- void (*img1_i1o1)(FZ_PIM);
- void (*img1_o4w3)(FZ_PID, FZ_BYTE*);
- void (*img1_i1o4w3)(FZ_PIM, FZ_BYTE*);
+ void (*glf_1c1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+ void (*glf_1o1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+ void (*glf_w3i1o4)(FZ_BYTE*,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
- void (*img4_g)(FZ_PID);
- void (*img4_o4)(FZ_PID);
- void (*img4_i1o4)(FZ_PIM);
+ void (*img_NcN)(FZ_PSRC, int sn, FZ_PDST, FZ_PCTM);
+ void (*img_1c1)(FZ_PSRC, FZ_PDST, FZ_PCTM);
+ void (*img_4c4)(FZ_PSRC, FZ_PDST, FZ_PCTM);
+ void (*img_1o1)(FZ_PSRC, FZ_PDST, FZ_PCTM);
+ void (*img_4o4)(FZ_PSRC, FZ_PDST, FZ_PCTM);
+ void (*img_w3i1o4)(FZ_BYTE*,FZ_PSRC,FZ_PDST,FZ_PCTM);
};
-#undef FZ_PIM
-#undef FZ_PID
#undef FZ_BYTE
struct fz_renderer_s
@@ -50,7 +53,6 @@ struct fz_renderer_s
fz_irect clip;
fz_pixmap *dest;
fz_pixmap *over;
- fz_pixmap *mask;
unsigned char rgb[3];
int flag;
};
diff --git a/include/mupdf/rsrc.h b/include/mupdf/rsrc.h
index 9139a8e5..91deb38d 100644
--- a/include/mupdf/rsrc.h
+++ b/include/mupdf/rsrc.h
@@ -155,7 +155,6 @@ struct pdf_font_s
fz_buffer *fontdata;
/* Type3 data */
- fz_rect bbox;
fz_matrix matrix;
fz_tree *charprocs[256];
};
diff --git a/mupdf/type3.c b/mupdf/type3.c
index 64ef9a2c..082f4ce8 100644
--- a/mupdf/type3.c
+++ b/mupdf/type3.c
@@ -99,6 +99,7 @@ pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict)
fz_obj *obj;
int first, last;
int i, k, n;
+ fz_rect bbox;
obj = fz_dictgets(dict, "Name");
if (obj)
@@ -128,13 +129,18 @@ printf(" matrix [%g %g %g %g %g %g]\n",
font->matrix.c, font->matrix.d,
font->matrix.e, font->matrix.f);
- /* TODO: scale bbox by fontmatrix * 1000 */
obj = fz_dictgets(dict, "FontBBox");
- fz_setfontbbox((fz_font*)font,
- fz_toreal(fz_arrayget(obj, 0)),
- fz_toreal(fz_arrayget(obj, 1)),
- fz_toreal(fz_arrayget(obj, 2)),
- fz_toreal(fz_arrayget(obj, 3)));
+ bbox.min.x = fz_toreal(fz_arrayget(obj, 0));
+ bbox.min.y = fz_toreal(fz_arrayget(obj, 1));
+ bbox.max.x = fz_toreal(fz_arrayget(obj, 2));
+ bbox.max.y = fz_toreal(fz_arrayget(obj, 3));
+ bbox = fz_transformaabb(font->matrix, bbox);
+ bbox.min.x = fz_floor(bbox.min.x * 1000);
+ bbox.min.y = fz_floor(bbox.min.x * 1000);
+ bbox.max.x = fz_ceil(bbox.max.x * 1000);
+ bbox.max.y = fz_ceil(bbox.max.x * 1000);
+ fz_setfontbbox((fz_font*)font, bbox.min.x, bbox.min.y, bbox.max.x, bbox.max.y);
+printf(" bbox [%g %g %g %g]\n", bbox.min.x,bbox.min.y,bbox.max.x,bbox.max.y);
/*
* Encoding
diff --git a/render/pixmap.c b/render/pixmap.c
index 21f36ee0..c024a025 100644
--- a/render/pixmap.c
+++ b/render/pixmap.c
@@ -33,6 +33,17 @@ fz_newpixmapwithrect(fz_pixmap **pixp, fz_irect r, int n)
r.max.y - r.min.y, n);
}
+fz_error *
+fz_newpixmapcopy(fz_pixmap **pixp, fz_pixmap *old)
+{
+ fz_error *error;
+ error = fz_newpixmap(pixp, old->x, old->y, old->w, old->h, old->n);
+ if (error)
+ return error;
+ memcpy((*pixp)->samples, old->samples, old->w * old->h * old->n);
+ return nil;
+}
+
void
fz_droppixmap(fz_pixmap *pix)
{
@@ -47,112 +58,6 @@ fz_clearpixmap(fz_pixmap *pix)
}
void
-fz_blendover(fz_pixmap *src, fz_pixmap *dst)
-{
- int x, y, k;
- fz_irect sr, dr, rect;
- unsigned char *s;
- unsigned char *d;
-
- assert(dst->n == src->n || src->n == 1);
-
- sr.min.x = src->x;
- sr.min.y = src->y;
- sr.max.x = src->x + src->w;
- sr.max.y = src->y + src->h;
-
- dr.min.x = dst->x;
- dr.min.y = dst->y;
- dr.max.x = dst->x + dst->w;
- dr.max.y = dst->y + dst->h;
-
- rect = fz_intersectirects(sr, dr);
-
- if (dst->n == src->n)
- {
- for (y = rect.min.y; y < rect.max.y; y++)
- {
- s = src->samples + ((rect.min.x - src->x) + (y - src->y) * src->w) * src->n;
- d = dst->samples + ((rect.min.x - dst->x) + (y - dst->y) * dst->w) * dst->n;
- for (x = rect.min.x; x < rect.max.x; x++)
- {
- int sa = s[0];
- int ssa = 255 - sa;
-
- for (k = 0; k < dst->n; k++)
- d[k] = s[k] + fz_mul255(d[k], ssa);
-
- s += src->n;
- d += dst->n;
- }
- }
- }
- else if (src->n == 1)
- {
- for (y = rect.min.y; y < rect.max.y; y++)
- {
- s = src->samples + ((rect.min.x - src->x) + (y - src->y) * src->w) * src->n;
- d = dst->samples + ((rect.min.x - dst->x) + (y - dst->y) * dst->w) * dst->n;
- for (x = rect.min.x; x < rect.max.x; x++)
- {
- int sa = s[0];
- int ssa = 255 - sa;
-
- d[0] = s[0] + fz_mul255(d[0], ssa);
- for (k = 1; k < dst->n; k++)
- d[k] = 0 + fz_mul255(d[k], ssa);
-
- s += src->n;
- d += dst->n;
- }
- }
- }
-}
-
-void
-fz_blendmask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk)
-{
- unsigned char *d;
- unsigned char *s;
- unsigned char *m;
- fz_irect sr, dr, mr, rect;
- int x, y, k;
-
- assert(src->n == dst->n);
-
- sr.min.x = src->x;
- sr.min.y = src->y;
- sr.max.x = src->x + src->w;
- sr.max.y = src->y + src->h;
-
- dr.min.x = dst->x;
- dr.min.y = dst->y;
- dr.max.x = dst->x + dst->w;
- dr.max.y = dst->y + dst->h;
-
- mr.min.x = msk->x;
- mr.min.y = msk->y;
- mr.max.x = msk->x + msk->w;
- mr.max.y = msk->y + msk->h;
-
- rect = fz_intersectirects(sr, dr);
- rect = fz_intersectirects(rect, mr);
-
- for (y = rect.min.y; y < rect.max.y; y++)
- {
- s = src->samples + ((rect.min.x - src->x) + (y - src->y) * src->w) * src->n;
- d = dst->samples + ((rect.min.x - dst->x) + (y - dst->y) * dst->w) * dst->n;
- m = msk->samples + ((rect.min.x - msk->x) + (y - msk->y) * msk->w) * msk->n;
- for (x = rect.min.x; x < rect.max.x; x++)
- {
- for (k = 0; k < dst->n; k++)
- *d++ = fz_mul255(*s++, *m);
- m += msk->n;
- }
- }
-}
-
-void
fz_gammapixmap(fz_pixmap *pix, float gamma)
{
unsigned char table[255];
diff --git a/render/rastnone.c b/render/rastnone.c
deleted file mode 100644
index 2af45882..00000000
--- a/render/rastnone.c
+++ /dev/null
@@ -1,385 +0,0 @@
-#include <fitz.h>
-
-/* XXX: half of these funcs are totally wrong. fix! */
-
-typedef unsigned char byte;
-
-/*
- * Mask -- blit one span (clipped and adjusted)
- *
- * mask_g
- * mask_i1
- * mask_o1
- * mask_i1o1
- * mask_o4w3
- * mask_i1o4w3
- */
-
-static void mask_g(int n, byte *src, byte *pix)
-{
- memcpy(pix, src, n);
-}
-
-static void mask_i1(int n, byte *src, byte *dst)
-{
- while (n--)
- {
- dst[0] = fz_mul255(src[0], dst[0]);
- src++;
- dst++;
- }
-}
-
-static void mask_o1(int n, byte *src, byte *dst)
-{
- while (n--)
- {
- dst[0] = src[0] + fz_mul255(dst[0], 255 - src[0]);
- src++;
- dst++;
- }
-}
-
-static void mask_i1o1(int n, byte *src, byte *msk, byte *dst)
-{
- while (n--)
- {
- byte sa = fz_mul255(src[0], msk[0]);
- dst[0] = sa + fz_mul255(dst[0], 255 - sa);
- src++;
- msk++;
- dst++;
- }
-}
-
-static void mask_o4w3(int n, byte *src, byte *dst, byte *rgb)
-{
- byte sa, ssa;
- while (n--)
- {
- sa = src[0];
- ssa = 255 - sa;
- dst[0] = sa + fz_mul255(dst[0], ssa);
- dst[1] = rgb[0] + fz_mul255((short)dst[1] - rgb[0], ssa);
- dst[2] = rgb[1] + fz_mul255((short)dst[2] - rgb[1], ssa);
- dst[3] = rgb[2] + fz_mul255((short)dst[3] - rgb[2], ssa);
- src ++;
- dst += 4;
- }
-}
-
-static void mask_i1o4w3(int n, byte *src, byte *msk, byte *dst, byte *rgb)
-{
- byte sa, ssa;
- while (n--)
- {
- sa = fz_mul255(src[0], msk[0]);
- ssa = 255 - sa;
- dst[0] = sa + fz_mul255(dst[0], ssa);
- dst[1] = rgb[0] + fz_mul255((short)dst[1] - rgb[0], ssa);
- dst[2] = rgb[1] + fz_mul255((short)dst[2] - rgb[1], ssa);
- dst[3] = rgb[2] + fz_mul255((short)dst[3] - rgb[2], ssa);
- src ++;
- msk ++;
- dst += 4;
- }
-}
-
-/*
- * Image -- blit entire image
- *
- * img1_g
- * img1_i1
- * img1_o1
- * img1_i1o1
- * img1_o4w3
- * img1_i1o4w3
- *
- * img4_g
- * img4_o4
- * img4_i1o4
- */
-
-#define lerpmsk(a,b,t) (a + (((b - a) * t) >> 16))
-
-static inline byte getmsk(byte *s, int w, int h, int u, int v)
-{
- if (u < 0 || u >= w) return 0;
- if (v < 0 || v >= h) return 0;
- return s[w * v + u];
-}
-
-static inline int samplemsk(byte *s, int w, int h, int u, int v)
-{
- int ui = u >> 16;
- int vi = v >> 16;
- int ud = u & 0xFFFF;
- int vd = v & 0xFFFF;
- int a = getmsk(s, w, h, ui, vi);
- int b = getmsk(s, w, h, ui+1, vi);
- int c = getmsk(s, w, h, ui, vi+1);
- int d = getmsk(s, w, h, ui+1, vi+1);
- int ab = lerpmsk(a, b, ud);
- int cd = lerpmsk(c, d, ud);
- return lerpmsk(ab, cd, vd);
-}
-
-static inline void lerpargb(byte *dst, byte *a, byte *b, int t)
-{
- dst[0] = lerpmsk(a[0], b[0], t);
- dst[1] = lerpmsk(a[1], b[1], t);
- dst[2] = lerpmsk(a[2], b[2], t);
- dst[3] = lerpmsk(a[3], b[3], t);
-}
-
-static inline byte *getargb(byte *s, int w, int h, int u, int v)
-{
- static byte zero[4] = { 0, 0, 0, 0 };
- if (u < 0 || u >= w) return zero;
- if (v < 0 || v >= h) return zero;
- return s + ((w * v + u) << 2);
-}
-
-static inline void sampleargb(byte *s, int w, int h, int u, int v, byte *abcd)
-{
- byte ab[4];
- byte cd[4];
- int ui = u >> 16;
- int vi = v >> 16;
- int ud = u & 0xFFFF;
- int vd = v & 0xFFFF;
- byte *a = getargb(s, w, h, ui, vi);
- byte *b = getargb(s, w, h, ui+1, vi);
- byte *c = getargb(s, w, h, ui, vi+1);
- byte *d = getargb(s, w, h, ui+1, vi+1);
- lerpargb(ab, a, b, ud);
- lerpargb(cd, c, d, ud);
- lerpargb(abcd, ab, cd, vd);
-}
-
-#define PSRC byte *src, int w, int h, int nx0, int ny
-#define PDST byte *dst0, int dstw
-#define PMSK byte *msk0, int mskw
-#define PCTM int u0, int v0, int fa, int fb, int fc, int fd
-
-#if 0
-static void example(PSRC, PDST, PMSK, PCTM)
-{
- while (ny--)
- {
- byte *dst = dst0;
- byte *msk = msk0;
- int u = u0;
- int v = v0;
- int nx = nx0;
- while (nx--)
- {
- // dst[0] = ... msk[0] ... sample(s, w, h, u, v);
- dst ++;
- msk ++;
- u += fa;
- v += fb;
- }
- u0 += fc;
- v0 += fd;
- dst0 += dstw;
- msk0 += mskw;
- }
-}
-#endif
-
-#define BEGLOOP \
- while (ny--) \
- { \
- byte *dst = dst0; \
- int u = u0; \
- int v = v0; \
- int nx = nx0; \
- while (nx--)
-
-#define ENDLOOP \
- u0 += fc; \
- v0 += fd; \
- dst0 += dstw; \
- }
-
-#define BEGLOOPM \
- while (ny--) \
- { \
- byte *dst = dst0; \
- byte *msk = msk0; \
- int u = u0; \
- int v = v0; \
- int nx = nx0; \
- while (nx--)
-
-#define ENDLOOPM \
- u0 += fc; \
- v0 += fd; \
- dst0 += dstw; \
- msk0 += mskw; \
- }
-
-static void img1_g(PSRC, PDST, PCTM)
-{
- BEGLOOP
- {
- dst[0] = samplemsk(src, w, h, u, v);
- dst ++;
- u += fa;
- v += fb;
- }
- ENDLOOP
-}
-
-static void img1_i1(PSRC, PDST, PCTM)
-{
- BEGLOOP
- {
- dst[0] = fz_mul255(dst[0], samplemsk(src, w, h, u, v));
- dst ++;
- u += fa;
- v += fb;
- }
- ENDLOOP
-}
-
-static void img1_o1(PSRC, PDST, PCTM)
-{
- BEGLOOP
- {
- byte sa = samplemsk(src, w, h, u, v);
- dst[0] = sa + fz_mul255(dst[0], 255 - sa);
- dst ++;
- u += fa;
- v += fb;
- }
- ENDLOOP
-}
-
-static void img1_i1o1(PSRC, PDST, PMSK, PCTM)
-{
- BEGLOOPM
- {
- byte sa = fz_mul255(msk[0], samplemsk(src, w, h, u, v));
- dst[0] = sa + fz_mul255(dst[0], 255 - sa);
- dst ++;
- msk ++;
- u += fa;
- v += fb;
- }
- ENDLOOPM
-}
-
-static void img1_o4w3(PSRC, PDST, PCTM, byte *rgb)
-{
- BEGLOOP
- {
- byte sa = samplemsk(src, w, h, u, v);
- byte ssa = 255 - sa;
- dst[0] = sa + fz_mul255(dst[0], ssa);
- dst[1] = rgb[0] + fz_mul255((short)dst[1] - rgb[0], ssa);
- dst[2] = rgb[1] + fz_mul255((short)dst[2] - rgb[1], ssa);
- dst[3] = rgb[2] + fz_mul255((short)dst[3] - rgb[2], ssa);
- dst += 4;
- u += fa;
- v += fb;
- }
- ENDLOOP
-}
-
-static void img1_i1o4w3(PSRC, PDST, PMSK, PCTM, byte *rgb)
-{
- BEGLOOPM
- {
- byte sa = fz_mul255(msk[0], samplemsk(src, w, h, u, v));
- byte ssa = 255 - sa;
- dst[0] = sa + fz_mul255(dst[0], ssa);
- dst[1] = rgb[0] + fz_mul255((short)dst[1] - rgb[0], ssa);
- dst[2] = rgb[1] + fz_mul255((short)dst[2] - rgb[1], ssa);
- dst[3] = rgb[2] + fz_mul255((short)dst[3] - rgb[2], ssa);
- dst += 4;
- msk ++;
- u += fa;
- v += fb;
- }
- ENDLOOPM
-}
-
-static void img4_g(PSRC, PDST, PCTM)
-{
- BEGLOOP
- {
- sampleargb(src, w, h, u, v, dst);
- dst += 4;
- u += fa;
- v += fb;
- }
- ENDLOOP
-}
-
-static void img4_o4(PSRC, PDST, PCTM)
-{
- byte argb[4];
- BEGLOOP
- {
- sampleargb(src, w, h, u, v, argb);
- byte sa = argb[0];
- byte ssa = 255 - sa;
- dst[0] = sa + fz_mul255(dst[0], ssa);
- dst[1] = argb[1] + fz_mul255(dst[1], ssa);
- dst[2] = argb[2] + fz_mul255(dst[2], ssa);
- dst[3] = argb[3] + fz_mul255(dst[3], ssa);
- dst += 4;
- u += fa;
- v += fb;
- }
- ENDLOOP
-}
-
-static void img4_i1o4(PSRC, PDST, PMSK, PCTM)
-{
- byte argb[4];
- BEGLOOPM
- {
- sampleargb(src, w, h, u, v, argb);
- byte sa = fz_mul255(msk[0], argb[0]);
- byte ssa = 255 - sa;
- dst[0] = argb[0] + fz_mul255(dst[0], ssa);
- dst[1] = argb[1] + fz_mul255((short)dst[1] - argb[1], ssa);
- dst[2] = argb[2] + fz_mul255((short)dst[2] - argb[2], ssa);
- dst[3] = argb[3] + fz_mul255((short)dst[3] - argb[3], ssa);
- dst += 4;
- msk ++;
- u += fa;
- v += fb;
- }
- ENDLOOPM
-}
-
-/*
- *
- */
-
-void
-fz_defaultrastfuncs(fz_rastfuncs *tab)
-{
- tab->mask_g = mask_g;
- tab->mask_i1 = mask_i1;
- tab->mask_o1 = mask_o1;
- tab->mask_i1o1 = mask_i1o1;
- tab->mask_o4w3 = mask_o4w3;
- tab->mask_i1o4w3 = mask_i1o4w3;
-
- tab->img1_g = img1_g;
- tab->img1_i1 = img1_i1;
- tab->img1_o1 = img1_o1;
- tab->img1_i1o1 = img1_i1o1;
- tab->img1_o4w3 = img1_o4w3;
- tab->img1_i1o4w3 = img1_i1o4w3;
-
- tab->img4_g = img4_g;
- tab->img4_o4 = img4_o4;
- tab->img4_i1o4 = img4_i1o4;
-}
-
diff --git a/render/rastport.c b/render/rastport.c
new file mode 100644
index 00000000..0daf3458
--- /dev/null
+++ b/render/rastport.c
@@ -0,0 +1,448 @@
+#include <fitz.h>
+
+/* XXX: half of these funcs are totally wrong. fix! */
+
+typedef unsigned char byte;
+
+/*
+ * General Porter-Duff compositing -- blit image regions
+ *
+ * duff_NoN
+ * duff_NiM
+ * duff_NiMoN
+ */
+
+/* dst = src over dst */
+static void
+duff_NoN(byte *sp0, int sw, int sn, byte *dp0, int dw, int w0, int h)
+{
+ int k;
+ while (h--)
+ {
+ byte *sp = sp0;
+ byte *dp = dp0;
+ int w = w0;
+ while (w--)
+ {
+ byte sa = sp[0];
+ byte ssa = 255 - sa;
+ for (k = 0; k < sn; k++)
+ {
+ dp[k] = sp[k] + fz_mul255(dp[k], ssa);
+ }
+ sp += sn;
+ dp += sn;
+ }
+ sp0 += sw;
+ dp0 += dw;
+ }
+}
+
+/* dst = src in msk */
+static void
+duff_NiMcN(byte *sp0, int sw, int sn, byte *mp0, int mw, int mn, byte *dp0, int dw, int w0, int h)
+{
+ int k;
+ while (h--)
+ {
+ byte *sp = sp0;
+ byte *mp = mp0;
+ byte *dp = dp0;
+ int w = w0;
+ while (w--)
+ {
+ byte ma = mp[0];
+ for (k = 0; k < sn; k++)
+ dp[k] = fz_mul255(sp[k], ma);
+ sp += sn;
+ mp += mn;
+ dp += sn;
+ }
+ sp0 += sw;
+ mp0 += mw;
+ dp0 += dw;
+ }
+}
+
+/* dst = src in msk over dst */
+static void
+duff_NiMoN(byte *sp0, int sw, int sn, byte *mp0, int mw, int mn, byte *dp0, int dw, int w0, int h)
+{
+ int k;
+ while (h--)
+ {
+ byte *sp = sp0;
+ byte *mp = mp0;
+ byte *dp = dp0;
+ int w = w0;
+ while (w--)
+ {
+ byte ma = mp[0];
+ byte sa = fz_mul255(sp[0], ma);
+ byte ssa = 255 - sa;
+ for (k = 0; k < sn; k++)
+ {
+ dp[k] = fz_mul255(sp[k], ma) + fz_mul255(dp[k], ssa);
+ }
+ sp += sn;
+ mp += mn;
+ dp += sn;
+ }
+ sp0 += sw;
+ mp0 += mw;
+ dp0 += dw;
+ }
+}
+
+static void duff_1o1(byte *sp0, int sw, byte *dp0, int dw, int w0, int h)
+{
+ duff_NoN(sp0, sw, 1, dp0, dw, w0, h);
+}
+
+static void duff_4o4(byte *sp0, int sw, byte *dp0, int dw, int w0, int h)
+{
+ duff_NoN(sp0, sw, 4, dp0, dw, w0, h);
+}
+
+static void duff_1i1c1(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h)
+{
+ duff_NiMcN(sp0, sw, 1, mp0, mw, 1, dp0, dw, w0, h);
+}
+
+static void duff_4i1c4(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h)
+{
+ duff_NiMcN(sp0, sw, 4, mp0, mw, 1, dp0, dw, w0, h);
+}
+
+static void duff_1i1o1(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h)
+{
+ duff_NiMoN(sp0, sw, 1, mp0, mw, 1, dp0, dw, w0, h);
+}
+
+static void duff_4i1o4(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h)
+{
+ duff_NiMoN(sp0, sw, 4, mp0, mw, 1, dp0, dw, w0, h);
+}
+
+/*
+ * Mask -- blit one scanline of mask
+ *
+ * msk_1c1
+ * msk_1o1
+ * msk_1i1c1
+ * msk_1i1o1
+ * msk_w3i1o4
+ * msk_w3i1i1o4
+ */
+
+static void msk_1c1(byte *src, byte *dst, int w)
+{
+ memcpy(dst, src, w);
+}
+
+static void msk_1o1(byte *src, byte *dst, int w)
+{
+ while (w--)
+ {
+ dst[0] = src[0] + fz_mul255(dst[0], 255 - src[0]);
+ src++;
+ dst++;
+ }
+}
+
+static void msk_w3i1o4(byte *rgb, byte *src, byte *dst, int n)
+{
+ byte sa, ssa;
+ while (n--)
+ {
+ sa = src[0];
+ ssa = 255 - sa;
+ dst[0] = sa + fz_mul255(dst[0], ssa);
+ dst[1] = rgb[0] + fz_mul255((short)dst[1] - rgb[0], ssa);
+ dst[2] = rgb[1] + fz_mul255((short)dst[2] - rgb[1], ssa);
+ dst[3] = rgb[2] + fz_mul255((short)dst[3] - rgb[2], ssa);
+ src ++;
+ dst += 4;
+ }
+}
+
+/*
+ * Image -- draw transformed image
+ *
+ */
+
+#define lerp(a,b,t) (a + (((b - a) * t) >> 16))
+
+static inline byte getcomp(byte *s, int w, int h, int u, int v, int n, int k)
+{
+ if (u < 0 || u >= w) return 0;
+ if (v < 0 || v >= h) return 0;
+ return s[(w * v + u) * n + k];
+}
+
+static inline int samplecomp(byte *s, int w, int h, int u, int v, int n, int k)
+{
+ int ui = u >> 16;
+ int vi = v >> 16;
+ int ud = u & 0xFFFF;
+ int vd = v & 0xFFFF;
+ int a = getcomp(s, w, h, ui, vi, n, k);
+ int b = getcomp(s, w, h, ui+1, vi, n, k);
+ int c = getcomp(s, w, h, ui, vi+1, n, k);
+ int d = getcomp(s, w, h, ui+1, vi+1, n, k);
+ int ab = lerp(a, b, ud);
+ int cd = lerp(c, d, ud);
+ return lerp(ab, cd, vd);
+}
+
+static inline byte getmask(byte *s, int w, int h, int u, int v)
+{
+ if (u < 0 || u >= w) return 0;
+ if (v < 0 || v >= h) return 0;
+ return s[w * v + u];
+}
+
+static inline int samplemask(byte *s, int w, int h, int u, int v)
+{
+ int ui = u >> 16;
+ int vi = v >> 16;
+ int ud = u & 0xFFFF;
+ int vd = v & 0xFFFF;
+ int a = getmask(s, w, h, ui, vi);
+ int b = getmask(s, w, h, ui+1, vi);
+ int c = getmask(s, w, h, ui, vi+1);
+ int d = getmask(s, w, h, ui+1, vi+1);
+ int ab = lerp(a, b, ud);
+ int cd = lerp(c, d, ud);
+ return lerp(ab, cd, vd);
+}
+
+static inline void lerpargb(byte *dst, byte *a, byte *b, int t)
+{
+ dst[0] = lerp(a[0], b[0], t);
+ dst[1] = lerp(a[1], b[1], t);
+ dst[2] = lerp(a[2], b[2], t);
+ dst[3] = lerp(a[3], b[3], t);
+}
+
+static inline byte *getargb(byte *s, int w, int h, int u, int v)
+{
+ static byte zero[4] = { 0, 0, 0, 0 };
+ if (u < 0 || u >= w) return zero;
+ if (v < 0 || v >= h) return zero;
+ return s + ((w * v + u) << 2);
+}
+
+static inline void sampleargb(byte *s, int w, int h, int u, int v, byte *abcd)
+{
+ byte ab[4];
+ byte cd[4];
+ int ui = u >> 16;
+ int vi = v >> 16;
+ int ud = u & 0xFFFF;
+ int vd = v & 0xFFFF;
+ byte *a = getargb(s, w, h, ui, vi);
+ byte *b = getargb(s, w, h, ui+1, vi);
+ byte *c = getargb(s, w, h, ui, vi+1);
+ byte *d = getargb(s, w, h, ui+1, vi+1);
+ lerpargb(ab, a, b, ud);
+ lerpargb(cd, c, d, ud);
+ lerpargb(abcd, ab, cd, vd);
+}
+
+/*
+ * img_NcN
+ * img_1c1
+ * img_4c4
+ * img_1o1
+ * img_4o4
+ * img_1i1c1
+ * img_1i1o1
+ * img_4i1c4
+ * img_4i1o4
+ * img_w3i1o4
+ * img_w3i1i1o4
+ */
+
+static void img_NcN(FZ_PSRC, int srcn, FZ_PDST, FZ_PCTM)
+{
+ int k;
+ while (h--)
+ {
+ byte *dstp = dst0;
+ int u = u0;
+ int v = v0;
+ int w = w0;
+ while (w--)
+ {
+ for (k = 0; k < srcn; k++)
+ {
+ dstp[k] = samplecomp(src, srcw, srch, u, v, srcn, k);
+ dstp += srcn;
+ u += fa;
+ v += fb;
+ }
+ }
+ dst0 += dstw;
+ u0 += fc;
+ v0 += fd;
+ }
+}
+
+static void img_1c1(FZ_PSRC, FZ_PDST, FZ_PCTM)
+{
+ while (h--)
+ {
+ byte *dstp = dst0;
+ int u = u0;
+ int v = v0;
+ int w = w0;
+ while (w--)
+ {
+ dstp[0] = samplemask(src, srcw, srch, u, v);
+ dstp ++;
+ u += fa;
+ v += fb;
+ }
+ dst0 += dstw;
+ u0 += fc;
+ v0 += fd;
+ }
+}
+
+static void img_4c4(FZ_PSRC, FZ_PDST, FZ_PCTM)
+{
+ while (h--)
+ {
+ byte *dstp = dst0;
+ int u = u0;
+ int v = v0;
+ int w = w0;
+ while (w--)
+ {
+ sampleargb(src, srcw, srch, u, v, dstp);
+ dstp += 4;
+ u += fa;
+ v += fb;
+ }
+ dst0 += dstw;
+ u0 += fc;
+ v0 += fd;
+ }
+}
+
+static void img_1o1(FZ_PSRC, FZ_PDST, FZ_PCTM)
+{
+ byte srca;
+ while (h--)
+ {
+ byte *dstp = dst0;
+ int u = u0;
+ int v = v0;
+ int w = w0;
+ while (w--)
+ {
+ srca = samplemask(src, srcw, srch, u, v);
+ dstp[0] = srca + fz_mul255(dstp[0], 255 - srca);
+ dstp ++;
+ u += fa;
+ v += fb;
+ }
+ dst0 += dstw;
+ u0 += fc;
+ v0 += fd;
+ }
+}
+
+static void img_4o4(FZ_PSRC, FZ_PDST, FZ_PCTM)
+{
+ byte argb[4];
+ while (h--)
+ {
+ byte *dstp = dst0;
+ int u = u0;
+ int v = v0;
+ int w = w0;
+ while (w--)
+ {
+ sampleargb(src, srcw, srch, u, v, argb);
+ byte ssa = 255 - argb[0];
+ dstp[0] = argb[0] + fz_mul255(dstp[0], ssa);
+ dstp[1] = argb[1] + fz_mul255((short)dstp[1] - argb[1], ssa);
+ dstp[2] = argb[2] + fz_mul255((short)dstp[2] - argb[2], ssa);
+ dstp[3] = argb[3] + fz_mul255((short)dstp[3] - argb[3], ssa);
+ dstp += 4;
+ u += fa;
+ v += fb;
+ }
+ dst0 += dstw;
+ u0 += fc;
+ v0 += fd;
+ }
+}
+
+static void img_w3i1o4(byte *rgb, FZ_PSRC, FZ_PDST, FZ_PCTM)
+{
+ byte sa, ssa;
+ while (h--)
+ {
+ byte *dstp = dst0;
+ int u = u0;
+ int v = v0;
+ int w = w0;
+ while (w--)
+ {
+ sa = samplemask(src, srcw, srch, u, v);
+ ssa = 255 - sa;
+ dstp[0] = sa + fz_mul255(dstp[0], ssa);
+ dstp[1] = rgb[0] + fz_mul255((short)dstp[1] - rgb[0], ssa);
+ dstp[2] = rgb[1] + fz_mul255((short)dstp[2] - rgb[1], ssa);
+ dstp[3] = rgb[2] + fz_mul255((short)dstp[3] - rgb[2], ssa);
+ dstp += 4;
+ u += fa;
+ v += fb;
+ }
+ dst0 += dstw;
+ u0 += fc;
+ v0 += fd;
+ }
+}
+
+/*
+ * Fill in the big fat vtable
+ */
+
+static fz_rastfuncs deftab =
+{
+ duff_NoN,
+ duff_NiMcN,
+ duff_NiMoN,
+ duff_1o1,
+ duff_4o4,
+ duff_1i1c1,
+ duff_4i1c4,
+ duff_1i1o1,
+ duff_4i1o4,
+
+ msk_1c1,
+ msk_1o1,
+ msk_w3i1o4,
+
+ nil,
+ nil,
+ nil,
+
+ img_NcN,
+ img_1c1,
+ img_4c4,
+ img_1o1,
+ img_4o4,
+ img_w3i1o4
+};
+
+void
+fz_defaultrastfuncs(fz_rastfuncs *tab)
+{
+ *tab = deftab;
+}
+
diff --git a/render/render.c b/render/render.c
index 6aee9c8a..b92c8fe0 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1,8 +1,9 @@
#include <fitz.h>
+#define DEBUG(args...) printf(args)
+
#define FNONE 0
#define FOVER 1
-#define FMASK 2
#define FRGB 4
static fz_error *rendernode(fz_renderer *gc, fz_node *node, fz_matrix ctm);
@@ -38,7 +39,6 @@ fz_newrenderer(fz_renderer **gcp, fz_colorspace *pcm, int maskonly, int gcmem)
fz_defaultrastfuncs(&gc->rast);
gc->dest = nil;
- gc->mask = nil;
gc->over = nil;
gc->rgb[0] = 0;
gc->rgb[1] = 0;
@@ -61,7 +61,6 @@ void
fz_droprenderer(fz_renderer *gc)
{
if (gc->dest) fz_droppixmap(gc->dest);
- if (gc->mask) fz_droppixmap(gc->mask);
if (gc->over) fz_droppixmap(gc->over);
if (gc->model) fz_dropcolorspace(gc->model);
@@ -79,14 +78,14 @@ static fz_error *
rendertransform(fz_renderer *gc, fz_transformnode *transform, fz_matrix ctm)
{
fz_error *error;
-//printf("transform [%g %g %g %g %g %g]\n",
-//transform->m.a, transform->m.b,
-//transform->m.c, transform->m.d,
-//transform->m.e, transform->m.f);
-//puts("{");
+DEBUG("transform [%g %g %g %g %g %g]\n",
+transform->m.a, transform->m.b,
+transform->m.c, transform->m.d,
+transform->m.e, transform->m.f);
+DEBUG("{\n");
ctm = fz_concat(transform->m, ctm);
error = rendernode(gc, transform->super.first, ctm);
-//puts("}");
+DEBUG("}\n");
return error;
}
@@ -112,14 +111,21 @@ rendercolor(fz_renderer *gc, fz_colornode *color, fz_matrix ctm)
gc->rgb[1] = rgb[1] * 255;
gc->rgb[2] = rgb[2] * 255;
-printf("color %s [%d %d %d]\n", color->cs->name, gc->rgb[0], gc->rgb[1], gc->rgb[2]);
-
- error = fz_newpixmapwithrect(&gc->dest, gc->clip, 4);
- if (error)
- return error;
+DEBUG("color %s [%d %d %d];\n", color->cs->name, gc->rgb[0], gc->rgb[1], gc->rgb[2]);
- p = gc->dest->samples;
- n = gc->dest->w * gc->dest->h;
+ if (gc->flag == FOVER)
+ {
+ p = gc->over->samples;
+ n = gc->over->w * gc->over->h;
+ }
+ else
+ {
+ error = fz_newpixmapwithrect(&gc->dest, gc->clip, 4);
+ if (error)
+ return error;
+ p = gc->dest->samples;
+ n = gc->dest->w * gc->dest->h;
+ }
while (n--)
{
@@ -144,7 +150,6 @@ struct spandata
fz_rastfuncs *rast;
int x, n;
fz_pixmap *dst;
- fz_pixmap *msk;
unsigned char *rgb;
int flag;
};
@@ -154,28 +159,24 @@ static void spanfunc(int y, int x, int n, unsigned char *path, void *userdata)
struct spandata *user = userdata;
fz_rastfuncs *rast = user->rast;
fz_pixmap *dst = user->dst;
- fz_pixmap *msk = user->msk;
- unsigned char *d;
- unsigned char *m = nil;
+ unsigned char *dstp;
path += user->x;
+ x += user->x;
- d = dst->samples + ( (y - dst->y) * dst->w + (x - dst->x) ) * dst->n;
- if (msk)
- m = msk->samples + ( (y - msk->y) * msk->w + (x - msk->x) ) * msk->n;
+ dstp = dst->samples + ( (y - dst->y) * dst->w + (x - dst->x) ) * dst->n;
switch (user->flag)
{
case FNONE:
- rast->mask_g(user->n, path, d); break;
+ assert(dst->n == 1);
+ rast->msk_1c1(path, dstp, user->n); break;
case FOVER:
- rast->mask_o1(user->n, path, d); break;
- case FOVER | FMASK:
- rast->mask_i1o1(user->n, path, m, d); break;
+ assert(dst->n == 1);
+ rast->msk_1o1(path, dstp, user->n); break;
case FOVER | FRGB:
- rast->mask_o4w3(user->n, path, d, user->rgb); break;
- case FOVER | FMASK | FRGB:
- rast->mask_i1o4w3(user->n, path, m, d, user->rgb); break;
+ assert(dst->n == 4);
+ rast->msk_w3i1o4(user->rgb, path, dstp, user->n); break;
default:
assert(!"impossible flag in path span function");
}
@@ -213,33 +214,28 @@ renderpath(fz_renderer *gc, fz_pathnode *path, fz_matrix ctm)
gbox = fz_boundgel(gc->gel);
clip = fz_intersectirects(gc->clip, gbox);
- if (clip.max.x <= clip.min.x)
- return nil;
- if (clip.max.y <= clip.min.y)
+ if (fz_isemptyrect(clip))
return nil;
-//printf("path clip[%d %d %d %d]\n", clip.min.x, clip.min.y, clip.max.x, clip.max.y);
+DEBUG("path %s;\n", path->paint == FZ_STROKE ? "stroke" : "fill");
user.rast = &gc->rast;
user.x = clip.min.x - gbox.min.x;
user.n = clip.max.x - clip.min.x;
user.flag = gc->flag;
+ user.rgb = gc->rgb;
- if (gc->flag == FNONE)
+ if (gc->flag & FOVER)
+ {
+ user.dst = gc->over;
+ }
+ else
{
error = fz_newpixmapwithrect(&gc->dest, clip, 1);
if (error)
return error;
fz_clearpixmap(gc->dest);
user.dst = gc->dest;
- user.msk = nil;
- user.rgb = gc->rgb;
- }
- else
- {
- user.dst = gc->over;
- user.msk = gc->mask;
- user.rgb = gc->rgb;
}
error = fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL,
@@ -259,6 +255,8 @@ static void drawglyph(fz_renderer *gc, fz_pixmap *dst, fz_glyph *src, int xorig,
unsigned char *dp, *sp;
int w, h;
+ int dx0 = dst->x;
+ int dy0 = dst->y;
int dx1 = dst->x + dst->w;
int dy1 = dst->y + dst->h;
@@ -272,14 +270,12 @@ static void drawglyph(fz_renderer *gc, fz_pixmap *dst, fz_glyph *src, int xorig,
int sx1 = src->w;
int sy1 = src->h;
- if (x1 < dst->x || x0 >= dx1) return;
- if (y1 < dst->y || y0 >= dy1) return;
-
- if (x0 < dst->x) { sx0 += dst->x - x0; x0 = dst->x; }
- if (y0 < dst->y) { sy0 += dst->y - y0; y0 = dst->y; }
-
- if (x1 >= dx1) { sx1 -= dx1 - x1; x1 = dx1; }
- if (y1 >= dy1) { sy1 -= dy1 - y1; y1 = dy1; }
+ if (x1 < dx0 || x0 >= dx1) return;
+ if (y1 < dy0 || y0 >= dy1) return;
+ if (x0 < dx0) { sx0 += dx0 - x0; x0 = dx0; }
+ if (y0 < dy0) { sy0 += dy0 - y0; y0 = dy0; }
+ if (x1 >= dx1) { sx1 += dx1 - x1; x1 = dx1; }
+ if (y1 >= dy1) { sy1 += dy1 - y1; y1 = dy1; }
sp = src->samples + (sy0 * src->w + sx0);
dp = dst->samples + ((y0 - dst->y) * dst->w + (x0 - dst->x)) * dst->n;
@@ -290,29 +286,32 @@ static void drawglyph(fz_renderer *gc, fz_pixmap *dst, fz_glyph *src, int xorig,
switch (gc->flag)
{
case FNONE:
+ assert(dst->n == 1);
while (h--)
{
- gc->rast.mask_g(w, sp, dp);
+ gc->rast.msk_1c1(sp, dp, w);
sp += src->w;
- dp += dst->w * dst->n;
+ dp += dst->w;
}
break;
case FOVER:
+ assert(dst->n == 1);
while (h--)
{
- gc->rast.mask_o1(w, sp, dp);
+ gc->rast.msk_1o1(sp, dp, w);
sp += src->w;
- dp += dst->w * dst->n;
+ dp += dst->w;
}
break;
case FOVER | FRGB:
+ assert(dst->n == 4);
while (h--)
{
- gc->rast.mask_o4w3(w, sp, dp, gc->rgb);
+ gc->rast.msk_w3i1o4(gc->rgb, sp, dp, w);
sp += src->w;
- dp += dst->w * dst->n;
+ dp += dst->w * 4;
}
break;
@@ -334,14 +333,11 @@ rendertext(fz_renderer *gc, fz_textnode *text, fz_matrix ctm)
tbox = fz_roundrect(fz_boundnode((fz_node*)text, ctm));
clip = fz_intersectirects(gc->clip, tbox);
-//printf("text %s n=%d [%g %g %g %g] clip[%d %d %d %d]\n",
-//text->font->name, text->len,
-//text->trm.a, text->trm.b, text->trm.c, text->trm.d,
-//clip.min.x, clip.min.y, clip.max.x, clip.max.y);
+DEBUG("text %s n=%d [%g %g %g %g];\n",
+text->font->name, text->len,
+text->trm.a, text->trm.b, text->trm.c, text->trm.d);
- if (clip.max.x <= clip.min.x)
- return nil;
- if (clip.max.y <= clip.min.y)
+ if (fz_isemptyrect(clip))
return nil;
clip.min.x ++;
@@ -349,7 +345,7 @@ rendertext(fz_renderer *gc, fz_textnode *text, fz_matrix ctm)
clip.max.x ++;
clip.max.y ++;
- if (gc->flag == FNONE)
+ if (!(gc->flag & FOVER))
{
error = fz_newpixmapwithrect(&gc->dest, clip, 1);
if (error)
@@ -374,7 +370,7 @@ rendertext(fz_renderer *gc, fz_textnode *text, fz_matrix ctm)
if (error)
return error;
- if (gc->flag == FNONE)
+ if (!(gc->flag & FOVER))
drawglyph(gc, gc->dest, &glyph, x, y);
else
drawglyph(gc, gc->over, &glyph, x, y);
@@ -423,19 +419,17 @@ renderimage(fz_renderer *gc, fz_imagenode *node, fz_matrix ctm)
int x0, y0;
int w, h;
-printf("renderimage %dx%d %d+%d %s\n", image->w, image->h, image->n, image->a, image->cs?image->cs->name:"(nil)");
+DEBUG("image %dx%d %d+%d %s\n{\n", image->w, image->h, image->n, image->a, image->cs?image->cs->name:"(nil)");
bbox = fz_roundrect(fz_boundnode((fz_node*)node, ctm));
clip = fz_intersectirects(gc->clip, bbox);
- if (clip.max.x <= clip.min.x)
- return nil;
- if (clip.max.y <= clip.min.y)
+ if (fz_isemptyrect(clip))
return nil;
calcimagescale(ctm, image->w, image->h, &dx, &dy);
-printf(" load image\n");
+DEBUG(" load image\n");
error = fz_newpixmap(&tile, 0, 0, image->w, image->h, image->n + 1);
if (error)
return error;
@@ -446,7 +440,7 @@ printf(" load image\n");
if (dx != 1 || dy != 1)
{
-printf(" scale image 1/%d 1/%d\n", dx, dy);
+DEBUG(" scale image 1/%d 1/%d\n", dx, dy);
fz_pixmap *temp;
error = fz_scalepixmap(&temp, tile, dx, dy);
if (error)
@@ -458,7 +452,7 @@ printf(" scale image 1/%d 1/%d\n", dx, dy);
if (image->cs && image->cs != gc->model)
{
fz_pixmap *temp;
-printf(" convert from %s to %s\n", image->cs->name, gc->model->name);
+DEBUG(" convert from %s to %s\n", image->cs->name, gc->model->name);
error = fz_newpixmap(&temp, tile->x, tile->y, tile->w, tile->h, gc->model->n + 1);
if (error)
goto cleanup;
@@ -486,11 +480,15 @@ printf(" convert from %s to %s\n", image->cs->name, gc->model->name);
fc = invmat.c * 65536;
fd = invmat.d * 65536;
+#define PSRC tile->samples, tile->w, tile->h
+#define PDST(p) p->samples + ((y0-p->y) * p->w + (x0-p->x)) * p->n, p->w * p->n
+#define PCTM u0, v0, fa, fb, fc, fd, w, h
+
switch (gc->flag)
{
case FNONE:
{
-printf(" fnone %d x %d\n", w, h);
+DEBUG(" fnone %d x %d\n", w, h);
if (image->cs)
error = fz_newpixmapwithrect(&gc->dest, clip, gc->model->n + 1);
else
@@ -499,50 +497,33 @@ printf(" fnone %d x %d\n", w, h);
goto cleanup;
if (image->cs)
- gc->rast.img4_g(
- tile->samples, tile->w, tile->h, w, h,
- gc->dest->samples, gc->dest->w * gc->dest->n,
- u0, v0, fa, fb, fc, fd);
+ gc->rast.img_4c4(PSRC, PDST(gc->dest), PCTM);
else
- gc->rast.img1_g(
- tile->samples, tile->w, tile->h, w, h,
- gc->dest->samples, gc->dest->w * gc->dest->n,
- u0, v0, fa, fb, fc, fd);
+ gc->rast.img_1c1(PSRC, PDST(gc->dest), PCTM);
}
break;
case FOVER:
{
-printf(" fover %d x %d\n", w, h);
+DEBUG(" fover %d x %d\n", w, h);
if (image->cs)
- gc->rast.img4_o4(
- tile->samples, tile->w, tile->h, w, h,
- gc->over->samples + ((y0 - gc->over->y) * gc->over->w + (x0 - gc->over->x)) * 4,
- gc->over->w * gc->over->n,
- u0, v0, fa, fb, fc, fd);
+ gc->rast.img_4o4(PSRC, PDST(gc->over), PCTM);
else
- gc->rast.img1_o1(
- tile->samples, tile->w, tile->h, w, h,
- gc->over->samples + ((y0 - gc->over->y) * gc->over->w + (x0 - gc->over->x)),
- gc->over->w * gc->over->n,
- u0, v0, fa, fb, fc, fd);
+ gc->rast.img_1o1(PSRC, PDST(gc->over), PCTM);
}
break;
case FOVER | FRGB:
- {
-printf(" fover+rgb %d x %d\n", w, h);
- gc->rast.img1_o4w3(
- tile->samples, tile->w, tile->h, w, h,
- gc->over->samples + ((y0 - gc->over->y) * gc->over->w + (x0 - gc->over->x)) * 4,
- gc->over->w * gc->over->n,
- u0, v0, fa, fb, fc, fd, gc->rgb);
- }
+DEBUG(" fover+rgb %d x %d\n", w, h);
+ gc->rast.img_w3i1o4(gc->rgb, PSRC, PDST(gc->over), PCTM);
break;
+
default:
assert(!"impossible flag in image span function");
}
+DEBUG("}\n");
+
fz_droppixmap(tile);
return nil;
@@ -555,24 +536,119 @@ cleanup:
* Over, Mask and Blend
*/
+static void
+blendover(fz_renderer *gc, fz_pixmap *src, fz_pixmap *dst)
+{
+ unsigned char *sp, *dp;
+ fz_irect sr, dr;
+ int x, y, w, h;
+
+ sr.min.x = src->x;
+ sr.min.y = src->y;
+ sr.max.x = src->x + src->w;
+ sr.max.y = src->y + src->h;
+
+ dr.min.x = dst->x;
+ dr.min.y = dst->y;
+ dr.max.x = dst->x + dst->w;
+ dr.max.y = dst->y + dst->h;
+
+ dr = fz_intersectirects(sr, dr);
+ x = dr.min.x;
+ y = dr.min.y;
+ w = dr.max.x - dr.min.x;
+ h = dr.max.y - dr.min.y;
+
+ sp = src->samples + ((y - src->y) * src->w + (x - src->x)) * src->n;
+ dp = dst->samples + ((y - dst->y) * dst->w + (x - dst->x)) * dst->n;
+
+ if (src->n == 1 && dst->n == 1)
+ gc->rast.duff_1o1(sp, src->w, dp, dst->w, w, h);
+ else if (src->n == 4 && dst->n == 4)
+ gc->rast.duff_4o4(sp, src->w * 4, dp, dst->w * 4, w, h);
+ else if (src->n == dst->n)
+ gc->rast.duff_NoN(sp, src->w * src->n, src->n, dp, dst->w * dst->n, w, h);
+ else
+ assert(!"blendover src and dst mismatch");
+}
+
+static void
+blendmask(fz_renderer *gc, fz_pixmap *src, fz_pixmap *msk, fz_pixmap *dst, int over)
+{
+ unsigned char *sp, *dp, *mp;
+ fz_irect sr, dr, mr;
+ int x, y, w, h;
+
+ sr.min.x = src->x;
+ sr.min.y = src->y;
+ sr.max.x = src->x + src->w;
+ sr.max.y = src->y + src->h;
+
+ dr.min.x = dst->x;
+ dr.min.y = dst->y;
+ dr.max.x = dst->x + dst->w;
+ dr.max.y = dst->y + dst->h;
+
+ mr.min.x = msk->x;
+ mr.min.y = msk->y;
+ mr.max.x = msk->x + msk->w;
+ mr.max.y = msk->y + msk->h;
+
+ dr = fz_intersectirects(sr, dr);
+ dr = fz_intersectirects(dr, mr);
+ x = dr.min.x;
+ y = dr.min.y;
+ w = dr.max.x - dr.min.x;
+ h = dr.max.y - dr.min.y;
+
+ sp = src->samples + ((y - src->y) * src->w + (x - src->x)) * src->n;
+ mp = msk->samples + ((y - msk->y) * msk->w + (x - msk->x)) * msk->n;
+ dp = dst->samples + ((y - dst->y) * dst->w + (x - dst->x)) * dst->n;
+
+ if (over)
+ {
+ if (src->n == 1 && msk->n == 1 && dst->n == 1)
+ gc->rast.duff_1i1o1(sp, src->w, mp, msk->w, dp, dst->w, w, h);
+ else if (src->n == 4 && msk->n == 1 && dst->n == 4)
+ gc->rast.duff_4i1o4(sp, src->w * 4, mp, msk->w, dp, dst->w * 4, w, h);
+ else if (src->n == dst->n)
+ gc->rast.duff_NiMoN(sp, src->w * src->n, src->n, mp, msk->w * msk->n, msk->n, dp, dst->w * dst->n, w, h);
+ else
+ assert(!"blendmaskover src and msk and dst mismatch");
+ }
+ else
+ {
+ if (src->n == 1 && msk->n == 1 && dst->n == 1)
+ gc->rast.duff_1i1c1(sp, src->w, mp, msk->w, dp, dst->w, w, h);
+ else if (src->n == 4 && msk->n == 1 && dst->n == 4)
+ gc->rast.duff_4i1c4(sp, src->w * 4, mp, msk->w, dp, dst->w * 4, w, h);
+ else if (src->n == dst->n)
+ gc->rast.duff_NiMcN(sp, src->w * src->n, src->n, mp, msk->w * msk->n, msk->n, dp, dst->w * dst->n, w, h);
+ else
+ assert(!"blendmask src and msk and dst mismatch");
+ }
+}
+
static fz_error *
renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm)
{
fz_error *error;
fz_node *child;
- int cluster = 0;;
-
-//printf("over\n{\n");
+ int cluster = 0;
if (!gc->over)
{
-//printf(" alloc dest!\n");
- error = fz_newpixmapwithrect(&gc->over, gc->clip, gc->maskonly ? 1 : 4);
+DEBUG("over cluster %d\n{\n", gc->maskonly ? 1 : 4);
+ cluster = 1;
+ if (gc->maskonly)
+ error = fz_newpixmapwithrect(&gc->over, gc->clip, 1);
+ else
+ error = fz_newpixmapwithrect(&gc->over, gc->clip, 4);
if (error)
return error;
fz_clearpixmap(gc->over);
- cluster = 1;
}
+else DEBUG("over\n{\n");
for (child = over->super.first; child; child = child->next)
{
@@ -581,7 +657,7 @@ renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm)
return error;
if (gc->dest)
{
- fz_blendover(gc->dest, gc->over);
+ blendover(gc, gc->dest, gc->over);
fz_droppixmap(gc->dest);
gc->dest = nil;
}
@@ -593,7 +669,7 @@ renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm)
gc->over = nil;
}
-//printf("}\n");
+DEBUG("}\n");
return nil;
}
@@ -602,12 +678,13 @@ static fz_error *
rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
{
fz_error *error;
+ int oldmaskonly;
fz_pixmap *oldover;
- fz_pixmap *oldmask;
fz_irect oldclip;
- fz_irect newclip;
- fz_pixmap *shapepix;
- fz_pixmap *colorpix;
+ fz_irect bbox;
+ fz_irect clip;
+ fz_pixmap *shapepix = nil;
+ fz_pixmap *colorpix = nil;
fz_node *shape;
fz_node *color;
float rgb[3];
@@ -628,7 +705,7 @@ rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
gc->rgb[2] = rgb[2] * 255;
gc->flag |= FRGB;
- /* we know these handle FOVER | FRGB */
+ /* we know these can handle the FRGB shortcut */
if (fz_ispathnode(shape))
return renderpath(gc, (fz_pathnode*)shape, ctm);
if (fz_istextnode(shape))
@@ -640,50 +717,77 @@ rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
oldclip = gc->clip;
oldover = gc->over;
- oldmask = gc->mask;
- newclip = fz_roundrect(fz_boundnode(shape, ctm));
- newclip = fz_intersectirects(newclip, gc->clip);
+ bbox = fz_roundrect(fz_boundnode(shape, ctm));
+ clip = fz_intersectirects(bbox, gc->clip);
+ bbox = fz_roundrect(fz_boundnode(color, ctm));
+ clip = fz_intersectirects(bbox, clip);
- gc->clip = newclip;
- gc->over = nil;
- gc->mask = nil;
+ if (fz_isemptyrect(clip))
+ return nil;
-printf("mask\n{\n");
+DEBUG("mask [%d %d %d %d]\n{\n", clip.min.x, clip.min.y, clip.max.x, clip.max.y);
- error = rendernode(gc, color, ctm);
- if (error)
- return error;
- colorpix = gc->dest;
- gc->dest = nil;
+{
+fz_irect sbox = fz_roundrect(fz_boundnode(shape, ctm));
+fz_irect cbox = fz_roundrect(fz_boundnode(color, ctm));
+if (cbox.min.x >= sbox.min.x && cbox.max.x <= sbox.max.x)
+if (cbox.min.y >= sbox.min.y && cbox.max.y <= sbox.max.y)
+DEBUG("potentially useless mask\n");
+}
+
+ gc->clip = clip;
+ gc->over = nil;
+
+ oldmaskonly = gc->maskonly;
+ gc->maskonly = 1;
error = rendernode(gc, shape, ctm);
if (error)
- return error;
+ goto cleanup;
shapepix = gc->dest;
gc->dest = nil;
- if (colorpix && shapepix)
- {
- error = fz_newpixmapwithrect(&gc->dest, gc->clip, colorpix->n);
- if (error)
- return error;
+ gc->maskonly = oldmaskonly;
- fz_clearpixmap(gc->dest);
+ error = rendernode(gc, color, ctm);
+ if (error)
+ goto cleanup;
+ colorpix = gc->dest;
+ gc->dest = nil;
- fz_blendmask(gc->dest, colorpix, shapepix);
+ gc->clip = oldclip;
+ gc->over = oldover;
+
+ if (shapepix && colorpix)
+ {
+ if (gc->over)
+ {
+ blendmask(gc, colorpix, shapepix, gc->over, 1);
+ }
+ else
+ {
+ clip.min.x = MAX(colorpix->x, shapepix->x);
+ clip.min.y = MAX(colorpix->y, shapepix->y);
+ clip.max.x = MIN(colorpix->x+colorpix->w, shapepix->x+shapepix->w);
+ clip.max.y = MIN(colorpix->y+colorpix->h, shapepix->y+shapepix->h);
+ error = fz_newpixmapwithrect(&gc->dest, clip, colorpix->n);
+ if (error)
+ goto cleanup;
+ blendmask(gc, colorpix, shapepix, gc->dest, 0);
+ }
}
+DEBUG("}\n");
+
if (shapepix) fz_droppixmap(shapepix);
if (colorpix) fz_droppixmap(colorpix);
-
- gc->over = oldover;
- gc->mask = oldmask;
- gc->clip = oldclip;
-
-printf("}\n");
-
return nil;
+
+cleanup:
+ if (shapepix) fz_droppixmap(shapepix);
+ if (colorpix) fz_droppixmap(colorpix);
+ return error;
}
/*
@@ -697,8 +801,8 @@ rendernode(fz_renderer *gc, fz_node *node, fz_matrix ctm)
return nil;
gc->flag = FNONE;
- if (gc->over) gc->flag |= FOVER;
- if (gc->mask) gc->flag |= FMASK;
+ if (gc->over)
+ gc->flag |= FOVER;
switch (node->kind)
{
@@ -718,6 +822,8 @@ rendernode(fz_renderer *gc, fz_node *node, fz_matrix ctm)
return renderimage(gc, (fz_imagenode*)node, ctm);
case FZ_NLINK:
return rendernode(gc, ((fz_linknode*)node)->tree->root, ctm);
+ case FZ_NMETA:
+ return rendernode(gc, node->first, ctm);
}
return nil;
@@ -731,33 +837,40 @@ fz_rendertree(fz_pixmap **outp,
fz_error *error;
gc->clip = bbox;
+ gc->over = nil;
- if (white)
- {
- assert(gc->maskonly == 0);
-
+ if (gc->maskonly)
+ error = fz_newpixmapwithrect(&gc->over, bbox, 1);
+ else
error = fz_newpixmapwithrect(&gc->over, bbox, 4);
- if (error)
- return error;
+ if (error)
+ return error;
+ if (white)
memset(gc->over->samples, 0xff, gc->over->w * gc->over->h * gc->over->n);
- }
+ else
+ memset(gc->over->samples, 0x00, gc->over->w * gc->over->h * gc->over->n);
+
+DEBUG("tree %d [%d %d %d %d]\n{\n",
+gc->maskonly ? 1 : 4,
+bbox.min.x, bbox.min.y, bbox.max.x, bbox.max.y);
error = rendernode(gc, tree->root, ctm);
if (error)
return error;
- if (white)
- {
- *outp = gc->over;
- gc->over = nil;
- }
- else
+DEBUG("}\n");
+
+ if (gc->dest)
{
- *outp = gc->dest;
+ blendover(gc, gc->dest, gc->over);
+ fz_droppixmap(gc->dest);
gc->dest = nil;
}
+ *outp = gc->over;
+ gc->over = nil;
+
return nil;
}
diff --git a/test/ximage.c b/test/ximage.c
index 9c368360..79c6670c 100644
--- a/test/ximage.c
+++ b/test/ximage.c
@@ -460,10 +460,17 @@ ximage_convert_bgra8888(PARAMS)
for (x = 0; x < w; x++) {
val = s[x];
d[x] =
+ (val >> 24) |
+ ((val >> 8) & 0xff) |
+ ((val << 8) & 0xff0000) |
+ (val << 24);
+/*
+ d[x] =
(((val >> 24) & 0xff) << 0) |
(((val >> 16) & 0xff) << 8) |
(((val >> 8) & 0xff) << 16) |
(((val >> 0) & 0xff) << 24);
+*/
}
d += dststride>>2;
s += srcstride>>2;
diff --git a/tree/debug.c b/tree/debug.c
index cbfffc20..0f4edada 100644
--- a/tree/debug.c
+++ b/tree/debug.c
@@ -6,6 +6,16 @@ static void indent(int level)
putchar(' ');
}
+static void showbbox(void *node0)
+{
+ fz_node *node = node0;
+ fz_irect bbox;
+ bbox = fz_roundrect(fz_boundnode(node, fz_identity()));
+ printf("[%d %d %d %d]",
+ bbox.min.x, bbox.min.y,
+ bbox.max.x, bbox.max.y);
+}
+
static void lispnode(fz_node *node, int level);
static void lispmeta(fz_metanode *node, int level)
@@ -26,7 +36,7 @@ static void lispover(fz_overnode *node, int level)
{
fz_node *child;
indent(level);
- printf("(over\n");
+ printf("(over "); showbbox(node); printf("\n");
for (child = node->super.first; child; child = child->next)
lispnode(child, level + 1);
indent(level);
@@ -37,7 +47,7 @@ static void lispmask(fz_masknode *node, int level)
{
fz_node *child;
indent(level);
- printf("(mask\n");
+ printf("(mask "); showbbox(node); printf("\n");
for (child = node->super.first; child; child = child->next)
lispnode(child, level + 1);
indent(level);
diff --git a/tree/node1.c b/tree/node1.c
index 19244721..2587077c 100644
--- a/tree/node1.c
+++ b/tree/node1.c
@@ -90,7 +90,7 @@ fz_boundnode(fz_node *node, fz_matrix ctm)
case FZ_NMETA:
return fz_boundmetanode((fz_metanode *) node, ctm);
}
- return fz_infiniterect();
+ return fz_emptyrect;
}
int
diff --git a/tree/node2.c b/tree/node2.c
index 1374a30f..5c3e3931 100644
--- a/tree/node2.c
+++ b/tree/node2.c
@@ -23,20 +23,20 @@ fz_boundovernode(fz_overnode *node, fz_matrix ctm)
{
fz_node *child;
fz_rect bbox;
- fz_rect r;
+ fz_rect temp;
- bbox = fz_infiniterect();
+ child = node->super.first;
+ if (!child)
+ return fz_emptyrect;
- for (child = node->super.first; child; child = child->next)
+ bbox = fz_boundnode(child, ctm);
+
+ child = child->next;
+ while (child)
{
- r = fz_boundnode(child, ctm);
- if (r.max.x >= r.min.x)
- {
- if (bbox.max.x >= bbox.min.x)
- bbox = fz_mergerects(r, bbox);
- else
- bbox = r;
- }
+ temp = fz_boundnode(child, ctm);
+ bbox = fz_mergerects(temp, bbox);
+ child = child->next;
}
return bbox;
@@ -63,25 +63,16 @@ fz_newmasknode(fz_node **nodep)
fz_rect
fz_boundmasknode(fz_masknode *node, fz_matrix ctm)
{
- fz_node *child;
- fz_rect bbox;
- fz_rect r;
-
- bbox = fz_infiniterect();
+ fz_node *shape;
+ fz_node *color;
+ fz_rect one, two;
- for (child = node->super.first; child; child = child->next)
- {
- r = fz_boundnode(child, ctm);
- if (r.max.x >= r.min.x)
- {
- if (bbox.max.x >= bbox.min.x)
- bbox = fz_intersectrects(r, bbox);
- else
- bbox = r;
- }
- }
+ shape = node->super.first;
+ color = shape->next;
- return bbox;
+ one = fz_boundnode(shape, ctm);
+ two = fz_boundnode(color, ctm);
+ return fz_intersectrects(one, two);
}
/*
@@ -110,25 +101,7 @@ fz_newblendnode(fz_node **nodep, fz_colorspace *cs, fz_blendkind b, int k, int i
fz_rect
fz_boundblendnode(fz_blendnode *node, fz_matrix ctm)
{
- fz_node *child;
- fz_rect bbox;
- fz_rect r;
-
- bbox = fz_infiniterect();
-
- for (child = node->super.first; child; child = child->next)
- {
- r = fz_boundnode(child, ctm);
- if (r.max.x >= r.min.x)
- {
- if (bbox.max.x >= bbox.min.x)
- bbox = fz_mergerects(r, bbox);
- else
- bbox = r;
- }
- }
-
- return bbox;
+ return fz_emptyrect;
}
/*
@@ -155,7 +128,7 @@ fz_rect
fz_boundtransformnode(fz_transformnode *node, fz_matrix ctm)
{
if (!node->super.first)
- return fz_infiniterect();
+ return fz_emptyrect;
return fz_boundnode(node->super.first, fz_concat(node->m, ctm));
}
@@ -198,7 +171,7 @@ fz_rect
fz_boundmetanode(fz_metanode *node, fz_matrix ctm)
{
if (!node->super.first)
- return fz_infiniterect();
+ return fz_emptyrect;
return fz_boundnode(node->super.first, ctm);
}
@@ -261,7 +234,7 @@ fz_newcolornode(fz_node **nodep, fz_colorspace *cs, int n, float *v)
fz_rect
fz_boundcolornode(fz_colornode *node, fz_matrix ctm)
{
- return fz_infiniterect();
+ return fz_infiniterect;
}
/*
diff --git a/tree/path.c b/tree/path.c
index 74e29a59..ac070025 100644
--- a/tree/path.c
+++ b/tree/path.c
@@ -168,18 +168,10 @@ fz_endpath(fz_pathnode *path, fz_pathkind paint, fz_stroke *stroke, fz_dash *das
static inline fz_rect boundexpand(fz_rect r, fz_point p)
{
- if (r.min.x > r.max.x)
- {
- r.min.x = r.max.x = p.x;
- r.min.y = r.max.y = p.y;
- }
- else
- {
- if (p.x < r.min.x) r.min.x = p.x;
- if (p.y < r.min.y) r.min.y = p.y;
- if (p.x > r.max.x) r.max.x = p.x;
- if (p.y > r.max.y) r.max.y = p.y;
- }
+ if (p.x < r.min.x) r.min.x = p.x;
+ if (p.y < r.min.y) r.min.y = p.y;
+ if (p.x > r.max.x) r.max.x = p.x;
+ if (p.y > r.max.y) r.max.y = p.y;
return r;
}
@@ -187,9 +179,18 @@ fz_rect
fz_boundpathnode(fz_pathnode *path, fz_matrix ctm)
{
fz_point p;
- fz_rect r = fz_infiniterect();
+ fz_rect r = fz_emptyrect;
int i = 0;
+ if (path->len)
+ {
+ p.x = path->els[1].v;
+ p.y = path->els[2].v;
+ p = fz_transformpoint(ctm, p);
+ r.min.x = r.max.x = p.x;
+ r.min.y = r.max.y = p.y;
+ }
+
while (i < path->len)
{
switch (path->els[i++].k)
diff --git a/tree/text.c b/tree/text.c
index a7581cf9..ef77f530 100644
--- a/tree/text.c
+++ b/tree/text.c
@@ -35,7 +35,7 @@ fz_boundtextnode(fz_textnode *text, fz_matrix ctm)
int i;
if (text->len == 0)
- return fz_infiniterect();
+ return fz_emptyrect;
/* find bbox of glyph origins in ctm space */
diff --git a/tree/tree.c b/tree/tree.c
index 0c7cefb1..f07e564f 100644
--- a/tree/tree.c
+++ b/tree/tree.c
@@ -39,7 +39,7 @@ fz_boundtree(fz_tree *tree, fz_matrix ctm)
{
if (tree->root)
return fz_boundnode(tree->root, ctm);
- return fz_infiniterect();
+ return fz_emptyrect;
}
void