├── docs
├── ZPL_Vol1.pdf
└── ZPL_Vol2.pdf
├── fonts
├── CodabarLarge.ttf
└── CodabarMedium.ttf
├── bin
└── debian-install.sh
├── etc
└── apache2
│ └── sites-available
│ └── printer-zebra
├── status.cgi
├── svg-render.pl
├── print.cgi
├── README
├── pbm2ZPL.pl
├── ZPL2pbm.pl
└── templates
└── 105x40.svg
/docs/ZPL_Vol1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpavlin/Printer-Zebra/HEAD/docs/ZPL_Vol1.pdf
--------------------------------------------------------------------------------
/docs/ZPL_Vol2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpavlin/Printer-Zebra/HEAD/docs/ZPL_Vol2.pdf
--------------------------------------------------------------------------------
/fonts/CodabarLarge.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpavlin/Printer-Zebra/HEAD/fonts/CodabarLarge.ttf
--------------------------------------------------------------------------------
/fonts/CodabarMedium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpavlin/Printer-Zebra/HEAD/fonts/CodabarMedium.ttf
--------------------------------------------------------------------------------
/bin/debian-install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh -x
2 |
3 | sudo apt-get install ttf-mscorefonts-installer librsvg2-bin netpbm rlpr libdata-dump-perl
4 |
5 | # install font system-wide
6 | #sudo ln -s `pwd`/fonts/AdvCBe.ttf /usr/share/fonts/truetype/
7 | sudo ls `pwd`/fonts/*.ttf | xargs -i ln -sfv {} /usr/share/fonts/truetype/
8 |
--------------------------------------------------------------------------------
/etc/apache2/sites-available/printer-zebra:
--------------------------------------------------------------------------------
1 | # test with:
2 | # wget --header='Host: printer-zebra.vbz.ffzg.hr' -O print.png 'http://10.60.0.10/print.cgi?print=1234' && qiv print.png
3 | # wget --header='Host: printer-zebra.vbz.ffzg.hr' -O - 'http://10.60.0.10/status.cgi'
4 |
5 |
$status\n\n"; 39 | } 40 | 41 | print qq{ 42 | 43 | 44 | }; 45 | -------------------------------------------------------------------------------- /svg-render.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use warnings; 3 | use strict; 4 | use autodie; 5 | 6 | # sudo apt-get install librsvg2-bin netpbm 7 | 8 | my $size = $ENV{SIZE} || '105x40'; 9 | my $width = $ENV{WIDTH} || 832; 10 | 11 | my $args = join(' ', @ARGV); 12 | die "usage: $0 1301272944 callnumber > label.pbm\n" unless $args; 13 | 14 | my ( $barcode, $call1, $call2, $call3, $call4 ) = split(/\s+/, $args, 5); 15 | 16 | open(my $from, '<', "templates/$size.svg"); 17 | open(my $to, '|-', "rsvg-convert --width=$width --format=png --background-color=white | pngtopnm | pnmdepth 2"); 18 | while(<$from>) { 19 | no warnings 'uninitialized'; 20 | s/1301272944/$barcode/gs && warn "# barcode $barcode\n"; 21 | s/##call1##/$call1/gs && warn "# 1: $call1\n"; 22 | s/##call2##/$call2/gs && warn "# 2: $call2\n"; 23 | s/##call3##/$call3/gs && warn "# 3: $call3\n"; 24 | s/##call4##/$call4/gs && warn "# 4: $call4\n"; 25 | 26 | print $to $_; 27 | } 28 | close($from); 29 | close($to); 30 | 31 | -------------------------------------------------------------------------------- /print.cgi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use warnings; 3 | use strict; 4 | 5 | use CGI; 6 | use CGI::Carp qw(fatalsToBrowser); 7 | use autodie; 8 | 9 | my $q = CGI->new; 10 | 11 | my $size = $q->param('size') || '105x40'; 12 | my $width = $q->param('width') || 832; 13 | 14 | my $print = $q->param('print') || die "no print?"; 15 | 16 | my $ip = $q->remote_addr; 17 | my $dir = '/srv/Printer-Zebra'; 18 | 19 | my ( $barcode, $call1, $call2, $call3, $call4 ) = split(/\s+/, $print, 5); 20 | 21 | my $tmp = '/tmp/zebra'; 22 | mkdir $tmp unless -e $tmp; 23 | 24 | open(my $from, '<', "$dir/templates/$size.svg"); 25 | open(my $to, '|-', "rsvg-convert --width=$width --format=png --background-color=white | tee $tmp/$barcode.png | pngtopnm > $tmp/$barcode.pnm"); 26 | while(<$from>) { 27 | no warnings 'uninitialized'; 28 | s/1301272944/$barcode/gs && warn "# barcode $barcode\n"; 29 | s/##call1##/$call1/gs && warn "# 1: $call1\n"; 30 | s/##call2##/$call2/gs && warn "# 2: $call2\n"; 31 | s/##call3##/$call3/gs && warn "# 3: $call3\n"; 32 | s/##call4##/$call4/gs && warn "# 4: $call4\n"; 33 | 34 | print $to $_; 35 | } 36 | close($from); 37 | close($to); 38 | 39 | system "./pbm2ZPL.pl $tmp/$barcode.pnm | rlpr --printhost=$ip --printer=zpl --windows --verbose"; 40 | 41 | unlink "$tmp/$barcode.pnm"; 42 | 43 | my $status = `rlpq --printhost=$ip --printer=zpl 2>&1 | tee $tmp/$ip.status`; 44 | die "$status\n" if $status =~ m/error/; 45 | 46 | if ( my $return = $q->param('return') ) { 47 | print $q->redirect( $q->param('return') . '&station=' . $ip ); 48 | } else { 49 | print "Content-type: image/png\r\n\r\n"; 50 | local $/ = undef; 51 | open(my $fh, '<', "$tmp/$barcode.png"); 52 | print <$fh>; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Zebra label printer ZPL interpreter and rasterizator 2 | 3 | 4 | Convert pbm image file to ZPL: 5 | 6 | pbm2ZPL.pl print.pnm > print.zpl 7 | 8 | Convert ZPL back into pbm image: 9 | 10 | ZPL2pbm.pl dump.zpl > dump.pbm 11 | 12 | 13 | 14 | This is my attempt to document various quirks using Zebra printers 15 | attached to Windows machines using USB: 16 | 17 | 18 | Windows printer driver doesn't seem to support ZPL when shared over CIFS. 19 | 20 | There is option to check pass-through, but then you have to wrap ZPL in 21 | start/end markers which cups printer driver doesn't do. 22 | 23 | Easier solution is to install port as Generic/Text printer under Windows 24 | and share printer using lpd which is available in Windows XP and newer. 25 | 26 | Install "zpl" printer with Generic / Text driver on Windows: 27 | 28 | Start > Printers and Faxes 29 | Add a printer > Next > 30 | Local printer attached to this computer > 31 | Use port: USB001 (Virtual printer port for USB) > Next > 32 | Generic > Generic / Text Only > Next > 33 | Printer name: zpl > default printer ? > No > Next > 34 | Do not share this printer > Next > 35 | Do you want to print a test page? > No > Next > Finish 36 | 37 | Install lpd server on Windows: 38 | 39 | Start > Control Panel 40 | Add or Remove programs > Add/Remove Windows Components > 41 | Other Network File and Print Services > Details > 42 | Print Services for Unix > OK > Next > Finish 43 | 44 | [ Restart Windows to complete install ] 45 | 46 | Allow connections from local subnet to port 515: 47 | 48 | Network Connections > Local Area Connection > Properties > 49 | Advanced - Windows Firewal > Settings > 50 | Exceptions > File and Printer Sharing > Add Port > 51 | Name: printer Port Number: 515 > TCP > Change scope > 52 | Ny network (subnet) only > OK > OK > OK ... 53 | 54 | Enable lpd service: 55 | 56 | Control Panel > Administrative Tools > Services > 57 | TCP/IP Print Server > Startup type: Automatic > Apply > 58 | Start > OK 59 | 60 | Verify that lpd and firewall settings are correct: 61 | 62 | dpavlin@t61p:~$ rlpq -H 10.60.1.30 -P zpl 63 | rlpq: warning: cannot bind to privileged port: lpd may reject 64 | 65 | Windows XP LPD Server 66 | Printer \\10.60.1.30\zpl 67 | 68 | Video of this procedure is available at: http://youtu.be/DMEo8rz-zo0 69 | 70 | -------------------------------------------------------------------------------- /pbm2ZPL.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use warnings; 3 | use strict; 4 | use autodie; 5 | use Data::Dump qw(dump); 6 | 7 | # DG compression is documented in ZPL II Programming Guide Volume Two, page 71-72 8 | 9 | my $darkness = $ENV{DARKNESS} || 0; 10 | my $compress = $ENV{COMPRESS} || 1; 11 | 12 | my $pnm_file = shift @ARGV || die "usage: $0 print.pnm > print.zpl\n"; 13 | 14 | open(my $fh, '<', $pnm_file); 15 | my $magic = <$fh>; chomp $magic; 16 | my $size = <$fh>; 17 | while ( $size =~ m/^#/ ) { $size = <$fh> }; # skip comments 18 | chomp $size; 19 | my ( $w, $h ) = split(/ /,$size,2); 20 | warn "WARNING: width of $pnm_file not 832 but $w !\n" if $w != 832; 21 | 22 | my $bitmap; 23 | 24 | if ( $magic eq 'P4' ) { 25 | local $/ = undef; 26 | $bitmap = <$fh>; 27 | } elsif ( $magic eq 'P6' ) { 28 | my $max_color = <$fh>; chomp $max_color; 29 | 30 | my $trashold = $max_color / 2; 31 | 32 | local $/ = undef; 33 | my $rgb = <$fh>; 34 | 35 | my $mask = 0x80; 36 | my $byte = 0; 37 | 38 | my $o = 0; 39 | while ( $o < length($rgb) ) { 40 | my $px = ord(substr($rgb,$o,1)); $o += 3; 41 | $byte ^= $mask if $px < $trashold; 42 | $mask >>= 1; 43 | if ( ! $mask ) { 44 | $bitmap .= chr($byte); 45 | $byte = 0; 46 | $mask = 0x80; 47 | } 48 | } 49 | 50 | warn dump $bitmap; 51 | 52 | } else { 53 | die "$pnm_file magick $magic not supported\n"; 54 | } 55 | 56 | 57 | 58 | print '^XA'; 59 | printf '~TA%03d', 0; # tear-off 60 | print '~JSN'; # sensor detect N = normal, 90% 61 | #print '^LT18'; # label top -120 .. 120 62 | print '^MNW'; # media tracking N = continuous Y/W = web sensing M = mark sensing 63 | print '^MTT'; # media type T = termal (ribbon) D = direct (termal paper) 64 | print '^PON'; # print orientation N = normal I = invert 65 | print '^PMN'; # print mirror Y/N 66 | print '^LH0,0'; # label home x,y 67 | print '^JMA'; # dots/mm A = 24/12/8/6 B = 12/6/4/3 68 | print '^PR4,4'; # print,slew,backfeed speed in inch/s 2 .. 12 [default: 2,6,2] 69 | printf '^MD%d', $darkness ; # media darkness -30 .. 30 / XiIIIPlus 0..30/0.1 increments 70 | print '^JUS'; # configuration update F = factory default R = recall S = save 71 | print '^LRN'; # label reverse Y/N 72 | print '^CI0'; # change international font 0..255 73 | print "^XZ\r\n"; 74 | 75 | printf "~DG000.GRF,%d,%d,\r\n", $w / 8 * $h, $w / 8; 76 | 77 | my $last_line = ''; 78 | 79 | sub zpl_compress { 80 | my $compress = shift; 81 | my $repeat = length($compress); 82 | my $out; 83 | while ( $repeat >= 400 ) { 84 | $out .= 'z'; 85 | $repeat -= 400; 86 | } 87 | if ( $repeat >= 20 ) { 88 | $out .= chr( ord('f') + ( $repeat / 20 ) ); 89 | $repeat %= 20; 90 | } 91 | if ( $repeat > 0 ) { 92 | $out .= chr( ord('F') + $repeat ); 93 | } 94 | $out .= substr($compress,0,1); # char 95 | warn "## zpl_compress $repeat = $compress -> $out\n"; 96 | return $out; 97 | } 98 | 99 | foreach my $y ( 0 .. $h - 1 ) { 100 | my $line = substr( $bitmap, $y * ( $w / 8 ), $w / 8 ); 101 | if ( $line eq $last_line ) { 102 | print ':'; 103 | warn "# $y repeat previous line\n"; 104 | } else { 105 | my $hex = unpack('H*', $line); 106 | if ( $compress ) { 107 | $last_line = $line; 108 | $hex =~ s/0+$/,/ && warn "# $y fill 0 to right\n"; 109 | $hex =~ s/F+$/!/i && warn "# $y fill 1 to right\n"; 110 | $hex =~ s/((.)\2+)/zpl_compress($1)/egs; 111 | } 112 | print $hex; 113 | } 114 | } 115 | 116 | print '^XA'; 117 | print '^MMT'; # print mode,prepeel T=tear-off P=peel-off R=rewind A=applicator C=cutter, Y/N 118 | printf '^LL%d', $h; # label length FIXME ignore empty bottom 119 | printf '^PW%d', $w; # print width 120 | print '^LS0'; # label shift -9999..9999 121 | printf '^FT%d,%d', 0, $h; # field typeset x,y graphic origin is bottom-left 122 | print '^XG000.GRF,1,1^FS'; # recall grapmic source/name,magnification_x,magnification_y 123 | print '^PQ1,0,1,Y'; # print quantity total,pause/cut,replicates,no_pause 124 | print "^XZ\r\n"; 125 | 126 | print '^XA'; 127 | print '^ID000.GRF^FS'; # object delete 128 | print "^XZ\r\n"; 129 | 130 | -------------------------------------------------------------------------------- /ZPL2pbm.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use warnings; 3 | use strict; 4 | use autodie; 5 | use Data::Dump qw(dump); 6 | 7 | # convert Zebra label printer ZPL to pbm image 8 | 9 | my $command; 10 | while() { 11 | chomp; 12 | my ( $cmd, $desc ) = split(/\s/,$_,2); 13 | $command->{$cmd} = $desc; 14 | } 15 | 16 | my $file = shift @ARGV || die "usage: $0 dump.zpl > dump.pbm\n"; 17 | 18 | open(my $in, '<', $file); 19 | 20 | our $line = ''; 21 | sub slurp_line { 22 | $line .= <$in> unless length $line > 3; 23 | } 24 | slurp_line; 25 | 26 | while( $line ) { 27 | $line =~ s/[\r\n]+$// && warn "## removed CR/LF\n"; 28 | warn "# line ",dump($line),$/ if length($line) < 80 or $ENV{DEBUG}; 29 | if ( $line =~ s/~DG(\w+:)?(.+)// ) { 30 | my ( $name, $total_bytes, $row_bytes ) = split(/,/,$2,4); 31 | 32 | warn "# ~DG$1 => [$name] $total_bytes bytes $row_bytes in row\n"; 33 | 34 | my $data = <$in>; 35 | 36 | my $w = $row_bytes * 2; # hex digits 37 | 38 | my $out = ''; 39 | # ZPL decompress 40 | my $repeat = 0; 41 | foreach my $p ( 0 .. length($data) - 1 ) { 42 | 43 | if ( length($out) == $total_bytes * 2 ) { 44 | warn "END of bitmap\n"; 45 | $line = substr($data,$p); 46 | slurp_line; 47 | last; 48 | }; 49 | 50 | my $c = substr($data,$p,1); 51 | 52 | if ( $c eq ',' ) { 53 | my $l = $w - ( length($out) % $w ); 54 | $l = $w if $l == 0; 55 | warn "# $p ZERO-to-EOL $c [$l]\n"; 56 | $out .= "0" x $l; 57 | } elsif ( $c eq '!' ) { 58 | my $l = $w - ( length($out) % $w ); 59 | $l = $w if $l == 0; 60 | warn "# $p ONE-to-EOL $c [$l]\n"; 61 | $out .= "F" x $l; 62 | } elsif ( $c eq ':' ) { 63 | # $out .= length($out) > $w ? substr($out,-$w) : "0" x $w; 64 | $out .= substr($out,-$w); 65 | warn "# $p repeat last line\n"; 66 | } elsif ( $c eq 'z' ) { 67 | $repeat += 400; 68 | } elsif ( $c ge 'g' && $c le 'y' ) { 69 | $repeat += 20 * ( ord($c) - ord('f') ); 70 | } elsif ( $c ge 'G' && $c le 'Y' ) { 71 | $repeat += ord($c) - ord('F'); 72 | } elsif ( $c =~ m/[0-9A-F]/i ) { 73 | if ( $repeat ) { 74 | warn "# $p $repeat $c\n"; 75 | $out .= $c x $repeat; 76 | $repeat = 0; 77 | } else { 78 | warn "# $p hex $c\n"; 79 | $out .= $c; 80 | } 81 | } else { 82 | die "ABORT: offset $p data [$c]"; 83 | } 84 | 85 | warn "## $repeat [$c] out = ",length($out),$/; 86 | } 87 | 88 | my $bitmap = pack('H*', $out); 89 | warn "# graphics of ",length($data)," bytes ZPL decompressed to ",length($out)," hex and ", length($bitmap), " bytes bitmap\n"; 90 | my $pw = $row_bytes * 8; 91 | my $ph = int(length($bitmap) / $row_bytes); 92 | print "P4\n$pw $ph\n", substr($bitmap,0,$ph*$row_bytes); 93 | 94 | } elsif ( $line =~ s/^([~\^][^~\^\r\n]*)// ) { 95 | my $cmd = substr($1,0,3); 96 | if ( my $desc = $command->{$cmd} ) { 97 | warn "ZPL: $1\t$desc\n"; 98 | } else { 99 | warn "UNKNOWN: ",dump($1),$/; 100 | } 101 | $line =~ s/^[\r\n]+// && warn "## removed CR/LF\n"; 102 | } else { 103 | my $unknown = $1 if $line =~ s/^(.)//; # printer seems to ignore invalid chars 104 | warn "IGNORE: ",dump($unknown); 105 | } 106 | 107 | slurp_line; 108 | } 109 | 110 | __DATA__ 111 | ^A Scalable/Bitmapped Font 112 | ^A@ Use Font Name to Call Font 113 | ^B1 Code 11 Bar Code 114 | ^B2 Interleaved 2 of 5 Bar Code 115 | ^B3 Code 39 Bar Code 116 | ^B4 Code 49 Bar Code 117 | ^B5 Planet Code bar code 118 | ^B7 PDF417 Bar Code 119 | ^B8 EAN-8 Bar Code 120 | ^B9 UPC-E Bar Code 121 | ^BA Code 93 Bar Code 122 | ^BB CODABLOCK Bar Code 123 | ^BC Code 128 Bar Code (Subsets A, B, and C) 124 | ^BD UPS MaxiCode Bar Code 125 | ^BE EAN-13 Bar Code 126 | ^BF Micro-PDF417 Bar Code 127 | ^BI Industrial 2 of 5 Bar Codes 128 | ^BJ Standard 2 of 5 Bar Code 129 | ^BK ANSI Codabar Bar Code 130 | ^BL LOGMARS Bar Code 131 | ^BM MSI Bar Code 132 | ^BO Aztec Bar Code Parameters 133 | ^BP Plessey Bar Code 134 | ^BQ QR Code Bar Code 135 | ^BR RSS (Reduced Space Symbology) Bar Code 136 | ^BS UPC/EAN Extensions 137 | ^BT TLC39 bar code 138 | ^BU UPC-A Bar Code 139 | ^BX Data Matrix Bar Code 140 | ^BY Bar Code Field Default 141 | ^BZ POSTNET Bar Code 142 | ^CC Change Carets 143 | ~CC Change Carets 144 | ^CD Change Delimiter 145 | ~CD Change Delimiter 146 | ^CF Change Alphanumeric Default Font 147 | ^CI Change International Font 148 | ^CM Change Memory Letter Designation 149 | ^CO Cache On 150 | ^CT Change Tilde 151 | ~CT Change Tilde 152 | ^CV Code Validation 153 | ^CW Font Identifier 154 | ~DB Download Bitmap Font 155 | ~DE Download Encoding 156 | ^DF Download Format 157 | ~DG Download Graphics 158 | ~DN Abort Download Graphic 159 | ~DS Download Scalable Font 160 | ~DT Download TrueType Font 161 | ~DU Download Unbounded TrueType Font 162 | ~DY Download Graphics 163 | ~EG Erase Download Graphics 164 | ^FB Field Block 165 | ^FC Field Clock (for Real-Time Clock) 166 | ^FD Field Data 167 | ^FH Field Hexadecimal Indicator 168 | ^FM Multiple Field Origin Locations 169 | ^FN Field Number 170 | ^FO Field Origin 171 | ^FP Field Parameter 172 | ^FR Field Reverse Print 173 | ^FS Field Separator 174 | ^FT Field Typeset 175 | ^FV Field Variable 176 | ^FW Field Orientation 177 | ^FX Comment 178 | ^GB Graphic Box 179 | ^GC Graphic Circle 180 | ^GD Graphic Diagonal Line 181 | ^GE Graphic Ellipse 182 | ^GF Graphic Field 183 | ^GS Graphic Symbol 184 | ~HB Battery Status 185 | ~HD Head Temperature Information 186 | ^HF Graphic Symbol 187 | ^HG Host Graphic 188 | ^HH Configuration Label Return 189 | ~HI Host Identification 190 | ~HM Host RAM Status 191 | ~HS Host Status Return 192 | ~HU Return ZebraNet Alert Configuration 193 | ^HV Host Verification 194 | ^HW Host Directory List 195 | ^HY Upload Graphics 196 | ^HZ Display Description Information 197 | ^ID Object Delete 198 | ^IL Image Load 199 | ^IM Image Move 200 | ^IS Image Save 201 | ~JA Cancel All 202 | ^JB Initialize Flash Memory 203 | ~JB Reset Optional Memory 204 | ~JC Set Media Sensor Calibration 205 | ~JD Enable Communications Diagnostics 206 | ~JE Disable Diagnostics 207 | ~JF Set Battery Condition 208 | ~JG Graphing Sensor Calibration 209 | ^JJ Set Auxiliary Port 210 | ~JL Set Label Length 211 | ^JM Set Dots per Millimeter 212 | ~JN Head Test Fatal 213 | ~JO Head Test Non fatal 214 | ~JP Pause and Cancel Format 215 | ~JR Power On Reset 216 | ^JS Sensor Select 217 | ~JS Change Backfeed Sequence 218 | ^JT Head Test Interval 219 | ^JU Configuration Update 220 | ^JW Set Ribbon Tension 221 | ~JX Cancel Current Partially Input Format 222 | ^JZ Reprint After Error 223 | ~KB Kill Battery (Battery Discharge Mode) 224 | ^KD Select Date and Time Format (for Real Time Clock) 225 | ^KL Define Language 226 | ^KN Define Printer Name 227 | ^KP Define Password 228 | ^LH Label Home 229 | ^LL Label Length 230 | ^LR Label Reverse Print 231 | ^LS Label Shift 232 | ^LT Label Top 233 | ^MC Map Clear 234 | ^MD Media Darkness 235 | ^MF Media Feed 236 | ^ML Maximum Label Length 237 | ^MM Print Mode 238 | ^MN Media Tracking 239 | ^MP Mode Protection 240 | ^MT Media Type 241 | ^MU Set Units of Measurement 242 | ^MW Modify Head Cold Warning 243 | ~NC Network Connect 244 | ^NI Network ID Number 245 | ~NR Set All Network Printers Transparent 246 | ^NS Change Networking Settings 247 | ~NT Set Currently Connected Printer Transparent 248 | ^PF Slew Given Number of Dot Rows 249 | ^PH Slew to Home Position 250 | ~PH Slew to Home Position 251 | ^PM Printing Mirror Image of Label 252 | ^PO Print Orientation 253 | ^PP Programmable Pause 254 | ~PP Programmable Pause 255 | ^PQ Print Quantity 256 | ^PR Print Rate 257 | ~PR Applicator Reprint 258 | ~PS Print Start 259 | ^PW Print Width 260 | ~RO Reset Advanced Counter 261 | ^SC Set Serial Communications 262 | ~SD Set Darkness 263 | ^SE Select Encoding 264 | ^SF Serialization Field (with a Standard ^FD String) 265 | ^SL Set Mode and Language (for Real-Time Clock) 266 | ^SN Serialization Data 267 | ^SO Set Offset (for Real-Time Clock) 268 | ^SP Start Print 269 | ^SQ Halt ZebraNet Alert 270 | ^SR Set Printhead Resistance 271 | ^SS Set Media Sensors 272 | ^ST Set Date and Time (for Real-Time Clock) 273 | ^SX Set ZebraNet Alert 274 | ^SZ Set ZPL 275 | ~TA Tear-off Adjust Position 276 | ^TO Transfer Object 277 | ~WC Print Configuration Label 278 | ^WD Print Directory Label 279 | ^XA Start Format 280 | ^XB Suppress Backfeed 281 | ^XF Recall Format 282 | ^XG Recall Graphic 283 | ^XZ End Format 284 | ^ZZ Printer Sleep 285 | -------------------------------------------------------------------------------- /templates/105x40.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 211 | --------------------------------------------------------------------------------