diff options
Diffstat (limited to 'platform/windows/mupdf_cpp/PrintPage.cpp')
-rw-r--r-- | platform/windows/mupdf_cpp/PrintPage.cpp | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/platform/windows/mupdf_cpp/PrintPage.cpp b/platform/windows/mupdf_cpp/PrintPage.cpp new file mode 100644 index 00000000..83d31791 --- /dev/null +++ b/platform/windows/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, (float) 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 |