Differences From BWIPP

metafloor edited this page Sep 28, 2017 · 2 revisions

For the vast majority of uses, bwip-js and BWIPP behave identically. For example, if you supply the same values in the bwip-js demo and the BWIPP online bar code generator, you will get the same image.

The primary differences are with fonts and background color.

OCR Fonts

bwip-js uses embedded versions of the OCR-A and OCR-B fonts. Barcodes and the OCR fonts are like chocolate and hazelnut; they were meant to go together. Unfortunately, most PostScript environments do not provide the OCR fonts and must fallback to Courier, Helvetica, and other less-than-ideal typefaces.

The following two images show the differences in typeface. The image below was rendered by bwip-js:

bwip-js ISBN

And the next image was rendered using BWIPP with Ghostscript:

BWIPP/Ghostscript ISBN

The font functionality is implemented with the following logic:

  • OCR-B is used as the default font for all barcodes.
  • OCR-A is used for the extra text on the ISBN, ISMN and ISSN symbols.

These defaults can be overridden using BWIPP options. The fonts are known to the PostScript emulation as OCR-A and OCR-B. For example, to switch the font to OCR-A, you would specify the option:


For the text above the barcode on the ISBN, ISMN, and ISSN symbols, the font can be changed using isbntextfont, ismntextfont, and issntextfont, respectively.

Background Color

A second difference between BWIPP and bwip-js rendering occurs with the backgroundcolor option. The BWIPP implementation of background color is a bit inconsistent. For some bar code types, the background color extends into the human readable text, and for others, it does not. bwip-js does not implement BWIPP's background color handling (it is commented out in the PostScript rendering logic). Instead, the front-end interfaces explicitly override the option and extend the background color to cover the entire image, including all human readable text.

The first/left image in each pair is from BWIPP using ghostscript, the second from bwip-js.

BWIPP EAN-13 bwip-js EAN-13

BWIPP Code128 bwip-js Code128


By default, if the backgroundcolor option is not specified, bwip-js renders the image with a transparent background.

parse Option

There is a minor incompatibility between the parse and parsefnc options. When specifying both options, you must protect carets used to prefix the parsefnc sequences from the parse option. For example, your bar code requires both parse parsefnc as options and the text contains:


The leading caret of the ^FNC1 sequence will be mis-processed by the parse option and cause a runtime error. The BWIPP-compatible solution is to replace the caret in the ^FNC1 sequence with the parse compatible sequence:


94 is the ASCII value for caret. bwip-js avoids this issue by processing the parse option prior to BWIPP code execution, and uses the JavaScript RegExp /\^\d\d\d/ to only convert entities that are meant to be converted. The conversion will also throw an error if the value represented by the three digits is greater than 255.

One additional benefit from this approach is the parse logic in the BWIPP code (which appears multiple times) is removed prior to cross-compiling, reducing code size.

Custom Renderers

The three BWIPP renderers renlinear, renmatrix and renmaximatrix have been replaced by versions customized for bwip-js. Specifically, all three previously used postscript eval semantics to convert a color string in either rrggbb or ccmmyykk format to its binary form. Supporting this option required specialized code to be added to bwip-js. By replacing the evals (and the setanycolor function bodies) with an internal setcolor operator, a considerable amount of code was eliminated (with a minor improvement in performance as well).

As mentioned above, the backgroundcolor option was also eliminated from the three renderers, reducing code size by a small margin.

The renmatrix renderer is based on an older version of BWIPP. The older version used the postscript imagemask operator to render the 2D patterns. This was fine for bwip-js as the implementation simply scaled each pixel in the mask proportionally. Other users of BWIPP had problems with imagemask as their postscript environments would use an image scaling algorithm that produced "fuzzy" images. The latter version in BWIPP draws each "dot" in the 2D bar codes as distinct graphics paths followed by a fill, which caused a major performance hit in bwip-js.

The most significant change by far is in the renmaximatrix code. This renderer is completely custom to bwip-js. The original renderer drew hexagons and circles to render the maxicode symbol. This required a significant amount of supporting code that was only used by this one renderer. And to be perfectly honest, the code did a lousy job drawing those hexagons and circles. To draw them with high precision would require an amount of code totally out of proportion to need.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.