How do I send data to a modern printer? PDF, PostScript, HPGL, etc How do I send data to a modern printer? PDF, PostScript, HPGL, etc windows windows

How do I send data to a modern printer? PDF, PostScript, HPGL, etc


'So, for example, in Postscript you can make a loop and say "print this circle 50,000 times", moving its exact location around. In PDF my understanding is that you can't do this, you have to specify each and every circle as a separate "object".'

Actually, the truth is a bit more towards the middle ground in between the two extremes you described.

  1. It's true: unlike PostScript, PDF is not a programming language (let alone a Turing-complete one), and you cannot define "loops".

  2. But also, you do not have to specify each and every circle (or embedded image, or other graphical object) separately. You can well define how to draw a circle (or image, or whatever) once, and then re-use that definition in other spots of the page or the PDF document. This is called "referencing an object". When you re-use an object, you can set different of its properties differently (color, scaling, rotation) by changing some current "enviromental" definitions (such as the graphics state which includes the CTM, the current transformation matrix).


About some of your other points:

  • No, there never were only two types of printers, HPGL and PostScript.

  • Even in the olden days, there were a dozen or so different 'printer languages'. PCL was more popular than HPGL even. Not to forget all the proprietary inventions of different printer languages. Ever heard of AFP, Advanced Function Printing? This language printed -- and still prints! -- more sheets of paper than PostScript ever did. It's no longer proprietary, but it was invented by IBM for host printing laaaarge runs of variable data, for billing purposes mainly... Ever heard of ESC/P? KPDL? XPS?

  • Yes, you can still send HPGL to a printer -- but not to every printer. The printer has always to be empowered for at least one of the languages you are able to generate and send off.

  • Yes, there are printer models nowadays which can consume PDF directly. But they are still not the predominant type. Some of them "cheat" and still have as their main built-in interpreter a PostScript engine: these take the PDF and silently convert it to PostScript first. Others can process PDF without the fallback to PostScript.


'In Windows, I know the "standard" way to print, which is to query device capabilities and request a device context, then you can draw lines, shapes and text using Windows calls on that context.'

Don't assume that the term 'device context' does mean that Windows talks to the printer hardware directly in order to query the capabilities and request the device context. Sometimes it does, sometimes not. It always relies on some software called a 'printer driver' (which also controls which printer language to print data should be converted to). The printer driver may be able to query the device and ask "Do you have a duplexer unit? Do you have a stapling device?" and then generate the required device context itself for the job.

Only a very modern approach, IPP Everywhere, developed by the 'Printer Working Group', will be able to get rid of most of what the olden model-specific printer drivers had to do, and will start to rely mostly on direct interrogation of the device before 'driverlessly' finalizing the exact print data to be passed to the physical device.

But IPP Everywhere is not yet widely popular, neither with vendors, nor with admins, nor with users. But it will, once the PCs are forgotten and 95% of computing devices will be super-mobile...


Since the OP didn't like my (or any other) original answer well enough to accept it he meanwhile even granted a bounty.

Let me try to add whatever may have been missing from my original answer.


"In the old days, there were two main types of printers: HP printers that understood HPGL and Postscript printers."

Even in the old days, there were more types of printers, or rather: page description languages... but PCL, HP/GL and PostScript may have been the most important for most people having to deal with printing technologies.

"So, you could send your print out in either of those two languages and the printer would convert your code to dots on the page."

No, this did not work in all cases.

This only works when the printer understands both these languages (what some of the more expensive HP models did).

Some printer models did (even in the old days) understand only HP/GL. Some did only understand a specific version of PCL (PCL, FWIW, is a complete family of printer languages consisting of about a dozen members: and some of the newer ones have hardly any genetic common ground with the older ones -- other than that HP marketing picked to call them PCL6 or PCL XL).

"So, how do modern printers work? Can I still send HPGL/PCL to a printer"

