--- /home/mburke/code/bwipp/postscriptbarcode/build/monolithic/barcode.ps	2021-08-09 14:49:02.985470860 +0100
+++ backend/tests/tools/bwipp_dump.ps	2021-08-09 14:50:05.624957661 +0100
@@ -26289,34 +26289,80 @@
         pop
     } ifelse
 
-    gsave
+    dontdraw not { gsave } if
 
     options (lintype) (ean13) put
     options (inkspread) (0) put
     options (dontdraw) true put
 
     % Plot the linear part
-    linear options //ean13 exec //renlinear exec
+    linear options //ean13 exec
+    dontdraw not {
+        //renlinear exec
+
+        % Plot the separator
+        -1 72 rmoveto <<
+            /ren //renmatrix
+            /pixs [
+                0 1  93 {0} repeat  1 0
+                1 0  93 {0} repeat  0 1
+                0 1  93 {0} repeat  1 0
+            ]
+            /pixx 97
+            /pixy 3
+            /height 6 72 div
+            /width 97 72 div
+            /opt options
+        >> //renmatrix exec
 
-    % Plot the separator
-    -1 72 rmoveto <<
-        /ren //renmatrix
-        /pixs [
-            0 1  93 {0} repeat  1 0
-            1 0  93 {0} repeat  0 1
-            0 1  93 {0} repeat  1 0
-        ]
-        /pixx 97
-        /pixy 3
-        /height 6 72 div
-        /width 97 72 div
-        /opt options
-    >> //renmatrix exec
+        % Plot the 2D part
+        -2 6 rmoveto comp options //gs1-cc exec //renmatrix exec
 
-    % Plot the 2D part
-    -2 6 rmoveto comp options //gs1-cc exec //renmatrix exec
+        grestore
+    } {
+        /linsym exch def
+        /linpixs [
+            linsym /sbs get { cvi 1 index 1 eq {{0}} {{1}} ifelse repeat } forall  % Alternates x 1/0's
+        ] def
+        /linheight linsym /bhs get 0 get 72 mul cvi def
+
+        /compsym comp options //gs1-cc exec def
+        /ccpixs compsym /pixs get def
+        /ccpixx compsym /pixx get def
+
+        /linpad [ ccpixx 97 sub {0} repeat ] def
+
+        /diff linpixs length linpad length add 2 add ccpixx sub def  % An add-on can make linear wider than composite
+        diff 0 gt {  % Left align composite
+            /ccrpad [ diff {0} repeat ] def
+            /pixx ccpixx diff add def
+        } {
+            /ccrpad 0 array def
+            /pixx ccpixx def
+        } ifelse
 
-    grestore
+        /pixs [
+            0 ccpixx ccpixs length 1 sub {
+                /i exch def
+                2 { ccpixs i ccpixx getinterval aload pop ccrpad aload pop } repeat
+            } for
+            2 { linpad aload pop 0 1  93 {0} repeat  1 0 ccrpad aload pop } repeat
+            2 { linpad aload pop 1 0  93 {0} repeat  0 1 ccrpad aload pop } repeat
+            2 { linpad aload pop 0 1  93 {0} repeat  1 0 ccrpad aload pop } repeat
+            linheight { linpad aload pop 0 linpixs aload pop 0 } repeat
+        ] def
+
+        /pixy pixs length pixx idiv def
+        <<
+        /ren //renmatrix
+        /pixs pixs
+        /pixx pixx
+        /pixy pixy
+        /height pixy 72 div
+        /width pixx 72 div
+        /opt options
+        >>
+    } ifelse
 
     end
 
@@ -26375,7 +26421,7 @@
         pop
     } ifelse
 
-    gsave
+    dontdraw not { gsave } if
 
     % Get the result of encoding with ean8 and gs1-cc
     options (lintype) (ean8) put
@@ -26383,29 +26429,75 @@
     options (dontdraw) true put
 
     % Plot the linear part
