I continue the topic of printing PDF documents from under .NET.
In principle, printing a document is not difficult, there are even ready-made solutions. Difficulties arise when you need to control certain print settings. In my practice, I was faced with the task of implementing a mini-typography - when, when printing documents, you need to specify from which tray to take another sheet, i.e. print documents by templates. First of all, I tried to find ready-made solutions, but not finding anything suitable, I began to invent my own.
')
The first thing that came to mind was to render the document pages in raster images and print them using standard .NET tools. It’s good that the PrintDocument class allows you to change the printer tray on the fly. I wrote about this approach in the
previous article.As soon as the first application started working, a significant drawback to this solution was revealed. After converting PDF into a picture, the file was swollen to enormous size, so printing went on for a very long time. At the same time, print volumes continued to grow, and I decided to find another way to find it.
I was helped by the PCL printer control language from Hewlett-Packard. On the Internet, information on it turned out to be extremely small, not to mention runet. The only intelligible description is the official specification. No sooner said than done. He launched the HEX editor + utility from HP JetAsm and began to study PCL. The devil is not so terrible as he is painted. The language, although binary, is fairly simple and logical. As a result, after a couple of hours I assembled a test application. And for the good of all to whom it can be useful and interesting, I will tell you a little about PCL.
Wikipedia says:
“PCL (from the English Printer Command Language) is a printer control language developed by Hewlett-Packard. In the first version, it was just a set of commands for printing ASCII characters, now, in PCL6 and PCL-X versions, it became possible to print in color, as well as print images, but this language is rarely used outside of Microsoft Windows and HP-UX ”
From myself I’ll add that this is a binary and stack language - incoming data is put onto the stack, and when an operator appears, data is taken from the stack as arguments of the operator.
The official description of PCL is on the Internet. The free utility from HP JetAsm will also help to understand and validate the contents of PCL files. Her and other useful files can be obtained from the official site without registration. To do this, click
on the link , click SDK-> Public and find the files of interest.
First we need somewhere to get the pcl file. Known from the
previous article utility GhostScript out of the box can convert PDF to PCL. You can do this with the command:
gswin64c.exe -o example.pcl -sDEVICE=pxlmono example.pdf
Thus, without unnecessary movement, we received a PCL file that can be sent to the printer as RawData.
However, if it is necessary not only to print the document, but also to distribute it among the trays of the printer (for example, according to some pattern), then you will have to modify the generated PCL file accordingly. For this you need to deal with its device.
So, open the PCL file in any HEX editor. I used
WinHex .
The language has a hierarchical structure. But first, the device needs to understand that the PCL data stream will continue to be transmitted, for this is the initialization string.
The hierarchy of PCL operators is as follows:
<> <> </> <> </> <> </> </>
In this case, there may be several sessions, and page elements may be nested in other elements.
Let's start in order
I have already said that at the beginning of the thread there is a standard line. It is for her that the device determines that the data in the PCLXL format will be transmitted further. The initial string length is 99 bytes.
Next comes the PCL data stream. To start describing the elements of the document, the session must be opened, for this there is a
BeginSession command with the code 0x41. This and other command codes can be found in the manual. In one file there can be one or several sessions, but more often one.
We also look at the arguments that need to be passed to the BeginSession.
The arguments have the following structure: [data type] [data] [attribute type] [attribute]
UnitsPerMeasure is the resolution of the working area x and y, has the data type uint16_xy is a structure of two two-byte words.
Measure - enumeration of units in which we will work {eInch | eMillimeter | eTenthsOfAMillimeter}
ErrorReport is an enumeration that defines how the device will handle errors.
BeginPage
The page is initialized in the same way. It is the
BeginPage operator
that allows
you to set the duplex mode and specify the tray from which the paper will be taken.
Let us analyze the arguments of the operator BeginPage.
Orientation - page orientation, can be {ePortraitOrientation | eLandscapeOrientation | eReversePortrait | eReverseLandscape}
MediaSize - page size, listing, in our case eA4Paper. Instead of the MediaSize type, there can be
CustomMediaSize ,
CustomMediaSizeUnits .
MediaSource - the source of the paper.
0 - eDefaultSource
1 - eAutoSelect
2 - eManualFeed
3 - eMultiPurposeTray
4 - eUpperCassette
5 - eLowerCassette
6 - eEnvelopeTray
7 - eThirdCassette
1-248 - External Trays
Instead MediaSource may be
MediaType with the name of the source.
SimplexPageMode - single page printing mode, the value must be eSimplexFrontSide = 0
Instead of SimplexPageMode can be
DuplexPageMode or
DuplexPageSide .
DuplexPageSide - prints one page on one sheet, but you can set on which side of the sheet {eFrontMediaSide | eBackMediaSide}
DuplexPageMode - two consecutive pages are printed on two sides of one sheet, you can set the values eDuplexHorizontalBinding = 0 and eDuplexVerticalBinding = 1
And all this ends with the command BeginPage with code 0x43
I hope the principle is clear. This is enough to develop the application and modify the PCL file so that you can change the Duplex - Simplex mode and specify which tray to pick up the paper from. To do this, you need to find the declaration of the next page in the file and change it as necessary.
I will tell you about the implementation of the PDF printing application in the vector following the template in the next article.
If there are inaccuracies or need more details, please write about it in the comments.
Cycle of articles:
Raster approachVector approach theoryVector approach practice