30#include <winrt/base.h> 
   31#include <winrt/Windows.Foundation.h> 
   32#include <winrt/Windows.Foundation.Collections.h> 
   33#include <winrt/Windows.Graphics.Printing.h> 
   34#include <winrt/Windows.UI.Xaml.h> 
   35#include <winrt/Windows.UI.Xaml.Controls.h> 
   36#include <winrt/Windows.UI.Xaml.Media.h> 
   37#include <winrt/Windows.UI.Xaml.Printing.h> 
   38#include <winrt/Windows.UI.Xaml.Hosting.h> 
   39#include <winrt/Windows.Storage.h> 
   40#include <winrt/Windows.Storage.Streams.h> 
   41#include <winrt/Windows.Data.Pdf.h> 
   42#include <winrt/Windows.Graphics.Imaging.h> 
   44#include <winrt/base.h> 
   45#include <winrt/Windows.Foundation.h> 
   46#include <winrt/Windows.Foundation.Collections.h> 
   47#include <winrt/Windows.Graphics.Printing.h> 
   48#include <winrt/Windows.UI.Xaml.h> 
   49#include <winrt/Windows.UI.Xaml.Controls.h> 
   50#include <winrt/Windows.UI.Xaml.Media.Imaging.h> 
   51#include <winrt/Windows.UI.Xaml.Printing.h> 
   52#include <winrt/Windows.UI.Xaml.Hosting.h> 
   53#include <winrt/Windows.Storage.h> 
   54#include <winrt/Windows.Storage.Streams.h> 
   55#include <winrt/Windows.Data.Pdf.h> 
   56#include <winrt/Windows.Graphics.Imaging.h> 
   63MIDL_INTERFACE(
"C5435A42-8D43-4E7B-A68A-EF311E392087")
 
   64IPrintManagerInterop : public ::IInspectable
 
   67    virtual HRESULT STDMETHODCALLTYPE GetForWindow(
 
   74         void **operation) = 0;
 
   78MIDL_INTERFACE(
"3cbcf1bf-2f76-4e9c-96ab-e84b37972554")
 
   79IDesktopWindowXamlSourceNative : public ::IUnknown
 
   82    virtual HRESULT STDMETHODCALLTYPE AttachToWindow(
 
   89static inline std::pair<uint32_t, uint32_t> 
DpToPixels( winrt::Windows::Data::Pdf::PdfPage 
const& page, 
double dpi )
 
   91    const auto   s = page.Size(); 
 
   92    const double scale = dpi / 96.0;
 
   93    uint32_t     w = 
static_cast<uint32_t
>( std::max( 1.0, std::floor( s.Width * 
scale + 0.5 ) ) );
 
   94    uint32_t     h = 
static_cast<uint32_t
>( std::max( 1.0, std::floor( s.Height * 
scale + 0.5 ) ) );
 
 
  101    winrt::Windows::UI::Xaml::Controls::Image 
image;
 
  102    winrt::Windows::Storage::Streams::InMemoryRandomAccessStream 
stream;
 
  105    ManagedImage(winrt::Windows::UI::Xaml::Controls::Image img, winrt::Windows::Storage::Streams::InMemoryRandomAccessStream str) : 
image(img), 
stream(str) {}
 
  108        : 
image(std::move(other.image)), 
stream(std::move(other.stream)) {}
 
 
  111        if (
this != &other) {
 
  112            image = std::move(other.image);
 
  113            stream = std::move(other.stream);
 
 
 
  124    auto page = pdf.GetPage( pageIndex );
 
  128        wxLogTrace( 
PRINTING_TRACE, 
"Failed to get page %u from PDF document", pageIndex );
 
  134    winrt::Windows::Data::Pdf::PdfPageRenderOptions opts;
 
  135    opts.DestinationWidth( pxW );
 
  136    opts.DestinationHeight( pxH );
 
  138    winrt::Windows::Storage::Streams::InMemoryRandomAccessStream stream;
 
  142        page.RenderToStreamAsync( stream, opts ).get(); 
 
  144    catch( std::exception& e )
 
  146        wxLogTrace( 
PRINTING_TRACE, 
"Failed to render page %u to image: %s", pageIndex, e.what() );
 
  151    winrt::Windows::UI::Xaml::Media::Imaging::BitmapImage bmp;
 
  156        bmp.SetSourceAsync( stream ).get();
 
  158    catch( 
const winrt::hresult_error& e )
 
  160        wxLogTrace( 
PRINTING_TRACE, 
"Failed to set BitmapImage source for page %u: %s", pageIndex, e.message().c_str() );
 
  163    catch( std::exception& e )
 
  165        wxLogTrace( 
PRINTING_TRACE, 
"Failed to set BitmapImage source for page %u: %s", pageIndex, e.what() );
 
  169    winrt::Windows::UI::Xaml::Controls::Image img;
 
  171    img.Stretch( winrt::Windows::UI::Xaml::Media::Stretch::Uniform );
 
 
  184    WIN_PDF_PRINTER( HWND hwndOwner, winrt::Windows::Data::Pdf::PdfDocument 
const& pdf ) :
 
 
  199        m_xamlSource = winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource();
 
  200        auto native = 
m_xamlSource.as<IDesktopWindowXamlSourceNative>();
 
  204            wxLogTrace( 
PRINTING_TRACE, 
"Failed to create XAML Island host" );
 
  208        RECT rc{ 0, 0, 100, 100 }; 
 
  209        m_host = ::CreateWindowExW( 0, 
L"STATIC", 
L"", WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
 
  210                                    rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, 
m_hwnd, 
nullptr,
 
  211                                    ::GetModuleHandleW( 
nullptr ), 
nullptr );
 
  213        auto cleanup_guard = std::unique_ptr<void, std::function<void( 
void* )>>
 
  214                            ( (
void*) 1, [
this]( 
void* ){ this->
cleanup(); } );
 
  222        if( FAILED( native->AttachToWindow( 
m_host ) ) )
 
  224            wxLogTrace( 
PRINTING_TRACE, 
"Failed to attach XAML Island to host window" );
 
  228        m_root = winrt::Windows::UI::Xaml::Controls::Grid();
 
  231        m_printDoc = winrt::Windows::UI::Xaml::Printing::PrintDocument();
 
  236                [
this]( winrt::Windows::Foundation::IInspectable 
const& sender, winrt::Windows::UI::Xaml::Printing::PaginateEventArgs 
const& e )
 
  238                    m_printDoc.SetPreviewPageCount( 
m_pageCount, winrt::Windows::UI::Xaml::Printing::PreviewPageCountType::Final );
 
  242                [
this]( winrt::Windows::Foundation::IInspectable 
const& sender, winrt::Windows::UI::Xaml::Printing::GetPreviewPageEventArgs 
const& e )
 
  244                    const uint32_t index = e.PageNumber() - 1; 
 
  246                    if( managedImg.image )
 
  255                [
this]( winrt::Windows::Foundation::IInspectable 
const& sender, winrt::Windows::UI::Xaml::Printing::AddPagesEventArgs 
const& e )
 
  260                        if( managedImg.image )
 
  272            auto factory = winrt::get_activation_factory<winrt::Windows::Graphics::Printing::PrintManager>();
 
  273            auto pmInterop = factory.as<IPrintManagerInterop>();
 
  275            winrt::Windows::Graphics::Printing::PrintManager 
printManager{ 
nullptr };
 
  277            if( FAILED( pmInterop->GetForWindow( 
m_hwnd,
 
  278                                                 winrt::guid_of<winrt::Windows::Graphics::Printing::PrintManager>(),
 
  281                wxLogTrace( 
PRINTING_TRACE, 
"Failed to get PrintManager for window" );
 
  288                    [
this]( winrt::Windows::Foundation::IInspectable 
const& sender, winrt::Windows::Graphics::Printing::PrintTaskRequestedEventArgs 
const& e )
 
  290                        auto task = e.Request().CreatePrintTask( 
L"KiCad PDF Print",
 
  291                                [
this]( winrt::Windows::Graphics::Printing::PrintTaskSourceRequestedArgs 
const& sourceRequestedArgs )
 
  294                                    sourceRequestedArgs.SetSource( 
m_docSrc );
 
  298            winrt::Windows::Foundation::IAsyncOperation<bool> asyncOp{ 
nullptr };
 
  301            if( FAILED( pmInterop->ShowPrintUIForWindowAsync( 
m_hwnd, winrt::put_abi(asyncOp) ) ) )
 
  303                wxLogTrace( 
PRINTING_TRACE, 
"Failed to show print UI for window" );
 
  311                shown = asyncOp.GetResults();
 
  313            catch( std::exception& e )
 
  315                wxLogTrace( 
PRINTING_TRACE, 
"GetResults threw an exception for the print window: %s", e.what() );
 
  321        catch( std::exception& e )
 
  323            wxLogTrace( 
PRINTING_TRACE, 
"Exception caught in print operation: %s", e.what() );
 
 
  354            ::DestroyWindow( 
m_host );
 
 
  363    winrt::Windows::Data::Pdf::PdfDocument 
m_pdf{ 
nullptr };
 
  365    winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource 
m_xamlSource{ 
nullptr };
 
  366    winrt::Windows::UI::Xaml::Controls::Grid                   
m_root{ 
nullptr };
 
  367    winrt::Windows::UI::Xaml::Printing::PrintDocument          
m_printDoc{ 
nullptr };
 
  368    winrt::Windows::Graphics::Printing::IPrintDocumentSource   
m_docSrc{ 
nullptr };
 
  371    winrt::Windows::Graphics::Printing::PrintManager 
m_rtPM{ 
nullptr };
 
 
  388    if( s.empty() ) 
return {};
 
  390    int          len = MultiByteToWideChar( CP_UTF8, 0, s.data(), (
int) s.size(), 
nullptr, 0 );
 
  391    std::wstring out( len, 
L'\0' );
 
  393    MultiByteToWideChar( CP_UTF8, 0, s.data(), (
int) s.size(), out.data(), len );
 
 
  400    DWORD attrs = GetFileAttributesA( aFile.c_str() );
 
  402    if( attrs == INVALID_FILE_ATTRIBUTES )
 
  406    winrt::Windows::Data::Pdf::PdfDocument pdf{ 
nullptr };
 
  411        auto file = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync( winrt::hstring( 
path ) ).get();
 
  412        pdf = winrt::Windows::Data::Pdf::PdfDocument::LoadFromFileAsync( file ).get();
 
  421    HWND hwndOwner = ::GetActiveWindow();
 
  422    if( !hwndOwner ) hwndOwner = ::GetForegroundWindow();
 
  428        return printer.Run();
 
ManagedImage & operator=(ManagedImage &&other) noexcept
 
winrt::Windows::UI::Xaml::Controls::Image image
 
winrt::Windows::Storage::Streams::InMemoryRandomAccessStream stream
 
ManagedImage(ManagedImage &&other) noexcept
 
ManagedImage(winrt::Windows::UI::Xaml::Controls::Image img, winrt::Windows::Storage::Streams::InMemoryRandomAccessStream str)
 
IPrintManagerInterop REFIID riid
 
static ManagedImage RenderPdfPageToImage(winrt::Windows::Data::Pdf::PdfDocument const &pdf, uint32_t pageIndex, double dpi)
 
virtual HRESULT STDMETHODCALLTYPE get_WindowHandle(HWND *hWnd)=0
 
virtual HRESULT STDMETHODCALLTYPE ShowPrintUIForWindowAsync(HWND appWindow, void **operation)=0
 
static std::pair< uint32_t, uint32_t > DpToPixels(winrt::Windows::Data::Pdf::PdfPage const &page, double dpi)
 
IPrintManagerInterop REFIID void ** printManager