-    linear options //ean8 exec //renlinear exec
+    linear options //ean8 exec
+    dontdraw not {
+        //renlinear exec
+
+        % Plot the separator
+        -1 72 rmoveto <<
+            /ren //renmatrix
+            /pixs [
+                0 1  65 {0} repeat  1 0
+                1 0  65 {0} repeat  0 1
+                0 1  65 {0} repeat  1 0
+            ]
+            /pixx 69
+            /pixy 3
+            /height 6 72 div
+            /width 69 72 div
+            /opt options
+        >> //renmatrix exec
+
+        % Plot the 2D part
+        comp options //gs1-cc exec
+        dup (pixx) get 69 exch sub 6 rmoveto
+        //renmatrix exec
 
-    % Plot the separator
-    -1 72 rmoveto <<
-        /ren //renmatrix
-        /pixs [
-            0 1  65 {0} repeat  1 0
-            1 0  65 {0} repeat  0 1
-            0 1  65 {0} repeat  1 0
-        ]
-        /pixx 69
-        /pixy 3
-        /height 6 72 div
-        /width 69 72 div
-        /opt options
-    >> //renmatrix exec
+        grestore
+    } {
+        /linsym exch def
+        /linpixs [
+            linsym /sbs get { cvi 1 index 1 eq {{0}} {{1}} ifelse repeat } forall  % Alternates x 1/0's
+        ] def
+        /linheight linsym /bhs get 0 get 72 mul cvi def
+
+        /compsym comp options //gs1-cc exec def
+        /ccpixs compsym /pixs get def
+        /ccpixx compsym /pixx get def
+
+        /linpad [ ccpixx 69 sub {0} repeat ] def
+
+        /diff linpixs length linpad length add 2 add ccpixx sub def  % An add-on can make linear wider than composite
+        diff 0 gt {  % Left align composite
+            /ccrpad [ diff {0} repeat ] def
+            /pixx ccpixx diff add def
+        } {
+            /ccrpad 0 array def
+            /pixx ccpixx def
+        } ifelse
 
-    % Plot the 2D part
-    comp options //gs1-cc exec
-    dup (pixx) get 69 exch sub 6 rmoveto
-    //renmatrix exec
+        /pixs [
+            0 ccpixx ccpixs length 1 sub {
+                /i exch def
+                2 { ccpixs i ccpixx getinterval aload pop ccrpad aload pop } repeat
+            } for
+            2 { linpad aload pop 0 1  65 {0} repeat  1 0 ccrpad aload pop } repeat
+            2 { linpad aload pop 1 0  65 {0} repeat  0 1 ccrpad aload pop } repeat
+            2 { linpad aload pop 0 1  65 {0} repeat  1 0 ccrpad aload pop } repeat
+            linheight { linpad aload pop 0 linpixs aload pop 0 } repeat
+        ] def
 
-    grestore
+        /pixy pixs length pixx idiv def
+        <<
+        /ren //renmatrix
+        /pixs pixs
+        /pixx pixx
+        /pixy pixy
+        /height pixy 72 div
+        /width pixx 72 div
+        /opt options
+        >>
+    } ifelse
 
     end
 
@@ -26464,34 +26556,80 @@
         pop
     } ifelse
 
-    gsave
+    dontdraw not { gsave } if
 
     options (lintype) (ean13) put
     options (inkspread) (0) put
     options (dontdraw) true put
 
     % Plot the linear part
-    linear options //upca exec //renlinear exec
+    linear options //upca exec
+    dontdraw not {
+        //renlinear exec
+
+        % Plot the separator
+        -1 72 rmoveto <<
+            /ren //renmatrix
+            /pixs [
+                0 1  93 {0} repeat  1 0
+                1 0  93 {0} repeat  0 1
+                0 1  93 {0} repeat  1 0
+            ]
+            /pixx 97
+            /pixy 3
+            /height 6 72 div
+            /width 97 72 div
+            /opt options
+        >> //renmatrix exec
 
-    % Plot the separator
-    -1 72 rmoveto <<
-        /ren //renmatrix
-        /pixs [
-            0 1  93 {0} repeat  1 0
-            1 0  93 {0} repeat  0 1
-            0 1  93 {0} repeat  1 0
-        ]
-        /pixx 97
-        /pixy 3
-        /height 6 72 div
-        /width 97 72 div
-        /opt options
-    >> //renmatrix exec
+        % Plot the 2D part
+        -2 6 rmoveto comp options //gs1-cc exec //renmatrix exec
 
-    % Plot the 2D part
-    -2 6 rmoveto comp options //gs1-cc exec //renmatrix exec
+        grestore
+    } {
+        /linsym exch def
+        /linpixs [
+            linsym /sbs get { cvi 1 index 1 eq {{0}} {{1}} ifelse repeat } forall  % Alternates x 1/0's
+        ] def
+        /linheight linsym /bhs get 0 get 72 mul cvi def
+
+        /compsym comp options //gs1-cc exec def
+        /ccpixs compsym /pixs get def
+        /ccpixx compsym /pixx get def
+
+        /linpad [ ccpixx 97 sub {0} repeat ] def
+
+        /diff linpixs length linpad length add 2 add ccpixx sub def  % An add-on can make linear wider than composite
+        diff 0 gt {  % Left align composite
+            /ccrpad [ diff {0} repeat ] def
+            /pixx ccpixx diff add def
+        } {
+            /ccrpad 0 array def
+            /pixx ccpixx def
+        } ifelse
 
-    grestore
+        /pixs [
+            0 ccpixx ccpixs length 1 sub {
+                /i exch def
+                2 { ccpixs i ccpixx getinterval aload pop ccrpad aload pop } repeat
+            } for
+            2 { linpad aload pop 0 1  93 {0} repeat  1 0 ccrpad aload pop } repeat
+            2 { linpad aload pop 1 0  93 {0} repeat  0 1 ccrpad aload pop } repeat
+            2 { linpad aload pop 0 1  93 {0} repeat  1 0 ccrpad aload pop } repeat
+            linheight { linpad aload pop 0 linpixs aload pop 0 } repeat
+        ] def
+
+        /pixy pixs length pixx idiv def
+        <<
+        /ren //renmatrix
+        /pixs pixs
+        /pixx pixx
+        /pixy pixy
+        /height pixy 72 div
+        /width pixx 72 div
+        /opt options
+        >>
+    } ifelse
 
     end
 
@@ -26565,34 +26703,80 @@
         /opt options
     >> def
 
