summaryrefslogtreecommitdiff
path: root/platform/winrt/mupdf_cpp/PrintPage.cpp
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2013-11-08 18:13:49 -0800
committerMichael Vrhel <michael.vrhel@artifex.com>2013-11-11 10:47:55 -0800
commit6afafa79e302e4d23b5c82182359619b59c64f6a (patch)
treef013fb415c1c7a1892c3b8f366e39671f293f033 /platform/winrt/mupdf_cpp/PrintPage.cpp
parent7570e7fa8a40cb41db6a1ab14b225cf00c4f56f5 (diff)
downloadmupdf-6afafa79e302e4d23b5c82182359619b59c64f6a.tar.xz
DirectX printing added
After much research it was determined that use of the DirectX 2D methods is the proper way to add printing support to a Windows 8 application. This enables the pages to be rendered as they are requested by the print thread. This occurs for both the print preview screen as well as the print to the output device.
Diffstat (limited to 'platform/winrt/mupdf_cpp/PrintPage.cpp')
-rw-r--r--platform/winrt/mupdf_cpp/PrintPage.cpp165
1 files changed, 165 insertions, 0 deletions
diff --git a/platform/winrt/mupdf_cpp/PrintPage.cpp b/platform/winrt/mupdf_cpp/PrintPage.cpp
new file mode 100644
index 00000000..5e14f191
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/PrintPage.cpp
@@ -0,0 +1,165 @@
+#include "pch.h"
+#include "PrintPage.h"
+
+using namespace Microsoft::WRL;
+using namespace Windows::Graphics::Printing;
+
+#pragma region IDocumentPageSource Methods
+
+/* This is the interface to the print thread calls */
+IFACEMETHODIMP
+PrintPages::GetPreviewPageCollection(IPrintDocumentPackageTarget* doc_target,
+ IPrintPreviewPageCollection** doc_collection)
+{
+ HRESULT hr = (doc_target != nullptr) ? S_OK : E_INVALIDARG;
+
+ if (SUCCEEDED(hr))
+ {
+ hr = doc_target->GetPackageTarget(ID_PREVIEWPACKAGETARGET_DXGI,
+ IID_PPV_ARGS(&m_dxgi_previewtarget));
+ }
+ ComPtr<IPrintPreviewPageCollection> page_collection;
+ if (SUCCEEDED(hr))
+ {
+ ComPtr<PrintPages> docSource(this);
+ hr = docSource.As<IPrintPreviewPageCollection>(&page_collection);
+ }
+ if (SUCCEEDED(hr))
+ hr = page_collection.CopyTo(doc_collection);
+
+ if (SUCCEEDED(hr))
+ this->m_renderer->SetPrintTarget((void*) this);
+ return hr;
+}
+
+IFACEMETHODIMP
+PrintPages::MakeDocument(IInspectable* doc_options, IPrintDocumentPackageTarget* doc_target)
+{
+ if (doc_options == nullptr || doc_target == nullptr)
+ return E_INVALIDARG;
+
+ PrintTaskOptions^ option = reinterpret_cast<PrintTaskOptions^>(doc_options);
+ PrintPageDescription page_desc = option->GetPageDescription(1);
+
+ D2D1_PRINT_CONTROL_PROPERTIES print_properties;
+
+ print_properties.rasterDPI = (float)(min(page_desc.DpiX, page_desc.DpiY));
+ print_properties.colorSpace = D2D1_COLOR_SPACE_SRGB;
+ print_properties.fontSubset = D2D1_PRINT_FONT_SUBSET_MODE_DEFAULT;
+
+ HRESULT hr = S_OK;
+
+ try
+ {
+ m_renderer->CreatePrintControl(doc_target, &print_properties);
+
+ D2D1_RECT_F imageableRect = D2D1::RectF(page_desc.ImageableRect.X,
+ page_desc.ImageableRect.Y,
+ page_desc.ImageableRect.X + page_desc.ImageableRect.Width,
+ page_desc.ImageableRect.Y + page_desc.ImageableRect.Height);
+
+ D2D1_SIZE_F pageSize = D2D1::SizeF(page_desc.PageSize.Width, page_desc.PageSize.Height);
+ m_totalpages = m_renderer->GetPrintPageCount();
+
+ for (uint32 page_num = 1; page_num <= m_totalpages; ++page_num)
+ m_renderer->PrintPage(page_num, imageableRect, pageSize, page_desc.DpiX, nullptr);
+ }
+ catch (Platform::Exception^ e)
+ {
+ hr = e->HResult;
+ }
+
+ HRESULT hrClose = m_renderer->ClosePrintControl();
+ if (SUCCEEDED(hr))
+ {
+ hr = hrClose;
+ }
+ return hr;
+}
+
+#pragma endregion IDocumentPageSource Methods
+
+#pragma region IPrintPreviewPageCollection Methods
+
+IFACEMETHODIMP
+PrintPages::Paginate(uint32 current_jobpage, IInspectable* doc_options)
+{
+ HRESULT hr = (doc_options != nullptr) ? S_OK : E_INVALIDARG;
+
+ if (SUCCEEDED(hr))
+ {
+ PrintTaskOptions^ option = reinterpret_cast<PrintTaskOptions^>(doc_options);
+ PrintPageDescription page_desc = option->GetPageDescription(current_jobpage);
+
+ hr = m_dxgi_previewtarget->InvalidatePreview();
+ m_totalpages = m_renderer->GetPrintPageCount();
+
+ if (SUCCEEDED(hr))
+ hr = m_dxgi_previewtarget->SetJobPageCount(PageCountType::FinalPageCount, m_totalpages);
+
+ if (SUCCEEDED(hr))
+ {
+ m_width = page_desc.PageSize.Width;
+ m_height = page_desc.PageSize.Height;
+ m_imageable_rect = D2D1::RectF(page_desc.ImageableRect.X, page_desc.ImageableRect.Y,
+ page_desc.ImageableRect.X + page_desc.ImageableRect.Width,
+ page_desc.ImageableRect.Y + page_desc.ImageableRect.Height);
+ m_paginate_called = true;
+ }
+ }
+ return hr;
+}
+
+float
+PrintPages::TransformedPageSize(float desired_width, float desired_height,
+ Windows::Foundation::Size* preview_size)
+{
+ float scale = 1.0f;
+
+ if (desired_width > 0 && desired_height > 0)
+ {
+ preview_size->Width = desired_width;
+ preview_size->Height = desired_height;
+ scale = m_width / desired_width;
+ }
+ else
+ {
+ preview_size->Width = 0;
+ preview_size->Height = 0;
+ }
+ return scale;
+}
+
+void
+PrintPages::ResetPreview()
+{
+ m_dxgi_previewtarget->InvalidatePreview();
+}
+
+IFACEMETHODIMP
+PrintPages::MakePage(uint32 desired_jobpage, float width, float height)
+{
+ HRESULT hr = (width > 0 && height > 0) ? S_OK : E_INVALIDARG;
+
+ if (desired_jobpage == JOB_PAGE_APPLICATION_DEFINED && m_paginate_called)
+ desired_jobpage = 1;
+
+ if (SUCCEEDED(hr) && m_paginate_called)
+ {
+ Windows::Foundation::Size preview_size;
+ float scale = TransformedPageSize(width, height, &preview_size);
+
+ try
+ {
+ m_renderer->DrawPreviewSurface(preview_size.Width, preview_size.Height,
+ scale, m_imageable_rect, desired_jobpage,
+ m_dxgi_previewtarget.Get());
+ }
+ catch (Platform::Exception^ e)
+ {
+ hr = e->HResult;
+ }
+ }
+ return hr;
+}
+#pragma region IPrintPreviewPageCollection Methods