From dba5c0206072986ae07111e4e62234bbc1156caa Mon Sep 17 00:00:00 2001
From: Robin Watts <robin.watts@artifex.com>
Date: Thu, 26 May 2016 15:57:21 +0100
Subject: Add facility to track usage of functions.

Use this for plotters so we can see which ones are being used
in any given build.

Build with -DTRACK_USAGE to enable.
---
 include/mupdf/fitz/system.h      |   1 +
 include/mupdf/fitz/track-usage.h |  35 ++++++++
 platform/win32/libmupdf.vcproj   |   8 ++
 source/fitz/draw-affine.c        | 184 +++++++++++++++++++++------------------
 source/fitz/draw-paint.c         | 146 +++++++++++++++++--------------
 source/fitz/track-usage.c        |  34 ++++++++
 6 files changed, 259 insertions(+), 149 deletions(-)
 create mode 100644 include/mupdf/fitz/track-usage.h
 create mode 100644 source/fitz/track-usage.c

diff --git a/include/mupdf/fitz/system.h b/include/mupdf/fitz/system.h
index cbc10285..be5504a5 100644
--- a/include/mupdf/fitz/system.h
+++ b/include/mupdf/fitz/system.h
@@ -31,6 +31,7 @@
 #include <setjmp.h>
 
 #include "mupdf/memento.h"
+#include "mupdf/fitz/track-usage.h"
 
 #define nelem(x) (sizeof(x)/sizeof((x)[0]))
 
diff --git a/include/mupdf/fitz/track-usage.h b/include/mupdf/fitz/track-usage.h
new file mode 100644
index 00000000..6c4409fb
--- /dev/null
+++ b/include/mupdf/fitz/track-usage.h
@@ -0,0 +1,35 @@
+#ifndef TRACK_USAGE_H
+#define TRACK_USAGE_H
+
+#ifdef TRACK_USAGE
+
+typedef struct track_usage_data_s {
+	int count;
+	const char *function;
+	int line;
+	const char *desc;
+	struct track_usage_data_s *next;
+} track_usage_data_t;
+
+#define TRACK_LABEL(A) \
+	do { \
+		static track_usage_data_t USAGE_DATA = { 0 };\
+		track_usage(&USAGE_DATA, __FILE__, __LINE__, A);\
+	} while (0)
+
+#define TRACK_FN() \
+	do { \
+		static track_usage_data_t USAGE_DATA = { 0 };\
+		track_usage(&USAGE_DATA, __FILE__, __LINE__, __FUNCTION__);\
+	} while (0)
+
+void track_usage(track_usage_data_t *data, const char *function, int line, const char *desc);
+
+#else
+
+#define TRACK_LABEL(A) do { } while (0)
+#define TRACK_FN() do { } while (0)
+
+#endif
+
+#endif
diff --git a/platform/win32/libmupdf.vcproj b/platform/win32/libmupdf.vcproj
index 7da59040..4f8610d1 100644
--- a/platform/win32/libmupdf.vcproj
+++ b/platform/win32/libmupdf.vcproj
@@ -1118,6 +1118,10 @@
 				RelativePath="..\..\source\fitz\unzip.c"
 				>
 			</File>
+			<File
+				RelativePath="..\..\source\fitz\track-usage.c"
+				>
+			</File>
 			<File
 				RelativePath="..\..\source\fitz\util.c"
 				>
@@ -1633,6 +1637,10 @@
 					RelativePath="..\..\include\mupdf\fitz\unzip.h"
 					>
 				</File>
+				<File
+					RelativePath="..\..\include\mupdf\fitz\track-usage.h"
+					>
+				</File>
 				<File
 					RelativePath="..\..\include\mupdf\fitz\util.h"
 					>
diff --git a/source/fitz/draw-affine.c b/source/fitz/draw-affine.c
index 6d9c7226..24ecbbe8 100644
--- a/source/fitz/draw-affine.c
+++ b/source/fitz/draw-affine.c
@@ -752,20 +752,20 @@ fz_paint_affine_lerp(byte * restrict dp, int da, const byte * restrict sp, int s
 			{
 				switch (n)
 				{
-				case 1: fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, hp); break;
-				case 3: fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, hp); break;
-				case 4: fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, hp); break;
-				default: fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, hp); break;
+				case 1: TRACK_LABEL("alds11"); fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, hp); break;
+				case 3: TRACK_LABEL("alds13"); fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, hp); break;
+				case 4: TRACK_LABEL("alds14"); fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, hp); break;
+				default: TRACK_LABEL("alds1n"); fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, hp); break;
 				}
 			}
 			else if (alpha > 0)
 			{
 				switch (n)
 				{
-				case 1: fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, alpha, hp); break;
-				case 3: fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, alpha, hp); break;
-				case 4: fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, alpha, hp); break;
-				default: fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, alpha, hp); break;
+				case 1: TRACK_LABEL("aldsa1"); fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, alpha, hp); break;
+				case 3: TRACK_LABEL("aldsa3"); fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, alpha, hp); break;
+				case 4: TRACK_LABEL("aldsa4"); fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, alpha, hp); break;
+				default: TRACK_LABEL("aldsan"); fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, alpha, hp); break;
 				}
 			}
 		}