-    gsave
+    dontdraw not { gsave } if
 
     options (lintype) (upce) put
     options (inkspread) (0) put
     options (dontdraw) true put
 
     % Plot the linear part
-    linear options //upce exec //renlinear exec
+    linear options //upce exec
+    dontdraw not {
+        //renlinear exec
+
+        % Plot the separator
+        -1 72 rmoveto <<
+            /ren //renmatrix
+            /pixs [
+                0 1  49 {0} repeat  1 0
+                1 0  49 {0} repeat  0 1
+                0 1  49 {0} repeat  1 0
+            ]
+            /pixx 53
+            /pixy 3
+            /height 6 72 div
+            /width 53 72 div
+            /opt options
+        >> //renmatrix exec
 
-    % Plot the separator
-    -1 72 rmoveto <<
-        /ren //renmatrix
-        /pixs [
-            0 1  49 {0} repeat  1 0
-            1 0  49 {0} repeat  0 1
-            0 1  49 {0} repeat  1 0
-        ]
-        /pixx 53
-        /pixy 3
-        /height 6 72 div
-        /width 53 72 div
-        /opt options
-    >> //renmatrix exec
+        % Plot the 2D part
+        -2 6 rmoveto comp options //gs1-cc exec //renmatrix exec
 
-    % Plot the 2D part
-    -2 6 rmoveto comp options //gs1-cc exec //renmatrix exec
+        grestore
+    } {
+        /linsym exch def
+        /linpixs [
+            linsym /sbs get { cvi 1 index 1 eq {{0}} {{1}} ifelse repeat } forall  % Alternates x 1/0's
+        ] def
+        /linheight linsym /bhs get 0 get 72 mul cvi def
+
+        /compsym comp options //gs1-cc exec def
+        /ccpixs compsym /pixs get def
+        /ccpixx compsym /pixx get def
+
+        /linpad [ ccpixx 53 sub {0} repeat ] def
+
+        /diff linpixs length linpad length add 2 add ccpixx sub def  % An add-on can make linear wider than composite
+        diff 0 gt {  % Left align composite
+            /ccrpad [ diff {0} repeat ] def
+            /pixx ccpixx diff add def
+        } {
+            /ccrpad 0 array def
+            /pixx ccpixx def
+        } ifelse
 
-    grestore
+        /pixs [
+            0 ccpixx ccpixs length 1 sub {
+                /i exch def
+                2 { ccpixs i ccpixx getinterval aload pop ccrpad aload pop } repeat
+            } for
+            2 { linpad aload pop 0 1  49 {0} repeat  1 0 ccrpad aload pop } repeat
+            2 { linpad aload pop 1 0  49 {0} repeat  0 1 ccrpad aload pop } repeat
+            2 { linpad aload pop 0 1  49 {0} repeat  1 0 ccrpad aload pop } repeat
+            linheight { linpad aload pop 0 linpixs aload pop 0 } repeat
+        ] def
+
+        /pixy pixs length pixx idiv def
+        <<
+        /ren //renmatrix
+        /pixs pixs
+        /pixx pixx
+        /pixy pixy
+        /height pixy 72 div
+        /width pixx 72 div
+        /opt options
+        >>
+    } ifelse
 
     end
 
@@ -26651,7 +26835,7 @@
         pop
     } ifelse
 
-    gsave
+    dontdraw not { gsave } if
 
     options (lintype) (databaromni) put
     options (linkage) true put
@@ -26662,7 +26846,7 @@
     linear options //databaromni exec
     dup (sbs) get /linsbs exch def
     dup (bhs) get 0 get 72 mul /linheight exch def
