summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2004-11-22 08:11:02 +0100
committerTor Andersson <tor@ghostscript.com>2004-11-22 08:11:02 +0100
commit459f682af16a1982745f2c40a368c1a54059b23e (patch)
treee3c02a0a7d56d02b41bd2f05b3ca747347d51911
parentce1bf1ef28a160c48c287d302ab7795330806cf0 (diff)
downloadmupdf-459f682af16a1982745f2c40a368c1a54059b23e.tar.xz
rewrite of render loop part 2
-rw-r--r--include/fitz/font.h2
-rw-r--r--mupdf/font.c26
-rw-r--r--mupdf/image2.c1
-rw-r--r--mupdf/type3.c2
-rw-r--r--render/glyphcache.c16
-rw-r--r--render/rastnone.c9
-rw-r--r--render/render.c274
7 files changed, 271 insertions, 59 deletions
diff --git a/include/fitz/font.h b/include/fitz/font.h
index 7e925461..27217c6c 100644
--- a/include/fitz/font.h
+++ b/include/fitz/font.h
@@ -43,7 +43,7 @@ struct fz_font_s
struct fz_glyph_s
{
int x, y, w, h;
- unsigned char *bitmap;
+ unsigned char *samples;
};
void fz_initfont(fz_font *font, char *name);
diff --git a/mupdf/font.c b/mupdf/font.c
index e2debc85..464d8c11 100644
--- a/mupdf/font.c
+++ b/mupdf/font.c
@@ -112,7 +112,7 @@ ftrender(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
glyph->h = 0;
glyph->x = 0;
glyph->y = 0;
- glyph->bitmap = nil;
+ glyph->samples = nil;
/* freetype mutilates complex glyphs if they are loaded
* with FT_Set_Char_Size 1.0. it rounds the coordinates
@@ -163,15 +163,15 @@ ftrender(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
glyph->h = face->glyph->bitmap.rows;
glyph->x = face->glyph->bitmap_left;
glyph->y = face->glyph->bitmap_top - glyph->h;
- glyph->bitmap = face->glyph->bitmap.buffer;
+ glyph->samples = face->glyph->bitmap.buffer;
int i;
unsigned char tmp[glyph->w * glyph->h];
- memcpy(tmp, glyph->bitmap, glyph->w * glyph->h);
+ memcpy(tmp, glyph->samples, glyph->w * glyph->h);
for (i = 0; i < glyph->h; i++)
{
- memcpy( glyph->bitmap + i * glyph->w,
+ memcpy( glyph->samples + i * glyph->w,
tmp + (glyph->h - i - 1) * glyph->w,
glyph->w );
}
@@ -312,9 +312,12 @@ printf("loading simple font %s -> %s\n", basefont, fontname);
symbolic = font->flags & 4;
- fz_setfontbbox((fz_font*)font,
- face->bbox.xMin, face->bbox.yMin,
- face->bbox.xMax, face->bbox.yMax);
+ if (face->bbox.xMax == face->bbox.xMin)
+ fz_setfontbbox((fz_font*)font, -1000, -1000, 2000, 2000);
+ else
+ fz_setfontbbox((fz_font*)font,
+ face->bbox.xMin, face->bbox.yMin,
+ face->bbox.xMax, face->bbox.yMax);
/*
* Encoding
@@ -615,9 +618,12 @@ printf(" collection %s\n", collection);
face = font->ftface;
kind = ftkind(face);
- fz_setfontbbox((fz_font*)font,
- face->bbox.xMin, face->bbox.yMin,
- face->bbox.xMax, face->bbox.yMax);
+ if (face->bbox.xMax == face->bbox.xMin)
+ fz_setfontbbox((fz_font*)font, -1000, -1000, 2000, 2000);
+ else
+ fz_setfontbbox((fz_font*)font,
+ face->bbox.xMin, face->bbox.yMin,
+ face->bbox.xMax, face->bbox.yMax);
/*
* Encoding
diff --git a/mupdf/image2.c b/mupdf/image2.c
index d46bdd0e..ad07e6bc 100644
--- a/mupdf/image2.c
+++ b/mupdf/image2.c
@@ -202,7 +202,6 @@ pdf_loadtile(fz_image *img, fz_pixmap *tile)
return fz_throw("rangecheck: unsupported bit depth: %d", src->bpc);
}
-printf(" unpack n=%d\n", tile->n);
for (y = 0; y < tile->h; y++)
{
for (x = 0; x < tile->w; x++)
diff --git a/mupdf/type3.c b/mupdf/type3.c
index ee7708c0..64ef9a2c 100644
--- a/mupdf/type3.c
+++ b/mupdf/type3.c
@@ -56,7 +56,7 @@ t3render(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
glyph->y = pixmap->y;
glyph->w = pixmap->w;
glyph->h = pixmap->h;
- glyph->bitmap = pixmap->samples;
+ glyph->samples = pixmap->samples;
return nil;
}
diff --git a/render/glyphcache.c b/render/glyphcache.c
index a5f9f2b6..c47ed0ed 100644
--- a/render/glyphcache.c
+++ b/render/glyphcache.c
@@ -36,7 +36,7 @@ struct fz_hash_s
struct fz_val_s
{
fz_hash *ent;
- unsigned char *data;
+ unsigned char *samples;
short w, h, x, y;
int uses;
};
@@ -276,7 +276,7 @@ evictlast(fz_glyphcache *arena)
return;
k = arena->load - 1;
- s = lru[k].data;
+ s = lru[k].samples;
e = s + lru[k].w * lru[k].h;
/* pack buffer to fill hole */
@@ -286,8 +286,8 @@ evictlast(fz_glyphcache *arena)
/* update lru pointers */
for (i = 0; i < k; i++)
- if (lru[i].data >= e)
- lru[i].data -= e - s;
+ if (lru[i].samples >= e)
+ lru[i].samples -= e - s;
/* remove hash entry */
key = lru[k].ent->key;
@@ -321,7 +321,7 @@ fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz
glyph->h = val->h;
glyph->x = val->x;
glyph->y = val->y;
- glyph->bitmap = val->data;
+ glyph->samples = val->samples;
bubble(arena, val - arena->lru);
@@ -356,12 +356,12 @@ fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz
val->h = glyph->h;
val->x = glyph->x;
val->y = glyph->y;
- val->data = arena->buffer + arena->used;
+ val->samples = arena->buffer + arena->used;
arena->used += size;
- memcpy(val->data, glyph->bitmap, glyph->w * glyph->h);
- glyph->bitmap = val->data;
+ memcpy(val->samples, glyph->samples, glyph->w * glyph->h);
+ glyph->samples = val->samples;
hashinsert(arena, &key, val);
diff --git a/render/rastnone.c b/render/rastnone.c
index 4e4066fa..2a575ccb 100644
--- a/render/rastnone.c
+++ b/render/rastnone.c
@@ -155,7 +155,7 @@ static inline void sampleargb(byte *s, int w, int h, int u, int v, byte *abcd)
lerpargb(abcd, ab, cd, vd);
}
-#define PSRC byte *src, int w, int h, int nx, int ny
+#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
@@ -169,6 +169,7 @@ static void example(PSRC, PDST, PMSK, PCTM)
byte *msk = msk0;
int u = u0;
int v = v0;
+ int nx = nx0;
while (nx--)
{
// dst[0] = ... msk[0] ... sample(s, w, h, u, v);
@@ -191,7 +192,8 @@ static void example(PSRC, PDST, PMSK, PCTM)
byte *dst = dst0; \
int u = u0; \
int v = v0; \
- while (nx--) \
+ int nx = nx0; \
+ while (nx--)
#define ELOOP \
u0 += fc; \
@@ -206,7 +208,8 @@ static void example(PSRC, PDST, PMSK, PCTM)
byte *msk = msk0; \
int u = u0; \
int v = v0; \
- while (nx--) \
+ int nx = nx0; \
+ while (nx--)
#define ELOOPM \
u0 += fc; \
diff --git a/render/render.c b/render/render.c
index 672f312f..13787ce4 100644
--- a/render/render.c
+++ b/render/render.c
@@ -213,6 +213,11 @@ 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)
+ return nil;
+
//printf("path clip[%d %d %d %d]\n", clip.min.x, clip.min.y, clip.max.x, clip.max.y);
user.rast = &gc->rast;
@@ -249,29 +254,71 @@ renderpath(fz_renderer *gc, fz_pathnode *path, fz_matrix ctm)
* Text
*/
-static void copyglyph(fz_renderer *gc, fz_pixmap *dst, fz_glyph *src, int xorig, int yorig)
+static void drawglyph(fz_renderer *gc, fz_pixmap *dst, fz_glyph *src, int xorig, int yorig)
{
- int x, y;
+ unsigned char *dp, *sp;
+ int w, h;
+
+ int dx1 = dst->x + dst->w;
+ int dy1 = dst->y + dst->h;
+
+ int x0 = xorig + src->x;
+ int y0 = yorig + src->y;
+ int x1 = x0 + src->w;
+ int y1 = y0 + src->h;
+
+ int sx0 = 0;
+ int sy0 = 0;
+ int sx1 = src->w;
+ int sy1 = src->h;
- xorig += src->x;
- yorig += src->y;
+ if (x1 < dst->x || x0 >= dx1) return;
+ if (y1 < dst->y || y0 >= dy1) return;
- for (y = 0; y < src->h; y++)
- for (x = 0; x < src->w; x++)
+ 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; }
+
+ sp = src->samples + (sy0 * src->w + sx0);
+ dp = dst->samples + ((y0 - dst->y) * dst->w + (x0 - dst->x)) * dst->n;
+
+ w = sx1 - sx0;
+ h = sy1 - sy0;
+
+ switch (gc->flag)
+ {
+ case FNONE:
+ while (h--)
+ {
+ gc->rast.mask_g(w, sp, dp);
+ sp += src->w;
+ dp += dst->w * dst->n;
+ }
+ break;
+
+ case FOVER:
+ while (h--)
{
- 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;
+ gc->rast.mask_o1(w, sp, dp);
+ sp += src->w;
+ dp += dst->w * dst->n;
}
+ break;
+
+ case FOVER | FRGB:
+ while (h--)
+ {
+ gc->rast.mask_o4w3(w, sp, dp, gc->rgb);
+ sp += src->w;
+ dp += dst->w * dst->n;
+ }
+ break;
+
+ default:
+ assert(!"impossible flag in text span function");
+ }
}
static fz_error *
@@ -291,18 +338,24 @@ 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);
+
+ if (clip.max.x <= clip.min.x)
+ return nil;
+ if (clip.max.y <= clip.min.y)
+ return nil;
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);
+ if (gc->flag == FNONE)
+ {
+ error = fz_newpixmapwithrect(&gc->dest, clip, 1);
+ if (error)
+ return error;
+ fz_clearpixmap(gc->dest);
+ }
tm = text->trm;
@@ -321,7 +374,10 @@ fflush(stdout);
if (error)
return error;
- copyglyph(gc, gc->dest, &glyph, x, y);
+ if (gc->flag == FNONE)
+ drawglyph(gc, gc->dest, &glyph, x, y);
+ else
+ drawglyph(gc, gc->over, &glyph, x, y);
}
return nil;
@@ -331,9 +387,156 @@ fflush(stdout);
* Image
*/
+static inline void
+calcimagescale(fz_matrix ctm, int w, int h, int *odx, int *ody)
+{
+ float sx, sy;
+ int dx, dy;
+
+ sx = sqrt(ctm.a * ctm.a + ctm.b * ctm.b);
+ dx = 1;
+ while (((w+dx-1)/dx)/sx > 2.0 && (w+dx-1)/dx > 1)
+ dx++;
+
+ sy = sqrt(ctm.c * ctm.c + ctm.d * ctm.d);
+ dy = 1;
+ while (((h+dy-1)/dy)/sy > 2.0 && (h+dy-1)/dy > 1)
+ dy++;
+
+ *odx = dx;
+ *ody = dy;
+}
+
static fz_error *
-renderimage(fz_renderer *gc, fz_imagenode *image, fz_matrix ctm)
+renderimage(fz_renderer *gc, fz_imagenode *node, fz_matrix ctm)
{
+ fz_error *error;
+ fz_image *image = node->image;
+ fz_irect bbox;
+ fz_irect clip;
+ int dx, dy;
+ fz_pixmap *tile;
+ fz_matrix imgmat;
+ fz_matrix invmat;
+ int fa, fb, fc, fd;
+ int u0, v0;
+ int x0, y0;
+ int w, h;
+
+ /* TODO: check validity of xxx->n + 1 */
+
+printf("renderimage %dx%d %d+%d %s\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)
+ return nil;
+
+ calcimagescale(ctm, image->w, image->h, &dx, &dy);
+
+printf(" load image\n");
+ error = fz_newpixmap(&tile, 0, 0, image->w, image->h, image->n + 1);
+ error = image->loadtile(image, tile);
+
+ if (dx != 1 || dy != 1)
+ {
+printf(" scale image 1/%d 1/%d\n", dx, dy);
+ fz_pixmap *temp;
+ error = fz_scalepixmap(&temp, tile, dx, dy);
+ fz_droppixmap(tile);
+ tile = temp;
+ }
+
+ if (image->cs && image->cs != gc->model)
+ {
+ fz_pixmap *temp;
+printf(" 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);
+ fz_convertpixmap(image->cs, tile, gc->model, temp);
+ fz_droppixmap(tile);
+ tile = temp;
+ }
+
+ imgmat.a = 1.0 / tile->w;
+ imgmat.b = 0.0;
+ imgmat.c = 0.0;
+ imgmat.d = -1.0 / tile->h;
+ imgmat.e = 0.0;
+ imgmat.f = 1.0;
+ invmat = fz_invertmatrix(fz_concat(imgmat, ctm));
+
+ w = clip.max.x - clip.min.x;
+ h = clip.max.y - clip.min.y;
+ x0 = clip.min.x;
+ y0 = clip.min.y;
+ u0 = (invmat.a * (x0+0.5) + invmat.c * (y0+0.5) + invmat.e) * 65536;
+ v0 = (invmat.b * (x0+0.5) + invmat.d * (y0+0.5) + invmat.f) * 65536;
+ fa = invmat.a * 65536;
+ fb = invmat.b * 65536;
+ fc = invmat.c * 65536;
+ fd = invmat.d * 65536;
+
+ switch (gc->flag)
+ {
+ case FNONE:
+ {
+printf(" fnone %d x %d\n", w, h);
+ if (image->cs)
+ error = fz_newpixmapwithrect(&gc->dest, clip, gc->model->n + 1);
+ else
+ error = fz_newpixmapwithrect(&gc->dest, clip, 1);
+ fz_clearpixmap(gc->dest);
+
+ 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);
+ 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);
+ }
+ break;
+
+ case FOVER:
+ {
+printf(" 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);
+ 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);
+ }
+ 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);
+ }
+ break;
+ default:
+ assert(!"impossible flag in image span function");
+ }
+
+ fz_droppixmap(tile);
+
return nil;
}
@@ -449,18 +652,19 @@ printf("mask\n{\n");
shapepix = gc->dest;
gc->dest = nil;
- error = fz_newpixmapwithrect(&gc->dest, gc->clip, colorpix->n);
- if (error)
- return error;
-
- fz_clearpixmap(gc->dest);
+ if (colorpix && shapepix)
+ {
+ error = fz_newpixmapwithrect(&gc->dest, gc->clip, colorpix->n);
+ if (error)
+ return error;
- fz_blendmask(gc->dest, colorpix, shapepix);
+ fz_clearpixmap(gc->dest);
-//fz_debugpixmap(gc->dest);getchar();
+ fz_blendmask(gc->dest, colorpix, shapepix);
+ }
- fz_droppixmap(shapepix);
- fz_droppixmap(colorpix);
+ if (shapepix) fz_droppixmap(shapepix);
+ if (colorpix) fz_droppixmap(colorpix);
gc->over = oldover;
gc->mask = oldmask;