@@ -775,20 +775,20 @@ fz_paint_affine_lerp(byte * restrict dp, int da, const byte * restrict sp, int s
 			{
 				switch (n)
 				{
-				case 1: fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, hp); break;
-				case 3: fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, hp); break;
-				case 4: fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, hp); break;
-				default: fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, hp); break;
+				case 1: TRACK_LABEL("ald11"); fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, hp); break;
+				case 3: TRACK_LABEL("ald13"); fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, hp); break;
+				case 4: TRACK_LABEL("ald14"); fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, hp); break;
+				default: TRACK_LABEL("ald1n"); fz_paint_affine_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, hp); break;
 				}
 			}
 			else if (alpha > 0)
 			{
 				switch (n)
 				{
-				case 1: fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, alpha, hp); break;
-				case 3: fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, alpha, hp); break;
-				case 4: fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, alpha, hp); break;
-				default: fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, alpha, hp); break;
+				case 1: TRACK_LABEL("alda1"); fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, alpha, hp); break;
+				case 3: TRACK_LABEL("alda3"); fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, alpha, hp); break;
+				case 4: TRACK_LABEL("alda4"); fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, alpha, hp); break;
+				default: TRACK_LABEL("aldan"); fz_paint_affine_alpha_N_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, alpha, hp); break;
 				}
 			}
 		}
@@ -801,20 +801,20 @@ fz_paint_affine_lerp(byte * restrict dp, int da, const byte * restrict sp, int s
 			{
 				switch (n)
 				{
-				case 1: fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, hp); break;
-				case 3: fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, hp); break;
-				case 4: fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, hp); break;
-				default: fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, hp); break;
+				case 1: TRACK_LABEL("als11"); fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, hp); break;
+				case 3: TRACK_LABEL("als13"); fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, hp); break;
+				case 4: TRACK_LABEL("als14"); fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, hp); break;
+				default: TRACK_LABEL("als1n"); fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, hp); break;
 				}
 			}
 			else if (alpha > 0)
 			{
 				switch (n)
 				{
-				case 1: fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, alpha, hp); break;
-				case 3: fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, alpha, hp); break;
-				case 4: fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, alpha, hp); break;
-				default: fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, alpha, hp); break;
+				case 1: TRACK_LABEL("alsa1"); fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, alpha, hp); break;
+				case 3: TRACK_LABEL("alsa3"); fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, alpha, hp); break;
+				case 4: TRACK_LABEL("alsa4"); fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, alpha, hp); break;
+				default: TRACK_LABEL("alsan"); fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, alpha, hp); break;
 				}
 			}
 		}
@@ -824,20 +824,20 @@ fz_paint_affine_lerp(byte * restrict dp, int da, const byte * restrict sp, int s
 			{
 				switch (n)
 				{
-				case 1: fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, hp); break;
-				case 3: fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, hp); break;
-				case 4: fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, hp); break;
-				default: fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, hp); break;
+				case 1: TRACK_LABEL("al11"); fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, hp); break;
+				case 3: TRACK_LABEL("al13"); fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, hp); break;
+				case 4: TRACK_LABEL("al14"); fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, hp); break;
+				default: TRACK_LABEL("al1n"); fz_paint_affine_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, hp); break;
 				}
 			}
 			else if (alpha > 0)
 			{
 				switch (n)
 				{
-				case 1: fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, alpha, hp); break;
-				case 3: fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, alpha, hp); break;
-				case 4: fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, alpha, hp); break;
-				default: fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, alpha, hp); break;
+				case 1: TRACK_LABEL("al11"); fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, alpha, hp); break;
+				case 3: TRACK_LABEL("al13"); fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, alpha, hp); break;
+				case 4: TRACK_LABEL("al14"); fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, alpha, hp); break;
+				default: TRACK_LABEL("al1n"); fz_paint_affine_alpha_N_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, alpha, hp); break;
 				}
 			}
 		}
@@ -853,10 +853,12 @@ fz_paint_affine_g2rgb_lerp(byte *dp, int da, const byte * restrict sp, int sw, i
 		{
 			if (alpha == 255)
 			{
+				TRACK_LABEL("aglds1");
 				fz_paint_affine_solid_g2rgb_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, hp);
 			}
 			else if (alpha > 0)
 			{
+				TRACK_LABEL("agldsa");
 				fz_paint_affine_alpha_g2rgb_lerp(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, alpha, hp);
 			}
 		}
@@ -864,10 +866,12 @@ fz_paint_affine_g2rgb_lerp(byte *dp, int da, const byte * restrict sp, int sw, i
 		{
 			if (alpha == 255)
 			{
+				TRACK_LABEL("agld1");
 				fz_paint_affine_solid_g2rgb_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, hp);
 			}
 			else if (alpha > 0)
 			{
+				TRACK_LABEL("aglda");
 				fz_paint_affine_alpha_g2rgb_lerp(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, alpha, hp);
 			}
 		}
@@ -878,10 +882,12 @@ fz_paint_affine_g2rgb_lerp(byte *dp, int da, const byte * restrict sp, int sw, i
 		{
 			if (alpha == 255)
 			{
+				TRACK_LABEL("agls1");
 				fz_paint_affine_solid_g2rgb_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, hp);
 			}
 			else if (alpha > 0)
 			{
+				TRACK_LABEL("aglsa");
 				fz_paint_affine_alpha_g2rgb_lerp(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, alpha, hp);
 			}
 		}
@@ -889,10 +895,12 @@ fz_paint_affine_g2rgb_lerp(byte *dp, int da, const byte * restrict sp, int sw, i
 		{
 			if (alpha == 255)
 			{
+				TRACK_LABEL("agl1");
 				fz_paint_affine_solid_g2rgb_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, hp);
 			}
 			else if (alpha > 0)
 			{
+				TRACK_LABEL("agla");
 				fz_paint_affine_alpha_g2rgb_lerp(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, alpha, hp);
 			}
 		}
