Using XPSDrv Print Drivers To Extend Windows Print Functionality

Using XPSDrv Print Drivers

To Extend Windows Print

Functionality

Feng Yuan

Technical Lead – Development

Digital Documents Platform and Solutions

Agenda

Filter Pipeline Extensibility

Extensibility Scenarios

Advanced Color

Configuration

Notifications

Sample Filter Walkthroughs

Assumes familiarity with XPSDrv architecture and interfaces

Filter Pipeline Extensibility

The filter pipeline is designed for modular and extensible IHV/ISV implementations

Primary extensibility points

Generic filters

Configuration DLL

New DrvDocumentEvents events

PrintTicket control

Filter service publishing

Notification

Custom Inter Filter Communicators (IFC)

Extensibility Scenario Overview

Win32 App WPF App

Win32

Monitoring

Application

MS Component

ISV Component

IHV Component

Win32 Print

APIs

WPF Print

APIs

Print Subsystem

XPS Doc

(Spool File)

Conversion

Render Module

Configuration

Module

Sample XPSDrv Print Driver

Filter Pipeline

Advanced

Color Filter

Configuration

Filter

Notification

Filter

XPS Doc

(PDL

Stream)

Printer

Scenario: Advanced Color

Windows Photo Gallery prints Windows Media Photo image to XPSDrv print driver for 8-color inkjet photo printer

Scenario: Advanced Color

XPS Documents support high dynamic range, wide gamut vector and image content

Using system services, filters can process rich color data to best match printed output to user intent and device capabilities

Windows Color System (WCS) – Enables extensive color conversion

Windows Imaging Components (WIC) – Image format support for Windows Media Photo and other

XPS image formats

PrintTicket – Supports an array of color processing keywords to enable consistent and unambiguous color control between app and device

Scenario: Advanced Color

Data Flow

Windows Photo Gallery allows user selection of print settings

MXDW driver encapsulates Windows Media

Photo image and print settings (as PrintTicket) in XPS Document

Filter process XPS file, decoding/transforming image, saving image to JPG format

Advanced Color Filter

Print Subsystem

XPS Doc

(Spool File)

Filter Pipeline

Advanced Color Filter

Identify All

Images in

XPS File

Convert

Images into Device

Color

Space

Convert

Images into JPGs

MS Component

ISV Component

IHV Component

Device Color

Profile

Windows Color

System

Windows

Imaging

Codecs

Color Filter: Main Method

HRESULT CColorFilter::StartOperation(void)

{

HRESULT hr = SetupColorTransform(L“wsRGB.cdmp") ;

CComPtr<IUnknown> pUnk; while (SUCCEEDED(hr = m_pProvider-> GetXpsPart(&pUnk) ))

{

CComPtr<IXpsDocument> pXD;

CComPtr<IFixedPage> pFP; if (SUCCEEDED(pUnk.QueryInterface(&pXD))) { hr = m_pConsumer->SendXpsDocument(pXD);

} else if ...

else if (SUCCEEDED(pUnk.

QueryInterface(&pFP) )) { hr = ProcessFixedPage(pFP) ; hr = m_pConsumer-> SendFixedPage(pFP) ;

}

} m_pConsumer->CloseSender(); m_pPrintPipeManager->FilterFinished();

DeleteColorTransform(m_hColorTrans) ; return hr;

}

Color Filter: Setup Transformation

HPROFILE OpenColorProfile(const WCHAR * pszProfileName)

{

PROFILE profile = { PROFILE_FILENAME, (PVOID) pszProfileName,

(DWORD) (wcslen(pszProfileName) * sizeof(WCHAR)) }; return WcsOpenColorProfile(&profile, NULL, NULL, PROFILE_READ,

FILE_SHARE_READ, OPEN_EXISTING, 0);

}

HRESULT SetupColorTransform(const WCHAR * pszDestProfileName)

{

HRESULT hr = S_OK; HPROFILE hProfile[2]; hProfile[0] = OpenColorProfile(L"wscRGB.cdmp"); hProfile[1] = OpenColorProfile(pszDestProfileName);

DWORD intents = INTENT_ABSOLUTE_COLORIMETRIC; m_hColorTrans = CreateMultiProfileTransform(hProfile, 2, &intents, 1,

WCS_ALWAYS | BEST_MODE, INDEX_DONT_CARE) ;

CloseColorProfile(hProfile[0]);

CloseColorProfile(hProfile[1]); return hr;

}

Color Filter: Page Processing

HRESULT CColorFilter::ProcessFixedPage(IFixedPage* pFP)

{

HRESULT hr = S_OK;

CComPtr<IPrintWriteStream> pWriter; if (SUCCEEDED(hr = pFP-> GetWriteStream(&pWriter) )) {

CComPtr<IPrintReadStream> pReader; if (SUCCEEDED(hr = pFP-> GetStream(&pReader) )) {

CXmlFilter filter(pWriter, pReader) ; // XML filter while ( filter.GetToken() ) if ( wcscmp(filter.m_token, L"ImageSource") == 0 ) { filter.GetToken(); // = filter.GetToken(); // URI for ImageSource

ConvertImage(filter.m_token, filter.m_tokenlen,

COUNTOF(filter.m_token), pFP) ;

}

}

} pWriter->Close();

} return hr;

}