-    //renlinear exec
+    dontdraw not { //renlinear exec } { pop } ifelse
 
     % Plot the separator
     /sepfinder {
@@ -26693,20 +26877,66 @@
     sep 0 [0 0 0] putinterval
     sep sep length 4 sub [0 0 0 0] putinterval
     18 sepfinder 64 sepfinder
-    0 linheight rmoveto <<
-        /ren //renmatrix
-        /pixs sep
-        /pixx sep length
-        /pixy 1
-        /height 1 72 div
-        /width sep length 72 div
-        /opt options
-    >> //renmatrix exec
+    dontdraw not {
+        0 linheight rmoveto <<
+            /ren //renmatrix
+            /pixs sep
+            /pixx sep length
+            /pixy 1
+            /height 1 72 div
+            /width sep length 72 div
+            /opt options
+        >> //renmatrix exec
 
-    % Plot the 2D part
-    -5 1 rmoveto comp options //gs1-cc exec //renmatrix exec
+        % Plot the 2D part
+        -5 1 rmoveto comp options //gs1-cc exec //renmatrix exec
 
-    grestore
+        grestore
+    } {
+        /compsym comp options //gs1-cc exec def
+        /ccpixs compsym /pixs get def
+        /ccpixx compsym /pixx get def
+
+        /linpixs [ 0  % Begin with left guard space
+            linsbs { cvi 1 index 0 eq {{1}} {{0}} ifelse repeat } forall  % Alternates x 1/0's
+        ] def
+        /sep [ 0 sep aload pop ] def  % Pad with left guard space
+
+        /linheight linheight cvi def
+        /diff linpixs length ccpixx sub def
+        diff 0 gt {  % Centre align composite, doubling up rows
+            /ccpad [ diff 2 idiv {0} repeat ] def
+            /pixs [
+                0 ccpixx ccpixs length 1 sub {
+                    /i exch def
+                    2 { ccpad aload pop ccpixs i ccpixx getinterval aload pop ccpad aload pop } repeat
+                } for
+                sep aload pop linheight { linpixs aload pop } repeat
+            ] def
+            /pixx linpixs length def
+        } {  % Right pad composite, doubling up rows, and left pad (right align) separator/linear
+            /linpad [ diff neg 1 add {0} repeat ] def
+            /pixs [
+                0 ccpixx ccpixs length 1 sub {  % Right pad composite with 1 space
+                    /i exch def
+                    2 { ccpixs i ccpixx getinterval aload pop 0 } repeat
+                } for
+                linpad aload pop sep aload pop linheight { linpad aload pop linpixs aload pop } repeat
+            ] def
+            /pixx ccpixx 1 add def
+        } ifelse
+
+        /pixy pixs length pixx idiv def
+        <<
+        /ren //renmatrix
+        /pixs pixs
+        /pixx pixx
+        /pixy pixy
+        /height pixy 72 div
+        /width pixx 72 div
+        /opt options
+        >>
+    } ifelse
 
     end
 
@@ -26764,7 +26994,7 @@
         pop
     } ifelse
 
-    gsave
+    dontdraw not { gsave } if
 
     options (lintype) (databarstacked) put
     options (linkage) true put
@@ -26775,7 +27005,7 @@
     linear options //databarstacked exec
     dup (pixs) get 0 2 index (pixx) get getinterval /bot exch def
     dup (pixy) get /linheight exch def
-    //renmatrix exec
+    dontdraw not { //renmatrix exec } { /pixs get /linpixs exch def } ifelse
 
     % Plot the separator
     /sepfinder {
@@ -26803,20 +27033,52 @@
     sep 0 [ 0 0 0 0 ] putinterval
     sep sep length 4 sub [ 0 0 0 0 ] putinterval
     18 sepfinder
-    0 linheight rmoveto <<
-        /ren //renmatrix
-        /pixs sep
-        /pixx sep length
-        /pixy 1
-        /height 1 72 div
-        /width sep length 72 div
-        /opt options
-    >> //renmatrix exec
+    dontdraw not {
+        0 linheight rmoveto <<
+            /ren //renmatrix
+            /pixs sep
+            /pixx sep length
+            /pixy 1
+            /height 1 72 div
+            /width sep length 72 div
+            /opt options
+        >> //renmatrix exec
 
-    % Plot the 2D part
-    1 1 rmoveto comp options //gs1-cc exec //renmatrix exec
+        % Plot the 2D part
+        1 1 rmoveto comp options //gs1-cc exec //renmatrix exec
 
-    grestore
+        grestore
+    } {
+        /compsym comp options //gs1-cc exec def
+        /ccpixs compsym /pixs get def
+        /ccpixx compsym /pixx get def
+
+        /linwidth sep length def
+        /pixx ccpixx 1 add def
+        /linpad [ pixx linwidth sub {0} repeat ] def
+        /pixs [
+            0 ccpixx ccpixs length 1 sub {  % Left pad composite with 1 space, doubling up rows
+                /i exch def
+                2 { 0 ccpixs i ccpixx getinterval aload pop } repeat
+            } for
+            sep aload pop linpad aload pop
+            0 linwidth linpixs length 1 sub {  % Right pad linear
+                /i exch def
+                linpixs i linwidth getinterval aload pop linpad aload pop
+            } for
+        ] def
+
+        /pixy pixs length pixx idiv def
+        <<
+        /ren //renmatrix
+        /pixs pixs
+        /pixx pixx
+        /pixy pixy
+        /height pixy 72 div
+        /width pixx 72 div
+        /opt options
+        >>
+    } ifelse
 
     end
 
@@ -26874,7 +27136,7 @@
         pop
     } ifelse
 
-    gsave
+    dontdraw not { gsave } if
 
     options (lintype) (databarstackedomni) put
     options (linkage) true put
@@ -26885,7 +27147,7 @@
     linear options //databarstackedomni exec
     dup (pixs) get 0 2 index (pixx) get getinterval /bot exch def
     dup (pixy) get /linheight exch def
-    //renmatrix exec
+    dontdraw not { //renmatrix exec } { /pixs get /linpixs exch def } ifelse
 
     % Plot the separator
     /sepfinder {
@@ -26913,20 +27175,52 @@
     sep 0 [ 0 0 0 0 ] putinterval
     sep sep length 4 sub [ 0 0 0 0 ] putinterval
     18 sepfinder
-    0 linheight rmoveto <<
-        /ren //renmatrix
-        /pixs sep
-        /pixx sep length
-        /pixy 1
-        /height 1 72 div
-        /width sep length 72 div
-        /opt options
-    >> //renmatrix exec
+    dontdraw not {
+        0 linheight rmoveto <<
+            /ren //renmatrix
+            /pixs sep
+            /pixx sep length
+            /pixy 1
+            /height 1 72 div
+            /width sep length 72 div
+            /opt options
+        >> //renmatrix exec
 
-    % Plot the 2D part
-    1 1 rmoveto comp options //gs1-cc exec //renmatrix exec
+        % Plot the 2D part
+        1 1 rmoveto comp options //gs1-cc exec //renmatrix exec
 
-    grestore
+        grestore
+    } {
+        /compsym comp options //gs1-cc exec def
+        /ccpixs compsym /pixs get def
+        /ccpixx compsym /pixx get def
+
+        /linwidth sep length def
+        /pixx ccpixx 1 add def
+        /linpad [ pixx linwidth sub {0} repeat ] def
+        /pixs [
+            0 ccpixx ccpixs length 1 sub {  % Left pad composite with 1 space, doubling up rows
+                /i exch def
+                2 { 0 ccpixs i ccpixx getinterval aload pop } repeat
+            } for
+            sep aload pop linpad aload pop
+            0 linwidth linpixs length 1 sub {  % Right pad linear
+                /i exch def
+                linpixs i linwidth getinterval aload pop linpad aload pop
+            } for
+        ] def
+
+        /pixy pixs length pixx idiv def
+        <<
+        /ren //renmatrix
+        /pixs pixs
+        /pixx pixx
+        /pixy pixy
+        /height pixy 72 div
+        /width pixx 72 div
+        /opt options
+        >>
+    } ifelse
 
     end
 
@@ -27099,7 +27393,7 @@
         pop
     } ifelse
 
-    gsave
+    dontdraw not { gsave } if
 
     options (lintype) (databarlimited) put
     options (linkage) true put
@@ -27110,7 +27404,7 @@
     linear options //databarlimited exec
     dup (sbs) get /linsbs exch def
     dup (bhs) get 0 get 72 mul /linheight exch def
-    //renlinear exec
+    dontdraw not { //renlinear exec } { pop } ifelse
 
     % Plot the separator
     mark
@@ -27118,22 +27412,68 @@
     counttomark 1 sub array astore /sep exch def pop pop
     sep 0 [0 0 0] putinterval
     sep sep length 9 sub [0 0 0 0 0 0 0 0 0] putinterval % 4 + 5 right guard spaces
-    0 linheight rmoveto <<
-        /ren //renmatrix
-        /pixs sep
-        /pixx sep length
-        /pixy 1
-        /height 1 72 div
-        /width sep length 72 div
-        /opt options
-    >> //renmatrix exec
+    dontdraw not {
+        0 linheight rmoveto <<
+            /ren //renmatrix
+            /pixs sep
+            /pixx sep length
+            /pixy 1
+            /height 1 72 div
+            /width sep length 72 div
+            /opt options
+        >> //renmatrix exec
+
+        % Plot the 2D part
+        comp options //gs1-cc exec
+        dup (pixx) get 72 exch sub 1 rmoveto
+        //renmatrix exec
 
-    % Plot the 2D part
-    comp options //gs1-cc exec
-    dup (pixx) get 72 exch sub 1 rmoveto
-    //renmatrix exec
+        grestore
+    } {
+        /compsym comp options //gs1-cc exec def
+        /ccpixs compsym /pixs get def
+        /ccpixx compsym /pixx get def
+
+        /linpixs [ 0  % Begin with left guard space
+            linsbs { cvi 1 index 0 eq {{1}} {{0}} ifelse repeat } forall  % Alternates x 1/0's
+        ] def
+        /sep [ 0 sep aload pop ] def  % Offset by 1
+
+        /linheight linheight cvi def
+        /diff linpixs length 5 sub ccpixx sub def % Adding 5 right guard spaces below so subtract 5
+        diff 0 gt {  % 2 column - centre align
+            /ccpad [ diff 2 idiv {0} repeat ] def
+            /pixs [
+                0 ccpixx ccpixs length 1 sub {
+                    /i exch def
+                    2 { ccpad aload pop ccpixs i ccpixx getinterval aload pop 0 0 0 0 0 ccpad aload pop } repeat
+                } for
+                sep aload pop linheight { linpixs aload pop } repeat
+            ] def
+            /pixx linpixs length def
+        } {  % 3/4 column - right pad 1 and right align separator/linear
+            /linpad [ diff neg 1 add {0} repeat ] def
+            /pixs [
+                0 ccpixx ccpixs length 1 sub {  % Right pad composite with 1 space + 5 right guard spaces
+                    /i exch def
+                    2 { ccpixs i ccpixx getinterval aload pop 0 0 0 0 0 0 } repeat
+                } for
+                linpad aload pop sep aload pop linheight { linpad aload pop linpixs aload pop } repeat
+            ] def
+            /pixx ccpixx 1 add def
+        } ifelse
 
-    grestore
+        /pixy pixs length pixx idiv def
+        <<
+        /ren //renmatrix
+        /pixs pixs
+        /pixx pixx
+        /pixy pixy
+        /height pixy 72 div
+        /width pixx 72 div
+        /opt options
+        >>
+    } ifelse
 
     end
 
@@ -27192,7 +27532,7 @@
         pop
     } ifelse
 
-    gsave
+    dontdraw not { gsave } if
 
     options (lintype) (databarexpanded) put
     options (linkage) true put
@@ -27203,7 +27543,7 @@
     linear options //databarexpanded exec
     dup (sbs) get /linsbs exch def
     dup (bhs) get 0 get 72 mul /linheight exch def
-    //renlinear exec
+    dontdraw not { //renlinear exec } { pop } ifelse
 
     % Plot the separator
     /sepfinder {
@@ -27232,20 +27572,60 @@
         18 98 bot length 13 sub {} for
         69 98 bot length 13 sub {} for
     ] {sepfinder} forall
-    0 linheight rmoveto <<
-        /ren //renmatrix
-        /pixs sep
-        /pixx sep length
-        /pixy 1
-        /height 1 72 div
-        /width sep length 72 div
-        /opt options
-    >> //renmatrix exec
+    dontdraw not {
+        0 linheight rmoveto <<
+            /ren //renmatrix
+            /pixs sep
+            /pixx sep length
+            /pixy 1
+            /height 1 72 div
+            /width sep length 72 div
+            /opt options
+        >> //renmatrix exec
 
-    % Plot the 2D part
-    1 1 rmoveto comp options //gs1-cc exec //renmatrix exec
+        % Plot the 2D part
+        1 1 rmoveto comp options //gs1-cc exec //renmatrix exec
 
-    grestore
+        grestore
+    } {
+        /compsym comp options //gs1-cc exec def
+        /ccpixs compsym /pixs get def
+        /ccpixx compsym /pixx get def
+
+        /linpixs [ 0  % Begin with left guard space
+            linsbs { cvi 1 index 0 eq {{1}} {{0}} ifelse repeat } forall  % Alternates x 1/0's
+        ] def
+        /sep [ 0 sep aload pop ] def  % Offset by 1
+
+        /linheight linheight cvi def
+        /diff linpixs length ccpixx sub def
+        diff 2 ge {
+            /cclpad [ 0 0 ] def
+            /ccrpad [ diff 2 sub {0} repeat ] def
+        } {
+            /cclpad [ diff {0} repeat ] def
+            /ccrpad 0 array def
+        } ifelse
+        /pixs [
+            0 ccpixx ccpixs length 1 sub {
+                /i exch def
+                2 { cclpad aload pop ccpixs i ccpixx getinterval aload pop ccrpad aload pop } repeat
+            } for
+            sep aload pop linheight { linpixs aload pop } repeat
+        ] def
+
+        /pixx linpixs length def
+        /pixy pixs length pixx idiv def
+        <<
+        /ren //renmatrix
+        /pixs pixs
+        /pixx pixx
+        /pixy pixy
+        /height pixy 72 div
+        /width pixx 72 div
+        /opt options
+        >>
+    } ifelse
 
     end
 
@@ -27303,7 +27683,7 @@
         pop
     } ifelse
 
-    gsave
+    dontdraw not { gsave } if
 
     options (lintype) (databarexpandedstacked) put
     options (linkage) true put
@@ -27314,7 +27694,7 @@
     linear options //databarexpandedstacked exec
     dup (pixs) get 0 2 index (pixx) get getinterval /bot exch def
     dup (pixy) get /linheight exch def
-    //renmatrix exec
+    dontdraw not { //renmatrix exec } { /pixs get /linpixs exch def } ifelse
 
     % Plot the separator
     /sepfinder {
@@ -27340,21 +27720,49 @@
         19 98 bot length 13 sub {} for
         70 98 bot length 13 sub {} for
     ] {sepfinder} forall
-    0 linheight rmoveto <<
-        /ren //renmatrix
-        /pixs sep
-        /pixx sep length
-        /pixy 1
-        /height 1 72 div
-        /width sep length 72 div
-        /opt options
-    >> //renmatrix exec
+    dontdraw not {
+        0 linheight rmoveto <<
+            /ren //renmatrix
+            /pixs sep
+            /pixx sep length
+            /pixy 1
+            /height 1 72 div
+            /width sep length 72 div
+            /opt options
+        >> //renmatrix exec
+
+        % Plot the 2D part
+        bot 0 get 0 eq {2} {0} ifelse 1 rmoveto
+        comp options //gs1-cc exec //renmatrix exec
 
-    % Plot the 2D part
-    bot 0 get 0 eq {2} {0} ifelse 1 rmoveto
-    comp options //gs1-cc exec //renmatrix exec
+        grestore
+    } {
+        /compsym comp options //gs1-cc exec def
+        /ccpixs compsym /pixs get def
+        /ccpixx compsym /pixx get def
+
+        /pixx sep length def
+        /cclpad [ pixx ccpixx sub 1 add 2 idiv {0} repeat ] def  % Add 1 to allow for odd difference
+        /ccrpad [ pixx ccpixx sub 2 idiv {0} repeat ] def
+        /pixs [
+            0 ccpixx ccpixs length 1 sub {  % Centre align composite
+                /i exch def
+                2 { cclpad aload pop ccpixs i ccpixx getinterval aload pop ccrpad aload pop } repeat
+            } for
+            sep aload pop linpixs aload pop
+        ] def
 
-    grestore
+        /pixy pixs length pixx idiv def
+        <<
+        /ren //renmatrix
+        /pixs pixs
+        /pixx pixx
+        /pixy pixy
+        /height pixy 72 div
+        /width pixx 72 div
+        /opt options
+        >>
+    } ifelse
 
     end
 
@@ -27413,7 +27821,7 @@
         pop
     } ifelse
 
-    gsave
+    dontdraw not { gsave } if
 
     options (inkspread) (0) put
     options (dontdraw) true put
@@ -27440,35 +27848,87 @@
     linear << options {} forall >> //gs1-128 exec
     dup (sbs) get /linsbs exch def
     dup (bhs) get 0 get 72 mul /linheight exch def
-    //renlinear exec
+    dontdraw not { //renlinear exec } { pop } ifelse
 
     % Plot the separator
     mark
     1 linsbs {1 index 0 eq {{1}} {{0}} ifelse repeat} forall
     counttomark 1 sub array astore /sep exch def pop pop
-    0 linheight rmoveto <<
-        /ren //renmatrix
-        /pixs sep
-        /pixx sep length
-        /pixy 1
-        /height 1 72 div
-        /width sep length 72 div
-        /opt options
-    >> //renmatrix exec
+    dontdraw not {
+        0 linheight rmoveto <<
+            /ren //renmatrix
+            /pixs sep
+            /pixx sep length
+            /pixy 1
+            /height 1 72 div
+            /width sep length 72 div
+            /opt options
+        >> //renmatrix exec
+    } if
 
     % Plot the 2D part
     linktype (a) eq {
         /s linwidth 2 sub 11 idiv def
         /p s 9 sub 2 idiv def
         /x s p sub 1 sub 11 mul 10 add p 0 eq {2 add} if 99 sub def
-        x 1 rmoveto
+        dontdraw not { x 1 rmoveto } if
     } {
-        -7 1 rmoveto
+        dontdraw not { -7 1 rmoveto } { /x -7 def } ifelse
     } ifelse
 
-    compsym //renmatrix exec
+    dontdraw not {
+        compsym //renmatrix exec
 
-    grestore
+        grestore
+    } {
+        /ccpixs compsym /pixs get def
+        /ccpixx compsym /pixx get def
+
+        /linpixs [
+            linsbs { cvi 1 index 1 eq {{0}} {{1}} ifelse repeat } forall  % Alternates x 1/0's
+        ] def
+
+        x 0 gt {  % Left pad composite
+            /cclpad [ x {0} repeat ] def
+            /linlpad 0 array def
+            /diff linwidth ccpixx x add sub def
+        } {  % Left pad linear
+            /cclpad 0 array def
+            /linlpad [ x neg {0} repeat ] def
+            /diff linwidth x sub ccpixx sub def
+        } ifelse
+
+        diff 0 gt {  % Right pad composite
+            /ccrpad [ diff {0} repeat ] def
+            /linrpad 0 array def
+        } {  % Right pad linear
+            /ccrpad 0 array def
+            /linrpad [ diff neg {0} repeat ] def
+        } ifelse
+
+        /linheight linheight cvi def
+        /ccrepeat linktype (a) eq {2} {3} ifelse def
+        /pixs [
+            0 ccpixx ccpixs length 1 sub {
+                /i exch def
+                ccrepeat { cclpad aload pop ccpixs i ccpixx getinterval aload pop ccrpad aload pop } repeat
+            } for
+            linlpad aload pop sep aload pop linrpad aload pop
+            linheight { linlpad aload pop linpixs aload pop linrpad aload pop } repeat
+        ] def
+
+        /pixx cclpad length ccpixx add ccrpad length add def
+        /pixy pixs length pixx idiv def
+        <<
+        /ren //renmatrix
+        /pixs pixs
+        /pixx pixx
+        /pixy pixy
+        /height pixy 72 div
+        /width pixx 72 div
+        /opt options
+        >>
+    } ifelse
 
     end
 
@@ -28901,3 +29361,189 @@
 % --END ENCODER hibcazteccode--
 
 % --END TEMPLATE--
+%!PS
+
+% To compress: tar cv bwipp_dump.ps | xz -e9 > bwipp_dump.ps.tar.xz
+
+% Dumps bwipp barcode binary to stdout. If `-sn` given, appends a newline after each symbol row, otherwise doesn't.
+%
+% To run e.g. gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=databarexpanded -sd='(01)98898765432106' -so='includetext segments=6' bwipp_dump.ps
+% where
+% `-sb=` is the bwipp barcode routine name
+% `-sd=` is the data (`sd2=` is also available for overspill data > 2K to get around Ghostscript arg_str_max)
+% `-so=` are options (as space separated key=val pairs (or just key if boolean true))
+
+% Command line "-s" options put into system dictionary as strings
+/n systemdict /n known def
+
+% Append d2 to d if given
+systemdict /d2 known {
+    /d d length d2 length add string dup dup 0 d putinterval d length d2 putinterval def
+} if
+
+% Strip start/end parens from data if any
+d 0 1 getinterval (\() eq d d length 1 sub 1 getinterval (\)) eq and {
+    /d d 1 d length 2 sub getinterval d length 2 sub string copy def
+} if
+
+% Options
+systemdict /o known {
+    o type /stringtype eq o length 0 gt and {
+        o length 2 ge {
+            % Strip start/end parens from options if any
+            o 0 1 getinterval (\() eq o o length 1 sub 1 getinterval (\)) eq and {
+                /o o 1 o length 2 sub getinterval o length 2 sub string copy def
+            } if
+        } if
+        3 dict begin
+        o {
+            token not {exit} if
+            dup length string cvs (=) search {
+                cvlit exch pop exch def
+            } {
+                cvlit true def
+            } ifelse
+        } loop
+        currentdict end /o exch def
+    } {
+        /o 1 dict def
+    } ifelse
+} {
+    /o 1 dict def
+} ifelse
+
+o (dontdraw) true put
+
+/ret d o b cvn /uk.co.terryburton.bwipp findresource exec def
+
+% pixs is renmatrix input
+ret /pixs known {
+    b (maxicode) eq {
+        /pixs 990 array def
+        0 1 989 { pixs exch 0 put } for
+        ret /pixs get { pixs exch 1 put } forall
+    } {
+        /pixs ret /pixs get def
+    } ifelse
+
+    /xs systemdict /xs known { systemdict /xs get cvi } { 0 } ifelse def
+    /xe systemdict /xe known { systemdict /xe get cvi } { 0 } ifelse def
+
+    n xs 0 ne or xe 0 ne or ret /pixx known and {  % If newlines or start/end indexes requested and have row width
+        /pixx ret /pixx get def
+        xs pixx pixs length 1 sub xe sub {  % For i = xs; i < pixs length - xe; i += pixx
+            pixs exch pixx xs sub xe sub getinterval {  % For j = i; j < i + pixx - xs -xe; j++
+                1 string cvs print
+            } forall
+            n { (\n) print } if
+        } for
+    } {  % Else dump the whole thing, no newlines
+        pixs { 1 string cvs print } forall
+    } ifelse
+} {
+    % sbs is renlinear input
+    ret /sbs known {
+        /sbs ret /sbs get def
+
+        % Check if given preprocessor override
+        systemdict /p known {
+            /p systemdict /p get cvx def
+        } {
+            /p { false } def
+        } ifelse
+
+        % Check if given ratio arg to adjust width of bars/spaces (e.g. "0.6" reduces 3 -> 2, "1.3" increases 2 -> 3)
+        systemdict /r known {
+            /r systemdict /r get cvr def
+            systemdict /c known {  % Apply ceiling ratio beforehand
+                /c systemdict /c get cvr def
+                /f { c mul ceiling cvi r mul round cvi } def
+            } {
+                /f { r mul round cvi } def
+            } ifelse
+        } {
+            /f {} def
+        } ifelse
+
+        % If should begin with space
+        systemdict /bs known { (0) print } if
+
+        % If should end sbs loop on bar (i.e. ignore last index of even-length sbs)
+        /limit systemdict /elb known {
+            sbs length 1 add 2 idiv 2 mul 2 sub
+        } {
+            sbs length 1 sub
+        } ifelse def
+
+        % If should use bhs/bbs to emulate rows (DAFT/pharmacode2) (hacky)
+        /nosbs false def
+        /minh 999999 def
+        /midh 0 def
+        /maxh 0 def
+        /maxb 0 def
+        systemdict /hs known ret /bhs known and ret /bbs known and {
+            /bhs ret /bhs get def
+            /bbs ret /bbs get def
+            0 1 bhs length 1 sub {
+                /i exch def
+                /h bhs i get def
+                /b bbs i get def
+                h minh lt { /minh h def } if
+                h maxh gt { /maxh h def } if
+                h minh ne h maxh ne and { /midh h def } if
+                b maxb gt { /maxb b def } if
+            } for
+            0 1 limit {
+                /i exch def
+                i 2 mod 0 eq {           % i is even
+                    /h bhs i 2 idiv get def
+                    /b bbs i 2 idiv get def
+                    h maxh eq h midh eq b maxb eq and or maxb 0 ne b maxb eq and midh 0 eq and h minh eq and or { (1) } { (0) } ifelse print  % Yeah, me too
+                } {
+                    (0) print
+                } ifelse
+            } for
+            n { (\n) print } if
+            maxb 0 ne midh 0 eq and maxb 0 eq minh maxh eq and or { /nosbs true def } if  % No tracker (pharmacode2)
+        } if
+
+        % Process sbs
+        nosbs not {
+            0 1 limit {
+                /i exch def
+                p not {  % If not preprocessed
+                    i 2 mod 0 eq {           % i is even
+                        sbs i get f cvi { (1) print } repeat
+                    } {
+                        sbs i get f cvi { (0) print } repeat
+                    } ifelse
+                } if
+            } for
+            n { (\n) print } if
+        } if
+
+        % Third row if DAFT, second row if no tracker (pharmacode2)
+        maxb 0 ne midh 0 ne or minh maxh eq or {
+            0 1 limit {
+                /i exch def
+                i 2 mod 0 eq {           % i is even
+                    /b bbs i 2 idiv get def
+                    b 0 eq { (1) } { (0) } ifelse print
+                } {
+                    (0) print
+                } ifelse
+            } for
+            n { (\n) print } if
+        } if
+    } if
+} ifelse
+
+% If have renderer
+ret /ren known {
+    % Scale
+    /s systemdict /s known { systemdict /s get cvi } { 2 } ifelse def
+    % If not -dNODISPLAY then render for debugging
+    currentpagedevice /Name get (nullpage) ne { s s scale 10 10 moveto ret ret /ren get exec } if
+} if
+
+% vim: set ts=4 sw=4 et :
