summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2004-11-19 08:49:17 +0100
committerTor Andersson <tor@ghostscript.com>2004-11-19 08:49:17 +0100
commit4c164469d43cf248e72d384137d59fbd7204afcb (patch)
treee471da0d278bfe8fca6ac1cc40747c357414bc36
parentd5a8ffc6e88c7853169b972ee94286702b214c6b (diff)
downloadmupdf-4c164469d43cf248e72d384137d59fbd7204afcb.tar.xz
rewrite of render loop part 1
-rw-r--r--Jamfile4
-rw-r--r--include/fitz/colorspace.h2
-rw-r--r--include/fitz/font.h2
-rw-r--r--include/fitz/pixmap.h1
-rw-r--r--include/fitz/render.h59
-rw-r--r--mupdf/colorspace1.c4
-rw-r--r--mupdf/font.c19
-rw-r--r--mupdf/image2.c2
-rw-r--r--mupdf/interpret.c2
-rw-r--r--mupdf/type3.c19
-rw-r--r--render/glyphcache.c12
-rw-r--r--render/pixmap.c9
-rw-r--r--render/rastnone.c379
-rw-r--r--render/render.c511
-rw-r--r--render/scale.c4
-rw-r--r--test/pdfrip.c2
-rw-r--r--test/x11pdf.c2
-rw-r--r--tree/colorspace.c4
18 files changed, 857 insertions, 180 deletions
diff --git a/Jamfile b/Jamfile
index a92637ac..4a56f5a9 100644
--- a/Jamfile
+++ b/Jamfile
@@ -87,10 +87,8 @@ Library libfitz :
render/fill.c
render/stroke.c
render/scale.c
+ render/rastnone.c
render/render.c
- render/rendertext.c
- render/renderpath.c
- render/renderimage.c
;
Library libmupdf :
diff --git a/include/fitz/colorspace.h b/include/fitz/colorspace.h
index 1d6c9a64..f6fae48c 100644
--- a/include/fitz/colorspace.h
+++ b/include/fitz/colorspace.h
@@ -4,6 +4,8 @@ typedef struct fz_colorcube1_s fz_colorcube1;
typedef struct fz_colorcube3_s fz_colorcube3;
typedef struct fz_colorcube4_s fz_colorcube4;
+enum { FZ_MAXCOLORS = 32 };
+
struct fz_colorspace_s
{
int refs;
diff --git a/include/fitz/font.h b/include/fitz/font.h
index ea1ad692..7e925461 100644
--- a/include/fitz/font.h
+++ b/include/fitz/font.h
@@ -42,7 +42,7 @@ struct fz_font_s
struct fz_glyph_s
{
- int w, h, lsb, top;
+ int x, y, w, h;
unsigned char *bitmap;
};
diff --git a/include/fitz/pixmap.h b/include/fitz/pixmap.h
index ecd45270..6d0391fa 100644
--- a/include/fitz/pixmap.h
+++ b/include/fitz/pixmap.h
@@ -13,6 +13,7 @@ struct fz_pixmap_s
fz_sample *samples;
};
+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);
void fz_debugpixmap(fz_pixmap *map);
void fz_clearpixmap(fz_pixmap *map);
diff --git a/include/fitz/render.h b/include/fitz/render.h
index 6e171a06..807b6227 100644
--- a/include/fitz/render.h
+++ b/include/fitz/render.h
@@ -1,25 +1,64 @@
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
+
+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 (*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 (*img4_g)(FZ_PID);
+ void (*img4_o4)(FZ_PID);
+ void (*img4_i1o4)(FZ_PIM);
+};
+
+#undef FZ_PIM
+#undef FZ_PID
+#undef FZ_BYTE
struct fz_renderer_s
{
+ int maskonly;
fz_colorspace *model;
fz_glyphcache *cache;
fz_gel *gel;
fz_ael *ael;
+
+ fz_rastfuncs rast;
+
fz_irect clip;
- fz_pixmap *tmp;
- fz_pixmap *acc;
- unsigned char r, g, b;
- int hasrgb;
+ fz_pixmap *dest;
+ fz_pixmap *over;
+ fz_pixmap *mask;
+ unsigned char rgb[3];
+ int flag;
};
-fz_error *fz_newrenderer(fz_renderer **gcp, fz_colorspace *pcm, int gcmem);
+void fz_defaultrastfuncs(fz_rastfuncs *);
+
+fz_error *fz_newrenderer(fz_renderer **gcp, fz_colorspace *pcm, int maskonly, int gcmem);
void fz_droprenderer(fz_renderer *gc);
-fz_error *fz_renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm);
-fz_error *fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm);
-fz_error *fz_rendertransform(fz_renderer *gc, fz_transformnode *xform, fz_matrix ctm);
-fz_error *fz_rendertext(fz_renderer *gc, fz_textnode *text, fz_matrix ctm);
-fz_error *fz_rendernode(fz_renderer *gc, fz_node *node, fz_matrix ctm);
fz_error *fz_rendertree(fz_pixmap **out, fz_renderer *gc, fz_tree *tree, fz_matrix ctm, fz_irect bbox, int white);
diff --git a/mupdf/colorspace1.c b/mupdf/colorspace1.c
index d666904d..5d943fdb 100644
--- a/mupdf/colorspace1.c
+++ b/mupdf/colorspace1.c
@@ -430,7 +430,7 @@ static void separationtoxyz(fz_colorspace *fzcs, float *sep, float *xyz)
{
struct separation *cs = (struct separation *)fzcs;
fz_error *error;
- float alt[32];
+ float alt[FZ_MAXCOLORS];
error = pdf_evalfunction(cs->tint, sep, fzcs->n, alt, cs->base->n);
if (error)
@@ -513,7 +513,7 @@ static void
indexedtoxyz(fz_colorspace *fzcs, float *ind, float *xyz)
{
pdf_indexed *cs = (pdf_indexed *)fzcs;
- float alt[32];
+ float alt[FZ_MAXCOLORS];
int i, k;
i = ind[0] * 255;
i = CLAMP(i, 0, cs->high);
diff --git a/mupdf/font.c b/mupdf/font.c
index 229ef932..e2debc85 100644
--- a/mupdf/font.c
+++ b/mupdf/font.c
@@ -110,8 +110,8 @@ ftrender(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
glyph->w = 0;
glyph->h = 0;
- glyph->lsb = 0;
- glyph->top = 0;
+ glyph->x = 0;
+ glyph->y = 0;
glyph->bitmap = nil;
/* freetype mutilates complex glyphs if they are loaded
@@ -161,10 +161,21 @@ ftrender(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
glyph->w = face->glyph->bitmap.width;
glyph->h = face->glyph->bitmap.rows;
- glyph->lsb = face->glyph->bitmap_left;
- glyph->top = face->glyph->bitmap_top;
+ glyph->x = face->glyph->bitmap_left;
+ glyph->y = face->glyph->bitmap_top - glyph->h;
glyph->bitmap = face->glyph->bitmap.buffer;
+ int i;
+ unsigned char tmp[glyph->w * glyph->h];
+ memcpy(tmp, glyph->bitmap, glyph->w * glyph->h);
+
+ for (i = 0; i < glyph->h; i++)
+ {
+ memcpy( glyph->bitmap + i * glyph->w,
+ tmp + (glyph->h - i - 1) * glyph->w,
+ glyph->w );
+ }
+
return nil;
}
diff --git a/mupdf/image2.c b/mupdf/image2.c
index 485766e6..d46bdd0e 100644
--- a/mupdf/image2.c
+++ b/mupdf/image2.c
@@ -141,7 +141,7 @@ static void loadtile8a(pdf_image *src, fz_pixmap *dst, int n)
static void
decodetile(fz_pixmap *pix, int bpc, int skip, float *decode)
{
- unsigned char table[32][256];
+ unsigned char table[FZ_MAXCOLORS][256];
float invtwon = 1.0 / ((1 << bpc) - 1);
int x, y, k, i;
diff --git a/mupdf/interpret.c b/mupdf/interpret.c
index 6f6f1aaf..c0a9b882 100644
--- a/mupdf/interpret.c
+++ b/mupdf/interpret.c
@@ -228,7 +228,7 @@ runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
float a, b, c, d, e, f;
float x, y, w, h;
fz_matrix m;
- float v[32];
+ float v[FZ_MAXCOLORS];
int what;
int i;
diff --git a/mupdf/type3.c b/mupdf/type3.c
index a2612b82..ee7708c0 100644
--- a/mupdf/type3.c
+++ b/mupdf/type3.c
@@ -27,7 +27,6 @@ t3render(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
fz_pixmap *pixmap;
fz_matrix ctm;
fz_irect bbox;
- int i;
if (cid < 0 || cid > 255)
return fz_throw("rangecheck: glyph out of range");
@@ -43,7 +42,7 @@ t3render(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
ctm = fz_concat(font->matrix, trm);
bbox = fz_roundrect(fz_boundtree(tree, ctm));
- error = fz_newrenderer(&gc, nil, GCMEM);
+ error = fz_newrenderer(&gc, pdf_devicegray, 1, GCMEM);
if (error)
return error;
error = fz_rendertree(&pixmap, gc, tree, ctm, bbox, 0);
@@ -53,24 +52,12 @@ t3render(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
assert(pixmap->n == 1);
- glyph->lsb = pixmap->x;
- glyph->top = pixmap->h + pixmap->y;
+ glyph->x = pixmap->x;
+ glyph->y = pixmap->y;
glyph->w = pixmap->w;
glyph->h = pixmap->h;
glyph->bitmap = pixmap->samples;
- unsigned char tmp[pixmap->w * pixmap->h];
- memcpy(tmp, pixmap->samples, pixmap->w * pixmap->h);
-
- for (i = 0; i < pixmap->h; i++)
- {
- memcpy( pixmap->samples + i * pixmap->w,
- tmp + (pixmap->h - i - 1) * pixmap->w,
- pixmap->w );
- }
-
- /* XXX flip bitmap in ftrender instead; free pixmap */
-
return nil;
}
diff --git a/render/glyphcache.c b/render/glyphcache.c
index 1d3b8117..a5f9f2b6 100644
--- a/render/glyphcache.c
+++ b/render/glyphcache.c
@@ -37,7 +37,7 @@ struct fz_val_s
{
fz_hash *ent;
unsigned char *data;
- short w, h, lsb, top;
+ short w, h, x, y;
int uses;
};
@@ -239,7 +239,7 @@ fz_debugglyphcache(fz_glyphcache *arena)
k->c / 65536.0,
k->d / 65536.0,
k->e, k->f,
- b->w, b->h, b->lsb, b->top);
+ b->w, b->h, b->x, b->y);
}
}
@@ -319,8 +319,8 @@ fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz
val->uses ++;
glyph->w = val->w;
glyph->h = val->h;
- glyph->lsb = val->lsb;
- glyph->top = val->top;
+ glyph->x = val->x;
+ glyph->y = val->y;
glyph->bitmap = val->data;
bubble(arena, val - arena->lru);
@@ -354,8 +354,8 @@ fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz
val->uses = 0;
val->w = glyph->w;
val->h = glyph->h;
- val->lsb = glyph->lsb;
- val->top = glyph->top;
+ val->x = glyph->x;
+ val->y = glyph->y;
val->data = arena->buffer + arena->used;
arena->used += size;
diff --git a/render/pixmap.c b/render/pixmap.c
index 396b8784..21f36ee0 100644
--- a/render/pixmap.c
+++ b/render/pixmap.c
@@ -24,6 +24,15 @@ fz_newpixmap(fz_pixmap **pixp, int x, int y, int w, int h, int n)
return nil;
}
+fz_error *
+fz_newpixmapwithrect(fz_pixmap **pixp, fz_irect r, int n)
+{
+ return fz_newpixmap(pixp,
+ r.min.x, r.min.y,
+ r.max.x - r.min.x,
+ r.max.y - r.min.y, n);
+}
+
void
fz_droppixmap(fz_pixmap *pix)
{
diff --git a/render/rastnone.c b/render/rastnone.c
new file mode 100644
index 00000000..4e4066fa
--- /dev/null
+++ b/render/rastnone.c
@@ -0,0 +1,379 @@
+#include <fitz.h>
+
+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 & 0xFF;
+ int vd = v & 0xFF;
+ 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 & 0xFF;
+ int vd = v & 0xFF;
+ 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 nx, 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;
+ 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 BLOOP \
+ while (ny--) \
+ { \
+ byte *dst = dst0; \
+ int u = u0; \
+ int v = v0; \
+ while (nx--) \
+
+#define ELOOP \
+ u0 += fc; \
+ v0 += fd; \
+ dst0 += dstw; \
+ }
+
+#define BLOOPM \
+ while (ny--) \
+ { \
+ byte *dst = dst0; \
+ byte *msk = msk0; \
+ int u = u0; \
+ int v = v0; \
+ while (nx--) \
+
+#define ELOOPM \
+ u0 += fc; \
+ v0 += fd; \
+ dst0 += dstw; \
+ msk0 += mskw; \
+ }
+
+static void img1_g(PSRC, PDST, PCTM)
+{
+ BLOOP
+ {
+ dst[0] = samplemsk(src, w, h, u, v);
+ dst ++;
+ u += fa;
+ v += fb;
+ }
+ ELOOP
+}
+
+static void img1_i1(PSRC, PDST, PCTM)
+{
+ BLOOP
+ {
+ dst[0] = fz_mul255(dst[0], samplemsk(src, w, h, u, v));
+ dst ++;
+ u += fa;
+ v += fb;
+ }
+ ELOOP
+}
+
+static void img1_o1(PSRC, PDST, PCTM)
+{
+ BLOOP
+ {
+ byte sa = samplemsk(src, w, h, u, v);
+ dst[0] = sa + fz_mul255(dst[0], 255 - sa);
+ dst ++;
+ u += fa;
+ v += fb;
+ }
+ ELOOP
+}
+
+static void img1_i1o1(PSRC, PDST, PMSK, PCTM)
+{
+ BLOOPM
+ {
+ 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;
+ }
+ ELOOPM
+}
+
+static void img1_o4w3(PSRC, PDST, PCTM, byte *rgb)
+{
+ BLOOP
+ {
+ 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;
+ }
+ ELOOP
+}
+
+static void img1_i1o4w3(PSRC, PDST, PMSK, PCTM, byte *rgb)
+{
+ BLOOPM
+ {
+ 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;
+ }
+ ELOOPM
+}
+
+static void img4_g(PSRC, PDST, PCTM)
+{
+ BLOOP
+ {
+ sampleargb(src, w, h, u, v, dst);
+ dst += 4;
+ u += fa;
+ v += fb;
+ }
+ ELOOP
+}
+
+static void img4_o4(PSRC, PDST, PCTM)
+{
+ byte argb[4];
+ BLOOP
+ {
+ sampleargb(src, w, h, u, v, argb);
+ byte ssa = 255 - argb[0];
+ 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;
+ u += fa;
+ v += fb;
+ }
+ ELOOP
+}
+
+static void img4_i1o4(PSRC, PDST, PMSK, PCTM)
+{
+ byte argb[4];
+ BLOOPM
+ {
+ 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;
+ }
+ ELOOPM
+}
+
+/*
+ *
+ */
+
+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/render.c b/render/render.c
index 62bce18d..672f312f 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1,30 +1,27 @@
#include <fitz.h>
-fz_error *fz_rendercolortext(fz_renderer*, fz_textnode*, fz_colornode*, fz_matrix);
-fz_error *fz_rendercolorpath(fz_renderer*, fz_pathnode*, fz_colornode*, fz_matrix);
-fz_error *fz_rendertext(fz_renderer*, fz_textnode*, fz_matrix);
-fz_error *fz_renderpath(fz_renderer*, fz_pathnode*, fz_matrix);
+#define FNONE 0
+#define FOVER 1
+#define FMASK 2
+#define FRGB 4
-fz_error *fz_rendercolorimage(fz_renderer*, fz_imagenode*, fz_colornode*, fz_matrix);
-fz_error *fz_renderimage(fz_renderer*, fz_imagenode*, fz_matrix);
+static fz_error *rendernode(fz_renderer *gc, fz_node *node, fz_matrix ctm);
fz_error *
-fz_newrenderer(fz_renderer **gcp, fz_colorspace *processcolormodel, int gcmem)
+fz_newrenderer(fz_renderer **gcp, fz_colorspace *pcm, int maskonly, int gcmem)
{
fz_error *error;
fz_renderer *gc;
- gc = *gcp = fz_malloc(sizeof(fz_renderer));
+ gc = fz_malloc(sizeof(fz_renderer));
if (!gc)
return fz_outofmem;
- gc->model = processcolormodel;
+ gc->maskonly = maskonly;
+ gc->model = pcm;
gc->cache = nil;
gc->gel = nil;
gc->ael = nil;
- gc->tmp = nil;
- gc->acc = nil;
- gc->hasrgb = 0;
error = fz_newglyphcache(&gc->cache, gcmem / 32, gcmem);
if (error)
@@ -38,230 +35,483 @@ fz_newrenderer(fz_renderer **gcp, fz_colorspace *processcolormodel, int gcmem)
if (error)
goto cleanup;
+ fz_defaultrastfuncs(&gc->rast);
+
+ gc->dest = nil;
+ gc->mask = nil;
+ gc->over = nil;
+ gc->rgb[0] = 0;
+ gc->rgb[1] = 0;
+ gc->rgb[2] = 0;
+ gc->flag = 0;
+
+ *gcp = gc;
return nil;
cleanup:
- if (gc->cache)
- fz_dropglyphcache(gc->cache);
- if (gc->gel)
- fz_dropgel(gc->gel);
- if (gc->ael)
- fz_dropael(gc->ael);
+ if (gc->model) fz_dropcolorspace(gc->model);
+ if (gc->cache) fz_dropglyphcache(gc->cache);
+ if (gc->gel) fz_dropgel(gc->gel);
+ if (gc->ael) fz_dropael(gc->ael);
fz_free(gc);
-
return error;
}
void
fz_droprenderer(fz_renderer *gc)
{
- if (gc->cache)
- fz_dropglyphcache(gc->cache);
- if (gc->gel)
- fz_dropgel(gc->gel);
- if (gc->ael)
- fz_dropael(gc->ael);
- if (gc->tmp)
- fz_droppixmap(gc->tmp);
- if (gc->acc)
- fz_droppixmap(gc->acc);
+ 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);
+ if (gc->cache) fz_dropglyphcache(gc->cache);
+ if (gc->gel) fz_dropgel(gc->gel);
+ if (gc->ael) fz_dropael(gc->ael);
fz_free(gc);
}
-fz_error *
-fz_rendercolor(fz_renderer *gc, fz_colornode *color, fz_matrix ctm)
+/*
+ * Transform
+ */
+
+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("{");
+ ctm = fz_concat(transform->m, ctm);
+ error = rendernode(gc, transform->super.first, ctm);
+puts("}");
+ return error;
+}
+
+/*
+ * Color
+ */
+
+static fz_error *
+rendercolor(fz_renderer *gc, fz_colornode *color, fz_matrix ctm)
{
fz_error *error;
- int x, y, w, h;
float rgb[3];
unsigned char *p;
+ int n;
- assert(gc->model);
+ if (gc->maskonly)
+ return fz_throw("assert: mask only renderer");
+ if (gc->model->n != 3)
+ return fz_throw("assert: non-rgb renderer");
fz_convertcolor(color->cs, color->samples, gc->model, rgb);
- gc->r = rgb[0] * 255;
- gc->g = rgb[1] * 255;
- gc->b = rgb[2] * 255;
+ gc->rgb[0] = rgb[0] * 255;
+ gc->rgb[1] = rgb[1] * 255;
+ gc->rgb[2] = rgb[2] * 255;
- x = gc->clip.min.x;
- y = gc->clip.min.y;
- w = gc->clip.max.x - gc->clip.min.x;
- h = gc->clip.max.y - gc->clip.min.y;
+printf("color %s [%d %d %d]\n", color->cs->name, gc->rgb[0], gc->rgb[1], gc->rgb[2]);
- error = fz_newpixmap(&gc->tmp, x, y, w, h, 4);
+ error = fz_newpixmapwithrect(&gc->dest, gc->clip, 4);
if (error)
return error;
- p = gc->tmp->samples;
+ p = gc->dest->samples;
+ n = gc->dest->w * gc->dest->h;
+
+ while (n--)
+ {
+ p[0] = 255;
+ p[1] = gc->rgb[0];
+ p[2] = gc->rgb[1];
+ p[3] = gc->rgb[2];
+ p += 4;
+ }
+
+ return nil;
+}
+
+/*
+ * Path
+ */
+
+enum { HS = 17, VS = 15, SF = 1 };
+
+struct spandata
+{
+ fz_rastfuncs *rast;
+ int x, n;
+ fz_pixmap *dst;
+ fz_pixmap *msk;
+ unsigned char *rgb;
+ int flag;
+};
+
+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;
- for (y = 0; y < gc->tmp->h; y++)
+ path += 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;
+
+ switch (user->flag)
{
- for (x = 0; x < gc->tmp->w; x++)
+ case FNONE:
+ rast->mask_g(user->n, path, d); break;
+ case FOVER:
+ rast->mask_o1(user->n, path, d); break;
+ case FOVER | FMASK:
+ rast->mask_i1o1(user->n, path, m, d); 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;
+ default:
+ assert(!"impossible flag in path span function");
+ }
+}
+
+static fz_error *
+renderpath(fz_renderer *gc, fz_pathnode *path, fz_matrix ctm)
+{
+ struct spandata user;
+ fz_error *error;
+ float flatness;
+ fz_irect gbox;
+ fz_irect clip;
+
+ flatness = 0.3 / fz_matrixexpansion(ctm);
+ if (flatness < 0.1)
+ flatness = 0.1;
+
+ fz_resetgel(gc->gel, HS, VS);
+
+ if (path->paint == FZ_STROKE)
+ {
+ if (path->dash)
+ error = fz_dashpath(gc->gel, path, ctm, flatness);
+ else
+ error = fz_strokepath(gc->gel, path, ctm, flatness);
+ }
+ else
+ error = fz_fillpath(gc->gel, path, ctm, flatness);
+ if (error)
+ return error;
+
+ fz_sortgel(gc->gel);
+
+ gbox = fz_boundgel(gc->gel);
+ clip = fz_intersectirects(gc->clip, gbox);
+
+//printf("path clip[%d %d %d %d]\n", clip.min.x, clip.min.y, clip.max.x, clip.max.y);
+
+ user.rast = &gc->rast;
+ user.x = clip.min.x - gbox.min.x;
+ user.n = clip.max.x - clip.min.x;
+ user.flag = gc->flag;
+
+ if (gc->flag == FNONE)
+ {
+ 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,
+ clip.min.y, clip.max.y, spanfunc, &user);
+ if (error)
+ return error;
+
+ return nil;
+}
+
+/*
+ * Text
+ */
+
+static void copyglyph(fz_renderer *gc, fz_pixmap *dst, fz_glyph *src, int xorig, int yorig)
+{
+ int x, y;
+
+ xorig += src->x;
+ yorig += src->y;
+
+ for (y = 0; y < src->h; y++)
+ for (x = 0; x < src->w; x++)
{
- *p++ = 255;
- *p++ = gc->r;
- *p++ = gc->g;
- *p++ = gc->b;
+ int dx = xorig + x - dst->x;
+ int dy = yorig + y - dst->y;
+
+ if (dx < 0) {puts("dx<0");continue;}
+ if (dy < 0) {puts("dy<0");continue;}
+ if (dx >= dst->w) {puts("dx>w");continue;}
+ if (dy >= dst->h) {puts("dy>h");continue;}
+
+ int a = src->bitmap[x + y * src->w];
+ int b = dst->samples[dx + dy * dst->w];
+ int c = a + fz_mul255(b, 255 - a);
+ dst->samples[dx + dy * dst->w] = a;
}
+}
+
+static fz_error *
+rendertext(fz_renderer *gc, fz_textnode *text, fz_matrix ctm)
+{
+ fz_error *error;
+ fz_irect tbox;
+ fz_irect clip;
+ fz_matrix tm, trm;
+ fz_glyph glyph;
+ int i, x, y, cid;
+
+ 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);
+fflush(stdout);
+
+ clip.min.x ++;
+ clip.min.y ++;
+ clip.max.x ++;
+ clip.max.y ++;
+
+ error = fz_newpixmapwithrect(&gc->dest, clip, 1);
+ if (error)
+ return error;
+
+ fz_clearpixmap(gc->dest);
+
+ tm = text->trm;
+
+ for (i = 0; i < text->len; i++)
+ {
+ cid = text->els[i].cid;
+ tm.e = text->els[i].x;
+ tm.f = text->els[i].y;
+ trm = fz_concat(tm, ctm);
+ x = fz_floor(trm.e);
+ y = fz_floor(trm.f);
+ trm.e = (trm.e - fz_floor(trm.e));
+ trm.f = (trm.f - fz_floor(trm.f));
+
+ error = fz_renderglyph(gc->cache, &glyph, text->font, cid, trm);
+ if (error)
+ return error;
+
+ copyglyph(gc, gc->dest, &glyph, x, y);
}
return nil;
}
-fz_error *
-fz_renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm)
+/*
+ * Image
+ */
+
+static fz_error *
+renderimage(fz_renderer *gc, fz_imagenode *image, fz_matrix ctm)
+{
+ return nil;
+}
+
+/*
+ * Over, Mask and Blend
+ */
+
+static fz_error *
+renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm)
{
fz_error *error;
fz_node *child;
int cluster = 0;;
- if (!gc->acc)
- {
- int x = gc->clip.min.x;
- int y = gc->clip.min.y;
- int w = gc->clip.max.x - gc->clip.min.x;
- int h = gc->clip.max.y - gc->clip.min.y;
+printf("over\n{\n");
- error = fz_newpixmap(&gc->acc, x, y, w, h, gc->model ? 4 : 1);
+ if (!gc->over)
+ {
+printf(" alloc dest!\n");
+ error = fz_newpixmapwithrect(&gc->over, gc->clip, gc->maskonly ? 1 : 4);
if (error)
return error;
-
- fz_clearpixmap(gc->acc);
-
+ fz_clearpixmap(gc->over);
cluster = 1;
}
for (child = over->super.first; child; child = child->next)
{
- error = fz_rendernode(gc, child, ctm);
+ error = rendernode(gc, child, ctm);
if (error)
return error;
-
- if (gc->tmp)
+ if (gc->dest)
{
- fz_blendover(gc->tmp, gc->acc);
- fz_droppixmap(gc->tmp);
- gc->tmp = nil;
+ fz_blendover(gc->dest, gc->over);
+ fz_droppixmap(gc->dest);
+ gc->dest = nil;
}
}
if (cluster)
{
- gc->tmp = gc->acc;
- gc->acc = nil;
+ gc->dest = gc->over;
+ gc->over = nil;
}
+printf("}\n");
+
return nil;
}
-fz_error *
-fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
+static fz_error *
+rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
{
fz_error *error;
- fz_pixmap *oldacc;
- fz_pixmap *colorpix;
+ fz_pixmap *oldover;
+ fz_pixmap *oldmask;
+ fz_irect oldclip;
+ fz_irect newclip;
fz_pixmap *shapepix;
- fz_node *color;
+ fz_pixmap *colorpix;
fz_node *shape;
- fz_irect newclip;
- fz_irect oldclip;
- int x, y, w, h;
+ fz_node *color;
+ float rgb[3];
shape = mask->super.first;
color = shape->next;
- if (gc->acc)
+ /* special case black voodo */
+ if (gc->flag & FOVER)
{
- if (fz_ispathnode(shape) && fz_iscolornode(color))
- return fz_rendercolorpath(gc, (fz_pathnode*)shape, (fz_colornode*)color, ctm);
- if (fz_istextnode(shape) && fz_iscolornode(color))
- return fz_rendercolortext(gc, (fz_textnode*)shape, (fz_colornode*)color, ctm);
- if (fz_isimagenode(shape) && fz_iscolornode(color))
- return fz_rendercolorimage(gc, (fz_imagenode*)shape, (fz_colornode*)color, ctm);
+ if (fz_iscolornode(color))
+ {
+ fz_colornode *colorn = (fz_colornode*)color;
+
+ fz_convertcolor(colorn->cs, colorn->samples, gc->model, rgb);
+ gc->rgb[0] = rgb[0] * 255;
+ gc->rgb[1] = rgb[1] * 255;
+ gc->rgb[2] = rgb[2] * 255;
+ gc->flag |= FRGB;
+
+ /* we know these handle FOVER | FRGB */
+ if (fz_ispathnode(shape))
+ return renderpath(gc, (fz_pathnode*)shape, ctm);
+ if (fz_istextnode(shape))
+ return rendertext(gc, (fz_textnode*)shape, ctm);
+ if (fz_isimagenode(shape))
+ return renderimage(gc, (fz_imagenode*)shape, ctm);
+ }
}
- oldacc = gc->acc;
oldclip = gc->clip;
+ oldover = gc->over;
+ oldmask = gc->mask;
+
newclip = fz_roundrect(fz_boundnode(shape, ctm));
newclip = fz_intersectirects(newclip, gc->clip);
- gc->acc = nil;
gc->clip = newclip;
+ gc->over = nil;
+ gc->mask = nil;
- gc->tmp = nil;
- error = fz_rendernode(gc, color, ctm);
+printf("mask\n{\n");
+
+ error = rendernode(gc, color, ctm);
if (error)
return error;
- colorpix = gc->tmp;
+ colorpix = gc->dest;
+ gc->dest = nil;
- gc->tmp = nil;
- error = fz_rendernode(gc, shape, ctm);
+ error = rendernode(gc, shape, ctm);
if (error)
return error;
- shapepix = gc->tmp;
-
- x = gc->clip.min.x;
- y = gc->clip.min.y;
- w = gc->clip.max.x - gc->clip.min.x;
- h = gc->clip.max.y - gc->clip.min.y;
+ shapepix = gc->dest;
+ gc->dest = nil;
- error = fz_newpixmap(&gc->tmp, x, y, w, h, colorpix->n);
+ error = fz_newpixmapwithrect(&gc->dest, gc->clip, colorpix->n);
if (error)
return error;
- fz_clearpixmap(gc->tmp);
+ fz_clearpixmap(gc->dest);
+
+ fz_blendmask(gc->dest, colorpix, shapepix);
- fz_blendmask(gc->tmp, colorpix, shapepix);
+//fz_debugpixmap(gc->dest);getchar();
fz_droppixmap(shapepix);
fz_droppixmap(colorpix);
- gc->acc = oldacc;
+ gc->over = oldover;
+ gc->mask = oldmask;
gc->clip = oldclip;
+printf("}\n");
+
return nil;
}
-fz_error *
-fz_rendertransform(fz_renderer *gc, fz_transformnode *transform, fz_matrix ctm)
-{
- ctm = fz_concat(transform->m, ctm);
- return fz_rendernode(gc, transform->super.first, ctm);
-}
+/*
+ * Dispatch
+ */
-fz_error *
-fz_rendernode(fz_renderer *gc, fz_node *node, fz_matrix ctm)
+static fz_error *
+rendernode(fz_renderer *gc, fz_node *node, fz_matrix ctm)
{
- assert(gc->tmp == nil);
-
if (!node)
return nil;
+ gc->flag = FNONE;
+ if (gc->over) gc->flag |= FOVER;
+ if (gc->mask) gc->flag |= FMASK;
+
switch (node->kind)
{
case FZ_NOVER:
- return fz_renderover(gc, (fz_overnode*)node, ctm);
+ return renderover(gc, (fz_overnode*)node, ctm);
case FZ_NMASK:
- return fz_rendermask(gc, (fz_masknode*)node, ctm);
+ return rendermask(gc, (fz_masknode*)node, ctm);
case FZ_NTRANSFORM:
- return fz_rendertransform(gc, (fz_transformnode*)node, ctm);
+ return rendertransform(gc, (fz_transformnode*)node, ctm);
case FZ_NCOLOR:
- return fz_rendercolor(gc, (fz_colornode*)node, ctm);
+ return rendercolor(gc, (fz_colornode*)node, ctm);
case FZ_NPATH:
- return fz_renderpath(gc, (fz_pathnode*)node, ctm);
+ return renderpath(gc, (fz_pathnode*)node, ctm);
case FZ_NTEXT:
- return fz_rendertext(gc, (fz_textnode*)node, ctm);
+ return rendertext(gc, (fz_textnode*)node, ctm);
case FZ_NIMAGE:
- return fz_renderimage(gc, (fz_imagenode*)node, ctm);
+ return renderimage(gc, (fz_imagenode*)node, ctm);
case FZ_NLINK:
- return fz_rendernode(gc, ((fz_linknode*)node)->tree->root, ctm);
- default:
- return nil;
+ return rendernode(gc, ((fz_linknode*)node)->tree->root, ctm);
}
+
+ return nil;
}
fz_error *
-fz_rendertree(fz_pixmap **outp, fz_renderer *gc, fz_tree *tree, fz_matrix ctm, fz_irect bbox, int white)
+fz_rendertree(fz_pixmap **outp,
+ fz_renderer *gc, fz_tree *tree, fz_matrix ctm,
+ fz_irect bbox, int white)
{
fz_error *error;
@@ -269,27 +519,28 @@ fz_rendertree(fz_pixmap **outp, fz_renderer *gc, fz_tree *tree, fz_matrix ctm, f
if (white)
{
- error = fz_newpixmap(&gc->acc,
- bbox.min.x, bbox.min.y,
- bbox.max.x - bbox.min.x, bbox.max.y - bbox.min.y, 4);
+ assert(gc->maskonly == 0);
+
+ error = fz_newpixmapwithrect(&gc->over, bbox, 4);
if (error)
return error;
- memset(gc->acc->samples, 0xff, gc->acc->w * gc->acc->h * gc->acc->n);
+
+ memset(gc->over->samples, 0xff, gc->over->w * gc->over->h * gc->over->n);
}
- error = fz_rendernode(gc, tree->root, ctm);
+ error = rendernode(gc, tree->root, ctm);
if (error)
return error;
if (white)
{
- *outp = gc->acc;
- gc->acc = nil;
+ *outp = gc->over;
+ gc->over = nil;
}
else
{
- *outp = gc->tmp;
- gc->tmp = nil;
+ *outp = gc->dest;
+ gc->dest = nil;
}
return nil;
diff --git a/render/scale.c b/render/scale.c
index a07d52a7..6b06dcfa 100644
--- a/render/scale.c
+++ b/render/scale.c
@@ -4,7 +4,7 @@ static void
scalerow(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom)
{
int x, left, k;
- int sum[32];
+ int sum[FZ_MAXCOLORS];
left = 0;
for (k = 0; k < ncomp; k++)
@@ -37,7 +37,7 @@ scalecols(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom)
{
int x, y, k;
unsigned char *s;
- int sum[32];
+ int sum[FZ_MAXCOLORS];
for (x = 0; x < w; x++)
{
diff --git a/test/pdfrip.c b/test/pdfrip.c
index 877be289..b34dfb11 100644
--- a/test/pdfrip.c
+++ b/test/pdfrip.c
@@ -49,7 +49,7 @@ void showpage(pdf_xref *xref, fz_obj *pageobj)
fz_matrix ctm;
fz_rect bbox;
- error = fz_newrenderer(&gc, pdf_devicergb, 1024 * 512);
+ error = fz_newrenderer(&gc, pdf_devicergb, 0, 1024 * 512);
if (error) fz_abort(error);
ctm = fz_concat(fz_translate(0, -page->mediabox.max.y), fz_scale(zoom, -zoom));
diff --git a/test/x11pdf.c b/test/x11pdf.c
index 9b1e94c7..b02b2c58 100644
--- a/test/x11pdf.c
+++ b/test/x11pdf.c
@@ -231,7 +231,7 @@ static void pdfopen(char *filename, char *password)
}
}
- error = fz_newrenderer(&rast, pdf_devicergb, 1024 * 512);
+ error = fz_newrenderer(&rast, pdf_devicergb, 0, 1024 * 512);
if (error) fz_abort(error);
image = nil;
diff --git a/tree/colorspace.c b/tree/colorspace.c
index f5025468..aabf531b 100644
--- a/tree/colorspace.c
+++ b/tree/colorspace.c
@@ -55,8 +55,8 @@ fz_stdconvcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *ds
void
fz_stdconvpixmap(fz_colorspace *srcs, fz_pixmap *src, fz_colorspace *dsts, fz_pixmap *dst)
{
- float srcv[32];
- float dstv[32];
+ float srcv[FZ_MAXCOLORS];
+ float dstv[FZ_MAXCOLORS];
int y, x, k;
unsigned char *s = src->samples;