Yes, this works still the same:

  • If your "modern printer" understands HP/GL, you can send HP/GL data to it.
  • If it understands PCL, you can send PCL.
  • If it understands PostScript, you can send PostScript.
  • If it understands PDF, you can send PDF.
  • If it understands XPS (ever heard of this?!?), you can send XPS.
  • However, if it only understands PCL3 (well, then it isn't a modern printer anyway :), you cannot send PCL6e...

If the device understands any combination of these languages, then you are free to send whatever it understands.

"Now, as I understand the PDF format it is similar to Postscript, but it is not a language like Postscript and can only include 'objects'. So, for example, in Postscript you can make a loop and say 'print this circle 50,000 times', moving its exact location around. In PDF my understanding is that you can't do this"

You are right, PDF (unlike PostScript), is not a programming language. It was a design decision, that PDF should not understand loop or conditional constructs (while PostScript does -- PostScript is even Turing-complete as a programming language, meaning: anything that is programmable at all, can be written as a PostScript program).

So, while you can still define a circle (or even a very complex graphical object) only once as a PDF object:

  • You cannot express a long loop through a very short programmatic statement telling the renderer to show this object during each iteration.
  • Instead you have to manually state each iteration separately (where you can then call for the pre-rendered object to be shown).

But you are not right when stating "the PDF format ... is similar to Postscript". It is not. The PDF is derived from the same graphics model as PostScript had originally established. But that's about it.

PDF keywords for operators are different. The structure of a typical PDF is completely different from a PostScript.

Most importantly, PDF extended that graphics model it inherited from PostScript (plus, it added some other aspects for a typical electronic document). It evolved in several directions:

  • Over time, it introduced more color spaces.
  • It supports more font types.
  • It implemented 'transparency' features for all drawn objects.
  • It came up with the concept of 'layers' ("optional content groups", OCG, in PDF parlance).
  • It introduced interactive elements (buttons, links, hyperlinks, form fields).
  • It supports more different compression schemes.
  • It can make use of a much richer set of document metadata.
  • It introduced ICC color profiles and a full-scaled ICC color management.
  • ...plus some more.

"Are all printers now standardized on Postscript?"

No.

If anything, then more modern printers prefer PDF over PostScript (while they still may keep PostScript processing capabilities as a fallback option). But better ask your vendor, or study their marketing manuals.

"If so, does that mean my best option is to generate Postscript and then send that raw to the printer?"

That has never been your best option anyway, not even in the "old days"!

After all, printing a more-complex-than-just-one-page job in most cases involved not just to ask for the number of copies, but...

  • ...you also wanted to select the pager size, maybe even select a specific tray for the first page (with the masthead letter or blue cover paper), another tray for the main body of pages and a third tray for the last sheet;
  • ...you wanted to tell the device to staple each set, or to punch holes into each sheet;
  • ...you wanted to center-fold and saddle-stitch some jobs in order to get finished pamphlets,
  • ...and what-not.

These job features cannot necessarily be controlled by "raw PostScript". To control specific print job options with most PostScript printer models you had two ways:

  1. Insert << ...vendor-specific or generic PS-code...>> setpagedevice statements of PostScript snippets into the job data stream, either on document or on individual page levels.

    What specific setpagedevice is needed for a specific feature to be executed by a specific printer model is defined in the PPD (short for PostScript Printer Description) file of the respective PostScript printer driver. This .ppd file has to be provided by the respective vendor alongside its printer driver(s). PPD is a file format specification defined by Adobe. In a way it extends the PostScript language and allows vendors to "invent" their own features when it comes to complex job setups.

  2. Prefix the actual print data (send as PostScript) with a PJL (short for Printer Job Language) header, consisting a few (or up to several dozen) lines to invoke specific job features.

PJL was originally invented by HP and used for PCL, but it was quickly adapted by other vendors for other printer languages. So nowadays you can use PJL header lines for most printers which can print PostScript, PCLxx, HP/GL or PDF, because it is commonly supported by most vendors. In this case the last PJL-line tells the printer what language the real job data is: PostScript, PCLxxx, PDF, HP/GL, whatever... by a statement like:

    ESC%-12345X@PJL ENTER LANGUAGE = PostScript 

"If I do send Postscript, do I have to tell the printer somehow that it is Postscript somehow?"

See last-but-one paragraph above if you pre-fix your job with a PJL header.

For a pure PostScript printer, you'd probably rather use <<..>>setpagedevice statements. And such a printer will automatically understand PostScript...

It would also help if you listed the printer models you have at your disposition.

"In Windows, I know the 'standard' way to print, which is to query device capabilities and request a device context, then you can draw lines, shapes and text using Windows calls on that context."

This is actually how it works also with PostScript printers on Windows (well, the newer XPS or OXPS-based printing workflows since Windows 8 are a bit different...). Typically, the "device capabilities" are known to and escrowed by the respective printer driver. When you're done to "draw lines, shapes and text using Windows calls" the driver will convert these calls to PostScript and send it to the printer.

That is different from how it works on Linux, Unix or Mac OS X:

  • On Linux (and Unix) every application has to generate the PostScript page descriptions which it wants to send to the printer all by itself. There is no "driver" helping to do that. If the final destination printer is not PostScript capable, CUPS will auto-convert that to the vendor- or model-specific page description format from the PostScript it received. (Some applications may be capable of generating one of the PCL languages.)

  • On Mac OS X, the applications typically generate PDF as a print spool format (and CUPS auto-converts this file to a different printer language, based on the vendor's printer driver which typically includes a pdf-to-someting CUPS filter as needed).

"However, obviously this is extremely primitive compared to Postscript (or HPGL/PCL)."

I do not understand why you should describe this as "extremely primitive" in this context.

"Is there a way I can either communicate directly with the printer driver, or tell Windows: 'here is my Postscript code, please pass it to the printer for printing'?"

As I said before: on Windows, an application typically does not generate its PostScript code itself [^1] if it wants to print to a PostScript printer, nor does it generate any other printer specific format itself (with the exception of the final device being an XPS-printer). Typically, it generates EMF as a spooling format, and lets the print subsystem (and printer driver) take care of any conversions that may be needed.

Or are you saying: "I have this ready-made PostScript file (generated elsewhere) which I want to print to a PostScript printer?" If so, then simply run a command like lpr -S remoteserver -P printername "-o l" jobfile.ps from a DOS box.

Having said that -- yes, there are at least two non-printer-driver ways which you could employ to query your print device:

  1. SNMP. If your device has a network (ethernet/wifi) interface and understands the Simple Network Management Protocol you may be able to query it through this channel and get returned answers to whatever SNMP-type of questions you ask. In plain language (SNMP parlance looks a bit different):

    • What are your current ink levels?
    • What is the maximum media size you can handle?
    • How many paper trays do you have?
    • What is the fill level of tray 1?
    • How many pages did you ever print in your live time? How many since the last boot-up?
    • Which printer languages can you process?
    • Which print data transfer protocol do you support? HPJetDirect/AppSocket? LPR/LPD? IPP?
    • Do you have harddisk space available?
    • How much RAM do you have?
    • Which other print clients are connected to you currently?
    • ...and many more.
  2. PJL queries. Some of the above information can also be retrieved by sending a few lines of simple PJL statements to the printer (and evaluate the responses).

  3. IPP queries. The Internet Printing Protocol also supports queries of device capabilities (if the devices can talk IPP).

Once more: "Is there a way I can ... tell Windows: 'here is my Postscript code, please pass it to the printer for printing'?"

You could even bye-pass Windows completely and use the netcat.exe utility (sometimes also called nc.exe) to send a jobfile to a printer:

  • Send a PostScript job to a network printer that waits on TCP port 9100 for incoming jobs:

    cat filename.ps | netcat.exe -h printer-ip-address-or-hostname -p 9100

    The same of course for PCL or any format jobs... IF the printer knows this format. Which exact TCP port you need to address depends on your specific model (look it up in the manual). How you create the PostScript, PCL or whatever file for the printer is up to you.


[^1] ...with the exception of some Adobe Programs like Acrobat, which can indeed generate their own PostScript.


I think of pdf as compiled postscript basically the same stuff if not the same stuff just one is compiled into binary blobs and the other is ascii.

No not all printers speak postscript, thankfully, they tend to charge extra for that when you can have it run on your computer for free and use less resources and print faster. (or on a cheap spooler)

PCL is pretty common on non-HP printers as well as HP. But there is no universal answer. You still have to go printer by printer and see which one that supports and/or what was purchased as an add on for it and then from that list what the admin has enabled on it. then of course the versions of whatever languages is speaks.

this is what CUPS is all about. one way to abstract and hide those details.