使用 XPS 光栅化服务
重要
新式打印平台是 Windows 与打印机通信的首选方式。 建议使用 Microsoft 的 IPP 收件箱类驱动程序以及打印支持应用 (PSA) 来自定义 Windows 10 和 11 中的打印体验,以便进行打印机设备开发。
有关详细信息,请参阅新式打印平台和打印支持应用设计指南。
XPS 光栅化服务实现了 XPS 光栅器对象,可将 XPS 文档中的固定页面转换为位图。 此服务简化了 XPSDrv 筛选器的设计,该筛选器可将 XPS 文档呈现为一系列位图图像。 该筛选器可以告诉 XPS 光栅器对象在固定页面中创建轴对齐矩形区域的位图图像。
例如,打印机的 XPSDrv 筛选器可能要求将固定页面作为一系列水平或垂直条带发送到打印机。 在这种情况下,筛选器会告诉 XPS 光栅器对象将每个带光栅化为单独的位图。 或者,如果打印机有足够的内存,筛选器可以告诉光栅器创建整个页面的位图图像。
XPS 光栅化服务通过系统文件 Xpsrasterservice.dll 来实现。 但是,XPSDrv 筛选器不会直接访问此 DLL 中的入口点。 相反,筛选器会通过从打印筛选器管道管理器接收的打印管道属性包来访问 XPS 光栅化服务的接口。
要供 XPSDrv 筛选器使用,则必须在描述打印筛选器管道中的筛选器的筛选器管道配置文件中指定 XPS 光栅化服务。 具体来说,配置文件必须包含一个 FilterServiceProvider 元素,该元素的 dll 属性设置为服务 DLL 名称,如下 XML 示例所示:
<FilterServiceProvider dll = "XpsRasterService.dll" />
FilterServiceProvider 元素是 Filters 元素的子元素,其中列出了管道中的筛选器。 在管道初始化过程中,打印筛选器管道管理器会加载 XPS 光栅化服务,并通过属性包让筛选器访问该服务。 有关加载 XPS 光栅化服务的筛选器管道配置文件的示例,请参阅 WDK 中的 XpsRasFilter 示例。 此示例位于 WDK 安装中的 Src\Print\Xpsrasfilter 文件夹中。
获取 XPS 光栅化工厂
在对 XPS 文档进行光栅化之前,XPSDrv 筛选器必须从打印管道属性包中获取光栅化工厂对象的引用。 此后,筛选器会为需要呈现的每个固定页面从工厂获取一个新的 XPS 光栅器对象。
要初始化 XPSDrv 筛选器,打印筛选器管道管理器会调用筛选器的 IPrintPipelineFilter::InitializeFilter 方法,并将属性包的 IPrintPipelinePropertyBag 接口作为输入参数传递给该方法。
要获取指向 XPS 光栅化工厂对象的指针,XPSDrv 筛选器会调用 IPrintPipelinePropertyBag::GetProperty 方法。 属性名称“MS_IXpsRasterizationFactory”可标识光栅化工厂对象。 对于此属性,从 GetProperty 获得的值是对光栅化工厂对象的 IUnknown 接口的引用。 获得此接口后,筛选器必须调用 IUnknown::QueryInterface 方法,以获得对象的 IXpsRasterizationFactory 接口的引用。 随后,筛选器可以调用 IXpsRasterizationFactory::CreateRasterizer 方法来创建 XPS 光栅器对象。
当不再需要工厂对象时,筛选器应调用该对象的 IXpsRasterizationFactory 接口上的 Release 方法来释放该对象。
以下代码示例显示了如何从 IPrintPipelinePropertyBag 接口实例中获取 IXpsRasterizationFactory 接口实例:
//
// Retrieve a reference to the XPS rasterization factory
// from the print pipeline property bag.
//
HRESULT CreateRasterizationFactory(
IPrintPipelinePropertyBag *pPropertyBag,
IXpsRasterizationFactory **ppXPSRasFactory)
{
if (ppXPSRasFactory != NULL)
{
*ppXPSRasFactory = NULL;
}
if (pPropertyBag == NULL || ppXPSRasFactory == NULL)
{
return E_POINTER;
}
HRESULT hr;
VARIANT var;
IXpsRasterizationFactory *pXPSRasFactory;
//
// Retrieve the factory object from the property bag.
//
VariantInit(&var);
hr = pPropertyBag->GetProperty(L"MS_IXpsRasterizationFactory",
&var);
if (SUCCEEDED(hr))
{
assert(var.vt == VT_UNKNOWN && var.punkVal != NULL);
//
// Get the factory object's IXpsRasterizationFactory interface.
//
IUnknown *pUnknown = var.punkVal;
hr = pUnknown->QueryInterface(__uuidof(IXpsRasterizationFactory),
reinterpret_cast<void**>(&pXPSRasFactory));
}
if (SUCCEEDED(hr))
{
//
// Give the caller our reference to the IXpsRasterizationFactory interface.
//
*ppXPSRasFactory = pXPSRasFactory;
}
VariantClear(&var);
return hr;
}
创建固定页面的 XPS 对象模型
创建 XPS 光栅化工厂后,XPSDrv 筛选器可使用该工厂来创建 XPS 光栅器对象。 XPS 光栅器对象有一个 IXpsRasterizer 接口。 每个 XPS 光栅器对象都专用于 XPS 文档的某个固定页面。 要创建 XPS 光栅器对象,工厂需要固定页面的 XPS 对象模型 (OM)。 XPS OM(固定页面)包含在一个具有 IXpsOMPage 接口的对象中。 XPS 光栅器对象使用此接口来访问固定页面的内容。 有关 IXpsOMPage 接口的详细信息,请参阅 Windows SDK 文档。
XPSDrv 筛选器会按照以下步骤来创建 XPS 光栅器对象:
该筛选器从输入流中读取带有 IFixedPage 接口的固定页面对象。
该筛选器会创建一个带有 IXpsOMPage 接口的 XPS OM 对象,以用于保存固定页面的内容。 XPS 光栅器稍后将使用此接口来访问固定页面的内容。
要创建 XPS 光栅器对象,筛选器会将 XPS OM 对象的 IXpsOMPage 接口传递给 XPS 光栅化工厂的 IXpsRasterizationFactory::CreateRasterizer 方法。
当不再需要 XPS 光栅器对象时,筛选器应调用该对象的 IXpsRasterizer 接口上的 Release 方法来释放该对象。 有关使用 XPS 光栅化服务的 XPSDrv 筛选器实现示例,请参阅 WDK 中的 XpsRasFilter 示例驱动程序。
与 XPS 光栅化服务一起使用时,固定页面内的画布和视觉画笔可嵌套到最多 64 层。 有关画布和视觉画笔的详细信息,请下载 XML 纸张规范。
位图分辨率和像素格式
固定页面的 XPS 光栅器对象必须知道页面的呈现分辨率。 XPSDrv 筛选器在调用 IXpsRasterizationFactory::CreateRasterizer 创建 XPS 光栅对象时,会将此分辨率(单位为每英寸点数 (DPI))指定为输入参数。 例如,如果显示设备的分辨率为 600 DPI,而固定页面描述的是标准 Letter 大小的页面,则整个页面的位图图像尺寸如下:
宽度 = (8.5 英寸)x(600 DPI) = 5100 点
高度 = (11 英寸)x(600 DPI) = 6600 点
要创建固定页面矩形区域的位图图像,XPSDrv 筛选器会调用 XPS 光栅器对象的 IXpsRasterizer::RasterizeRect 方法。 此方法始终生成像素大小为 32 位的位图。 像素格式由 GUID 值 GUID_WICPixelFormat32bppPBGRA 指定,该值在头文件 Wincodec.h 中定义。 该格式包含 8 位红、绿、蓝分量,并使用标准 (sRGB) 颜色空间。 此外,该格式还包含一个 8 位 alpha 分量。 每个像素值中的颜色分量都会预先乘以 Alpha 分量。 有关此格式的更多信息,请参阅原生像素格式概述。
某些 XPSDrv 筛选器可能会对 XPS 光栅器对象生成的位图进行额外的处理。 例如,彩色打印机的筛选器可能会将位图转换为 CMYK 像素格式,然后再将位图封装为打印机的页描述语言并发送给打印机。
有关 XPS 光栅化服务用于与 XPSDrv 筛选器通信的接口的详细信息,请参阅 xpsrassvc.h 标头 DDI 参考。
XPSRas 和高精度像素格式
在 Windows 8 中,XPS 光栅化服务公开了一个新接口 IXpsRasterizationFactory1, 它是 IXpsRasterizationFactory 的新版本。 IXpsRasterizationFactory1 公开了一种新方法 IXpsRasterizationFactory1::CreateRasterizer,该方法与 Windows 7 版本 (IXpsRasterizationFactory::CreateRasterizer) 完全相同,只是在输出像素格式方面增加了一个新参数。
此功能公开了一个新的枚举 XPSRAS_PIXEL_FORMAT,它允许调用方选择 IXpsRasterizer::RasterizeRect 方法返回的 IWICBitmap 接口所使用的像素格式。
XPSRas 和 GPU
如果计算机运行的是带有 WDDM 1.2 显示驱动程序的 Windows 8,并且满足 XPSRas GPU 使用决策树中显示的所有条件,那么将始终使用 GPU 硬件加速。 这意味着,开发人员无需执行任何步骤,即可从 GPU 提供的性能提升中大受裨益。 但是,为了进一步优化系统的图形性能,还应该考虑采取以下措施:
以一致的矩形尺寸调用 RasterizeRect 方法。 如果无法做到这一点,最佳做法是在首次调用 RasterizeRect 时提供所需的最大矩形尺寸,并在后续调用中请求较小的矩形尺寸。
只有在绝对必要时才使用抗锯齿。 当提供给 IXpsRasterizationFactory::CreateRasterizer 方法的 DPI 值相当高时,失真文本和矢量看起来会与抗失真文本和矢量相同。 例如,DPI 值大于 200DPI 即为高值。 此时应进行测试,以确保在使用失真文本和矢量以及高 DPI 时,特定设备上的输出质量足以满足需要。
如果可以在对 IXpsOMPage 进行光栅化之前对文档进行处理,那么对字体进行子集化并对在多个页面上重复出现的元素使用资源字典将提高 XPSRas 的性能。