bwipp / postscriptbarcode

Barcode Writer in Pure PostScript
https://bwipp.terryburton.co.uk
MIT License
462 stars 64 forks source link

Rotated Barcodes #264

Closed PDFDeveloper closed 5 months ago

PDFDeveloper commented 5 months ago

I have a PowerShell Wrapper for generating PDF Files from PostScript. I wanted to add barcodes into the mix, so I added functionality to use the BWIPP. However, I have come across an issue I can't seem to resolve. Namely, rotation of barcodes - while they all "rotate" some rotate more than others. For example if I rotate an ISBN barcode, it results in a rotated page if I use the option "includetext" and if I don't, the barcode rotates as expected. Here is a sample of my test code.

</PageSize [100 150]>> setpagedevice % Include the BWIPP resource, either directly or from PS (barcode.ps) run % Now make the calls to BWIPP /Helvetica findfont 10 scalefont setfont

% This would rotate the resulting PDF Page %gsave % 90 rotate % 50 -50 moveto .25 .25 scale (978-1-56581-231-4) (includetext) /isbn /uk.co.terryburton.bwipp findresource exec %grestore

% This keeps the selected orientation gsave 90 rotate 50 -50 moveto .25 .25 scale (978-1-56581-231-4) () /isbn /uk.co.terryburton.bwipp findresource exec grestore showpage

So my question is - what do I have to do to create a rotated barcode, like ISBN (and I assume EAN variants) that include the text? Thanks in advance.

PDF Dev

terryburton commented 5 months ago

Please provide a minimum, complete PS document that demonstrates your issue.

PDFDeveloper commented 5 months ago

Terry,

The following BWIPP_1 rotates the PDF Page.

<</PageSize [100 150]>> setpagedevice
% Include the BWIPP resource, either directly or from PS
(barcode.ps) run
% Now make the calls to BWIPP
/Helvetica findfont 10 scalefont setfont
gsave
    90 rotate
    50 -50 moveto .25 .25 scale (978-1-56581-231-4) (includetext) /isbn /uk.co.terryburton.bwipp findresource exec
grestore

The following code BWIPP_2 doesn't rotate the page

<</PageSize [100 150]>> setpagedevice
% Include the BWIPP resource, either directly or from PS
(barcode.ps) run
% Now make the calls to BWIPP
/Helvetica findfont 10 scalefont setfont
gsave
    90 rotate
    50 -50 moveto .25 .25 scale (978-1-56581-231-4) () /isbn /uk.co.terryburton.bwipp findresource exec
grestore

I used 'ps2pdf' to convert the above snippets and the results are different. Here (hopefully) is a screenshot of the PDF Internals. As expected both PDFs have the same media size [100 150] and while the content streams differ (for the additional markup associated to (includetext), the first has a rotate 90 assocatied to the page.

RotatedBarcodes

PDFDeveloper commented 5 months ago

I ran the code (after a C&P of barcode into the snippet) and processed that with the Acrobat Distiller - it worked as expected. So my PostScript appears correct and makes me think this could be a GhostScript issue. The downside is that Acrobat Distiller other "limitations" ....

terryburton commented 5 months ago

You're getting stung by GhostScript's AutoRotatePages heuristic that uses the flow of text on a page to set the orientation. See https://superuser.com/a/156265/263960.

You can disable this with:

ps2pdf -dAutoRotatePages=/None ...
PDFDeveloper commented 5 months ago

Would be interesting to understand why this "does what it does" with Ghostscript. I'd prefer to go down that route rather than Distiller.

terryburton commented 5 months ago

GhostScript's auto rotate pages heuristic has existed for more than twenty years but the priority between the majority text orientation heuristic vs explicit DSC comments has changed back and forth, with the current behaviour intended to match that of Distiller:

commit fd75e1678500f1ba60296ddf8fbb17e60aedcd6d
Author: Ken Sharp <ken.sharp@artifex.com>
Date:   Fri Jun 24 10:28:39 2016 +0100

    Match Acrobat's use of AutoRotatePages and DSC

    When AutoRotatePages is set to anything except /None Acrobat will
    honour DSC Orientation comments and use them in preference to the
    heuristically determined value, which we weren't doing.

    This commit matches Acrobat, including the ability to have the heuristic
    override the DSC comments by setting -dParseDSCComments=false.

    The documentation is updated and now correct, including mentioning that
    the heuristic can be preferred by turning off DSC parsing.

From https://ghostscript.readthedocs.io/en/latest/VectorDevices.html#setting-page-orientation:

Setting page orientation

By default Ghostscript determines viewing page orientation based on the dominant text orientation on the page. Sometimes, when the page has text in several orientations or has no text at all, wrong orientation can be selected.

Acrobat Distiller parameter AutoRotatePages controls the automatic orientation selection algorithm. On Ghostscript, besides input stream, Distiller parameters can be given as command line arguments. For instance: -dAutoRotatePages=/None or /All or /PageByPage.

When there is no text on the page or automatic page rotation is set to /None an orientation value from setpagedevice is used. Valid values are: 0 (portrait), 3 (landscape), 2 (upside down), and 1 (seascape). The orientation can be set from the command line as -c "<</Orientation 3>> setpagedevice" using Ghostscript directly but cannot be set in ps2pdf.

Ghostscript passes the orientation values from DSC comments to the pdfwrite driver, and these are compared with the auto-rotate heuristic. If they are different then the DSC value will be used preferentially. If the heuristic is to be preferred over the DSC comments then comment parsing can be disabled by setting -dParseDSCComments=false.