summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-03-16 15:32:05 +0000
committerRobin Watts <robin.watts@artifex.com>2016-03-16 16:20:49 +0000
commitf1254a760f718b8d7cbf687e8798ddd02806bc0c (patch)
tree7f662e24d84e2d5fb5d63e0a6deb0db52e2621ea
parent069b8fdcd374b9ba6560cc884e83738409ae84bc (diff)
downloadmupdf-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.
-rw-r--r--platform/win32/libmupdf.vcproj4
-rw-r--r--source/fitz/draw-paint.c171
-rw-r--r--source/fitz/paint-glyph.h233
3 files changed, 270 insertions, 138 deletions
diff --git a/platform/win32/libmupdf.vcproj b/platform/win32/libmupdf.vcproj
index 0fdf568d..3f7cfb69 100644
--- a/platform/win32/libmupdf.vcproj
+++ b/platform/win32/libmupdf.vcproj
@@ -971,6 +971,10 @@
>
</File>
<File
+ RelativePath="..\..\source\fitz\paint-glyph.h"
+ >
+ </File>
+ <File
RelativePath="..\..\source\fitz\path.c"
>
</File>
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