diff options
Diffstat (limited to 'draw')
-rw-r--r-- | draw/imagedraw.c | 123 | ||||
-rw-r--r-- | draw/imageunpack.c | 2 | ||||
-rw-r--r-- | draw/pathscan.c | 54 | ||||
-rw-r--r-- | draw/porterduff.c | 53 |
4 files changed, 223 insertions, 9 deletions
diff --git a/draw/imagedraw.c b/draw/imagedraw.c index 9f6d93bf..81d2bb05 100644 --- a/draw/imagedraw.c +++ b/draw/imagedraw.c @@ -22,6 +22,16 @@ getargb(byte *s, int w, int h, int u, int v) return s + ((w * v + u) << 2); } +static inline byte * +getag(byte *s, int w, int h, int u, int v) +{ + if (u < 0) u = 0; + if (v < 0) v = 0; + if (u >= w) u = w - 1; + if (v >= h) v = h - 1; + return s + ((w * v + u) << 1); +} + static inline int getcolor(byte *s, int w, int h, int n, int u, int v, int k) { @@ -39,6 +49,13 @@ lerp(int a, int b, int t) } static inline void +lerpag(byte *dst, byte *a, byte *b, int t) +{ + dst[0] = lerp(a[0], b[0], t); + dst[1] = lerp(a[1], b[1], t); +} + +static inline void lerpargb(byte *dst, byte *a, byte *b, int t) { dst[0] = lerp(a[0], b[0], t); @@ -64,6 +81,24 @@ samplemask(byte *s, int w, int h, int u, int v) } static inline void +sampleag(byte *s, int w, int h, int u, int v, byte *out) +{ + byte ab[4]; + byte cd[4]; + int ui = u >> 16; + int vi = v >> 16; + int ud = u & 0xFFFF; + int vd = v & 0xFFFF; + byte *a = getag(s, w, h, ui, vi); + byte *b = getag(s, w, h, ui+1, vi); + byte *c = getag(s, w, h, ui, vi+1); + byte *d = getag(s, w, h, ui+1, vi+1); + lerpag(ab, a, b, ud); + lerpag(cd, c, d, ud); + lerpag(out, ab, cd, vd); +} + +static inline void sampleargb(byte *s, int w, int h, int u, int v, byte *out) { byte ab[4]; @@ -129,6 +164,35 @@ img_1o1(byte * restrict src, byte cov, int len, byte * restrict dst, } static void +img_2o2(byte * restrict src, byte cov, int len, byte * restrict dst, + fz_pixmap *image, int u, int v, int fa, int fb) +{ + byte *samples = image->samples; + int w = image->w; + int h = image->h; + byte ag[2]; + + while (len--) + { + int sa; + cov += *src; *src = 0; src++; + if (cov != 0) + { + sampleag(samples, w, h, u, v, ag); + sa = FZ_COMBINE(FZ_EXPAND(ag[0]), FZ_EXPAND(cov)); + if (sa != 0) + { + dst[0] = FZ_BLEND(255, dst[0], sa); + dst[1] = FZ_BLEND(ag[1], dst[1], sa); + } + } + dst += 2; + u += fa; + v += fb; + } +} + +static void img_4o4(byte * restrict src, byte cov, int len, byte * restrict dst, fz_pixmap *image, int u, int v, int fa, int fb) { @@ -160,6 +224,63 @@ img_4o4(byte * restrict src, byte cov, int len, byte * restrict dst, } static void +img_w2i1o2(byte *ag, byte * restrict src, byte cov, int len, byte * restrict dst, + fz_pixmap *image, int u, int v, int fa, int fb) +{ + byte *samples = image->samples; + int w = image->w; + int h = image->h; + int alpha = FZ_EXPAND(ag[0]); + byte g = ag[1]; + + if (alpha == 0) + return; + if (alpha != 256) + { + while (len--) + { + int ca; + cov += *src; *src = 0; src++; + if (cov != 0) + { + ca = samplemask(samples, w, h, u, v); + ca =FZ_COMBINE(FZ_EXPAND(cov),FZ_EXPAND(ca)); + ca = FZ_COMBINE(ca, alpha); + if (ca != 0) + { + dst[0] = FZ_BLEND(255, dst[0], ca); + dst[1] = FZ_BLEND(g, dst[1], ca); + } + } + dst += 2; + u += fa; + v += fb; + } + } + else + { + while (len--) + { + int ca; + cov += *src; *src = 0; src++; + if (cov != 0) + { + ca = samplemask(samples, w, h, u, v); + ca =FZ_COMBINE(FZ_EXPAND(cov),FZ_EXPAND(ca)); + if (ca != 0) + { + dst[0] = FZ_BLEND(255, dst[0], ca); + dst[1] = FZ_BLEND(g, dst[1], ca); + } + } + dst += 2; + u += fa; + v += fb; + } + } +} + +static void img_w4i1o4(byte *argb, byte * restrict src, byte cov, int len, byte * restrict dst, fz_pixmap *image, int u, int v, int fa, int fb) { @@ -223,5 +344,7 @@ img_w4i1o4(byte *argb, byte * restrict src, byte cov, int len, byte * restrict d } void (*fz_img_1o1)(byte*, byte, int, byte*, fz_pixmap *image, int u, int v, int fa, int fb) = img_1o1; +void (*fz_img_2o2)(byte*, byte, int, byte*, fz_pixmap *image, int u, int v, int fa, int fb) = img_2o2; void (*fz_img_4o4)(byte*, byte, int, byte*, fz_pixmap *image, int u, int v, int fa, int fb) = img_4o4; +void (*fz_img_w2i1o2)(byte*, byte*, byte, int, byte*, fz_pixmap *image, int u, int v, int fa, int fb) = img_w2i1o2; void (*fz_img_w4i1o4)(byte*, byte*, byte, int, byte*, fz_pixmap *image, int u, int v, int fa, int fb) = img_w4i1o4; diff --git a/draw/imageunpack.c b/draw/imageunpack.c index 4c9923fd..4e876092 100644 --- a/draw/imageunpack.c +++ b/draw/imageunpack.c @@ -28,7 +28,7 @@ static void decodetile(fz_pixmap *pix, int skip, float *decode) min[i] = decode[(i - skip) * 2] * 255; max[i] = decode[(i - skip) * 2 + 1] * 255; sub[i] = max[i] - min[i]; - needed |= (min[i] != 0) | (max[i] != 255); + needed |= (min[i] != 0) | (max[i] != 255); justinvert &= min[i] == 255 && max[i] == 0 && sub[i] == -255; } diff --git a/draw/pathscan.c b/draw/pathscan.c index 5a656144..319cfeb1 100644 --- a/draw/pathscan.c +++ b/draw/pathscan.c @@ -422,7 +422,7 @@ static inline void toalpha(unsigned char *list, int n) static inline void blit(fz_pixmap *pix, int x, int y, unsigned char *list, int skipx, int len, - unsigned char *argb, fz_pixmap *image, fz_matrix *invmat) + unsigned char *color, fz_pixmap *image, fz_matrix *invmat) { unsigned char *dst; unsigned char cov; @@ -443,17 +443,61 @@ static inline void blit(fz_pixmap *pix, int x, int y, int v = (invmat->b * (x + 0.5f) + invmat->d * (y + 0.5f) + invmat->f) * 65536; int fa = invmat->a * 65536; int fb = invmat->b * 65536; - if (argb) - fz_img_w4i1o4(argb, list, cov, len, dst, image, u, v, fa, fb); + assert(image->n == pix->n); + if (color) + { + switch (pix->n) + { + case 2: + fz_img_w2i1o2(color, list, cov, len, dst, image, u, v, fa, fb); + break; + case 4: + fz_img_w4i1o4(color, list, cov, len, dst, image, u, v, fa, fb); + break; + default: + assert("Write fz_img_wni1on" != NULL); + //fz_img_wni1on(color, list, cov, len, dst, image, u, v, fa, fb); + break; + } + } else if (image->colorspace) + { + assert(image->colorspace->n == image->n-1); + switch (pix->n) + { + case 2: + fz_img_2o2(list, cov, len, dst, image, u, v, fa, fb); + break; + case 4: fz_img_4o4(list, cov, len, dst, image, u, v, fa, fb); + break; + default: + assert("Write fz_img_non" != NULL); + //fz_img_non(list, cov, len, dst, image, u, v, fa, fb); + break; + } + } else fz_img_1o1(list, cov, len, dst, image, u, v, fa, fb); } else { - if (argb) - fz_path_w4i1o4(argb, list, cov, len, dst); + if (color) + { + switch (pix->n) + { + case 2: + fz_path_w2i1o2(color, list, cov, len, dst); + break; + case 4: + fz_path_w4i1o4(color, list, cov, len, dst); + break; + default: + assert("Write fz_path_wni1on" != NULL); + //fz_path_wni1on(color, list, cov, len, dst); + break; + } + } else fz_path_1o1(list, cov, len, dst); } diff --git a/draw/porterduff.c b/draw/porterduff.c index 34d5cee8..4616e3fa 100644 --- a/draw/porterduff.c +++ b/draw/porterduff.c @@ -20,7 +20,8 @@ duff_non(byte * restrict sp, int sw, int sn, byte * restrict dp, int dw, int w0, { /* RJW: Alpha handling suspicious here; sp[0] counts twice */ int sa = FZ_EXPAND(sp[0]); - for (k = 0; k < sn; k++) + dp[0] = FZ_BLEND(255, dp[k], sa); + for (k = 1; k < sn; k++) { dp[k] = FZ_BLEND(sp[k], dp[k], sa); } @@ -47,7 +48,8 @@ duff_nimon(byte * restrict sp, int sw, int sn, byte * restrict mp, int mw, int m { /* TODO: validate this */ int ma = FZ_COMBINE(FZ_EXPAND(mp[0]), FZ_EXPAND(sp[0])); - for (k = 0; k < sn; k++) + dp[k] = FZ_BLEND(255, dp[k], ma); + for (k = 1; k < sn; k++) { dp[k] = FZ_BLEND(sp[k], dp[k], ma); } @@ -93,7 +95,7 @@ duff_4o4(byte *sp, int sw, byte *dp, int dw, int w0, int h) while (w--) { int alpha = FZ_EXPAND(sp[0]); - dp[0] = FZ_BLEND(sp[0], dp[0], alpha); + dp[0] = FZ_BLEND(255, dp[0], alpha); dp[1] = FZ_BLEND(sp[1], dp[1], alpha); dp[2] = FZ_BLEND(sp[2], dp[2], alpha); dp[3] = FZ_BLEND(sp[3], dp[3], alpha); @@ -174,12 +176,30 @@ path_1o1(byte * restrict src, byte cov, int len, byte * restrict dst) } static void +path_w2i1o2(byte * restrict ag, byte * restrict src, byte cov, int len, byte * restrict dst) +{ + int alpha = FZ_EXPAND(ag[0]); + byte g = ag[1]; + + while (len--) + { + int ca; + cov += *src; *src = 0; src++; + ca = FZ_COMBINE(FZ_EXPAND(cov), alpha); + dst[0] = FZ_BLEND(255, dst[0], ca); + dst[1] = FZ_BLEND(g, dst[1], ca); + dst += 2; + } +} + +static void path_w4i1o4(byte * restrict argb, byte * restrict src, byte cov, int len, byte * restrict dst) { int alpha = FZ_EXPAND(argb[0]); byte r = argb[1]; byte g = argb[2]; byte b = argb[3]; + while (len--) { int ca; @@ -218,12 +238,37 @@ text_1o1(byte * restrict src, int srcw, byte * restrict dst, int dstw, int w0, i } static void +text_w2i1o2(byte * restrict ag, byte * restrict src, int srcw, byte * restrict dst, int dstw, int w0, int h) +{ + int alpha = FZ_EXPAND(ag[0]); + byte g = ag[1]; + + srcw -= w0; + dstw -= w0<<1; + while (h--) + { + int w = w0; + while (w--) + { + int c = FZ_COMBINE(FZ_EXPAND(src[0]), alpha); + dst[0] = FZ_BLEND(255, dst[0], c); + dst[1] = FZ_BLEND(g, dst[1], c); + src ++; + dst += 2; + } + src += srcw; + dst += dstw; + } +} + +static void text_w4i1o4(byte * restrict argb, byte * restrict src, int srcw, byte * restrict dst, int dstw, int w0, int h) { int alpha = FZ_EXPAND(argb[0]); byte r = argb[1]; byte g = argb[2]; byte b = argb[3]; + srcw -= w0; dstw -= w0<<2; while (h--) @@ -256,7 +301,9 @@ void (*fz_duff_1i1o1)(byte*,int,byte*,int,byte*,int,int,int) = duff_1i1o1; void (*fz_duff_4i1o4)(byte*,int,byte*,int,byte*,int,int,int) = duff_4i1o4; void (*fz_path_1o1)(byte*,byte,int,byte*) = path_1o1; +void (*fz_path_w2i1o2)(byte*,byte*,byte,int,byte*) = path_w2i1o2; void (*fz_path_w4i1o4)(byte*,byte*,byte,int,byte*) = path_w4i1o4; void (*fz_text_1o1)(byte*,int,byte*,int,int,int) = text_1o1; +void (*fz_text_w2i1o2)(byte*,byte*,int,byte*,int,int,int) = text_w2i1o2; void (*fz_text_w4i1o4)(byte*,byte*,int,byte*,int,int,int) = text_w4i1o4; |