@@ -910,22 +918,22 @@ fz_paint_affine_near(byte *dp, int da, const byte * restrict sp, int sw, int sh,
 			{
 				switch (n)
 				{
-				case 0: fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 0, hp); break;
-				case 1: fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, hp); break;
-				case 3: fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, hp); break;
-				case 4: fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, hp); break;
-				default: fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, hp); break;
+				case 0: TRACK_LABEL("ads10"); fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 0, hp); break;
+				case 1: TRACK_LABEL("ads11"); fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, hp); break;
+				case 3: TRACK_LABEL("ads13"); fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, hp); break;
+				case 4: TRACK_LABEL("ads14"); fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, hp); break;
+				default: TRACK_LABEL("ads1n"); fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, hp); break;
 				}
 			}
 			else if (alpha > 0)
 			{
 				switch (n)
 				{
-				case 0: fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 0, alpha, hp); break;
-				case 1: fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, alpha, hp); break;
-				case 3: fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, alpha, hp); break;
-				case 4: fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, alpha, hp); break;
-				default: fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, alpha, hp); break;
+				case 0: TRACK_LABEL("adsa0"); fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 0, alpha, hp); break;
+				case 1: TRACK_LABEL("adsa1"); fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, alpha, hp); break;
+				case 3: TRACK_LABEL("adsa3"); fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, alpha, hp); break;
+				case 4: TRACK_LABEL("adsa4"); fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, alpha, hp); break;
+				default: TRACK_LABEL("adsan"); fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, alpha, hp); break;
 				}
 			}
 		}
@@ -935,22 +943,22 @@ fz_paint_affine_near(byte *dp, int da, const byte * restrict sp, int sw, int sh,
 			{
 				switch (n)
 				{
-				case 0: fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 0, hp); break;
-				case 1: fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, hp); break;
-				case 3: fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, hp); break;
-				case 4: fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, hp); break;
-				default: fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, hp); break;
+				case 0: TRACK_LABEL("ad10"); fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 0, hp); break;
+				case 1: TRACK_LABEL("ad11"); fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, hp); break;
+				case 3: TRACK_LABEL("ad13"); fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, hp); break;
+				case 4: TRACK_LABEL("ad14"); fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, hp); break;
+				default: TRACK_LABEL("ad1n"); fz_paint_affine_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, hp); break;
 				}
 			}
 			else if (alpha > 0)
 			{
 				switch (n)
 				{
-				case 0: fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 0, alpha, hp); break;
-				case 1: fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, alpha, hp); break;
-				case 3: fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, alpha, hp); break;
-				case 4: fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, alpha, hp); break;
-				default: fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, alpha, hp); break;
+				case 0: TRACK_LABEL("ada0"); fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 0, alpha, hp); break;
+				case 1: TRACK_LABEL("ada1"); fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, alpha, hp); break;
+				case 3: TRACK_LABEL("ada3"); fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, alpha, hp); break;
+				case 4: TRACK_LABEL("ada4"); fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, alpha, hp); break;
+				default: TRACK_LABEL("adan"); fz_paint_affine_alpha_N_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, alpha, hp); break;
 				}
 			}
 		}
@@ -963,20 +971,20 @@ fz_paint_affine_near(byte *dp, int da, const byte * restrict sp, int sw, int sh,
 			{
 				switch (n)
 				{
-				case 1: fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, hp); break;
-				case 3: fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, hp); break;
-				case 4: fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, hp); break;
-				default: fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, hp); break;
+				case 1: TRACK_LABEL("as11"); fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, hp); break;
+				case 3: TRACK_LABEL("as13"); fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, hp); break;
+				case 4: TRACK_LABEL("as14"); fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, hp); break;
+				default: TRACK_LABEL("as1n"); fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, hp); break;
 				}
 			}
 			else if (alpha > 0)
 			{
 				switch (n)
 				{
-				case 1: fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, alpha, hp); break;
-				case 3: fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, alpha, hp); break;
-				case 4: fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, alpha, hp); break;
-				default: fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, alpha, hp); break;
+				case 1: TRACK_LABEL("asa1"); fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 1, alpha, hp); break;
+				case 3: TRACK_LABEL("asa2"); fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 3, alpha, hp); break;
+				case 4: TRACK_LABEL("asa3"); fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, 4, alpha, hp); break;
+				default: TRACK_LABEL("asa4"); fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, n, alpha, hp); break;
 				}
 			}
 		}
@@ -986,20 +994,20 @@ fz_paint_affine_near(byte *dp, int da, const byte * restrict sp, int sw, int sh,
 			{
 				switch (n)
 				{
-				case 1: fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, hp); break;
-				case 3: fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, hp); break;
-				case 4: fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, hp); break;
-				default: fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, hp); break;
+				case 1: TRACK_LABEL("a11"); fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, hp); break;
+				case 3: TRACK_LABEL("a13"); fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, hp); break;
+				case 4: TRACK_LABEL("a14"); fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, hp); break;
+				default: TRACK_LABEL("a1n"); fz_paint_affine_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, hp); break;
 				}
 			}
 			else if (alpha > 0)
 			{
 				switch (n)
 				{
-				case 1: fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, alpha, hp); break;
-				case 3: fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, alpha, hp); break;
-				case 4: fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, alpha, hp); break;
-				default: fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, alpha, hp); break;
+				case 1: TRACK_LABEL("asa1"); fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 1, alpha, hp); break;
+				case 3: TRACK_LABEL("asa3"); fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 3, alpha, hp); break;
+				case 4: TRACK_LABEL("asa4"); fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, 4, alpha, hp); break;
+				default: TRACK_LABEL("asan"); fz_paint_affine_alpha_N_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, n, alpha, hp); break;
 				}
 			}
 		}
