预分析基础结构

重要

建议使用 Microsoft 的 IPP 收件箱类驱动程序以及打印支持应用 (PSA) ,自定义 Windows 10 和 11 中的打印体验,以便进行打印机设备开发。

有关详细信息,请参阅 打印支持应用设计指南

预分析基础结构是 Unidrv 强制对打印作业进行条带化的机制,以便每个页面的第一个波段重播是包含整个页面的带区。 预分析阶段不允许任何呈现,并且仅用于在呈现对象之前启用对页面上对象的分析。

为了允许整页预分析,Unidrv 首先在 DrvEnableSurface 函数中指定整页设备图面,然后通过 DrvQueryPerBandInfo 指示第一个波段是整个页面的大小。 在预分析完成后,Unidrv 使用 DrvQueryPerBandInfo 将剪辑区域还原到启用预分析之前的大小;Unidrv 随后将呈现到该图面。 由于 GDI 的实现限制,仅当 N-up 模式ONE_UP或呈现带是整个页面时,才能启用预分析。

以下伪代码演示了用于预分析的逻辑。

DrvEnableSurface
if( preanalysis enabled )
   Use dummy device surface
DrvStartDoc
For each physical page 
{
   DrvStartPage
   DrvStartBanding
   For each banding surface 
   {
      DrvQueryPerBandInfo
// Set sizlBand member of PERBANDINFO
      if( preanalysis_pass ) 
         pbi.sizlBand = {whole page}
      else 
         pbi.sizlBand = {normal band}
      Carry out rendering operations
      if ( ( preanalysis pass && OEM preanalysis enabled ) || !preanalysis_pass ) {
         Call OEM hooks
         DrvNextBand
      }
      if ( ( preanalysis pass && OEM preanalysis enabled ) || !preanalysis_pass )
         Call OEMNextBand
      if( preanalysis pass ) {
         Disable preanalysis
         Switch from dummy device surface to real device surface
      }
      if( last band ) 
         Write end page character from GPD
   }  // for each banding surface

}  // for each physical page
DrvEndDoc

由于预分析功能必须与当前通用打印机说明 (GPD) 文件和插件一起使用,因此文本 z 顺序、空白带检测和其他操作是从微型驱动程序的角度实现的。 微型驱动程序可以挂钩 DrvStartBandingDrvNextBand,但它不会收到对 DrvNextBand 的第一次调用,因为对 DrvNextBand 的第一次调用不包括任何呈现。 仅当插件在 GPD 中设置了启用 OEM 对象级预分析 (*PreAnalysisOptions:8) 的标志时,插件才会接收第一个 DrvNextBand 调用。 在这种情况下,插件必须挂钩 DrvStartBandingDrvNextBand,插件必须检查 DrvStartBanding 函数的 pptl 参数。 如果 pptl 参数为非 NULL,则禁用预分析。 如果 pptl 参数为 NULL,则指示分析前阶段的开始时间。 在这种情况下,插件应假定对插件已挂钩的 DDI 的所有调用都来自预分析传递。 预分析传递以对 DrvNextBand 函数的第一次调用结束,呈现传递在对 DrvNextBand 函数的第一次调用之后开始。 对此函数的后续调用将包含呈现数据。

*PreAnalysisOptions 模式

预分析模式在 GPD 文件中由 *PreAnalysisOptionsn 属性名称和属性参数控制。 下表列出了可与 *PreAnalysisOptions 属性名称一起使用的参数值。 可以组合其中两个或更多个值来启用多个选项。

参数含义值 0

禁用所有预分析模式。

1

默认模式。 启用单色 z 顺序文本分析和空白带优化。 此模式适用于支持可下载字体或设备字体以及高分辨率 (600 dpi 或更高) 、24 BPP 呈现模式的设备。

2

为 24 个 BPP IPrintOemUni ImageProcessing 回调启用 1 BPP 优化。

4

启用设备 StretchBlt 操作。

8

启用 OEM 对象级预分析。

使用空白带优化的单色 Z 顺序文本分析

