Barcode Writer in Pure PostScript
Homepage: https://bwipp.terryburton.co.uk
Online demo: https://the-burtons.xyz/barcode-generator/
-
100% direct PostScript. Platform, OS and language independent.
-
A set of PostScript “named resources” that allow you to insert a barcode in the page markup as simply as:
0 0 moveto (Hello world) (version=4) /qrcode /uk.co.terryburton.bwipp findresource exec
-
Executed wholly in a PostScript printer, pre-processor/RIP (GhostScript, Distiller, Jaws, Harlequin), document management system (CUPS) or printer filter driver.
-
Your application need only emit ASCII text. No need to link to any libraries, perform pre-processing, etc. Ideal for use with both modern and legacy reporting languages.
-
Support for ~100 barcode symbologies and variants, including syntaxes such as GS1 Application Identifiers and GS1 Digital Link.
-
Free software. MIT/X Licence: Permissive, non-copyleft.
-
Not a “turn-key solution” but a developer resource akin to a library. Developers integrate it rather than run it directly.
BWIPP was not the first implementation of a pure PostScript "barcode"...
"The barcode ... has been programmed entirely in PostScript, thus the features are absolutely accurate to the resolution of the output device. The code is broken into 16 "digits", each of which begins with a thick bar; the digit's value is determined by the distance to the next thick bar and the number/placement of thin bars encountered within this span. An 8-bar "comb" pattern has been appended to the edges of the main barcode to provide good resolution reaching beyond the edges of the basic code ... It was originally printed across a full page using a Linotronic 200 printer with 1200 DPI resolution, and photographically reduced by a factor of 7 (down to 24 x 24 mm) onto a conventional 7-mil high-contrast negative, which was back-illuminated using LED's and a condenser lens."
Paradiso, J. (1994) "Testing and Development of Extended Range Straightness Monitor Systems,"
GEM [Muon Detector] Collaboration Report (SSCL), GEM-TN-93-331.
Original PS: https://github.com/bwipp/postscriptbarcode/tree/master/contrib/history/gem-muon-detector
Background
-
Began June 2004 by Terry Burton who continues as the principal developer.
-
Terry Burton is an elected lifetime member of AIDC 100 and is engaged in the development of barcode symbology standards through AIM Technical Symbology Committee, ISO/IEC JTC 1/SC 31/WG 1 and other affiliations.
-
Was a small bit of code to scratch an itch: Include Code 39 symbols in LaTeX-based invoices, logistics notes, etc.
-
In June 2004 placed 150 lines of code on personal website in case it was useful to others, but expected it to be vapourware.
-
By end of 2004 had 100s of users on the mailing list and support for ~10 symbologies.
-
Now ~100 symbologies, 1000s direct users and an unquantifiable number of indirect users. Still growing, despite PostScript language use otherwise waning.
-
Extensive features and maturity of the barcode implementations are sufficient to motivate integrators to overcome the PostScript language barrier, e.g. by cross-compiling to JavaScript.
-
Actively developed and supported since its inception but has always been maintained as a “spare time” project in the hope that it will be useful to the AIDC community. Very many late nights!
BWIPP Symbology Milestones
-
2004: Initial release in June with support for Code 39. Followed by community requests for EAN-13, EAN-8, UPC-A, UPC-E, ISBN, 2 of 5, ITF, Code 128 (UCC/EAN-128), Codabar, USPS POSTNET 4-state.
-
2005: “ISBN-13”, EAN-2/5 (add ons), Code 93, Code 11, MSI, Plessey (UK), RM4SCC, USPS FIM, AusPost, KIX.
-
2006: USPS OneCode (Intelligent Mail), Reduced Space Symbology (GS1 DataBar) family, Pharmacode.
-
2007: MaxiCode.
-
2008: Matrix ("2D") barcodes: PDF417, Data Matrix, Aztec Code, QR Code, Micro QR Code.
-
2010: Telepen, Two-track Pharmacode, BC412, PosiCode, Channel Code. ISSN, ISMN, Code 32, PZN, Code 39/93 Extended. GS1 symbols (GS1-128, ITF-14, GS1-14, SSCC-18), HIBC symbols, Deutsche Post Leitcode/Identcode.
-
2011: MicroPDF417, GS1 Composite symbols. Some mostly historic value symbols: Code One (first 2D code, by Ted Williams), Code 49, Code 16K, Codablock F.
-
Mid 2014: Optimised high-level encoding to ensure minimal symbol size for given input.
-
Late 2014: Convenience encoders: Micro QR Code, Telepen Numeric, 2 of 5 (Industrial, IATA, Matrix, COOP, Datalogic), Compact PDF417, Aztec Runes.
-
2016: Data Matrix Rectangular Extension (DMRE). Han Xin.
-
2017: GS1 North American Coupons. DotCode. UltraCode.
-
2018: Preliminary work on JAB Code. "Dotty Data Matrix" and other dotty matrix codes.
-
2019: Royal Mail 2D Mailmark.
-
2020: Rectangular Micro QR Code. Extended Channel Interpretation (ECI).
-
2021: GS1 AI syntax linting.
-
2022: GS1 Syntax Dictionary integration. Variants of QR Code and Data Matrix with GS1 Digital Link URI linting.
-
2024: Named colours, advanced colour spaces, spot colours and separations. GS1 Digital Link HRI extraction.
What is the PostScript Language?
-
Much more than a page description language.
-
Turing complete programming language focused on vector-based graphical output.
-
Stack-based, akin to Forth. Program is streamed to and “consumed” by the printer. Instructions modify the graphics state and are discarded after execution.
-
Loose distinction between code and data.
-
Refreshing: Very far from the usual programming paradigm of a Program Counter guided by tablets of stone.
What is the PostScript Language?
Very rich language (over 400 operators) with usual plethora of features:
-
Stack manipulation: dup, pop, exch, index, roll, copy, mark, cleartomark
-
Maths: add, sub, mul, div, idiv, mod, abs, neg, sin, exp, ln, floor, srand, rand
-
Boolean: true, false, eq, ne, gt, lt, ge, le, not, and, or, xor
-
Strings: string, ( … ), < ... >, length, getinterval, putinterval, search, token
-
Arrays: array, [ … ], astore, aload, length, getinterval, putinterval, copy, forall
-
Associative arrays: dict, << … >>, known, where, get, put, begin, end, def, currentdict
-
Control: if, loop, for, forall, repeat, exit
-
Exception handling: stop, stopped
-
Drawing: newpath, currentpoint, moveto, lineto, curveto, closepath, stroke, fill, image
-
Fonts: findfont, scalefont, setfont, show, stringwidth
-
Graphical state: gsave, grestore, translate, scale, rotate, transform, dtransform
-
File IO: file, closefile, readstring, writestring, flush, %stdout, %stderr, run
-
File and image filters: ASCII85, LZW (compression), DCT (lossy image compression)
-
Named resources (libraries): defineresource, findresource
PostScript language features useful for barcoding
-
“Exiting the job server loop” provides ability for state (procedures, structures, etc) to gain persistence across jobs, e.g. have a "bootstrap print job" that places barcode generation routines into the VM so that they are available for all subsequent jobs (until power cycle).
-
“Named Resources” provide ability for procedures to be packaged and stored on printer/document-manager’s disk (and cached by printer) to gain persistence across power cycles. Enhance base capabilities of the printer using only software, i.e. No barcode font chips required™.
-
“Forms” feature can cache expensive-to-RIP graphical components enabling lightweight Variable Data Printing (VDP). Render any intensive imagery then execute PostScript procedures over variable data (e.g. GTINs) supplied continuously at the tail of the datastream to create differing content with which to finalise the output (e.g. overlay barcodes onto a complex background). RIP once at fixed cost and print many variants essentially for free without the need for overlay printing.
Form caching for VDP: A Nested PostScript Forms Example
Each fern logo is a single form (F) consisting of an expensive to compute (~750 ms) fractal.
Each rectangular label is a form (L) that includes the fern logo form F and accompanying text.
Each page outline is a form (P) consisting of a watermark instance of form F and a grid of form L.
Complete pages are created by plotting form P and overlaying the variable data barcodes.
Printing takes 30 ms per page, after first page. Would be >10 secs per page with no form cache.
PostScript imaging features useful for barcoding
-
Provides true vector output all the way to the RIP. Absolutely accurate to the native resolution of the output device. Directly draw lines and modules of a barcode symbol as paths not pixels.
-
PostScript can probe the “device space” (output device properties such as pitch, orientation) so that you can perform “grid fitting”, i.e. alignment of user space lines/modules to device space pixels to avoid grazing and ensure integer-multiple mapping for bars of differing widths.
-
For future colour barcodes we can directly specify colours in RGB, CMYK, HSB colour spaces and perform separations such as in the use of spot colour processes.
Alternatively…
-
You can avoid PostScript’s imaging system and just perform the symbol bitmap generation using BWIPP then an application can import the data structure directly for custom rendering.
Barcode Imaging Issues
Anti-aliasing:
- Great for text
- Horrendous for barcodes as these require hard edges.
Barcode Imaging Issues: Pixel Grazing
"Graphics software used to create bar codes on pixel-based printers must scale each bar and space exactly to the pixel pitch of the printer being used. For edge to similar edge decodable symbologies like Code 128 the number of pixels comprising each symbol character must be a fixed and constant integer multiple of the number of modules in the symbol character.
General purpose printing software designed to support a wide range of printers should provide the user the capability of adjusting the X dimension and bar width growth or loss."
ISO/IEC 15417 (Code 128) and other specifications
Grid-fitting: Required not just for bars, also spaces.
Barcode Imaging Issues: Pixel Grazing
"Graphics software used to create bar codes on pixel-based printers must scale each bar and space exactly to the pixel pitch of the printer being used. For edge to similar edge decodable symbologies like Code 128 the number of pixels comprising each symbol character must be a fixed and constant integer multiple of the number of modules in the symbol character.
General purpose printing software designed to support a wide range of printers should provide the user the capability of adjusting the X dimension and bar width growth or loss."
ISO/IEC 15417 (Code 128) and other specifications
Lo-res, grid-fitted. Scans perfectly.
Hi-res.
Lo-res, not grid-fitted.
Not scannable due to pixel grazing!
Zoomed images:
BWIPP Imaging Milestones
-
Linear renderer (1D barcodes: EAN-13, Code 39, ...)
-
2004: stroke operator with setlinewidth.
-
2022: fill operator with polygon path. (Work around new GhostScript renderer bug.)
-
-
Matrix renderer (2D barcodes: Data Matrix, QR Code, Han Xin, …)
-
2004: image operator. Thwarted by anti-aliasing in viewers that treated it as a bitmap, i.e. fuzzy output when magnified on-screen.
-
2008: imagemask operator (“stencil”). A vector clipping mask. Initially better, but some applications became cleverer (i.e. worse!) over time, enabling anti-aliasing, e.g. MacOS Preview.
-
2014: Filled, adjacent square paths. Problem solved but resulting image is composed of many individual image components. Ⓐ
- 2016: Optimal number of filled polygon paths. Ink bleed compensation for matrix barcodes. Ⓑ
-
Ⓑ 2016
(30 polygons)
Ⓐ 2014
(226 squares)
Actual appearance
BWIPP Imaging Milestones
-
Linear renderer (1D barcodes: EAN-13, Code 39, ...)
-
2004: stroke operator with setlinewidth.
-
2022: fill operator with polygon path. (Work around new GhostScript render bug.)
Matrix renderer (2D barcodes: Data Matrix, QR Code, Han Xin, …)
-
2004: image operator. Thwarted by anti-aliasing in viewers that treated it as a bitmap, i.e. fuzzy output when magnified on-screen.
-
2008: imagemask operator (“stencil”). A vector clipping mask. Initially better, but some applications became cleverer (i.e. worse!) over time, e.g. Preview application on Mac.
-
2014: Filled, adjacent square paths. Problem solved but resulting image is composed of many individual image components. Ⓐ
- 2016: Optimal number of filled polygon paths. Ink bleed compensation for matrix barcodes.
-
2017: Now available in technicolor!
Project Hosting and Tooling
-
2004: Initially hosted code on personal website.
-
2006: Moved hosting to Google Code (first subversion, later git).
-
2013: Migrated hosting to GitHub foreseeing the closure of Google Code.
-
Good news - more eyes on the commit diffs improves code review!
-
Bad news - GitHub stopped showing diffs of non-generated PS files (treats them as binary). Fewer eyes on… https://github.com/github/linguist/issues/2962. Please nudge this issue!
-
-
2014: Travis CI integration:
-
Continuous Integration for all commits. Does it build and pass tests?
-
(2020: Created dedicated PostScript unit test framework.)
-
-
Continuous Delivery: Build and uploads tarballs to GitHub Releases when a tag is pushed.
-
-
2016: openSUSE Build Service integration:
-
Automated distribution packaging (deb, RPM, Arch). https://goo.gl/422q5B
-
-
2020: Migrated CI and CD pipelines from Travis to GitHub Actions.
Development Priorities
The author is in full-time employment and his days are busy doing non-barcoding things...
… but what about evenings and weekends?
-
Critical bug fixes
-
Features being sponsored *
-
Integrating contributed code
-
What the author finds interesting or fun
-
Wish list items that people are shouting about
-
Anything else (may never get done!)
* For core code the sponsor agrees to assign copyright to the author and all development will be released in the main corpus of code under the project’s current license.
User Support
-
Primary source of documentation is the GitHub wiki (Markdown format). Commit access available on request (feel free to improve it).
-
Automated conversion of Markdown to PDF format via LaTeX using Pandoc to create documentation suitable for print. https://goo.gl/b4eidU
-
-
Community support is best efforts and code-centric.
-
Support and issue tracker.
-
-
Support is available on a commercial basis from Terry Burton Consulting Ltd:
Third-Party Frontends and Uses
Easy to use third-party “frontends” are available which package BWIPP as an application, plugin or more conventional development library.
-
LaTeX - pst-barcode module for PSTricks. Direct use within a TeX document.
-
BWIP-JS - Barcode Writer in Pure JavaScript. A cross-compilation of the PostScript into JavaScript and executed within a browser or hosted via a Node.js server.
-
Integration libraries for Python (treepoem), Perl and Ruby languages.
-
SAP ABAP and Smart Forms driver.
-
Scribus barcode generator plugin. Directly generate barcodes within the DTP application.
-
Vendored into commercial desktop applications, e.g. Label LIVE.
-
Vendored into Adobe InDesign plugins, e.g. Soft Horizons Chartbot, others under NDA.
-
Embedded within several models of high-end laser printers (more NDAs).
-
Is a test target for xpost2, a minimal PostScript interpreter.
Many other uses, both open source and commercial.
Contributors - Thanks!
Martin Bailey
Jean-François Barbeau
Eric Belshaw
Tim Brunson
Hann-Huei Chiou
John Desrosiers
Lars Dɪᴇᴄᴋᴏᴡ
Alexandre Fiori
Chapman Flack
gitlost
Anders Hammarquist
Matthew Harmon
Adrian Head
Christian Hitz
Bue Jensen
Ray Johnson
Janos Juhasz
Reinhold Kainhofer
Gerd Knop
Michael Landers
Ross McFarland
Rudolf Meier
Greg Menke
Matthew Newton
Harald Oehlmann
John Reiser
Herbert Voß
Jörg Walter
Community
-
Numerous valuable contributions over time.
-
Supporters tend to come and go – solve their problem then move on.
-
Difficult to build an active community around such a specialised project.
-
Tiny active developer community: Succession is an unsolved problem.
How to Help
- Use it for fun and/or profit.
-
Enjoy learning the PostScript language.
- Deep dive into barcode encoding. Most reviewers agree that the implementations are the best that they've seen.
-
Fixes and other code contributions are most welcome, including improved documentation.
-
Develop against it. Test against it. Transliterate the encoder implementations into your non-PostScript projects - just give credit and report any bugs that you find!
-
Sponsor a feature (see open issues: https://github.com/bwipp/postscriptbarcode/issues)
-
A symbology. Specifications and resource kits often cost in excess of £500 and may take several weeks of (spare time) development:
- JAB Code, Ultracode, ...
- Imaging improvements
- Anything else that users need.
-
A symbology. Specifications and resource kits often cost in excess of £500 and may take several weeks of (spare time) development:
ISBN 0-911261-12-5 (1997)
Comprehensive history.
Extensive symbology reference.
Biographies of key players.
ISBN 0-911261-07-9 (1994)
Symbologies and applications.
Technology considerations.
Deployment case studies.
Online Discussion and Learning Materials:
-
PSTricks - dvips/*.pro files make a great PS graphics cookbook
Barcode Writer in Pure PostScript
Homepage: https://bwipp.terryburton.co.uk
Online demo: https://the-burtons.xyz/barcode-generator/
Barcode Writer in Pure PostScript
By Terry Burton
Barcode Writer in Pure PostScript
- 66,612