@@ -1015,10 +1023,12 @@ fz_paint_affine_g2rgb_near(byte *dp, int da, const byte * restrict sp, int sw, i
 		{
 			if (alpha == 255)
 			{
+				TRACK_LABEL("agds1");
 				fz_paint_affine_solid_g2rgb_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, hp);
 			}
 			else if (alpha > 0)
 			{
+				TRACK_LABEL("agdsa");
 				fz_paint_affine_alpha_g2rgb_near(dp, 1, sp, sw, sh, ss, 1, u, v, fa, fb, w, alpha, hp);
 			}
 		}
@@ -1026,10 +1036,12 @@ fz_paint_affine_g2rgb_near(byte *dp, int da, const byte * restrict sp, int sw, i
 		{
 			if (alpha == 255)
 			{
+				TRACK_LABEL("agd1");
 				fz_paint_affine_solid_g2rgb_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, hp);
 			}
 			else if (alpha > 0)
 			{
+				TRACK_LABEL("agda");
 				fz_paint_affine_alpha_g2rgb_near(dp, 1, sp, sw, sh, ss, 0, u, v, fa, fb, w, alpha, hp);
 			}
 		}
@@ -1040,10 +1052,12 @@ fz_paint_affine_g2rgb_near(byte *dp, int da, const byte * restrict sp, int sw, i
 		{
 			if (alpha == 255)
 			{
+				TRACK_LABEL("ags1");
 				fz_paint_affine_solid_g2rgb_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, hp);
 			}
 			else if (alpha > 0)
 			{
+				TRACK_LABEL("agsa");
 				fz_paint_affine_alpha_g2rgb_near(dp, 0, sp, sw, sh, ss, 1, u, v, fa, fb, w, alpha, hp);
 			}
 		}
@@ -1051,10 +1065,12 @@ fz_paint_affine_g2rgb_near(byte *dp, int da, const byte * restrict sp, int sw, i
 		{
 			if (alpha == 255)
 			{
+				TRACK_LABEL("ag1");
 				fz_paint_affine_solid_g2rgb_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, hp);
 			}
 			else if (alpha > 0)
 			{
+				TRACK_LABEL("aga");
 				fz_paint_affine_alpha_g2rgb_near(dp, 0, sp, sw, sh, ss, 0, u, v, fa, fb, w, alpha, hp);
 			}
 		}
@@ -1068,20 +1084,20 @@ fz_paint_affine_color_lerp(byte *dp, int da, const byte * restrict sp, int sw, i
 	{
 		switch (n)
 		{
-		case 1: fz_paint_affine_color_N_lerp(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, 1, color, hp); break;
-		case 3: fz_paint_affine_color_N_lerp(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, 3, color, hp); break;
-		case 4: fz_paint_affine_color_N_lerp(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, 4, color, hp); break;
-		default: fz_paint_affine_color_N_lerp(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, n, color, hp); break;
+		case 1: TRACK_LABEL("acld1"); fz_paint_affine_color_N_lerp(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, 1, color, hp); break;
+		case 3: TRACK_LABEL("acld3"); fz_paint_affine_color_N_lerp(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, 3, color, hp); break;
+		case 4: TRACK_LABEL("acld4"); fz_paint_affine_color_N_lerp(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, 4, color, hp); break;
+		default: TRACK_LABEL("acldn"); fz_paint_affine_color_N_lerp(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, n, color, hp); break;
 		}
 	}
 	else
 	{
 		switch (n)
 		{
-		case 1: fz_paint_affine_color_N_lerp(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, 1, color, hp); break;
-		case 3: fz_paint_affine_color_N_lerp(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, 3, color, hp); break;
-		case 4: fz_paint_affine_color_N_lerp(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, 4, color, hp); break;
-		default: fz_paint_affine_color_N_lerp(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, n, color, hp); break;
+		case 1: TRACK_LABEL("acl1"); fz_paint_affine_color_N_lerp(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, 1, color, hp); break;
+		case 3: TRACK_LABEL("acl3"); fz_paint_affine_color_N_lerp(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, 3, color, hp); break;
+		case 4: TRACK_LABEL("acl4"); fz_paint_affine_color_N_lerp(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, 4, color, hp); break;
+		default: TRACK_LABEL("acln"); fz_paint_affine_color_N_lerp(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, n, color, hp); break;
 		}
 	}
 }
