由于楼主不太喜欢我的(或任何其他人的)原始答案,因此他甚至授予了赏金。
让我尝试添加可能缺失的内容到我的原始答案中。
在早期,有两种主要类型的打印机:理解HPGL的惠普打印机和Postscript打印机。即使在早期,也有更多类型的打印机,或者说是页面描述语言...但对于大多数需要处理打印技术的人来说,PCL、HP/GL和PostScript可能是最重要的。因此,您可以使用这两种语言之一发送打印输出,打印机会将您的代码转换为页面上的点。但并非所有情况都适用,仅当打印机理解这两种语言时才可行(某些更昂贵的惠普型号可以实现)。
一些打印机型号(即便在旧时代)只能理解HP/GL。有些则只能理解特定版本的PCL
(PCL是一个完整的打印机语言家族,由大约十几个成员组成:其中一些较新的成员与旧成员几乎没有任何遗传相似之处,除了HP营销决定将它们称为PCL6或PCL XL之外)。
“那么现代打印机是如何工作的?我仍然可以向打印机发送HPGL/PCL吗?”
是的,这仍然有效:
- 如果你的“现代打印机”能够理解HP/GL,那么你可以向它发送HP/GL数据。
- 如果它能够理解PCL,你可以发送PCL。
- 如果它能够理解PostScript,你可以发送PostScript。
- 如果它能够理解PDF,你可以发送PDF。
- 如果它能够理解
XPS
(你听说过吗?!?),你可以发送XPS。
- 但是,如果它只能理解PCL3(那么它就不是一台现代打印机:),你不能发送PCL6e...
如果设备能够理解这些语言的任何组合,那么你可以自由地发送它所理解的内容。
“现在,我了解PDF格式与Postscript类似,但它不像Postscript那样是一种语言,只能包含'对象'。例如,在Postscript中,你可以创建一个循环并说'打印这个圆形50,000次',同时移动它的确切位置。在PDF中,我的理解是你不能这样做。”
你说得对,PDF(与PostScript不同)不是一种编程语言。这是一个设计决策,PDF不应理解循环或条件结构(而PostScript可以-PostScript甚至作为一种编程语言是图灵完备的,这意味着:任何可编程的东西都可以编写成一个PostScript程序)。
因此,虽然您仍然可以将圆(甚至非常复杂的图形对象)定义为PDF对象:
- 您不能通过非常短的编程语句来表达长循环,告诉渲染器在每次迭代期间显示该对象。
- 相反,您必须手动分别声明每个迭代(在那里您可以调用预先呈现的对象来显示)。
但是当您陈述“PDF格式...类似于Postscript”时,您并不正确。它不是。 PDF源自与PostScript最初建立的相同的图形模型。但就这些而言。
PDF运算符的关键字是不同的。典型PDF的结构与PostScript完全不同。
最重要的是,PDF扩展了它从PostScript继承的图形模型(此外,它还添加了一些其他方面,以适合典型的电子文档)。它朝着几个方向发展:
- 随着时间推移,它引入了更多的颜色空间。
- 它支持更多字体类型。
- 它为所有绘制的对象实现了“透明度”功能。
- 它提出了“图层”的概念(PDF术语中的“可选内容组”,OCG)。
- 它引入了交互式元素(按钮、链接、超链接、表单字段)。
- 它支持更多不同的压缩方案。
- 它可以利用更丰富的文档元数据集合。
- 它引入了ICC颜色配置文件和全面的ICC颜色管理。
- ...还有一些其他的特性。
"现在所有的打印机都是基于Postscript标准吗?"
不是的。
如果说有什么的话,现代的打印机更喜欢PDF而不是PostScript(虽然它们仍然可能保留PostScript处理能力作为备选选项)。但最好向您的供应商咨询,或者研究他们的营销手册。
"如果是这样,那么我的最佳选择是生成Postscript,然后将其原始发送到打印机,对吗?"
那从来不是您最好的选择,即使在“旧日子”里也不是!
毕竟,大多数情况下,打印比单页复杂的工作不仅涉及要求副本数量,还需要...
- ...您还想选择页面大小,甚至为第一页(带有标头信件或蓝色封面纸)选择特定的托盘,为主体页面选择另一个托盘,为最后一张纸选择第三个托盘;
- ...您想告诉设备将每个集合装订起来,或者在每张纸上打孔;
- ...您想中心折叠和鞍钉一些工作,以获得成品小册子,
- ...等等。
这些作业功能不一定可以通过“原始PostScript”进行控制。要使用大多数PostScript打印机型号控制特定的打印作业选项,有两种方法:
将PostScript代码片段中的<< ...vendor-specific or generic PS-code...>> setpagedevice
语句插入作业数据流中,可以在文档或单个页面级别上进行。
要执行特定功能所需的特定setpagedevice
是由相应的PostScript打印机驱动程序的PPD
文件定义的。这个.ppd
文件必须由相应的供应商与其打印机驱动程序一起提供。 PPD是由Adobe定义的文件格式规范。在某种程度上,它扩展了PostScript语言,并允许供应商在复杂的作业设置方面“发明”自己的功能。
在实际打印数据(以PostScript发送)之前,用包含几行(或多达几十行)以调用特定作业功能的PJL
(简称打印机作业语言)头部对其进行前缀。
PJL最初由惠普公司发明并用于PCL,但很快被其他供应商用于其他打印机语言。因此,现在大多数支持PostScript、PCLxx、HP/GL或PDF的打印机都可以使用PJL头行,因为它通常得到了大多数供应商的支持。在这种情况下,最后一条PJL行告诉打印机真正的作业数据是什么语言:PostScript、PCLxxx、PDF、HP/GL等等,通过类似于以下语句的方式:
ESC%-12345X@PJL ENTER LANGUAGE = PostScript
如果我发送Postscript,那么我是否需要告诉打印机它是Postscript呢?
如果您在作业前添加PJL标头,则请参阅上面倒数第二段。
对于纯PostScript打印机,您可能更愿意使用<<..>>setpagedevice语句。这样的打印机会自动理解PostScript...
如果您列出您可以使用的打印机型号,这也将有所帮助。
在Windows中,我知道打印的“标准”方式,即查询设备功能并请求设备上下文,然后可以使用Windows调用在该上下文上绘制线条、形状和文本。
这实际上是在Windows上通过PostScript打印机(好吧,自从Windows 8以来基于XPS
或OXPS
的新打印工作流程有些不同......)也是如此运作的。通常,“设备功能”已知并由相应的打印机驱动程序托管。当您使用Windows调用绘制线条、形状和文本时,驱动程序将把这些调用转换为PostScript并发送到打印机。
这与Linux、Unix或Mac OS X的工作方式不同:
在Linux(和Unix)中,每个应用程序都必须自己生成要发送到打印机的PostScript页面描述。没有“驱动程序”来帮助完成这项工作。如果最终目标打印机不支持PostScript,则CUPS将自动将其从收到的PostScript转换为供应商或型号特定的页面描述格式。(一些应用程序可能能够生成其中一种PCL语言。)
在Mac OS X上,应用程序通常会生成PDF作为打印池格式(而CUPS会自动将此文件转换为不同的打印机语言,基于供应商的打印机驱动程序,该驱动程序通常包括所需的
pdf-to-someting
CUPS过滤器)。
“然而,显然与Postscript(或HPGL / PCL)相比,这是极其原始的。”
我不明白为什么您应该在这种情况下将其描述为“极其原始”。
“有没有办法我可以直接与打印机驱动程序通信,或者告诉Windows:'这是我的Postscript代码,请将其传递给打印机进行打印'?”
如我之前所说:在Windows上,如果一个应用程序想要打印到PostScript打印机,通常不会自己生成其PostScript代码
[^1],也不会生成任何其他打印机特定格式的内容(除了最终设备是XPS打印机的情况)。通常,它会生成
EMF
作为溢出格式,并让打印子系统(和打印机驱动程序)处理可能需要的任何转换。
或者你是在说:
"我有这个预先制作的PostScript文件(在其他地方生成),我想要将其打印到PostScript打印机?" 如果是这样,那么只需从DOS命令行运行像
lpr -S remoteserver -P printername "-o l" jobfile.ps
这样的命令即可。
话虽如此--
是的,至少有两种非打印机驱动程序的方法可以用来查询您的打印设备:
SNMP. 如果您的设备具有网络(以太网/ WiFi)接口并且理解简单网络管理协议,则可以通过此通道查询它,并获得对您所提出的任何SNMP类型问题的回答。用简单的语言来说(SNMP术语看起来有点不同):
- 您当前的墨水水平是多少?
- 您能处理的最大介质尺寸是多少?
- 您有多少张纸盒?
- 托盘1的填充水平是多少?
- 您曾经打印过多少页?自上次启动以来打印了多少页?
- 您可以处理哪些打印机语言?
- 您支持哪种打印数据传输协议?HPJetDirect / AppSocket?LPR / LPD?IPP?
- 您是否有可用的硬盘空间?
- 您有多少RAM?
- 目前还连接了哪些其他打印客户端?
- ...等等。
PJL查询。 通过向打印机发送几行简单的PJL
语句(并评估响应),也可以检索上述某些信息。
IPP查询。 如果设备可以使用IPP,则Internet Printing Protocol也支持查询设备功能。
再说一遍:"有没有办法让我告诉Windows:'这是我的Postscript代码,请将其传递给打印机进行打印'?"
您甚至可以完全绕过Windows,使用 netcat.exe
实用程序(有时也称为 nc.exe
)向打印机发送作业文件:
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] ...除了一些像Acrobat这样的Adobe程序,它们确实可以生成自己的PostScript。
[windows]
。你指的是哪个版本的Windows?Server 2000?XP?2003?Vista?Server 2012?Windows 8?8.1?10?RT?Mobile?CE?Phone? - Kurt Pfeifle