Our Data Loss Prevention Development team used Deviare to add watermarks to printed documents by intercepting XPS Print API interfaces. This technique can be applied to all printing jobs on virtual or physical printing devices. Get the code.
The requirements are:
- An operating system with XPS Print API (Windows Vista SP2 with Platform Update or higher)
- Visual Studio 2008 with Service Pack 1
- MS Windows Platform SDK 7.1 or higher
- .NET Framework 2.0
- Internet Explorer 9.0 or higher
This solution consists of two C# projects and one C++ project. The first C# project is IEPrintWatermark, which initiates the hooking process and loads the custom C++ DLL and C# plugin. The second is IEPrintWatermarkHelperCS, which is the plugin itself and does all the internal XPS watermark drawing operations. The C++ project is IEPrintWatermarkHelper, and it just gets a pointer to a specific internal interface.
To build the project, we use the “Batch Build” feature of the VS IDE. Since the x64 binaries depend on the x86 version of IEPrintWatermarkHelper, first we build the solution for the x86 platform so the x64 build can obtain the required dependencies. This is required due to the IE architecture where the main process runs in 64-bits, while the child IExplore.exe processes run in 32-bits.
After a successful build, run IEPrintWatermark. The default IE installation will be launched. Navigate to your desired page, and print the page to an XPS-compatible printer. A sample watermark consisting of a purple box and semitransparent, rotated text strings will be superimposed on the text or image on the page.
We used the .NET framework tools to import the Microsoft XPS Print API from the SDK xpsobjectmodel.idl file. The converted file, MSXPS.DLL, is located in the binary folders.
Additional code snippets were included to make it easier to use XPS Document API in C#. See for example the MakeMatrixTransform function which generates transformation matrices for rotating, translating and scaling the visual objects in the XPS document, and the MakeXPSColorfunction which generates a proper RGBA color value.
In XPS documents, all font resources are embedded from file streams. We have included a small font name to TTF filename mapping code (see GetSystemFontFileName function) for easier handling. Font name is case sensitive.
XPS font size is specified in “ems”, not pixels or points. 1 document inch equals to 96 XPS logical units.
All object transformations are relative to page origin (top-left is 0,0).