@@ -1093,20 +1109,20 @@ fz_paint_affine_color_near(byte *dp, int da, const byte * restrict sp, int sw, i
 	{
 		switch (n)
 		{
-		case 1: fz_paint_affine_color_N_near(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, 1, color, hp); break;
-		case 3: fz_paint_affine_color_N_near(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, 3, color, hp); break;
-		case 4: fz_paint_affine_color_N_near(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, 4, color, hp); break;
-		default: fz_paint_affine_color_N_near(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, n, color, hp); break;
+		case 1: TRACK_LABEL("acd1"); fz_paint_affine_color_N_near(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, 1, color, hp); break;
+		case 3: TRACK_LABEL("acd3"); fz_paint_affine_color_N_near(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, 3, color, hp); break;
+		case 4: TRACK_LABEL("acd4"); fz_paint_affine_color_N_near(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, 4, color, hp); break;
+		default: TRACK_LABEL("acdn"); fz_paint_affine_color_N_near(dp, 1, sp, sw, sh, ss, u, v, fa, fb, w, n, color, hp); break;
 		}
 	}
 	else
 	{
 		switch (n)
 		{
-		case 1: fz_paint_affine_color_N_near(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, 1, color, hp); break;
-		case 3: fz_paint_affine_color_N_near(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, 3, color, hp); break;
-		case 4: fz_paint_affine_color_N_near(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, 4, color, hp); break;
-		default: fz_paint_affine_color_N_near(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, n, color, hp); break;
+		case 1: TRACK_LABEL("acd1"); fz_paint_affine_color_N_near(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, 1, color, hp); break;
+		case 3: TRACK_LABEL("acd3"); fz_paint_affine_color_N_near(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, 3, color, hp); break;
+		case 4: TRACK_LABEL("acd4"); fz_paint_affine_color_N_near(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, 4, color, hp); break;
+		default: TRACK_LABEL("acdn"); fz_paint_affine_color_N_near(dp, 0, sp, sw, sh, ss, u, v, fa, fb, w, n, color, hp); break;
 		}
 	}
 }
diff --git a/source/fitz/draw-paint.c b/source/fitz/draw-paint.c
index bd6bdbc1..1652b218 100644
--- a/source/fitz/draw-paint.c
+++ b/source/fitz/draw-paint.c
@@ -263,20 +263,20 @@ fz_paint_solid_color(byte * restrict dp, int n, int w, const byte * restrict col
 	{
 		switch (n)
 		{
-		case 2: fz_paint_solid_color_2_da(dp, w, color); break;
-		case 4: fz_paint_solid_color_4_da(dp, w, color); break;
-		case 5: fz_paint_solid_color_5_da(dp, w, color); break;
-		default: fz_paint_solid_color_N(dp, n, w, color, 1); break;
+		case 2: TRACK_LABEL("p1cd2"); fz_paint_solid_color_2_da(dp, w, color); break;
+		case 4: TRACK_LABEL("p1cd4"); fz_paint_solid_color_4_da(dp, w, color); break;
+		case 5: TRACK_LABEL("p1cd5"); fz_paint_solid_color_5_da(dp, w, color); break;
+		default: TRACK_LABEL("p1cdn"); fz_paint_solid_color_N(dp, n, w, color, 1); break;
 		}
 	}
 	else
 	{
 		switch (n)
 		{
-		case 1: fz_paint_solid_color_N(dp, 1, w, color, 0); break;
-		case 3: fz_paint_solid_color_N(dp, 3, w, color, 0); break;
-		case 4: fz_paint_solid_color_N(dp, 4, w, color, 0); break;
-		default: fz_paint_solid_color_N(dp, n, w, color, 0); break;
+		case 1: TRACK_LABEL("p1c1"); fz_paint_solid_color_N(dp, 1, w, color, 0); break;
+		case 3: TRACK_LABEL("p1c3"); fz_paint_solid_color_N(dp, 3, w, color, 0); break;
+		case 4: TRACK_LABEL("p1c4"); fz_paint_solid_color_N(dp, 4, w, color, 0); break;
+		default: TRACK_LABEL("p1cn"); fz_paint_solid_color_N(dp, n, w, color, 0); break;
 		}
 	}
 }
@@ -509,20 +509,20 @@ fz_paint_span_with_color(byte * restrict dp, const byte * restrict mp, int n, in
 	{
 		switch (n)
 		{
-		case 2: fz_paint_span_with_color_2_da(dp, mp, w, color); break;
-		case 4: fz_paint_span_with_color_4_da(dp, mp, w, color); break;
-		case 5: fz_paint_span_with_color_5_da(dp, mp, w, color); break;
-		default: fz_paint_span_with_color_N(dp, mp, n, w, color, 1); break;
+		case 2: TRACK_LABEL("pscd2"); fz_paint_span_with_color_2_da(dp, mp, w, color); break;
+		case 4: TRACK_LABEL("pscd4"); fz_paint_span_with_color_4_da(dp, mp, w, color); break;
+		case 5: TRACK_LABEL("pscd5"); fz_paint_span_with_color_5_da(dp, mp, w, color); break;
+		default: TRACK_LABEL("pscdn"); fz_paint_span_with_color_N(dp, mp, n, w, color, 1); break;
 		}
 	}
 	else
 	{
 		switch (n)
 		{
-		case 1: fz_paint_span_with_color_N(dp, mp, 1, w, color, 0); break;
-		case 3: fz_paint_span_with_color_N(dp, mp, 3, w, color, 0); break;
-		case 4: fz_paint_span_with_color_N(dp, mp, 4, w, color, 0); break;
-		default: fz_paint_span_with_color_N(dp, mp, n, w, color, 0); break;
+		case 1: TRACK_LABEL("pscd1"); fz_paint_span_with_color_N(dp, mp, 1, w, color, 0); break;
+		case 3: TRACK_LABEL("pscd3"); fz_paint_span_with_color_N(dp, mp, 3, w, color, 0); break;
+		case 4: TRACK_LABEL("pscd4"); fz_paint_span_with_color_N(dp, mp, 4, w, color, 0); break;
+		default: TRACK_LABEL("pscdn"); fz_paint_span_with_color_N(dp, mp, n, w, color, 0); break;
 		}
 	}
 }