*PreAnalysisOptions: 1

将 *PreAnalysisOptions 参数设置为 1 允许 Unidrv 执行以下操作:

  • 检测单色打印机中文本和图形对象之间的 z 顺序问题。

  • 执行空白带优化。

第一个操作处理下载到单色打印机的文本稍后被覆盖或与图形对象交互时出现的 z 顺序问题。 Z 顺序问题通常是由包含复杂剪辑的图形对象引起的,因此 Unidrv 无法下载清除以前下载的文本的白色矩形。

Unidrv 在执行呈现传递之前,会对每个页面执行预分析传递。 Unidrv 执行此操作的目的是确定任何文本是否会叠加使用使用无法模拟的复杂剪辑的位块传输 (blt) 对象。 因此,文本将呈现到图面位图上,而不是直接下载,以便稍后呈现的对象将与文本正确交互。

此外,对于不支持白色矩形的设备,Unidrv 会检查由 blt 覆盖的任何文本,即使它们不包含复杂的剪辑也是如此。 Unidrv 将文本呈现到表面上,而不是直接下载到打印机。

以下绘图命令针对可能由后续 blt 覆盖的文本进行测试:

因此,此模式应更正文本和填充区域对象之间的所有 z 顺序问题。 请注意,文本和叠加行仍可能存在问题。 不包括这些情况,因为这种解决方案可能会导致几乎所有文本被下载,而不是被绘制。

此功能无法更正与使用设备字体相关的 z 顺序问题。 如果应用程序或驱动程序选择了设备字体模式,则驱动程序无法更正此问题,并且无法将设备字体呈现到图面上。

第二个操作允许 Unidrv 针对页面上的空白区域进行优化。 在此模式下,Unidrv 跳过空白的上边距和下边距,以及页面中间的任何大型空白区域。 此模式旨在用于彩色打印,通过最大程度地减少呈现页面所需的带通道数来提高性能。

在预分析阶段,Unidrv 确定绘图将在页面上发生的位置。 每当启用预分析或打印机使用 24 个 BPP 渲染带时, (600 dpi 或更高的高分辨率) 时,将启用空白带优化。这应该会导致喷墨打印机的 24 BPP 渲染性能明显提高,并且无需更改现有 OEM 插件。

黑带优化

*PreAnalysisOptions: 2  *% 1 bpp ImageProcessing bitmaps

将 *PreAnalysisOptions 参数设置为 2 可让 Unidrv 使用更大的 1 BPP 镶边图面来呈现仅包含实心黑色对象的区域,而不是以 24 BPP 的速度呈现整个页面。 此模式类似于空白带优化,但不同之处是,它还确定 (纯色黑色区域,而不是页面上) 的颜色区域。 只有纯黑色 (没有灰色底纹) 的对象才能在 1 BPP 镶边图面中呈现,因为设置为 24 BPP 颜色的半色调在 1 BPP 单色中未正确呈现。

Unidrv 在 DrvEnableSurface 函数中创建两个表面:一个用于颜色,另一个用于 1 BPP 单色。 Unidrv 对每个内存使用相同的内存,因此不需要额外的内存。 页面预分析确定页面是包含纯黑色区域还是空白区域,对于这些区域,可以使用比包含颜色的区域更大的带。 只有颜色区域需要使用较小的色带图面。

使用相同内存量的 1 BPP 单色表面可以是 24 BPP 彩色表面的 24 倍。 因此,仅在页面中间包含颜色的图像可以分为三个区域:顶部区域、包含颜色的区域和底部区域。 这三个区域可以按如下所示进行条带:顶部区域可以放置在单个单色带中,包含颜色的区域可以划分为覆盖它所需的任意数量的颜色带,底部区域可以放置在单个单色带中。

此功能要求 OEM 支持 IPrintOemUni ImageProcessing 回调并处理光栅数据的转储。 必须增强 对 IPrintOemUni ImageProcessing 回调的当前 OEM 插件支持,以便接受 24 个 BPP 波段或 1 个 BPP 实心黑色波段。

