diff options
author | Robin Watts <robin.watts@artifex.com> | 2016-03-16 15:32:05 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2016-03-16 16:20:49 +0000 |
commit | f1254a760f718b8d7cbf687e8798ddd02806bc0c (patch) | |
tree | 7f662e24d84e2d5fb5d63e0a6deb0db52e2621ea /source/fitz | |
parent | 069b8fdcd374b9ba6560cc884e83738409ae84bc (diff) | |
download | mupdf-f1254a760f718b8d7cbf687e8798ddd02806bc0c.tar.xz |
glyph plotter; Use repeated inclusion of header
To avoid having to duplicate a fairly large block of code several
times, use repeated inclusion of a header with some macros to
generate optimised glyph plotters.
Diffstat (limited to 'source/fitz')
-rw-r--r-- | source/fitz/draw-paint.c | 171 | ||||
-rw-r--r-- | source/fitz/paint-glyph.h | 233 |
2 files changed, 266 insertions, 138 deletions
diff --git a/source/fitz/draw-paint.c b/source/fitz/draw-paint.c index b2083bd6..33a72450 100644 --- a/source/fitz/draw-paint.c +++ b/source/fitz/draw-paint.c @@ -1155,6 +1155,7 @@ intermediate_run: } } +#if 0 static inline void fz_paint_glyph_alpha_N(unsigned char *colorbv, int n, int span, unsigned char *dp, fz_glyph *glyph, int w, int h, int skip_x, int skip_y) { @@ -1291,139 +1292,33 @@ intermediate_run: dp += span; } } +#endif -static inline void -fz_paint_glyph_solid_N(unsigned char *colorbv, int n, int span, unsigned char *dp, fz_glyph *glyph, int w, int h, int skip_x, int skip_y) -{ - while (h--) - { - int skip_xx, ww, len, extend; - unsigned char *runp; - unsigned char *ddp = dp; - int offset = ((int *)(glyph->data))[skip_y++]; - if (offset >= 0) - { - int eol = 0; - runp = &glyph->data[offset]; - extend = 0; - ww = w; - skip_xx = skip_x; - while (skip_xx) - { - int v = *runp++; - switch (v & 3) - { - case 0: /* Extend */ - extend = v>>2; - len = 0; - break; - case 1: /* Transparent */ - len = (v>>2) + 1 + (extend<<6); - extend = 0; - if (len > skip_xx) - { - len -= skip_xx; - goto transparent_run; - } - break; - case 2: /* Solid */ - eol = v & 4; - len = (v>>3) + 1 + (extend<<5); - extend = 0; - if (len > skip_xx) - { - len -= skip_xx; - goto solid_run; - } - break; - default: /* Intermediate */ - eol = v & 4; - len = (v>>3) + 1 + (extend<<5); - extend = 0; - if (len > skip_xx) - { - runp += skip_xx; - len -= skip_xx; - goto intermediate_run; - } - runp += len; - break; - } - if (eol) - { - ww = 0; - break; - } - skip_xx -= len; - } - while (ww > 0) - { - int v = *runp++; - switch(v & 3) - { - case 0: /* Extend */ - extend = v>>2; - break; - case 1: /* Transparent */ - len = (v>>2) + 1 + (extend<<6); - extend = 0; -transparent_run: - if (len > ww) - len = ww; - ww -= len; - ddp += len * n; - break; - case 2: /* Solid */ - eol = v & 4; - len = (v>>3) + 1 + (extend<<5); - extend = 0; -solid_run: - if (len > ww) - len = ww; - ww -= len; - do - { - int k = 0; - do - { - *ddp++ = colorbv[k++]; - } - while (k != n); - } - while (--len); - break; - default: /* Intermediate */ - eol = v & 4; - len = (v>>3) + 1 + (extend<<5); - extend = 0; -intermediate_run: - if (len > ww) - len = ww; - ww -= len; - do - { - int k = 0; - int a = *runp++; - a = FZ_EXPAND(a); - do - { - *ddp = FZ_BLEND(colorbv[k++], *ddp, a); - ddp++; - } - while (k != n-1); - *ddp = FZ_BLEND(0xFF, *ddp, a); - ddp++; - } - while (--len); - break; - } - if (eol) - break; - } - } - dp += span; - } -} +#define N 2 +#include "paint-glyph.h" + +#define N 4 +#include "paint-glyph.h" + +#define N 5 +#include "paint-glyph.h" + +#include "paint-glyph.h" + +#define ALPHA +#define N 2 +#include "paint-glyph.h" + +#define ALPHA +#define N 4 +#include "paint-glyph.h" + +#define ALPHA +#define N 5 +#include "paint-glyph.h" + +#define ALPHA +#include "paint-glyph.h" static inline void fz_paint_glyph_alpha(unsigned char *colorbv, int n, int span, unsigned char *dp, fz_glyph *glyph, int w, int h, int skip_x, int skip_y) @@ -1431,13 +1326,13 @@ fz_paint_glyph_alpha(unsigned char *colorbv, int n, int span, unsigned char *dp, switch (n) { case 2: - fz_paint_glyph_alpha_N(colorbv, 2, span, dp, glyph, w, h, skip_x, skip_y); + fz_paint_glyph_alpha_2(colorbv, span, dp, glyph, w, h, skip_x, skip_y); break; case 4: - fz_paint_glyph_alpha_N(colorbv, 4, span, dp, glyph, w, h, skip_x, skip_y); + fz_paint_glyph_alpha_4(colorbv, span, dp, glyph, w, h, skip_x, skip_y); break; case 5: - fz_paint_glyph_alpha_N(colorbv, 5, span, dp, glyph, w, h, skip_x, skip_y); + fz_paint_glyph_alpha_5(colorbv, span, dp, glyph, w, h, skip_x, skip_y); break; default: fz_paint_glyph_alpha_N(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y); @@ -1451,13 +1346,13 @@ fz_paint_glyph_solid(unsigned char *colorbv, int n, int span, unsigned char *dp, switch (n) { case 2: - fz_paint_glyph_solid_N(colorbv, 2, span, dp, glyph, w, h, skip_x, skip_y); + fz_paint_glyph_solid_2(colorbv, span, dp, glyph, w, h, skip_x, skip_y); break; case 4: - fz_paint_glyph_solid_N(colorbv, 4, span, dp, glyph, w, h, skip_x, skip_y); + fz_paint_glyph_solid_4(colorbv, span, dp, glyph, w, h, skip_x, skip_y); break; case 5: - fz_paint_glyph_solid_N(colorbv, 5, span, dp, glyph, w, h, skip_x, skip_y); + fz_paint_glyph_solid_5(colorbv, span, dp, glyph, w, h, skip_x, skip_y); break; default: fz_paint_glyph_solid_N(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y); diff --git a/source/fitz/paint-glyph.h b/source/fitz/paint-glyph.h new file mode 100644 index 00000000..055693b2 --- /dev/null +++ b/source/fitz/paint-glyph.h @@ -0,0 +1,233 @@ +/* + This file is #included by draw-paint.c multiple times to + produce optimised plotters. +*/ + +#ifdef ALPHA +#define NAME alpha +#else +#define NAME solid +#endif + +#define FUNCTION_NAMER(NAME,N) fz_paint_glyph_##NAME##_##N +#define FUNCTION_NAME(NAME,N) FUNCTION_NAMER(NAME,N) + +static inline void +FUNCTION_NAME(NAME,N)(unsigned char *colorbv, +#ifndef N + int n, +#endif + int span, unsigned char *dp, fz_glyph *glyph, int w, int h, int skip_x, int skip_y) +{ +#ifdef N + const int n = N; +#endif +#ifdef ALPHA + int sa = FZ_EXPAND(colorbv[n-1]); +#endif + while (h--) + { + int skip_xx, ww, len, extend; + unsigned char *runp; + unsigned char *ddp = dp; + int offset = ((int *)(glyph->data))[skip_y++]; + if (offset >= 0) + { + int eol = 0; + runp = &glyph->data[offset]; + extend = 0; + ww = w; + skip_xx = skip_x; + while (skip_xx) + { + int v = *runp++; + switch (v & 3) + { + case 0: /* Extend */ + extend = v>>2; + len = 0; + break; + case 1: /* Transparent */ + len = (v>>2) + 1 + (extend<<6); + extend = 0; + if (len > skip_xx) + { + len -= skip_xx; + goto transparent_run; + } + break; + case 2: /* Solid */ + eol = v & 4; + len = (v>>3) + 1 + (extend<<5); + extend = 0; + if (len > skip_xx) + { + len -= skip_xx; + goto solid_run; + } + break; + default: /* Intermediate */ + eol = v & 4; + len = (v>>3) + 1 + (extend<<5); + extend = 0; + if (len > skip_xx) + { + runp += skip_xx; + len -= skip_xx; + goto intermediate_run; + } + runp += len; + break; + } + if (eol) + { + ww = 0; + break; + } + skip_xx -= len; + } + while (ww > 0) + { + int v = *runp++; + switch(v & 3) + { + case 0: /* Extend */ + extend = v>>2; + break; + case 1: /* Transparent */ + len = (v>>2) + 1 + (extend<<6); + extend = 0; +transparent_run: + if (len > ww) + len = ww; + ww -= len; + ddp += len * n; + break; + case 2: /* Solid */ + eol = v & 4; + len = (v>>3) + 1 + (extend<<5); + extend = 0; +solid_run: + if (len > ww) + len = ww; + ww -= len; + do + { +#ifdef ALPHA +#if defined(N) && N == 2 + ddp[0] = FZ_BLEND(colorbv[0], ddp[0], sa); + ddp[1] = FZ_BLEND(0xFF, ddp[1], sa); + ddp += 2; +#elif defined(N) && N == 4 + ddp[0] = FZ_BLEND(colorbv[0], ddp[0], sa); + ddp[1] = FZ_BLEND(colorbv[1], ddp[1], sa); + ddp[2] = FZ_BLEND(colorbv[2], ddp[2], sa); + ddp[3] = FZ_BLEND(0xFF, ddp[3], sa); + ddp += 4; +#elif defined(N) && N == 5 + ddp[0] = FZ_BLEND(colorbv[0], ddp[0], sa); + ddp[1] = FZ_BLEND(colorbv[1], ddp[1], sa); + ddp[2] = FZ_BLEND(colorbv[2], ddp[2], sa); + ddp[3] = FZ_BLEND(colorbv[3], ddp[3], sa); + ddp[4] = FZ_BLEND(0xFF, ddp[4], sa); + ddp += 5; +#else + int k = 0; + do + { + *ddp = FZ_BLEND(colorbv[k++], *ddp, sa); + ddp++; + } + while (k != n-1); + *ddp = FZ_BLEND(0xFF, *ddp, sa); + ddp++; +#endif +#else +#if defined(N) && N == 2 + ddp[0] = colorbv[0]; + ddp[1] = colorbv[1]; + ddp += 2; +#elif defined(N) && N == 4 + *(uint32_t *)ddp = *(uint32_t*)colorbv; + ddp += 4; +#elif defined(N) && N == 5 + ddp[0] = colorbv[0]; + ddp[1] = colorbv[1]; + ddp[2] = colorbv[2]; + ddp[3] = colorbv[3]; + ddp[4] = colorbv[4]; + ddp += 5; +#else + int k = 0; + do + { + *ddp++ = colorbv[k++]; + } + while (k != n); +#endif +#endif + } + while (--len); + break; + default: /* Intermediate */ + eol = v & 4; + len = (v>>3) + 1 + (extend<<5); + extend = 0; +intermediate_run: + if (len > ww) + len = ww; + ww -= len; + do + { + int k = 0; + int a = *runp++; +#ifdef ALPHA + a = FZ_COMBINE(sa, FZ_EXPAND(a)); +#else + a = FZ_EXPAND(a); +#endif + (void)k; +#if defined(N) && N == 2 + ddp[0] = FZ_BLEND(colorbv[0], ddp[0], a); + ddp[1] = FZ_BLEND(0xFF, ddp[1], a); + ddp += 2; +#elif defined(N) && N == 4 + ddp[0] = FZ_BLEND(colorbv[0], ddp[0], a); + ddp[1] = FZ_BLEND(colorbv[1], ddp[1], a); + ddp[2] = FZ_BLEND(colorbv[2], ddp[2], a); + ddp[3] = FZ_BLEND(0xFF, ddp[3], a); + ddp += 4; +#elif defined(N) && N == 5 + ddp[0] = FZ_BLEND(colorbv[0], ddp[0], a); + ddp[1] = FZ_BLEND(colorbv[1], ddp[1], a); + ddp[2] = FZ_BLEND(colorbv[2], ddp[2], a); + ddp[3] = FZ_BLEND(colorbv[3], ddp[3], a); + ddp[4] = FZ_BLEND(0xFF, ddp[4], a); + ddp += 5; +#else + do + { + *ddp = FZ_BLEND(colorbv[k++], *ddp, a); + ddp++; + } + while (k != n-1); + *ddp = FZ_BLEND(0xFF, *ddp, a); + ddp++; +#endif + } + while (--len); + break; + } + if (eol) + break; + } + } + dp += span; + } +} + +#undef NAME +#undef ALPHA +#undef N +#undef FUNCTION_NAMER +#undef FUNCTION_NAME |