预分析基础结构

重要

新式打印平台是 Windows 与打印机通信的首选方式。 建议使用 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 模式

预分析模式由 *PreAnalysisOptions: n 属性名称和属性参数在 GPD 文件中进行控制。 下表列出了可与 *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 纯黑色条带。

支持设备 StretchBlt 操作

*PreAnalysisOptions: 4

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

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

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

每当在系统上呈现其他数据时将对象直接下载到设备时,都可能会出现 z 顺序问题或半色调不一致。 此模式使用预分析来确定可以直接下载哪些 stretchblt。 仅考虑直接下载不包含遮罩或复杂剪辑的 stretchblt。 如果以后的对象叠加要考虑直接下载的任何 stretchblt,则不会直接下载任何对象。 此原则应会提升性能,并确保系统和设备中的图标不包含半色调,这会导致质量不佳的打印输出。

OEM 对象级预分析挂钩

*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参数的条带表面尚未呈现,因此插件不应将其内容发送到设备。