@@ -869,20 +869,20 @@ fz_paint_span_with_mask(byte * restrict dp, int da, const byte * restrict sp, in
 		{
 			switch (n)
 			{
-			case 1: fz_paint_span_with_mask_1(dp, 1, sp, 1, mp, w); break;
-			case 3: fz_paint_span_with_mask_3(dp, 1, sp, 1, mp, w); break;
-			case 4: fz_paint_span_with_mask_4(dp, 1, sp, 1, mp, w); break;
-			default: fz_paint_span_with_mask_N(dp, 1, sp, 1, mp, n, w); break;
+			case 1: TRACK_LABEL("pmds1"); fz_paint_span_with_mask_1(dp, 1, sp, 1, mp, w); break;
+			case 3: TRACK_LABEL("pmds3"); fz_paint_span_with_mask_3(dp, 1, sp, 1, mp, w); break;
+			case 4: TRACK_LABEL("pmds4"); fz_paint_span_with_mask_4(dp, 1, sp, 1, mp, w); break;
+			default: TRACK_LABEL("pmdsn"); fz_paint_span_with_mask_N(dp, 1, sp, 1, mp, n, w); break;
 			}
 		}
 		else
 		{
 			switch (n)
 			{
-			case 1: fz_paint_span_with_mask_1(dp, 1, sp, 0, mp, w); break;
-			case 3: fz_paint_span_with_mask_3(dp, 1, sp, 0, mp, w); break;
-			case 4: fz_paint_span_with_mask_4(dp, 1, sp, 0, mp, w); break;
-			default: fz_paint_span_with_mask_N(dp, 1, sp, 0, mp, n, w); break;
+			case 1: TRACK_LABEL("pmd1"); fz_paint_span_with_mask_1(dp, 1, sp, 0, mp, w); break;
+			case 3: TRACK_LABEL("pmd3"); fz_paint_span_with_mask_3(dp, 1, sp, 0, mp, w); break;
+			case 4: TRACK_LABEL("pmd4"); fz_paint_span_with_mask_4(dp, 1, sp, 0, mp, w); break;
+			default: TRACK_LABEL("pmdn"); fz_paint_span_with_mask_N(dp, 1, sp, 0, mp, n, w); break;
 			}
 		}
 	}
@@ -892,20 +892,20 @@ fz_paint_span_with_mask(byte * restrict dp, int da, const byte * restrict sp, in
 		{
 			switch (n)
 			{
-			case 1: fz_paint_span_with_mask_1(dp, 0, sp, 1, mp, w); break;
-			case 3: fz_paint_span_with_mask_3(dp, 0, sp, 1, mp, w); break;
-			case 4: fz_paint_span_with_mask_4(dp, 0, sp, 1, mp, w); break;
-			default: fz_paint_span_with_mask_N(dp, 0, sp, 1, mp, n, w); break;
+			case 1: TRACK_LABEL("pms1"); fz_paint_span_with_mask_1(dp, 0, sp, 1, mp, w); break;
+			case 3: TRACK_LABEL("pms3"); fz_paint_span_with_mask_3(dp, 0, sp, 1, mp, w); break;
+			case 4: TRACK_LABEL("pms4"); fz_paint_span_with_mask_4(dp, 0, sp, 1, mp, w); break;
+			default: TRACK_LABEL("pmsn"); fz_paint_span_with_mask_N(dp, 0, sp, 1, mp, n, w); break;
 			}
 		}
 		else
 		{
 			switch (n)
 			{
-			case 1: fz_paint_span_with_mask_1(dp, 0, sp, 0, mp, w); break;
-			case 3: fz_paint_span_with_mask_3(dp, 0, sp, 0, mp, w); break;
-			case 4: fz_paint_span_with_mask_4(dp, 0, sp, 0, mp, w); break;
-			default: fz_paint_span_with_mask_N(dp, 0, sp, 0, mp, n, w); break;
+			case 1: TRACK_LABEL("pm1"); fz_paint_span_with_mask_1(dp, 0, sp, 0, mp, w); break;
+			case 3: TRACK_LABEL("pm3"); fz_paint_span_with_mask_3(dp, 0, sp, 0, mp, w); break;
+			case 4: TRACK_LABEL("pm4"); fz_paint_span_with_mask_4(dp, 0, sp, 0, mp, w); break;
+			default: TRACK_LABEL("pmn"); fz_paint_span_with_mask_N(dp, 0, sp, 0, mp, n, w); break;
 			}
 		}
 	}
@@ -1205,21 +1205,21 @@ fz_paint_span(byte * restrict dp, int da, const byte * restrict sp, int sa, int
 			{
 				switch (n)
 				{
-				case 0: fz_paint_span_1_dasa(dp, sp, w); break;
-				case 1: fz_paint_span_1(dp, 1, sp, 1, w); break;
-				case 3: fz_paint_span_3(dp, 1, sp, 1, w); break;
-				case 4: fz_paint_span_4(dp, 1, sp, 1, w); break;
-				default: fz_paint_span_N(dp, 1, sp, 1, n, w); break;
+				case 0: TRACK_LABEL("psds0"); fz_paint_span_1_dasa(dp, sp, w); break;
+				case 1: TRACK_LABEL("psds1"); fz_paint_span_1(dp, 1, sp, 1, w); break;
+				case 3: TRACK_LABEL("psds3"); fz_paint_span_3(dp, 1, sp, 1, w); break;
+				case 4: TRACK_LABEL("psds4"); fz_paint_span_4(dp, 1, sp, 1, w); break;
+				default: TRACK_LABEL("psdsn"); fz_paint_span_N(dp, 1, sp, 1, n, w); break;
 				}
 			}
 			else if (alpha > 0)
 			{
 				switch (n)
 				{
-				case 1: fz_paint_span_1_with_alpha(dp, 1, sp, 1, w, alpha); break;
-				case 3: fz_paint_span_3_with_alpha(dp, 1, sp, 1, w, alpha); break;
-				case 4: fz_paint_span_4_with_alpha(dp, 1, sp, 1, w, alpha); break;
-				default: fz_paint_span_N_with_alpha(dp, 1, sp, 1, n, w, alpha); break;
+				case 1: TRACK_LABEL("psdsa2"); fz_paint_span_1_with_alpha(dp, 1, sp, 1, w, alpha); break;
+				case 3: TRACK_LABEL("psdsa3"); fz_paint_span_3_with_alpha(dp, 1, sp, 1, w, alpha); break;
+				case 4: TRACK_LABEL("psdsa4"); fz_paint_span_4_with_alpha(dp, 1, sp, 1, w, alpha); break;
+				default: TRACK_LABEL("psdsan"); fz_paint_span_N_with_alpha(dp, 1, sp, 1, n, w, alpha); break;
 				}
 			}
 		}