支持 Device StretchBlt 操作

*PreAnalysisOptions: 4

将 *PreAnalysisOptions 参数设置为 4 允许 Unidrv 将 DrvStretchBlt 调用直接下载到支持 stretchblt 操作的设备。

当 Unidrv 生成 24 BPP 颜色数据时,所有拉伸图像都会拉伸到设备的分辨率,这会导致大量光栅数据必须下载。 除了许多东亚打印机的内存不足情况外,这还会导致性能缓慢。

需要微型驱动程序呈现插件才能利用 stretchblt 模式,因为它必须挂钩 OEMStretchBlt 并提供自己的图像下载命令。 Unidrv 仅允许在可直接下载的调用上挂接 OEMStretchBlt。 因此,插件不负责处理 z 顺序问题。 插件只需直接下载它收到的 OEMStretchBlt 调用中包含的源映像数据。 如果图像采用插件不支持或无法下载的格式,则插件还可以选择将图像打回 Unidrv。

每当在系统上呈现其他数据时将对象直接下载到设备时,都可能存在 z 顺序问题或半色调不一致。 此模式使用预分析来确定可以直接下载的弹力图。 仅考虑直接下载不包含掩码或复杂剪裁的弹力。 如果以后的对象覆盖了考虑进行直接下载的任何拉伸链接,则不会直接下载任何对象。 此原则应提高性能,并确保没有任何图像包含来自系统和设备的半色调,这会导致打印输出质量不佳。

OEM Object-Level预分析挂钩

*PreAnalysisOptions: 8

将 *PreAnalysisOptions 参数设置为 8 允许 OEM 启动预分析传递,以便在 DrvStartBanding 调用后播放整个页面上的所有对象,而不考虑带大小。 在预分析过程中,Unidrv 中不允许绘制,但 OEM 可以挂钩所有 DrvXxx 绘图调用来分析页面上的对象。

此模式下的功能侧重于彩色喷墨打印机,以便 OEM 可以使用基于对象的颜色校正或渲染。 例如,某些打印机需要以不同的方式处理黑色对象,如果它们与颜色对象相交,而不是它们自己显示的黑色对象。 其他 OEM 可能希望为与 bitblt 对象不同的 stretchblt 对象提供半色调。 Stretchblt 对象可以采用 Windows 支持的任何图形文件格式,例如.png或.jpg。 Bitblt 对象是排他位图。

在 GPD 中启用此模式时,Unidrv 会将图面定义为带状图面,但会导致第一次播放整个页面。 为此,Unidrv 将 GDI 剪辑窗口设置为整个页面。 Unidrv 允许挂钩所有绘图命令,但在可以执行任何绘制之前返回 。 在后续传递中,Unidrv 将剪辑窗口重置回正常带大小和波段, 就像往常一样。

OEM 在 GPD 中启用此模式后,需要同时挂接 DrvStartBandingDrvNextBand 。 他们必须测试 DrvStartBanding 函数的 pptl 参数,以确定 Unidrv 是否可以在指定页面上的此模式下启用预分析。 如果 pptl 参数为 NULL,则 Unidrv 已启用预分析。 Unidrv 使用 pptl 参数,因为它此时没有意义, (它尚未使用带位置进行更新。 对于预分析,带位置始终设置为 (0, 0) ) 。 如果 pptl 参数为 NULL,则 OEM 应将第一个 DrvNextBand 之前的所有绘图调用视为预分析的一部分,并且不应允许在图面上绘制。

通过调用 OEMNextBand 函数来发出预分析结束的信号。 传递给 OEMNextBandpptl 参数不是 NULL。 此调用仅用于将适当的 pptl 值返回到 Unidrv。 插件可以自行设置 pptl 值,也可以回调 Unidrv (,如本文开头的上述伪代码示例) 。 由于首次调用 OEMNextBand 中指定的 OEMNextBand的 pso 参数尚未呈现的条带表面,因此插件不应将其内容发送到设备。