Color Filter: Transform Image

HRESULT ConvertWriteImage(pStream, imageUri, pFixedPage)

{

HRESULT hr = S_OK;

CComPtr<IUnknown> pRead;

CComPtr<IPartImage> pImagePart;

CComPtr<IPrintReadStream> pImageStream; if (SUCCEEDED(hr = pFixedPage->GetPagePart(imageUri, &pRead) ) &&

SUCCEEDED(hr = pRead.QueryInterface(&pImagePart)) &&

SUCCEEDED(hr = pImagePart->GetStream(&pImageStream) )) {

CImage src; CImage dst;

CPrintStream2IStream readStream(pImageStream, NULL); hr = src.Load(& readStream, m_pImagingFactory) ; hr = dst.Create(src.m_Width,src.m_Height,BM_BGRTRIPLETS) ;

TranslateBitmapBits(m_hColorTrans, src.m_pBuffer, src.m_icmFormat, src.m_Width, src.m_Height, src.m_Stride, dst.m_pBuffer, dst.m_icmFormat, dst.m_Stride, NULL, NULL) ;

}

CPrintStream2IStream writeStream(NULL, pStream); hr = dst.Save(& writeStream, m_pImagingFactory) ;

} return hr;

Scenario: Configuration

During printing, XPSDrv configuration module optimizes

PrintTicket settings and provides additional services to

XPSDrv filters

Scenario: Configuration

The XPSDrv architecture supports the ability to customize the configuration data and offer additional configuration services

DrvDocumentEvents – Using new document events, XPSDrv configuration modules can pre-process PrintTicket setting sent by

Windows Presentation Foundation

(WPF) applications

Filter Services – The configuration module can publish helper services for use at print time by filters

Scenario: Configuration

Example Data Flow

User prints from a WPF application

DocumentEvents are intercepted by the configuration module and PrintTickets are added or modified

When filters are processing the XPS file, the filter queries a configuration service to assist in constraint resolution

Configuration Architecture

WPF Print

APIs

XPS Spool

File

Sample XPSDrv Print Driver

Configuration Module

Implement and

Register for PT

DrvDocum entEvents

Overwrite

FDS

PrintTicket

Remove

FD/FP

PrintTicket

(s)

Filter Pipeline

Configuration Filter

Extract all settings from embedded

PrintTicket

Retrieve

Control

Strings

MS Component

ISV Component

IHV Component

Print Subsystem

Add

Control

String to

Content

IPrintCoreHelper

Filter Service

Configuration Module