@@ -1229,20 +1229,20 @@ fz_paint_span(byte * restrict dp, int da, const byte * restrict sp, int sa, int
 			{
 				switch (n)
 				{
-				case 1: fz_paint_span_1(dp, 1, sp, 0, w); break;
-				case 3: fz_paint_span_3(dp, 1, sp, 0, w); break;
-				case 4: fz_paint_span_4(dp, 1, sp, 0, w); break;
-				default: fz_paint_span_N(dp, 1, sp, 0, n, w); break;
+				case 1: TRACK_LABEL("psd1"); fz_paint_span_1(dp, 1, sp, 0, w); break;
+				case 3: TRACK_LABEL("psd3"); fz_paint_span_3(dp, 1, sp, 0, w); break;
+				case 4: TRACK_LABEL("psd4"); fz_paint_span_4(dp, 1, sp, 0, w); break;
+				default: TRACK_LABEL("psdn"); fz_paint_span_N(dp, 1, sp, 0, n, w); break;
 				}
 			}
 			else if (alpha > 0)
 			{
 				switch (n)
 				{
-				case 1: fz_paint_span_1_with_alpha(dp, 1, sp, 0, w, alpha); break;
-				case 3: fz_paint_span_3_with_alpha(dp, 1, sp, 0, w, alpha); break;
-				case 4: fz_paint_span_4_with_alpha(dp, 1, sp, 0, w, alpha); break;
-				default: fz_paint_span_N_with_alpha(dp, 1, sp, 0, n, w, alpha); break;
+				case 1: TRACK_LABEL("psda1"); fz_paint_span_1_with_alpha(dp, 1, sp, 0, w, alpha); break;
+				case 3: TRACK_LABEL("psda3"); fz_paint_span_3_with_alpha(dp, 1, sp, 0, w, alpha); break;
+				case 4: TRACK_LABEL("psda4"); fz_paint_span_4_with_alpha(dp, 1, sp, 0, w, alpha); break;
+				default: TRACK_LABEL("psdan"); fz_paint_span_N_with_alpha(dp, 1, sp, 0, n, w, alpha); break;
 				}
 			}
 		}
@@ -1255,20 +1255,20 @@ fz_paint_span(byte * restrict dp, int da, const byte * restrict sp, int sa, int
 			{
 				switch (n)
 				{
-				case 1: fz_paint_span_1(dp, 0, sp, 1, w); break;
-				case 3: fz_paint_span_3(dp, 0, sp, 1, w); break;
-				case 4: fz_paint_span_4(dp, 0, sp, 1, w); break;
-				default: fz_paint_span_N(dp, 0, sp, 1, n, w); break;
+				case 1: TRACK_LABEL("pss1"); fz_paint_span_1(dp, 0, sp, 1, w); break;
+				case 3: TRACK_LABEL("pss3"); fz_paint_span_3(dp, 0, sp, 1, w); break;
+				case 4: TRACK_LABEL("pss4"); fz_paint_span_4(dp, 0, sp, 1, w); break;
+				default: TRACK_LABEL("pssn"); fz_paint_span_N(dp, 0, sp, 1, n, w); break;
 				}
 			}
 			else if (alpha > 0)
 			{
 				switch (n)
 				{
-				case 1: fz_paint_span_1_with_alpha(dp, 0, sp, 1, w, alpha); break;
-				case 3: fz_paint_span_3_with_alpha(dp, 0, sp, 1, w, alpha); break;
-				case 4: fz_paint_span_4_with_alpha(dp, 0, sp, 1, w, alpha); break;
-				default: fz_paint_span_N_with_alpha(dp, 0, sp, 1, n, w, alpha); break;
+				case 1: TRACK_LABEL("pssa1"); fz_paint_span_1_with_alpha(dp, 0, sp, 1, w, alpha); break;
+				case 3: TRACK_LABEL("pssa3"); fz_paint_span_3_with_alpha(dp, 0, sp, 1, w, alpha); break;
+				case 4: TRACK_LABEL("pssa4"); fz_paint_span_4_with_alpha(dp, 0, sp, 1, w, alpha); break;
+				default: TRACK_LABEL("pssan"); fz_paint_span_N_with_alpha(dp, 0, sp, 1, n, w, alpha); break;
 				}
 			}
 		}
