生成基本的 v4 打印机驱动程序-OMConvertor.cpp
- OMConvertor.cpp
//
// File Name:
//
// omconvertor.cpp
//
// Abstract:
//
// Object model conversion routines. This class provides routines
// to convert from filter pipeline objects into Xps Object Model
// objects.
//
#include "precomp.h"
#include "WppTrace.h"
#include "CustomWppCommands.h"
#include "Exception.h"
#include "filtertypes.h"
#include "UnknownBase.h"
#include "OMConvertor.h"
#include "OMConvertor.tmh"
namespace MyV4PrintDriver_Render_Filter
{
//
//Routine Name:
//
// CreateXpsOMPageFromIFixedPage
//
//Routine Description:
//
// This is the main method called by the filter. It
// proceeds to call the remaining Create* methods
// to convert from the print pipeline Object Model
// to the Xps Object Model.
//
// Takes an IFixedPage (print pipeline Object Model)
// and converts it to an IXpsOMPage (Xps Object Model).
//
//Arguments:
//
// pPageIn - IFixedPage to convert
// pOMFactory - Xps Object Model Object Factory
// pOpcFactory - Opc Object Factory
//
//Return Value:
//
// IXpsOMPage_t (smart pointer)
// Result IXpsOMPage
//
IXpsOMPage_t
CreateXpsOMPageFromIFixedPage(
const IFixedPage_t &pPageIn,
const IXpsOMObjectFactory_t &pOMFactory,
const IOpcFactory_t &pOpcFactory
)
{
//
// Get additional page parameters (uri and stream)
//
IOpcPartUri_t pPartUri;
IStream_t pPartStream;
pPartStream = GetStreamFromPart(
static_cast<IPartBase_t>(pPageIn)
);
pPartUri = CreateOpcPartUriFromPart(
static_cast<IPartBase_t>(pPageIn),
pOpcFactory
);
//
// Call Xps Object Model to create the page resource
//
IXpsOMPage_t pPageOut;
THROW_ON_FAILED_HRESULT(
pOMFactory->CreatePageFromStream(
pPartStream,
pPartUri,
CollectPageResources(pPageIn, pOMFactory, pOpcFactory),
FALSE, // Do not reuse objects
&pPageOut
)
);
return pPageOut;
}
//
//Routine Name:
//
// CreateImageFromIPartImage
//
//Routine Description:
//
// Takes an IPartImage (print pipeline Object Model)
// and converts it to an IXpsOMImageResource (Xps Object Model).
//
//Arguments:
//
// pImageIn - IPartImage to convert
// pOMFactory - Xps Object Model Object Factory
// pOpcFactory - Opc Object Factory
//
//Return Value:
//
// IXpsOMImageResource_t (smart pointer)
// Result IXpsOMImageResource
//
IXpsOMImageResource_t
CreateImageFromIPartImage(
const IPartImage_t &pImageIn,
const IXpsOMObjectFactory_t &pOMFactory,
const IOpcFactory_t &pOpcFactory
)
{
//
// Get IPartBase parameters (stream and uri)
//
IStream_t pPartStream;
IOpcPartUri_t pPartUri;
pPartStream = GetStreamFromPart(
static_cast<IPartBase_t>(pImageIn)
);
pPartUri = CreateOpcPartUriFromPart(
static_cast<IPartBase_t>(pImageIn),
pOpcFactory
);
//
// Get the image type and convert it to the corresponding enum
//
BSTR_t strContentType;
XPS_IMAGE_TYPE type = XPS_IMAGE_TYPE_WDP;
THROW_ON_FAILED_HRESULT(
pImageIn->GetImageProperties(&strContentType)
);
if (0 == _wcsicmp(strContentType, L"image/jpeg"))
{
type = XPS_IMAGE_TYPE_JPEG;
}
else if (0 == _wcsicmp(strContentType, L"image/png"))
{
type = XPS_IMAGE_TYPE_PNG;
}
else if (0 == _wcsicmp(strContentType, L"image/tiff"))
{
type = XPS_IMAGE_TYPE_TIFF;
}
else if (0 == _wcsicmp(strContentType, L"image/vnd.ms-photo"))
{
type = XPS_IMAGE_TYPE_WDP;
}
else
{
//
// unknown content type
//
THROW_ON_FAILED_HRESULT(E_INVALIDARG);
}
//
// Call Xps Object Model to create the image resource
//
IXpsOMImageResource_t pImageOut;
THROW_ON_FAILED_HRESULT(
pOMFactory->CreateImageResource(
pPartStream,
type,
pPartUri,
&pImageOut
)
);
return pImageOut;
}
//
//Routine Name:
//
// CreateProfileFromIPartColorProfile
//
//Routine Description:
//
// Takes an IPartColorProfile (print pipeline Object Model)
// and converts it to an IXpsOMColorProfileResource (Xps Object Model).
//
//Arguments:
//
// pProfileIn - IPartColorProfile to convert
// pOMFactory - Xps Object Model Object Factory
// pOpcFactory - Opc Object Factory
//
//Return Value:
//
// IXpsOMColorProfileResource_t (smart pointer)
// Result IXpsOMColorProfileResource
//
IXpsOMColorProfileResource_t
CreateProfileFromIPartColorProfile(
const IPartColorProfile_t &pProfileIn,
const IXpsOMObjectFactory_t &pOMFactory,
const IOpcFactory_t &pOpcFactory
)
{
//
// Get IPartBase parameters (stream and uri)
//
IStream_t pPartStream;
IOpcPartUri_t pPartUri;
pPartStream = GetStreamFromPart(
static_cast<IPartBase_t>(pProfileIn)
);
pPartUri = CreateOpcPartUriFromPart(
static_cast<IPartBase_t>(pProfileIn),
pOpcFactory
);
//
// Call Xps Object Model to create the color profile resource
//
IXpsOMColorProfileResource_t pProfileOut;
THROW_ON_FAILED_HRESULT(
pOMFactory->CreateColorProfileResource(
pPartStream,
pPartUri,
&pProfileOut
)
);
return pProfileOut;
}
//
//Routine Name:
//
// CreateDictionaryFromIPartResourceDictionary
//
//Routine Description:
//
// Takes an IPartResourceDictionary (print pipeline Object Model)
// and converts it to an IXpsOMRemoteDictionaryResource (Xps Object Model).
//
//Arguments:
//
// pDictionaryIn - IPartResourceDictionary to convert
// pOMFactory - Xps Object Model Object Factory
// pOpcFactory - Opc Object Factory
// pResources - The resources of the fixed page
//
//Return Value:
//
// IXpsOMRemoteDictionaryResource_t (smart pointer)
// Result IXpsOMRemoteDictionaryResource
//
IXpsOMRemoteDictionaryResource_t
CreateDictionaryFromIPartResourceDictionary(
const IPartResourceDictionary_t &pDictionaryIn,
const IXpsOMObjectFactory_t &pOMFactory,
const IOpcFactory_t &pOpcFactory,
const IXpsOMPartResources_t &pResources
)
{
//
// Get IPartBase parameters (stream and uri)
//
IStream_t pPartStream;
IOpcPartUri_t pPartUri;
pPartStream = GetStreamFromPart(
static_cast<IPartBase_t>(pDictionaryIn)
);
pPartUri = CreateOpcPartUriFromPart(
static_cast<IPartBase_t>(pDictionaryIn),
pOpcFactory
);
//
// Call Xps Object Model to create the remote dictionary resource
//
IXpsOMRemoteDictionaryResource_t pDictionaryOut;
THROW_ON_FAILED_HRESULT(
pOMFactory->CreateRemoteDictionaryResourceFromStream(
pPartStream,
pPartUri,
pResources,
&pDictionaryOut)
);
return pDictionaryOut;
}
//
//Routine Name:
//
// CreateFontFromIPartFont
//
//Routine Description:
//
// Takes an IPartFont (print pipeline Object Model)
// and converts it to an IXpsOMFontResource (Xps Object Model).
//
//Arguments:
//
// pFontIn - IPartFont to convert
// pFactory - Xps Object Model Object Factory
// pOpcFactory - Opc Object Factory
//
//Return Value:
//
// IXpsOMFontResource_t (smart pointer)
// Result IXpsOMFontResource
//
IXpsOMFontResource_t
CreateFontFromIPartFont(
const IPartFont_t &pFontIn,
const IXpsOMObjectFactory_t &pOMFactory,
const IOpcFactory_t &pOpcFactory
)
{
//
// Get IPartBase parameters (stream and uri)
//
IStream_t pPartStream;
IOpcPartUri_t pPartUri;
pPartStream = GetStreamFromPart(
static_cast<IPartBase_t>(pFontIn)
);
pPartUri = CreateOpcPartUriFromPart(
static_cast<IPartBase_t>(pFontIn),
pOpcFactory
);
//
// Get the font restriction
//
EXpsFontRestriction eFontRestriction = Xps_Restricted_Font_Installable;
{
IPartFont2_t pFont2In;
if (SUCCEEDED(pFontIn->QueryInterface(__uuidof(IPartFont2), reinterpret_cast<void **>(&pFont2In))))
{
pFont2In->GetFontRestriction(&eFontRestriction);
}
}
//
// Get the font obfuscation
//
EXpsFontOptions eFontOptions;
{
BSTR_t contentType;
THROW_ON_FAILED_HRESULT(
pFontIn->GetFontProperties(&contentType, &eFontOptions)
);
}
//
// It is necessary to combine the obfuscation and restriction
// attributes from the print pipeline into the one parameter that
// the Xps Object Model consumes.
//
XPS_FONT_EMBEDDING omEmbedding;
if (eFontOptions == Font_Normal)
{
omEmbedding = XPS_FONT_EMBEDDING_NORMAL;
}
else if (eFontOptions == Font_Obfusticate &&
(eFontRestriction &
(Xps_Restricted_Font_PreviewPrint |
Xps_Restricted_Font_NoEmbedding)))
{
//
// If the font is obfuscated, and either the PreviewPrint or
// NoEmbedding restriction flags are set, then create a
// Restricted font
//
omEmbedding = XPS_FONT_EMBEDDING_RESTRICTED;
}
else
{
omEmbedding = XPS_FONT_EMBEDDING_OBFUSCATED;
}
//
// Call Xps Object Model to create the font resource
//
IXpsOMFontResource_t pFontOut;
THROW_ON_FAILED_HRESULT(
pOMFactory->CreateFontResource(
pPartStream,
omEmbedding,
pPartUri,
FALSE, // fonts received from the pipeline are already de-obfuscated
&pFontOut
)
);
return pFontOut;
}
//
//Routine Name:
//
// CollectPageResources
//
//Routine Description:
//
// Iterates over all of the resources related to
// a fixed page and adds them to a resource
// collection.
//
//Arguments:
//
// pPage - The page to query for resources
// pOMFactory - Xps Object Model Object Factory
// pOpcFactory - Opc Object Factory
//
//Return Value:
//
// IXpsOMPartResources_t (smart pointer)
// The resource collection of all of the resources of the page
//
IXpsOMPartResources_t
CollectPageResources(
const IFixedPage_t &pPage,
const IXpsOMObjectFactory_t &pOMFactory,
const IOpcFactory_t &pOpcFactory
)
{
IXpsOMPartResources_t pResources;
IXpsOMFontResourceCollection_t pFonts;
IXpsOMImageResourceCollection_t pImages;
IXpsOMColorProfileResourceCollection_t pProfiles;
IXpsOMRemoteDictionaryResourceCollection_t pDictionaries;
//
// collection of resource dictionaries saved for later processing.
//
ResourceDictionaryList_t dictionaryList;
//
// Create the resource collection and get all of the
// resource-specific sub-collections.
//
THROW_ON_FAILED_HRESULT(
pOMFactory->CreatePartResources(&pResources)
);
THROW_ON_FAILED_HRESULT(
pResources->GetFontResources(&pFonts)
);
THROW_ON_FAILED_HRESULT(
pResources->GetImageResources(&pImages)
);
THROW_ON_FAILED_HRESULT(
pResources->GetColorProfileResources(&pProfiles)
);
THROW_ON_FAILED_HRESULT(
pResources->GetRemoteDictionaryResources(&pDictionaries)
);
//
// Get the XpsPartIterator and iterate through all of the parts
// related to this fixed page.
//
IXpsPartIterator_t itPart;
THROW_ON_FAILED_HRESULT(
pPage->GetXpsPartIterator(&itPart)
);
for (; !itPart->IsDone(); itPart->Next())
{
BSTR_t uri;
IUnknown_t pUnkPart;
THROW_ON_FAILED_HRESULT(
itPart->Current(&uri, &pUnkPart)
);
IPartFont_t pFontPart;
IPartImage_t pImagePart;
IPartColorProfile_t pProfilePart;
IPartResourceDictionary_t pDictionaryPart;
if (SUCCEEDED(pUnkPart.QueryInterface(&pFontPart)))
{
//
// Convert the font part to Xps Object Model and add it to the
// font resource collection
//
THROW_ON_FAILED_HRESULT(
pFonts->Append(
CreateFontFromIPartFont(
pFontPart,
pOMFactory,
pOpcFactory
)
)
);
}
else if (SUCCEEDED(pUnkPart.QueryInterface(&pImagePart)))
{
//
// Convert the image part to Xps Object Model and add it to the
// image resource collection
//
THROW_ON_FAILED_HRESULT(
pImages->Append(
CreateImageFromIPartImage(
pImagePart,
pOMFactory,
pOpcFactory
)
)
);
}
else if (SUCCEEDED(pUnkPart.QueryInterface(&pProfilePart)))
{
//
// Convert the color profile part to Xps Object Model and add it
// to the color profile resource collection
//
THROW_ON_FAILED_HRESULT(
pProfiles->Append(
CreateProfileFromIPartColorProfile(
pProfilePart,
pOMFactory,
pOpcFactory
)
)
);
}
else if (SUCCEEDED(pUnkPart.QueryInterface(&pDictionaryPart)))
{
//
// In order to process the remote resource dictionary, all of
// its linked resources must be present in pResources. To ensure
// this, we delay the conversion of the remote resource
// dictionaries until all of the other resources have been converted.
//
dictionaryList.push_back(pDictionaryPart);
}
else
{
DoTraceMessage(RENDERFILTER_TRACE_INFO, L"Unhandled Page Resource");
}
}
for (ResourceDictionaryList_t::const_iterator it = dictionaryList.begin();
it != dictionaryList.end();
++it)
{
//
// Convert the remote dictionary to Xps Object Model and add it
// to the remote dictionary collection
//
THROW_ON_FAILED_HRESULT(
pDictionaries->Append(
CreateDictionaryFromIPartResourceDictionary(
*it,
pOMFactory,
pOpcFactory,
pResources
)
)
);
}
return pResources;
}
//
//Routine Name:
//
// GetStreamFromPart
//
//Routine Description:
//
// Gets the IStream from this part.
//
//Arguments:
//
// pPart - An Xps Part
//
//Return Value:
//
// IStream_t (smart pointer)
// The stream of the part's content
//
IStream_t
GetStreamFromPart(
const IPartBase_t &pPart
)
{
//
// Get the IPrintReadStream for the part from the pipeline Object Model
//
IPrintReadStream_t pStream;
THROW_ON_FAILED_HRESULT(
pPart->GetStream(&pStream)
);
return CreateIStreamFromIPrintReadStream(pStream);
}
//
//Routine Name:
//
// CreateIStreamFromIPrintReadStream
//
//Routine Description:
//
// Creates an IStream from an IPrintReadStream.
//
//Arguments:
//
// pReadStream - A Print Pipeline IPrintReadStream
//
//Return Value:
//
// IStream_t (smart pointer)
// A stream with the same content as the argument stream.
//
IStream_t
CreateIStreamFromIPrintReadStream(
const IPrintReadStream_t &pReadStream
)
{
//
// Get the size of the stream
//
ULONGLONG tmpPos;
size_t partSize;
THROW_ON_FAILED_HRESULT(
pReadStream->Seek(0, SEEK_END, &tmpPos)
);
//
// GlobalAlloc can only allocate size_t bytes, so
// throw if the part is larger than that
//
THROW_ON_FAILED_HRESULT(
ULongLongToSizeT(tmpPos, &partSize)
);
THROW_ON_FAILED_HRESULT(
pReadStream->Seek(0, SEEK_SET, &tmpPos)
);
//
// Allocate an HGLOBAL for the part cache
//
SafeHGlobal_t pHBuf(
new SafeHGlobal(GMEM_FIXED, partSize)
);
//
// Read the part into the cache
//
{
//
// Lock the HGLOBAL and get the address of the buffer
// from the RAII lock object
//
HGlobalLock_t lock = pHBuf->Lock();
BYTE *pBuffer = lock->GetAddress();
//
// Allow the number of bytes to read to be clipped to max ULONG
// and then spin on fEOF until the stream is exhausted
//
ULONG numToRead;
if (FAILED(SizeTToULong(partSize, &numToRead)))
{
numToRead = MAXUINT;
}
BOOL fEOF;
ULONG numRead;
size_t pos = 0;
//
// Iterate until all bytes from the stream
// have been read into the buffer
//
do
{
THROW_ON_FAILED_HRESULT(
pReadStream->ReadBytes(pBuffer + pos, numToRead, &numRead, &fEOF)
);
pos += numRead;
} while (!fEOF && numRead);
}
//
// Create an IStream from the part cache
//
IStream_t pIStream = pHBuf->ConvertToIStream();
LARGE_INTEGER zero = {0};
THROW_ON_FAILED_HRESULT(
pIStream->Seek(zero, SEEK_SET, NULL)
);
return pIStream;
}
//
//Routine Name:
//
// CreateOpcPartUriFromPart
//
//Routine Description:
//
// Gets the Opc Uri from the Xps Part.
//
//Arguments:
//
// pPart - An Xps Part
// pFactory - Opc Factory
//
//Return Value:
//
// IOpcPartUri_t (smart pointer)
// The Uri of the part
//
IOpcPartUri_t
CreateOpcPartUriFromPart(
const IPartBase_t &pPart,
const IOpcFactory_t &pFactory
)
{
BSTR_t strPartUri;
THROW_ON_FAILED_HRESULT(
pPart->GetUri(&strPartUri)
);
IOpcPartUri_t pPartUri;
THROW_ON_FAILED_HRESULT(
pFactory->CreatePartUri(strPartUri, &pPartUri)
);
return pPartUri;
}
} // namespace MyV4PrintDriver_Render_Filter
文件概述
- 功能:定义了一系列函数,用于将打印管道中的对象(如页面、图像、字体、颜色配置文件、资源字典等)转换为 XPS 对象模型中的对应对象。这些转换是 Windows 打印驱动程序渲染流程的核心部分。
- 主要内容:
提供了多个 Create* 函数,用于将特定类型的打印管道对象转换为 XPS 对象模型对象。
使用智能指针(如 IXpsOMPage_t)管理 COM 对象的生命周期。
使用 WPP(Windows 软件跟踪预处理器)记录日志,结合异常处理确保代码健壮性。 - 命名空间:
MyV4PrintDriver_Render_Filter,用于组织代码并避免符号冲突。
代码结构与功能详解
- 头文件与预处理器
- 作用:
包含必要的头文件,提供预编译宏、WPP 跟踪、自定义 WPP 命令、异常处理(Exception.h)、过滤器类型(filtertypes.h)、COM 基类(UnknownBase.h)和转换函数的声明(OMConvertor.h)。
OMConvertor.tmh是 WPP 跟踪生成的头文件,用于日志记录。
- 命名空间
namespace MyV4PrintDriver_Render_Filter
- 作用: 使用命名空间
MyV4PrintDriver_Render_Filter组织代码,避免符号冲突。
- 函数详解
CreateXpsOMPageFromIFixedPage
IXpsOMPage_t CreateXpsOMPageFromIFixedPage(
const IFixedPage_t &pPageIn,
const IXpsOMObjectFactory_t &pOMFactory,
const IOpcFactory_t &pOpcFactory
)
- 功能: 将打印管道的
IFixedPage对象转换为 XPS 对象模型的IXpsOMPage对象。这是过滤器的主要入口函数,负责协调其他转换函数。 - 参数:
pPageIn: 输入的打印管道页面对象(IFixedPage)。
pOMFactory: XPS 对象模型工厂(IXpsOMObjectFactory),用于创建 XPS 对象。
pOpcFactory: OPC(Open Packaging Conventions)工厂(IOpcFactory),用于创建 URI 等。 - 逻辑:
1.获取页面部件的流(pPartStream)和 URI(pPartUri),通过调用GetStreamFromPart和CreateOpcPartUriFromPart。
2.调用CollectPageResources收集页面相关的资源(如字体、图像等)。
3.使用pOMFactory->CreatePageFromStream创建 XPS 页面对象,传入流、URI 和资源集合。
4.如果调用失败,抛出异常(通过THROW_ON_FAILED_HRESULT)。
5.返回智能指针 IXpsOMPage_t,指向创建的页面对象。 - 异常处理:
使用THROW_ON_FAILED_HRESULT宏(可能调用ThrowHRException)抛出 HRESULT 异常。 - 作用:
实现页面级别的对象模型转换,是渲染过滤器的核心功能。
CreateXpsOMPageFromIFixedPage
IXpsOMPage_t CreateXpsOMPageFromIFixedPage(
const IFixedPage_t &pPageIn,
const IXpsOMObjectFactory_t &pOMFactory,
const IOpcFactory_t &pOpcFactory
)
- 功能: 将打印管道的 IPartImage 对象转换为 XPS 对象模型的 IXpsOMImageResource 对象。
- 参数:
pImageIn: 输入的图像部件(IPartImage)。
pOMFactory和pOpcFactory: 同上。 - 逻辑:
1.获取图像部件的流(pPartStream)和 URI(pPartUri)。
2.获取图像的内容类型(strContentType),并根据类型(如image/jpeg、image/png)映射到 XPS 图像类型枚举(XPS_IMAGE_TYPE)。
3.如果内容类型未知,抛出E_INVALIDARG异常。
4.调用pOMFactory->CreateImageResource创建 XPS 图像资源。
5.返回智能指针IXpsOMImageResource_t。 - 异常处理:
异常处理: 使用 THROW_ON_FAILED_HRESULT 确保操作成功。 - 作用:
处理页面中的图像资源,确保正确转换到 XPS 模型。
CreateProfileFromIPartColorProfile
IXpsOMColorProfileResource_t CreateProfileFromIPartColorProfile(
const IPartColorProfile_t &pProfileIn,
const IXpsOMObjectFactory_t &pOMFactory,
const IOpcFactory_t &pOpcFactory
)
- 功能: 将打印管道的
IPartColorProfile对象转换为 XPS 对象模型的IXpsOMColorProfileResource对象。 - 参数:
pProfileIn: 输入的颜色配置文件部件(IPartColorProfile)。
pOMFactory和pOpcFactory: 同上。 - 逻辑:
1.获取颜色配置文件的流和 URI。
2.调用pOMFactory->CreateColorProfileResource创建 XPS 颜色配置文件资源。
3.返回智能指针IXpsOMColorProfileResource_t。 - 异常处理:
异常处理: 使用 THROW_ON_FAILED_HRESULT。 - 作用:
处理颜色配置文件,确保打印输出的颜色准确性。
CreateDictionaryFromIPartResourceDictionary
IXpsOMRemoteDictionaryResource_t CreateDictionaryFromIPartResourceDictionary(
const IPartResourceDictionary_t &pDictionaryIn,
const IXpsOMObjectFactory_t &pOMFactory,
const IOpcFactory_t &pOpcFactory,
const IXpsOMPartResources_t &pResources
)
- 功能: 将打印管道的
IPartResourceDictionary对象转换为 XPS 对象模型的IXpsOMRemoteDictionaryResource对象。 - 参数:
pDictionaryIn: 输入的资源字典部件(IPartResourceDictionary)。
pResources: 已收集的页面资源集合(IXpsOMPartResources)。
pOMFactory和pOpcFactory: 同上。 - 逻辑:
1.获取资源字典的流和 URI。
2.调用 pOMFactory->CreateRemoteDictionaryResourceFromStream 创建 XPS 远程资源字典。
3.返回智能指针 IXpsOMRemoteDictionaryResource_t。 - 异常处理:
异常处理: 使用 THROW_ON_FAILED_HRESULT。 - 作用:
处理页面中的共享资源字典(如样式或模板)。
CreateFontFromIPartFont
IXpsOMFontResource_t CreateFontFromIPartFont(
const IPartFont_t &pFontIn,
const IXpsOMObjectFactory_t &pOMFactory,
const IOpcFactory_t &pOpcFactory
)
- 功能: 将打印管道的
IPartFont对象转换为 XPS 对象模型的IXpsOMFontResource对象。 - 参数:
pFontIn: 输入的字体部件(IPartFont)。
pOMFactory和pOpcFactory: 同上。 - 逻辑:
1.获取字体的流和 URI。
2.查询字体限制(eFontRestriction),通过IPartFont2接口获取(如可安装、预览打印或禁止嵌入)。
3.获取字体属性(contentType和eFontOptions),判断字体是否需要混淆(obfuscation)。
4.根据字体选项和限制,设置 XPS 字体嵌入模式(XPS_FONT_EMBEDDING),支持正常、混淆或受限嵌入。
5.调用pOMFactory->CreateFontResource创建 XPS 字体资源,指定嵌入模式。
6.返回智能指针IXpsOMFontResource_t。 - 异常处理:
异常处理: 使用 THROW_ON_FAILED_HRESULT。 - 作用:
处理页面中的字体资源,确保字体在 XPS 文档中正确嵌入或引用。
CollectPageResources
IXpsOMPartResources_t CollectPageResources(
const IFixedPage_t &pPage,
const IXpsOMObjectFactory_t &pOMFactory,
const IOpcFactory_t &pOpcFactory
)
- 功能: 收集页面相关的所有资源(字体、图像、颜色配置文件、资源字典),并转换为 XPS 对象模型的资源集合。
- 参数:
pPage: 输入的页面对象(IFixedPage)。
pOMFactory和pOpcFactory: 同上。 - 逻辑:
1.创建资源集合(IXpsOMPartResources)及其子集合(字体、图像、颜色配置文件、资源字典)。
2.获取页面的部件迭代器(IXpsPartIterator),遍历所有相关部件。
3.对每个部件,尝试转换为特定类型(IPartFont、IPartImage、IPartColorProfile、IPartResourceDictionary):
如果是字体,调用CreateFontFromIPartFont并添加到字体集合。
如果是图像,调用CreateImageFromIPartImage并添加到图像集合。
如果是颜色配置文件,调用CreateProfileFromIPartColorProfile并添加到颜色配置文件集合。
如果是资源字典,暂存到dictionaryList,延迟处理。
4.遍历完成后,处理延迟的资源字典,调用CreateDictionaryFromIPartResourceDictionary并添加到字典集合。
5.返回智能指针IXpsOMPartResources_t。 - 异常处理:
异常处理: 使用 THROW_ON_FAILED_HRESULT。 - 作用:
确保页面中的所有资源都被正确收集并转换,供页面创建使用。 - 延迟处理资源字典:
资源字典可能依赖其他资源(如字体或图像),因此延迟处理以确保所有相关资源已添加。
GetStreamFromPart
IStream_t GetStreamFromPart(const IPartBase_t &pPart)
- 功能: 从 XPS 部件(IPartBase)获取其数据流(IStream)。
- 参数:
pPart: 输入的部件(如页面、字体、图像等)。 - 逻辑:
1.调用pPart->GetStream获取打印管道的IPrintReadStream。
2.调用CreateIStreamFromIPrintReadStream将其转换为IStream。
3.返回智能指针IStream_t。 - 异常处理:
异常处理: 使用 THROW_ON_FAILED_HRESULT。 - 作用:
提供统一的方法从部件获取数据流,供后续转换使用。
CreateIStreamFromIPrintReadStream
IStream_t CreateIStreamFromIPrintReadStream(const IPrintReadStream_t &pReadStream)
- 功能: 将打印管道的 IPrintReadStream 转换为 COM 的 IStream。
- 参数:
pReadStream: 输入的打印管道流。 - 逻辑:
1.获取流的总大小(通过Seek到末尾)。
2.检查大小是否适合size_t,否则抛出异常。
3.分配全局内存(HGLOBAL)缓存流内容。
4.读取流数据到缓存(分块读取,直到流结束)。
5.将缓存转换为IStream(通过SafeHGlobal::ConvertToIStream)。
6.将流指针重置到开头。
7.返回智能指针IStream_t。 - 异常处理:
异常处理: 使用 THROW_ON_FAILED_HRESULT。 - 作用:
实现打印管道流到 COM 流的转换,兼容 XPS 对象模型。
CreateOpcPartUriFromPart
IOpcPartUri_t CreateOpcPartUriFromPart(const IPartBase_t &pPart, const IOpcFactory_t &pFactory)
- 功能: 从 XPS 部件获取其 OPC URI(IOpcPartUri)。
- 参数:
pPart: 输入的部件。
pFactory: OPC工厂。 - 逻辑:
1.调用pPart->GetUri获取部件的 URI 字符串(BSTR)。
2.使用pFactory->CreatePartUri创建 OPC URI 对象。
3.返回智能指针IOpcPartUri_t。 - 异常处理:
异常处理: 使用 THROW_ON_FAILED_HRESULT。 - 作用:
提供部件的 URI,用于 XPS 对象模型中的资源引用。
代码总结
- 主要功能:
- 提供从打印管道对象模型到 XPS 对象模型的转换功能,涵盖页面、图像、字体、颜色配置文件和资源字典。
- 使用智能指针(如 IXpsOMPage_t)管理 COM 对象,简化内存管理。
- 通过 WPP 日志(DoTraceMessage)和异常处理(THROW_ON_FAILED_HRESULT)确保代码健壮性和可调试性。
- 关键点:
CreateXpsOMPageFromIFixedPage是核心入口,协调其他转换函数。- 资源收集(
CollectPageResources)通过迭代器遍历页面部件,处理不同类型的资源,并延迟处理资源字典以解决依赖问题。 - 流和 URI 的获取(
GetStreamFromPart和CreateOpcPartUriFromPart)是通用的辅助函数。 - 字体处理(
CreateFontFromIPartFont)考虑了字体限制和混淆选项,确保符合 XPS 规范。
- 应用场景:
- 该代码是 Windows 打印驱动程序渲染过滤器的一部分,用于将打印管道中的 XPS 数据转换为 XPS 对象模型,以便进一步渲染或处理。
- 常用于打印管道中的 XPS 文档处理,确保页面内容和资源正确转换。
- 异常处理:
- 使用 THROW_ON_FAILED_HRESULT 宏,结合 Exception.h 中的 ThrowHRException,抛出 HRESULT 异常。
- 异常通常在调用 COM 接口或分配内存失败时触发。
原始资料地址:
生成基本的 v4 打印机驱动程序
如有侵权联系删除 仅供学习交流使用