DOCEVENT_FILTER * p = (DOCEVENT_FILTER*) pvOut; switch (iEsc) { case DOCUMENTEVENT_XPS_QUERYFILTER : if (p->cElementsAllocated >= 7) { p->aDocEventCall[0] =

DOCUMENTEVENT_XPS_ADDFIXEDDOCUMENTSEQUENCEPRINTTICKETPRE ; p->aDocEventCall[1] =

DOCUMENTEVENT_XPS_ADDFIXEDDOCUMENTSEQUENCEPRINTTICKETPOST ;

...

p->cElementsReturned = 7;

} else { p->cElementsNeeded = 7; } break; case DOCUMENTEVENT_XPS_ADDFIXEDDOCUMENTSEQUENCEPRINTTICKETPRE :

*((PrintPropertiesCollection **) pvOut) =

ReplacePT((PrintPropertiesCollection *) pvIn); break; case DOCUMENTEVENT_XPS_ADDFIXEDDOCUMENTSEQUENCEPRINTTICKETPOST :

DeleteCollection(*((PrintPropertiesCollection **) pvIn)); break;

}

Configuration Filter

HRESULT STDMETHODCALLTYPE StartOperation(VOID)

{

HRESULT hr;

CComPtr<IPartPrintTicket> pPrintTicket; while (SUCCEEDED(hr = m_pProvider->GetXpsPart(&pUnk)) {

CComPtr<IXpsDocument> pXD;

CComPtr<IFixedDocumentSequence> pFDS; if (SUCCEEDED(pUnk.QueryInterface(&pXD))) { hr = m_pConsumer->SendXpsDocument(pXD);

} else if (SUCCEEDED(pUnk.QueryInterface(&pFDS))) { if (pPrintTicket == NULL) { pFDS->GetPrintTicket(& pPrintTicket);

} hr = m_pConsumer->SendFixedDocumentSequence(pFDS);

}

...

}

AddPage(pPrintTicket);

...

return hr;

}

Configuration Filter

HRESULT CConfigurationFilter::AddPage(IPartPrintTicket * pPrintTicket)

{

CComPtr<IFixedPage> pNewPage;

CComPtr<IPrintWriteStream> pNewPageMarkupStream;

CComPtr<IPartFont> pNewFont;

CComPtr<IPrintWriteStream> pNewFontStream; m_pConsumer->GetNewEmptyPart(L"newpage.xaml", IID_IFixedPage, reinterpret_cast<void **>(&pNewPage), &pNewPageMarkupStream); m_pConsumer->GetNewEmptyPart(L"new.ttf", IID_IPartFont, reinterpret_cast<void **>(&pNewFont), &pNewFontStream);

AddFontToPage(L"new.ttf", pNewFont, pNewFontStream, pNewPage);

CComPtr<IPrintReadStream> ptStream; pPrintTicket->GetStream(& ptStream);

AddTextToPage(pNewPageMarkupStream, ptStream, m_pCoreHelper, "new.ttf"); return S_OK;

}

Configuration Filter

HRESULT AddTextToPage(IPrintWriteStream *pPageMarkupStream,

IPrintReadStream * ptStream, IPrintCoreHelperUni * pPrintHelper, const char * pFont)

{

CXpsWriter writer(pPageMarkupStream); writer.Write("<FixedPage Width=\"816\" Height=\"1056\" xmlns="

"\"http://schemas.microsoft.com/xps/2005/06\" xml:lang=\"en-US\">");

{ CPrintTicketSaxHandler sax(writer, pFont, black);

CComPtr<ISAXXMLReader> pSaxRdr; pSaxRdr.CoCreateInstance(CLSID_SAXXMLReader60); pSaxRdr->putContentHandler(& sax); pfp::PrintReadStreamToSeqStream reader(ptStream); pSaxRdr->parse(CComVariant(& reader));

}

{ CComPtr<IStream> pStream; pPrintHelper->CreateDefaultGDLSnapshot(0, & pStream);

CGDLSaxHandler sax(writer, pFont, black);

CComPtr<ISAXXMLReader> pSaxRdr; pSaxRdr.CoCreateInstance(CLSID_SAXXMLReader60); pSaxRdr->putContentHandler(& sax); pSaxRdr->parse(CComVariant(pStream);

} return writer.Write("</FixedPage>");

}

Scenario: Notifications

While processing a print job, a filter sends async notifications to a custom status monitor

Scenario: Notifications

The hierarchy of XPS Documents and the modular nature of XPSDrv filters facilitate incremental process that can be communicated using system services

Async Notification – The Windows Vista spooler includes an async notification engine for communication and UI messages

XPS IFC – The structured nature of the

XPS Document and the XPS Inter-filter

Communicator identify key steps in document processing

Scenario: Notifications

Example Data Flow

As an XPS Document is rendered in filters, rendering progress is communicated through notification events dispatched by the filter

Notification Architecture

MS Component

ISV Component

IHV Component

Print Subsystem

XPS Doc

(Spool File)

Filter Pipeline

Notification Filter

Send Job

Processing via

ReportJob

Progress

Notification Filter

STDMETHODIMP XpsFilter::InitializeFilter(

__in IInterFilterCommunicator *pIfc,

__in IPrintPipelinePropertyBag *pIPropertyBag,

__in IPrintPipelineManagerControl *pIPipelineControl

)

{

...

VARIANT var;

VariantInit(&var); pIPropertyBag->GetProperty(XPS_FP_PROGRESS_REPORT, &var);

Tools::SmartPtr<IUnknown> pUnk = V_UNKNOWN(&var);

VariantClear(&var); pUnk->QueryInterface(IID_IPrintPipelineProgressReport, reinterpret_cast<void **>(&m_pProgressReport));

...

}

Notification Filter

HRESULT XpsFilter::ProcessFixedDoc(__in void *pVoid)

{

Tools::SmartPtr<IFixedDocument> pIFixedDocument; pIFixedDocument.Attach(static_cast<IFixedDocument *>(pVoid));

HRESULT hRes = m_pXpsConsumer->SendFixedDocument(pIFixedDocument); if (SUCCEEDED(hRes))

{ m_pProgressReport->ReportProgress(XpsJob_FixedDocumentAdded);

} return hRes;

}

HRESULT XpsFilter::ProcessFixedPage(__in void *pVoid)

{

Tools::SmartPtr<IFixedPage> pIFixedPage; pIFixedPage.Attach(static_cast<IFixedPage *>(pVoid));

HRESULT hRes = m_pXpsConsumer->SendFixedPage(pIFixedPage); if (SUCCEEDED(hRes))

{ m_pProgressReport->ReportProgress(XpsJob_FixedPageAdded);

} return hRes;

}

Call To Action

Test for compatibility now!

Test the GDI Print Path, XPS Print Path and compatibility paths

Report problems immediately

Plan for XPSDrv support

Host-based printers

Pass-through XPSDrv drivers for XPScapable devices (direct consumption)

Start implementation now

Aim for Windows Vista launch availability

Call To Action

Understand your company logo goals and review new logo requirements

Basic and Premium

At WinHEC

Practice driver dev and testing skills in XPS Printing hands on labs

Ask the Experts at lunch today

Visit the Microsoft Pavilion to see XPS demos

Read XPSDrv Print Drivers and the Windows Color System on http://www.microsoft.com/whdc/device/print/default.mspx

Attend related sessions

PRI050 Inside Printer Installation on Windows Vista

PRI039 Using the Windows Color System in Device Drivers

PRI077 Print Driver and XPSDrv Testing in Windows Vista

PRI019 Developing XPSDrv Print Drivers

PRI115 Windows Media Photo: A New Format for

End-to-End Digital Imaging

Additional Resources

Technical advice

XPSinfo @ microsoft.com

Prninfo @ microsoft.com

mscolor @ microsoft.com

WDK and SDK

Online

XPS Portal http://www.microsoft.com/xps , links to relevant blogs, white papers, specs

WHDC Printing documents http://www.microsoft.com/whdc/device/print/default.mspx

WHDC Color documents http://www.microsoft.com/whdc/device/display/color/default.mspx

Windows Digital Documents Platform Team Newsletter https://profile.microsoft.com/RegSysProfileCenter/subscriptionwizard.aspx

?wizid=77d9786e-9500-40a4-ba20-a4c7504d83ca&lcid=1033

© 2006 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.

The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation.

MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.