@@ -1278,20 +1278,20 @@ fz_paint_span(byte * restrict dp, int da, const byte * restrict sp, int sa, int
 			{
 				switch (n)
 				{
-				case 1: fz_paint_span_1(dp, 0, sp, 0, w); break;
-				case 3: fz_paint_span_3(dp, 0, sp, 0, w); break;
-				case 4: fz_paint_span_4(dp, 0, sp, 0, w); break;
-				default: fz_paint_span_N(dp, 0, sp, 0, n, w); break;
+				case 1: TRACK_LABEL("ps1"); fz_paint_span_1(dp, 0, sp, 0, w); break;
+				case 3: TRACK_LABEL("ps3"); fz_paint_span_3(dp, 0, sp, 0, w); break;
+				case 4: TRACK_LABEL("ps4"); fz_paint_span_4(dp, 0, sp, 0, w); break;
+				default: TRACK_LABEL("psn"); fz_paint_span_N(dp, 0, sp, 0, n, w); break;
 				}
 			}
 			else if (alpha > 0)
 			{
 				switch (n)
 				{
-				case 1: fz_paint_span_1_with_alpha(dp, 0, sp, 0, w, alpha); break;
-				case 3: fz_paint_span_3_with_alpha(dp, 0, sp, 0, w, alpha); break;
-				case 4: fz_paint_span_4_with_alpha(dp, 0, sp, 0, w, alpha); break;
-				default: fz_paint_span_N_with_alpha(dp, 0 ,sp, 0, n, w, alpha); break;
+				case 1: TRACK_LABEL("psa1"); fz_paint_span_1_with_alpha(dp, 0, sp, 0, w, alpha); break;
+				case 3: TRACK_LABEL("psa3"); fz_paint_span_3_with_alpha(dp, 0, sp, 0, w, alpha); break;
+				case 4: TRACK_LABEL("psa4"); fz_paint_span_4_with_alpha(dp, 0, sp, 0, w, alpha); break;
+				default: TRACK_LABEL("psan"); fz_paint_span_N_with_alpha(dp, 0 ,sp, 0, n, w, alpha); break;
 				}
 			}
 		}
@@ -1614,15 +1614,19 @@ fz_paint_glyph_alpha(const unsigned char * restrict colorbv, int n, int span, un
 		switch (n)
 		{
 		case 1:
+			TRACK_LABEL("pgda1");
 			fz_paint_glyph_alpha_1_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		case 3:
+			TRACK_LABEL("pgda3");
 			fz_paint_glyph_alpha_3_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		case 4:
+			TRACK_LABEL("pgda4");
 			fz_paint_glyph_alpha_4_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		default:
+			TRACK_LABEL("pgdan");
 			fz_paint_glyph_alpha_N_da(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		}
@@ -1632,15 +1636,19 @@ fz_paint_glyph_alpha(const unsigned char * restrict colorbv, int n, int span, un
 		switch (n)
 		{
 		case 1:
+			TRACK_LABEL("pga1");
 			fz_paint_glyph_alpha_1(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		case 3:
+			TRACK_LABEL("pga3");
 			fz_paint_glyph_alpha_3(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		case 4:
+			TRACK_LABEL("pga4");
 			fz_paint_glyph_alpha_4(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		default:
+			TRACK_LABEL("pgan");
 			fz_paint_glyph_alpha_N(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		}
@@ -1655,15 +1663,19 @@ fz_paint_glyph_solid(const unsigned char * restrict colorbv, int n, int span, un
 		switch (n)
 		{
 		case 1:
+			TRACK_LABEL("pg1d1");
 			fz_paint_glyph_solid_1_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		case 3:
+			TRACK_LABEL("pg1d3");
 			fz_paint_glyph_solid_3_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		case 4:
+			TRACK_LABEL("pg1d4");
 			fz_paint_glyph_solid_4_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		default:
+			TRACK_LABEL("pg1dn");
 			fz_paint_glyph_solid_N_da(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		}
@@ -1673,15 +1685,19 @@ fz_paint_glyph_solid(const unsigned char * restrict colorbv, int n, int span, un
 		switch (n)
 		{
 		case 1:
+			TRACK_LABEL("pg11");
 			fz_paint_glyph_solid_1(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		case 3:
+			TRACK_LABEL("pg13");
 			fz_paint_glyph_solid_3(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		case 4:
+			TRACK_LABEL("pg14");
 			fz_paint_glyph_solid_4(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		default:
+			TRACK_LABEL("pg1n");
 			fz_paint_glyph_solid_N(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y);
 			break;
 		}
diff --git a/source/fitz/track-usage.c b/source/fitz/track-usage.c
new file mode 100644
index 00000000..f2d8af49
--- /dev/null
+++ b/source/fitz/track-usage.c
@@ -0,0 +1,34 @@
+#include "mupdf/fitz.h"
+
+#ifdef TRACK_USAGE
+
+static track_usage_data_t *usage_head = NULL;
+
+static void dump_usage(void)
+{
+	track_usage_data_t *u = usage_head;
+
+	while (u)
+	{
+		fprintf(stderr, "USAGE: %s (%s:%d) %d calls\n",
+			u->desc, u->function, u->line, u->count);
+		u = u->next;
+	}
+}
+
+void track_usage(track_usage_data_t *data, const char *function, int line, const char *desc)
+{
+	int c = data->count++;
+	if (c == 0)
+	{
+		data->function = function;
+		data->line = line;
+		data->desc = desc;
+		if (usage_head == NULL)
+			atexit(dump_usage);
+		data->next = usage_head;
+		usage_head = data;
+	}
+}
+
+#endif
-- 
cgit v1.2.3