summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2013-11-04 10:36:10 -0800
committerMichael Vrhel <michael.vrhel@artifex.com>2013-11-04 10:37:18 -0800
commit52ec654a3a5e36f8a6c1ffd52c57fe8ec8fbb29b (patch)
tree5a22a9199bd6a5bb106e6983d6029c9e1e53a978 /platform
parent77ceaf6e2398957fe53a5056c24413b21e548f4b (diff)
downloadmupdf-52ec654a3a5e36f8a6c1ffd52c57fe8ec8fbb29b.tar.xz
Addition of printing support.
This uses the xaml printing methods. It is likely that I need to go do a DirectX approach since the xaml printing method could run into memory problems as it seems the architecture requires all the pages to be rendered prior to the print job even starting. Currently checking on this with a contact at MS. I wanted to get this code in place now since it is working and it has the needed framework for much of what we want. A change to DirectX requires a changes in the solution file that may be complicated and so it makes sense to do a split here with respect to providing printing support.
Diffstat (limited to 'platform')
-rw-r--r--platform/winrt/mupdf_cpp/DocumentPage.h1
-rw-r--r--platform/winrt/mupdf_cpp/MainPage.xaml.cpp616
-rw-r--r--platform/winrt/mupdf_cpp/MainPage.xaml.h98
3 files changed, 665 insertions, 50 deletions
diff --git a/platform/winrt/mupdf_cpp/DocumentPage.h b/platform/winrt/mupdf_cpp/DocumentPage.h
index 336e6007..89bf6674 100644
--- a/platform/winrt/mupdf_cpp/DocumentPage.h
+++ b/platform/winrt/mupdf_cpp/DocumentPage.h
@@ -14,6 +14,7 @@ typedef enum {
THUMBNAIL,
DUMMY,
OLD_RESOLUTION,
+ PRINT_PREVIEW,
NOTSET
} Page_Content_t;
diff --git a/platform/winrt/mupdf_cpp/MainPage.xaml.cpp b/platform/winrt/mupdf_cpp/MainPage.xaml.cpp
index 51fbe2ab..767cba97 100644
--- a/platform/winrt/mupdf_cpp/MainPage.xaml.cpp
+++ b/platform/winrt/mupdf_cpp/MainPage.xaml.cpp
@@ -5,6 +5,8 @@
#include "pch.h"
#include "MainPage.xaml.h"
+#include <regex>
+#include <sstream>
#define LOOK_AHEAD 1 /* A +/- count on the pages to pre-render */
#define LOOK_AHEAD_SCALE 10 /* A +/- count on the pages to adjust for scale change */
@@ -12,6 +14,7 @@
#define MIN_SCALE 0.5
#define SCALE_THUMB 0.1
+#define PRINT_PREVIEW_SCALE 0.5
#define BLANK_WIDTH 17
#define BLANK_HEIGHT 22
@@ -25,6 +28,8 @@
#define ZOOM_IN 0
#define ZOOM_OUT 1
+#define PRINTPREVIEWDPI 96;
+
static float screenScale = 1;
using namespace mupdf_cpp;
@@ -36,6 +41,7 @@ using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::Graphics::Display;
+using namespace Windows::Graphics::Printing;
//****************** Added *****************
using namespace Windows::Storage::Pickers;
@@ -75,7 +81,7 @@ extern "C" {
#endif /* not NDEBUG */
-mupdf_cpp::MainPage::MainPage()
+MainPage::MainPage()
{
InitializeComponent();
Application::Current->Suspending +=
@@ -86,10 +92,12 @@ mupdf_cpp::MainPage::MainPage()
m_linkcolor="#40AC7225";
mu_doc = nullptr;
m_docPages = ref new Platform::Collections::Vector<DocumentPage^>();
+ m_printpages = ref new Platform::Collections::Vector<DocumentPage^>();
m_thumbnails = ref new Platform::Collections::Vector<DocumentPage^>();
m_page_link_list = ref new Platform::Collections::Vector<IVector<RectList^>^>();
m_text_list = ref new Platform::Collections::Vector<RectList^>();
m_linkset = ref new Platform::Collections::Vector<int>();
+ RegisterForPrinting();
CleanUp();
RecordMainThread();
/* So that we can catch special loading events (e.g. open with) */
@@ -123,7 +131,7 @@ void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
}
-void mupdf_cpp::MainPage::ExceptionHandler(Object^ sender, UnhandledExceptionEventArgs^ e)
+void MainPage::ExceptionHandler(Object^ sender, UnhandledExceptionEventArgs^ e)
{
if (!this->m_init_done)
{
@@ -140,22 +148,22 @@ void mupdf_cpp::MainPage::ExceptionHandler(Object^ sender, UnhandledExceptionEve
}
}
-void mupdf_cpp::MainPage::App_Suspending(Object^ sender, SuspendingEventArgs^ e)
+void MainPage::App_Suspending(Object^ sender, SuspendingEventArgs^ e)
{
}
-void mupdf_cpp::MainPage::ExitInvokedHandler(Windows::UI::Popups::IUICommand^ command)
+void MainPage::ExitInvokedHandler(Windows::UI::Popups::IUICommand^ command)
{
}
-void mupdf_cpp::MainPage::OKInvokedHandler(Windows::UI::Popups::IUICommand^ command)
+void MainPage::OKInvokedHandler(Windows::UI::Popups::IUICommand^ command)
{
}
-void mupdf_cpp::MainPage::NotifyUser(String^ strMessage, NotifyType_t type)
+void MainPage::NotifyUser(String^ strMessage, int type)
{
MessageDialog^ msg = ref new MessageDialog(strMessage);
UICommand^ ExitCommand = nullptr;
@@ -165,7 +173,7 @@ void mupdf_cpp::MainPage::NotifyUser(String^ strMessage, NotifyType_t type)
{
case StatusMessage:
OKCommand = ref new UICommand("OK",
- ref new UICommandInvokedHandler(this, &mupdf_cpp::MainPage::OKInvokedHandler));
+ ref new UICommandInvokedHandler(this, &MainPage::OKInvokedHandler));
msg->Commands->Append(OKCommand);
/// Set the command that will be invoked by default
msg->DefaultCommandIndex = 0;
@@ -174,7 +182,7 @@ void mupdf_cpp::MainPage::NotifyUser(String^ strMessage, NotifyType_t type)
break;
case ErrorMessage:
ExitCommand = ref new UICommand("Exit",
- ref new UICommandInvokedHandler(this, &mupdf_cpp::MainPage::ExitInvokedHandler));
+ ref new UICommandInvokedHandler(this, &MainPage::ExitInvokedHandler));
msg->Commands->Append(ExitCommand);
/// Set the command that will be invoked by default
msg->DefaultCommandIndex = 0;
@@ -188,7 +196,7 @@ void mupdf_cpp::MainPage::NotifyUser(String^ strMessage, NotifyType_t type)
msg->ShowAsync();
}
-bool mupdf_cpp::MainPage::EnsureUnsnapped()
+bool MainPage::EnsureUnsnapped()
{
// FilePicker APIs will not work if the application is in a snapped state.
// If an app wants to show a FilePicker while snapped, it must attempt to unsnap first
@@ -202,7 +210,7 @@ bool mupdf_cpp::MainPage::EnsureUnsnapped()
return unsnapped;
}
-void mupdf_cpp::MainPage::Picker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void MainPage::Picker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (!EnsureUnsnapped())
return;
@@ -407,7 +415,7 @@ void MainPage::CreateBlank(int width, int height)
m_BlankBmp = bmp;
}
-void mupdf_cpp::MainPage::SetFlipView()
+void MainPage::SetFlipView()
{
int height = this->ActualHeight;
int width = this->ActualWidth;
@@ -422,7 +430,7 @@ void mupdf_cpp::MainPage::SetFlipView()
/* Clean up everything as we are opening a new document after having another
one open */
-void mupdf_cpp::MainPage::CleanUp()
+void MainPage::CleanUp()
{
m_init_done = false;
/* Remove current pages in the flipviews */
@@ -430,11 +438,15 @@ void mupdf_cpp::MainPage::CleanUp()
m_docPages->Clear();
if (m_thumbnails != nullptr && m_thumbnails->Size > 0)
m_thumbnails->Clear();
+ if (m_printpages != nullptr && m_printpages->Size > 0)
+ m_printpages->Clear();
/* With the ref counting this should not leak */
if (m_page_link_list != nullptr && m_page_link_list->Size > 0)
m_page_link_list->Clear();
if (m_text_list->Size > 0)
m_text_list->Clear();
+ m_ppage_num_list.clear();
+
if (m_linkset != nullptr && m_linkset->Size > 0)
m_linkset->Clear();
@@ -469,7 +481,7 @@ void mupdf_cpp::MainPage::CleanUp()
}
/* Create the thumbnail images */
-void mupdf_cpp::MainPage::RenderThumbs()
+void MainPage::RenderThumbs()
{
spatial_info_t spatial_info = this->InitSpatial(1);
int num_pages = this->m_num_pages;
@@ -553,7 +565,7 @@ void mupdf_cpp::MainPage::RenderThumbs()
}
-void mupdf_cpp::MainPage::OpenDocumentPrep(StorageFile^ file)
+void MainPage::OpenDocumentPrep(StorageFile^ file)
{
if (this->m_num_pages != -1)
{
@@ -590,7 +602,7 @@ void mupdf_cpp::MainPage::OpenDocumentPrep(StorageFile^ file)
}
}
-void mupdf_cpp::MainPage::OpenDocument(StorageFile^ file)
+void MainPage::OpenDocument(StorageFile^ file)
{
this->SetFlipView();
@@ -635,7 +647,7 @@ void mupdf_cpp::MainPage::OpenDocument(StorageFile^ file)
}, task_continuation_context::use_current());
}
-void mupdf_cpp::MainPage::InitialRender()
+void MainPage::InitialRender()
{
assert(IsMainThread());
m_num_pages = mu_doc->GetNumPages();
@@ -649,6 +661,8 @@ void mupdf_cpp::MainPage::InitialRender()
m_currpage = 0;
}
+ //m_print.RegisterForPrinting();
+
/* Initialize all the flipvew items with blanks and the thumbnails. */
for (int k = 0; k < m_num_pages; k++)
{
@@ -664,6 +678,7 @@ void mupdf_cpp::MainPage::InitialRender()
doc_page->LinkBox = nullptr;
m_docPages->Append(doc_page);
m_thumbnails->Append(doc_page);
+ m_printpages->Append(doc_page);
/* Create empty lists for our links and specify that they have
not been computed for these pages */
Vector<RectList^>^ temp_link = ref new Vector<RectList^>();
@@ -710,7 +725,8 @@ void mupdf_cpp::MainPage::InitialRender()
this->m_init_done = true;
}
-void mupdf_cpp::MainPage::RenderRange(int curr_page)
+
+void MainPage::RenderRange(int curr_page)
{
/* Render +/- the look ahead from where we are if blank page is present */
//spatial_info_t spatial_info = InitSpatial(1);
@@ -770,7 +786,7 @@ void mupdf_cpp::MainPage::RenderRange(int curr_page)
}
}
-void mupdf_cpp::MainPage::FlipView_SelectionChanged(Object^ sender, SelectionChangedEventArgs^ e)
+void MainPage::FlipView_SelectionChanged(Object^ sender, SelectionChangedEventArgs^ e)
{
if (m_init_done && !m_page_update)
{
@@ -803,18 +819,18 @@ void mupdf_cpp::MainPage::FlipView_SelectionChanged(Object^ sender, SelectionCha
}
/* Slider via drag */
-void mupdf_cpp::MainPage::Slider_ValueChanged(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e)
+void MainPage::Slider_ValueChanged(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e)
{
Slider_Common();
}
/* Slider via keyboard */
-void mupdf_cpp::MainPage::Slider_Key(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
+void MainPage::Slider_Key(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{
Slider_Common();
}
-void mupdf_cpp::MainPage::Slider_Common()
+void MainPage::Slider_Common()
{
if (IsNotStandardView())
return;
@@ -854,13 +870,13 @@ void mupdf_cpp::MainPage::Slider_Common()
}
/* Search Related Code */
-void mupdf_cpp::MainPage::Searcher(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void MainPage::Searcher(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
ShowSearchBox();
UpdateAppBarButtonViewState();
}
-void mupdf_cpp::MainPage::ShowSearchBox()
+void MainPage::ShowSearchBox()
{
/* Update the app bar so that we can do the search */
StackPanel^ leftPanel = (StackPanel^) this->TopAppBar->FindName("LeftPanel");
@@ -886,14 +902,14 @@ void mupdf_cpp::MainPage::ShowSearchBox()
}
}
-void mupdf_cpp::MainPage::ClearTextSearch()
+void MainPage::ClearTextSearch()
{
/* Clear out any old search result */
if (m_text_list->Size > 0)
m_text_list->Clear();
}
-void mupdf_cpp::MainPage::ShowSearchResults(int page_num, int box_count)
+void MainPage::ShowSearchResults(int page_num, int box_count)
{
int old_page = this->m_currpage;
int new_page = page_num;
@@ -947,7 +963,7 @@ void mupdf_cpp::MainPage::ShowSearchResults(int page_num, int box_count)
return;
}
-void mupdf_cpp::MainPage::SearchNext(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void MainPage::SearchNext(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (IsNotStandardView())
return;
@@ -960,7 +976,7 @@ void mupdf_cpp::MainPage::SearchNext(Platform::Object^ sender, Windows::UI::Xaml
SearchInDirection(1, textToFind);
}
-void mupdf_cpp::MainPage::SearchPrev(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void MainPage::SearchPrev(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (IsNotStandardView())
return;
@@ -973,14 +989,14 @@ void mupdf_cpp::MainPage::SearchPrev(Platform::Object^ sender, Windows::UI::Xaml
SearchInDirection(-1, textToFind);
}
-void mupdf_cpp::MainPage::CancelSearch(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void MainPage::CancelSearch(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
m_searchcts.cancel();
xaml_ProgressStack->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
this->m_search_active = false;
}
-void mupdf_cpp::MainPage::AddTextCanvas()
+void MainPage::AddTextCanvas()
{
/* Go ahead and set our doc item to this in the vertical and horizontal view */
auto doc_page = this->m_docPages->GetAt(m_currpage);
@@ -992,12 +1008,12 @@ void mupdf_cpp::MainPage::AddTextCanvas()
this->m_search_active = false;
}
-void mupdf_cpp::MainPage::SearchProgress(IAsyncOperationWithProgress<int, double>^ operation, double status)
+void MainPage::SearchProgress(IAsyncOperationWithProgress<int, double>^ operation, double status)
{
xaml_Progress->Value = status;
}
-void mupdf_cpp::MainPage::SearchInDirection(int dir, String^ textToFind)
+void MainPage::SearchInDirection(int dir, String^ textToFind)
{
cancellation_token_source cts;
auto token = cts.get_token();
@@ -1047,7 +1063,7 @@ void mupdf_cpp::MainPage::SearchInDirection(int dir, String^ textToFind)
}
/* This is here to handle when we rotate or go into the snapview mode */
-void mupdf_cpp::MainPage::GridSizeChanged()
+void MainPage::GridSizeChanged()
{
int height = this->ActualHeight;
int width = this->ActualWidth;
@@ -1107,7 +1123,7 @@ void mupdf_cpp::MainPage::GridSizeChanged()
}
}
-void mupdf_cpp::MainPage::UpDatePageSizes()
+void MainPage::UpDatePageSizes()
{
/* Reset the thumb view scaling value */
if (m_num_pages > 0)
@@ -1135,7 +1151,7 @@ void mupdf_cpp::MainPage::UpDatePageSizes()
};
/* Link related code */
-void mupdf_cpp::MainPage::Linker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void MainPage::Linker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
m_links_on = !m_links_on;
@@ -1147,7 +1163,7 @@ void mupdf_cpp::MainPage::Linker(Platform::Object^ sender, Windows::UI::Xaml::Ro
ClearLinks();
}
-void mupdf_cpp::MainPage::ClearLinks()
+void MainPage::ClearLinks()
{
/* Make sure surrounding render pages lose their links */
for (int k = m_currpage - LOOK_AHEAD; k <= m_currpage + LOOK_AHEAD; k++)
@@ -1163,14 +1179,14 @@ void mupdf_cpp::MainPage::ClearLinks()
}
}
-void mupdf_cpp::MainPage::InvalidateLinks()
+void MainPage::InvalidateLinks()
{
for (int k = 0; k < m_num_pages; k++)
m_linkset->SetAt(k, false);
}
/* Add in the link rects. If we have not already computed them then do that now */
-void mupdf_cpp::MainPage::AddLinkCanvas()
+void MainPage::AddLinkCanvas()
{
/* See if the link object for this page has already been computed */
int link_page = m_linkset->GetAt(m_currpage);
@@ -1231,7 +1247,7 @@ void mupdf_cpp::MainPage::AddLinkCanvas()
}
/* A link was tapped */
-void mupdf_cpp::MainPage::LinkTapped(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e)
+void MainPage::LinkTapped(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e)
{
Rectangle^ rect = safe_cast<Rectangle^>(e->OriginalSource);
String^ str_index = safe_cast<String^>(rect->Tag);
@@ -1270,7 +1286,7 @@ void mupdf_cpp::MainPage::LinkTapped(Platform::Object^ sender, Windows::UI::Xaml
}
/* Bring up the contents */
-void mupdf_cpp::MainPage::ContentDisplay(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void MainPage::ContentDisplay(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (this->m_num_pages < 0)
return;
@@ -1317,7 +1333,7 @@ void mupdf_cpp::MainPage::ContentDisplay(Platform::Object^ sender, Windows::UI::
}
}
-void mupdf_cpp::MainPage::ContentSelected(Platform::Object^ sender, Windows::UI::Xaml::Controls::ItemClickEventArgs^ e)
+void MainPage::ContentSelected(Platform::Object^ sender, Windows::UI::Xaml::Controls::ItemClickEventArgs^ e)
{
ContentItem^ b = safe_cast<ContentItem^>(e->ClickedItem);
int newpage = b->Page;
@@ -1336,7 +1352,7 @@ void mupdf_cpp::MainPage::ContentSelected(Platform::Object^ sender, Windows::UI:
}
}
-void mupdf_cpp::MainPage::Reflower(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void MainPage::Reflower(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (this->m_num_pages < 0) return;
@@ -1365,7 +1381,7 @@ void mupdf_cpp::MainPage::Reflower(Platform::Object^ sender, Windows::UI::Xaml::
}
/* Need to handle resizing of app bar to make sure everything fits */
-void mupdf_cpp::MainPage::topAppBar_Loaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void MainPage::topAppBar_Loaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
/* Remove search box in snapped view as we don't have the room for it */
if (ApplicationView::Value == ApplicationViewState::Snapped && m_insearch)
@@ -1373,7 +1389,7 @@ void mupdf_cpp::MainPage::topAppBar_Loaded(Platform::Object^ sender, Windows::UI
UpdateAppBarButtonViewState();
}
-void mupdf_cpp::MainPage::UpdateAppBarButtonViewState()
+void MainPage::UpdateAppBarButtonViewState()
{
String ^viewState = Windows::UI::ViewManagement::ApplicationView::Value.ToString();
VisualStateManager::GoToState(Search, viewState, true);
@@ -1387,7 +1403,7 @@ void mupdf_cpp::MainPage::UpdateAppBarButtonViewState()
}
/* Manipulation zooming with touch input */
-void mupdf_cpp::MainPage::ScrollChanged(Platform::Object^ sender,
+void MainPage::ScrollChanged(Platform::Object^ sender,
Windows::UI::Xaml::Controls::ScrollViewerViewChangedEventArgs^ e)
{
ScrollViewer^ scrollviewer = safe_cast<ScrollViewer^> (sender);
@@ -1442,13 +1458,13 @@ Windows::UI::Xaml::FrameworkElement^ FindVisualChildByName(DependencyObject^ obj
return ret;
}
-void mupdf_cpp::MainPage::ZoomInPress(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void MainPage::ZoomInPress(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (!m_init_done || IsNotStandardView()) return;
NonTouchZoom(ZOOM_IN);
}
-void mupdf_cpp::MainPage::ZoomOutPress(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void MainPage::ZoomOutPress(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (!m_init_done || IsNotStandardView()) return;
NonTouchZoom(ZOOM_OUT);
@@ -1521,7 +1537,7 @@ void MainPage::OnKeyDown(KeyRoutedEventArgs^ e)
return;
}
-void mupdf_cpp::MainPage::PasswordOK(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void MainPage::PasswordOK(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
/* If password checks out then go ahead and start rendering */
if (mu_doc->ApplyPassword(xaml_password->Password))
@@ -1537,8 +1553,512 @@ void mupdf_cpp::MainPage::PasswordOK(Platform::Object^ sender, Windows::UI::Xaml
/* So that we know if we are in a standard view case and not in reflow, or
* content type */
-bool mupdf_cpp::MainPage::IsNotStandardView()
+bool MainPage::IsNotStandardView()
{
return (this->xaml_ListView->Opacity == 1.0 ||
xaml_WebView->Visibility == Windows::UI::Xaml::Visibility::Visible);
}
+
+/* The following code is for print support. This is just a simple demonstration of
+ printing with MuPDF in the Windows 8 environment */
+void MainPage::RegisterForPrinting()
+{
+ m_printdoc = ref new PrintDocument();
+ m_printdoc_source = m_printdoc->DocumentSource;
+ m_printdoc->Paginate +=
+ ref new Windows::UI::Xaml::Printing::PaginateEventHandler(this, &MainPage::CreatePrintPreviewPages);
+ m_printdoc->GetPreviewPage +=
+ ref new Windows::UI::Xaml::Printing::GetPreviewPageEventHandler(this, &MainPage::GetPrintPreviewPages);
+ m_printdoc->AddPages +=
+ ref new Windows::UI::Xaml::Printing::AddPagesEventHandler(this, &MainPage::AddPrintPages);
+
+ PrintManager^ printMan = PrintManager::GetForCurrentView();
+ m_printTaskRequestedEventToken =
+ printMan->PrintTaskRequested +=
+ ref new TypedEventHandler<PrintManager^, PrintTaskRequestedEventArgs^>(this, &MainPage::PrintTaskRequested);
+}
+
+void MainPage::UnregisterForPrinting()
+{
+ // Remove the handler for printing initialization.
+ PrintManager^ printMan = PrintManager::GetForCurrentView();
+ printMan->PrintTaskRequested -= m_printTaskRequestedEventToken;
+}
+
+void MainPage::PrintTaskRequested(PrintManager^ sender, PrintTaskRequestedEventArgs^ e)
+{
+ auto printTaskRef = std::make_shared<PrintTask^>(nullptr);
+ *printTaskRef = e->Request->CreatePrintTask("MuPDF Printing",
+ ref new PrintTaskSourceRequestedHandler([this, printTaskRef](PrintTaskSourceRequestedArgs^ args)
+ {
+ PrintTask^ printTask = *printTaskRef;
+ PrintTaskOptionDetails^ printDetailedOptions =
+ PrintTaskOptionDetails::GetFromPrintTaskOptions(printTask->Options);
+
+ // Some standard printer options
+ printDetailedOptions->DisplayedOptions->Clear();
+ printDetailedOptions->DisplayedOptions->Append(Windows::Graphics::Printing::StandardPrintTaskOptions::MediaSize);
+ printDetailedOptions->DisplayedOptions->Append(Windows::Graphics::Printing::StandardPrintTaskOptions::Copies);
+
+ // Our custom options
+ PrintCustomItemListOptionDetails^ resolution =
+ printDetailedOptions->CreateItemListOption("resolution", "Render Resolution");
+ resolution->AddItem("sres72", "72 dpi");
+ resolution->AddItem("sres150", "150 dpi");
+ resolution->AddItem("sres300", "300 dpi");
+ resolution->AddItem("sres600", "600 dpi");
+ resolution->TrySetValue("sres600");
+ m_printresolution = 600;
+ printDetailedOptions->DisplayedOptions->Append("resolution");
+
+ PrintCustomItemListOptionDetails^ scaling = printDetailedOptions->CreateItemListOption("scaling", "Scaling");
+ scaling->AddItem("sScaleToFit", "Scale To Fit");
+ scaling->AddItem("sCrop", "Crop");
+ // Add the custom option to the option list.
+ printDetailedOptions->DisplayedOptions->Append("scaling");
+ scaling->TrySetValue("sScaleToFit");
+ m_printcrop = false;
+ printTask->Options->MediaSize = PrintMediaSize::NorthAmericaLetter;
+
+ PrintCustomItemListOptionDetails^ pageFormat = printDetailedOptions->CreateItemListOption(L"PageRange", L"Page Range");
+ pageFormat->AddItem(L"PrintAll", L"Print all");
+ pageFormat->AddItem(L"PrintRange", L"Print Range");
+ printDetailedOptions->DisplayedOptions->Append(L"PageRange");
+ PrintCustomTextOptionDetails^ pageRangeEdit = printDetailedOptions->CreateTextOption(L"PageRangeEdit", L"Range");
+
+ printDetailedOptions->OptionChanged +=
+ ref new TypedEventHandler<PrintTaskOptionDetails^, PrintTaskOptionChangedEventArgs^>(this, &MainPage::PrintOptionsChanged);
+
+ // Invoked when the print job is completed.
+ printTask->Completed += ref new TypedEventHandler<PrintTask^, PrintTaskCompletedEventArgs^>(
+ [=](PrintTask^ sender, PrintTaskCompletedEventArgs^ e)
+ {
+ auto callback = ref new Windows::UI::Core::DispatchedHandler(
+ [=]()
+ {
+ ClearPrintCollection();
+ m_printpagedesc = PrintPageDesc();
+ if (e->Completion == Windows::Graphics::Printing::PrintTaskCompletion::Failed)
+ {
+ NotifyUser("Sorry, printing failed", StatusMessage);
+ }
+ });
+ Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, callback);
+ });
+ // Set the document source.
+ args->SetSource(PrintDocumentSource);
+ }));
+}
+
+void MainPage::PrintOptionsChanged(PrintTaskOptionDetails^ sender, PrintTaskOptionChangedEventArgs^ args)
+{
+ bool force_reset = false;
+
+ if (args->OptionId == nullptr)
+ return;
+
+ String^ optionId = safe_cast<String^>(args->OptionId);
+
+ if (optionId == "resolution")
+ {
+ IPrintOptionDetails^ resolution = sender->Options->Lookup(optionId);
+ String^ resolutionValue = safe_cast<String^>(resolution->Value);
+
+ if (resolutionValue == "sres72")
+ {
+ m_printresolution = 72;
+ }
+ else if (resolutionValue == "sres150")
+ {
+ m_printresolution = 150;
+ }
+ else if (resolutionValue == "sres300")
+ {
+ m_printresolution = 300;
+ }
+ else if(resolutionValue == "sres600")
+ {
+ m_printresolution = 600;
+ }
+ }
+
+ /* Need to update preview with a change of this one */
+ if (optionId == "scaling")
+ {
+ IPrintOptionDetails^ scaling = sender->Options->Lookup(optionId);
+ String^ scaleValue = safe_cast<String^>(scaling->Value);
+
+ if (scaleValue == "sScaleToFit")
+ {
+ m_printcrop = false;
+ }
+ if (scaleValue == "sCrop")
+ {
+ m_printcrop = true;
+ }
+ force_reset = true;
+ }
+
+ if (optionId == L"PageRange")
+ {
+ IPrintOptionDetails^ pagerange = sender->Options->Lookup(optionId);
+ String^ pageRangeValue = pagerange->Value->ToString();
+
+ if(pageRangeValue == L"PrintRange")
+ {
+ sender->DisplayedOptions->Append(L"PageRangeEdit");
+ m_pageRangeEditVisible = true;
+ }
+ else
+ {
+ RemovePageRangeEdit(sender);
+ }
+ RefreshPreview();
+ }
+
+ if (optionId == L"PageRangeEdit")
+ {
+ IPrintOptionDetails^ pagerange = sender->Options->Lookup(optionId);
+
+ std::wregex rangePattern(L"^\\s*\\d+\\s*(\\-\\s*\\d+\\s*)?(\\,\\s*\\d+\\s*(\\-\\s*\\d+\\s*)?)*$");
+ std::wstring pageRangeValue(pagerange->Value->ToString()->Data());
+
+ if(!std::regex_match(pageRangeValue.begin(), pageRangeValue.end(), rangePattern))
+ {
+ pagerange->ErrorText = L"Invalid Page Range (eg: 1-3, 5)";
+ }
+ else
+ {
+ pagerange->ErrorText = L"";
+ try
+ {
+ GetPagesInRange(pagerange->Value->ToString());
+ }
+ catch(PageRangeException* rangeException)
+ {
+ pagerange->ErrorText = ref new String(rangeException->get_DisplayMessage().data());
+ delete rangeException;
+ }
+ force_reset = true;
+ }
+ }
+ if (force_reset)
+ {
+ RefreshPreview();
+ }
+}
+
+void MainPage::SplitString(String^ string, wchar_t delimiter, std::vector<std::wstring>& words)
+{
+ std::wistringstream iss(string->Data());
+
+ std::wstring part;
+ while(std::getline(iss, part, delimiter))
+ {
+ words.push_back(part);
+ };
+}
+
+void MainPage::GetPagesInRange(String^ pagerange)
+{
+ std::vector<std::wstring> vector_range;
+ SplitString(pagerange, ',', vector_range);
+
+ m_ppage_num_list.clear();
+ for(std::vector<std::wstring>::iterator it = vector_range.begin(); it != vector_range.end(); ++ it)
+ {
+ int intervalPos = static_cast<int>((*it).find('-'));
+ if( intervalPos != -1)
+ {
+ int start = _wtoi((*it).substr(0, intervalPos).data());
+ int end = _wtoi((*it).substr(intervalPos + 1, (*it).length() - intervalPos - 1).data());
+
+ if ((start < 1) || (end > static_cast<int>(m_num_pages)) || (start >= end))
+ {
+ std::wstring message(L"Invalid page(s) in range ");
+
+ message.append(std::to_wstring(start));
+ message.append(L" - ");
+ message.append(std::to_wstring(end));
+
+ throw new PageRangeException(message);
+ }
+
+ for(int intervalPage=start; intervalPage <= end; ++intervalPage)
+ {
+ m_ppage_num_list.push_back(intervalPage);
+ }
+ }
+ else
+ {
+ int pageNr = _wtoi((*it).data());
+ std::wstring message(L"Invalid page ");
+
+ if (pageNr < 1)
+ {
+ message.append(std::to_wstring(pageNr));
+ throw new PageRangeException(message);
+ }
+ if (pageNr > static_cast<int>(m_num_pages))
+ {
+ message.append(std::to_wstring(pageNr));
+ throw new PageRangeException(message);
+ }
+ m_ppage_num_list.push_back(pageNr);
+ }
+ }
+ std::sort(m_ppage_num_list.begin(), m_ppage_num_list.end(), std::less<int>());
+ std::unique(m_ppage_num_list.begin(), m_ppage_num_list.end());
+}
+
+void MainPage::RemovePageRangeEdit(PrintTaskOptionDetails^ printTaskOptionDetails)
+{
+ if (m_pageRangeEditVisible)
+ {
+ unsigned int index;
+ if(printTaskOptionDetails->DisplayedOptions->IndexOf(ref new String(L"PageRangeEdit"), &index))
+ {
+ printTaskOptionDetails->DisplayedOptions->RemoveAt(index);
+ }
+ m_pageRangeEditVisible = false;
+ }
+}
+
+void MainPage::ClearPrintCollection()
+{
+ m_printlock.lock();
+ for (int k = 0; k < m_num_pages; k++)
+ {
+ auto thumb_page = this->m_thumbnails->GetAt(k);
+ this->m_printpages->SetAt(k, thumb_page);
+ }
+ m_printlock.unlock();
+}
+
+/* Just use the thumbnail images for now */
+void MainPage::CreatePrintPreviewPages(Object^ sender, PaginateEventArgs^ e)
+{
+ InterlockedIncrement64(&m_requestCount);
+ PrintPageDesc ppageDescription;
+ PrintTaskOptionDetails^ printDetailedOptions =
+ PrintTaskOptionDetails::GetFromPrintTaskOptions(e->PrintTaskOptions);
+ PrintPageDescription DeviceDescription =
+ e->PrintTaskOptions->GetPageDescription(0);
+
+ /* This has the media dimension */
+ ppageDescription.pagesize = DeviceDescription.PageSize;
+
+ ppageDescription.resolution.Width = DeviceDescription.DpiX;
+ ppageDescription.resolution.Height = DeviceDescription.DpiY;
+
+ ppageDescription.margin.Width = (std::max)(DeviceDescription.ImageableRect.Left,
+ DeviceDescription.ImageableRect.Right -
+ DeviceDescription.PageSize.Width);
+
+ ppageDescription.margin.Height = (std::max)(DeviceDescription.ImageableRect.Top,
+ DeviceDescription.ImageableRect.Bottom -
+ DeviceDescription.PageSize.Height);
+
+ ppageDescription.printpagesize.Width = DeviceDescription.PageSize.Width -
+ ppageDescription.margin.Width * 2;
+ ppageDescription.printpagesize.Height = DeviceDescription.PageSize.Height -
+ ppageDescription.margin.Height * 2;
+
+ ClearPrintCollection();
+ PrintDocument^ printDocument = safe_cast<PrintDocument^>(sender);
+ m_printpagedesc = ppageDescription;
+
+ if (m_ppage_num_list.size() > 0)
+ {
+ printDocument->SetPreviewPageCount(m_ppage_num_list.size(),
+ PreviewPageCountType::Intermediate);
+ }
+ else
+ {
+ printDocument->SetPreviewPageCount(m_num_pages,
+ PreviewPageCountType::Intermediate);
+ }
+}
+
+/* Set the page with the new raster information */
+void MainPage::UpdatePreview(int page_num, InMemoryRandomAccessStream^ ras,
+ Point ras_size, Page_Content_t content_type, double zoom_in)
+{
+ assert(IsMainThread());
+
+ WriteableBitmap ^bmp = ref new WriteableBitmap(ras_size.X, ras_size.Y);
+ bmp->SetSource(ras);
+
+ DocumentPage^ doc_page = ref new DocumentPage();
+ doc_page->Image = bmp;
+
+ doc_page->Height = ras_size.Y;
+ doc_page->Width = ras_size.X;
+ doc_page->Content = content_type;
+ doc_page->Zoom = zoom_in;
+ this->m_printpages->SetAt(page_num, doc_page);
+}
+
+void MainPage::CleanUpPreview(int page_num)
+{
+ for (int k = page_num - 1; k <= page_num + 1; k++)
+ {
+ if (k >= 0 && k < this->m_num_pages && k != page_num)
+ {
+ auto doc = this->m_printpages->GetAt(k);
+ if (doc->Content == THUMBNAIL) return;
+
+ if (this->m_thumbnails->Size > k)
+ {
+ auto thumb_page = this->m_thumbnails->GetAt(k);
+ this->m_printpages->SetAt(k, thumb_page);
+ }
+ }
+ }
+}
+
+void MainPage::RefreshPreview()
+{
+ auto callback =
+ ref new Windows::UI::Core::DispatchedHandler([this]()
+ {
+ m_printdoc->InvalidatePreview();
+ });
+ Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, callback);
+}
+
+void MainPage::GetPrintPreviewPages(Object^ sender, GetPreviewPageEventArgs^ e)
+{
+ PrintDocument^ printDocument = safe_cast<PrintDocument^>(sender);
+
+ LONGLONG requestNumber = 0;
+ InterlockedExchange64(&requestNumber, m_requestCount);
+ int index_page_num = e->PageNumber;
+ int ren_page_num = index_page_num;
+
+ if (m_ppage_num_list.size() > 0)
+ {
+ ren_page_num = m_ppage_num_list[index_page_num - 1];
+ }
+ auto doc_curr = this->m_printpages->GetAt(ren_page_num - 1);
+ if (doc_curr->Content == PRINT_PREVIEW)
+ {
+ auto bitmap = doc_curr->Image;
+ Image^ image = ref new Image();
+ image->Source = bitmap;
+ image->HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Center;
+ image->VerticalAlignment = Windows::UI::Xaml::VerticalAlignment::Center;
+ image->Stretch = Stretch::UniformToFill;
+ image->Width = bitmap->PixelWidth;
+ image->Height = bitmap->PixelHeight;
+ printDocument->SetPreviewPage(index_page_num, image);
+ }
+ else
+ {
+ /* Determine the scale to fit case or crop */
+ spatial_info_t spatial_info = InitSpatial(1.0);
+ int pagNum = ren_page_num - 1;
+ Point ras_size = ComputePageSize(spatial_info, pagNum);
+ float scale = 1.0;
+
+ if (!(this->m_printcrop))
+ {
+ float scaleY = m_printpagedesc.printpagesize.Height / ras_size.Y;
+ float scaleX = m_printpagedesc.printpagesize.Width / ras_size.X;
+ scale = (std::min)(scaleY, scaleX);
+ }
+ auto render_task =
+ create_task(mu_doc->RenderPageAsync(pagNum, ras_size.X, ras_size.Y, true));
+ render_task.then([=] (InMemoryRandomAccessStream^ ras)
+ {
+ UpdatePreview(pagNum, ras, ras_size, PRINT_PREVIEW, scale);
+ auto doc_curr = this->m_printpages->GetAt(pagNum);
+ auto bitmap = doc_curr->Image;
+ Image^ image = ref new Image();
+ image->Source = bitmap;
+ image->HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Center;
+ image->VerticalAlignment = Windows::UI::Xaml::VerticalAlignment::Center;
+ image->Stretch = Stretch::UniformToFill;
+ image->Width = bitmap->PixelWidth * scale;
+ image->Height = bitmap->PixelHeight * scale;
+ printDocument->SetPreviewPage(index_page_num, image);
+ }, task_continuation_context::use_current());
+ }
+ this->CleanUpPreview(ren_page_num - 1);
+}
+
+void MainPage::AddPrintPages(Object^ sender, AddPagesEventArgs^ e)
+{
+ PrintDocument^ printDocument = safe_cast<PrintDocument^>(sender);
+
+ /* We create a list of tasks to create the pages for printing. Once all the
+ pages are created then we can go ahead and start adding them for printing */
+ std::vector<concurrency::task<void>> createPageTasks;
+ double res_scale = ((double) m_printresolution / 72.0);
+ int page_count = m_num_pages;
+
+ if (m_ppage_num_list.size() > 0)
+ page_count = m_ppage_num_list.size();
+
+ for(int i = 0; i < page_count; ++i)
+ {
+ m_printlock.lock();
+
+ int page_num = i;
+ if (m_ppage_num_list.size() > 0)
+ page_num = m_ppage_num_list[i] - 1;
+
+ auto doc_curr = this->m_printpages->GetAt(page_num);
+ if (doc_curr->Content != FULL_RESOLUTION)
+ {
+ spatial_info_t spatial_info = InitSpatial(res_scale);
+ Point ras_size = ComputePageSize(spatial_info, page_num);
+ float scale = 1.0;
+
+ if (!(this->m_printcrop))
+ {
+ spatial_info = InitSpatial(1.0);
+ ras_size = ComputePageSize(spatial_info, page_num);
+ float scaleY = m_printpagedesc.printpagesize.Height / ras_size.Y;
+ float scaleX = m_printpagedesc.printpagesize.Width / ras_size.X;
+ scale = (std::min)(scaleY, scaleX);
+ spatial_info = InitSpatial(res_scale * scale);
+ ras_size = ComputePageSize(spatial_info, page_num);
+ }
+ auto render_task =
+ create_task(mu_doc->RenderPageAsync(page_num, ras_size.X, ras_size.Y, true));
+ createPageTasks.push_back(render_task.then([=] (InMemoryRandomAccessStream^ ras)
+ {
+ UpdatePreview(page_num, ras, ras_size, FULL_RESOLUTION, 1.0);
+ }, task_continuation_context::use_current()));
+ }
+ m_printlock.unlock();
+ }
+
+ /* When all the tasks have finished then go ahead and add them to the print
+ document */
+ concurrency::when_all(createPageTasks.begin(), createPageTasks.end()). then([=]
+ {
+ for (int i = 0; i < page_count; i++)
+ {
+ int page_num = i;
+ if (m_ppage_num_list.size() > 0)
+ page_num = m_ppage_num_list[i] - 1;
+ auto doc_curr = this->m_printpages->GetAt(page_num);
+ auto bitmap = doc_curr->Image;
+ Image^ image = ref new Image();
+ image->Source = bitmap;
+ image->HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Center;
+ image->VerticalAlignment = Windows::UI::Xaml::VerticalAlignment::Center;
+ image->Stretch = Stretch::UniformToFill;
+ image->Width = bitmap->PixelWidth / res_scale;
+ image->Height = bitmap->PixelHeight / res_scale;
+ printDocument->AddPage(image);
+ }
+ /* All pages provided. */
+ printDocument->AddPagesComplete();
+ /* Reset the current page description as soon as possible since the
+ PrintTask.Completed event might fire later */
+ m_printpagedesc = PrintPageDesc();
+ });
+}
diff --git a/platform/winrt/mupdf_cpp/MainPage.xaml.h b/platform/winrt/mupdf_cpp/MainPage.xaml.h
index b60cf96c..fd94e971 100644
--- a/platform/winrt/mupdf_cpp/MainPage.xaml.h
+++ b/platform/winrt/mupdf_cpp/MainPage.xaml.h
@@ -33,6 +33,14 @@ using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::ApplicationModel;
using namespace mupdfwinrt;
+using namespace Windows::Graphics::Display;
+using namespace Windows::Graphics::Printing;
+using namespace Windows::UI;
+using namespace Windows::UI::Text;
+using namespace Windows::UI::Xaml::Documents;
+using namespace Windows::Graphics::Printing::OptionDetails;
+using namespace Windows::UI::Xaml::Printing;
+
typedef enum
{
StatusMessage,
@@ -54,6 +62,55 @@ typedef struct spatial_info_s
namespace mupdf_cpp
{
+
+ class PageRangeException
+ {
+ private:
+ std::wstring m_message;
+ public:
+ PageRangeException(std::wstring &message)
+ {
+ m_message = message;
+ }
+ ~PageRangeException()
+ {
+ }
+ std::wstring get_DisplayMessage()
+ {
+ return m_message;
+ }
+ };
+
+ public value class PrintPageDesc
+ {
+ public:
+ Size margin;
+ Size pagesize;
+ Size printpagesize;
+ Size resolution;
+
+ friend bool operator == (PrintPageDesc pp1, PrintPageDesc pp2)
+ {
+ bool equal = (std::abs(pp1.pagesize.Width - pp2.pagesize.Width) < FLT_EPSILON) &&
+ (std::abs(pp1.pagesize.Height - pp2.pagesize.Height) < FLT_EPSILON);
+ if (equal)
+ {
+ equal = (std::abs(pp1.printpagesize.Width - pp2.printpagesize.Width) < FLT_EPSILON) &&
+ (std::abs(pp1.printpagesize.Height - pp2.printpagesize.Height) < FLT_EPSILON);
+ }
+ if (equal)
+ {
+ equal = (std::abs(pp1.resolution.Width - pp2.resolution.Width) < FLT_EPSILON) &&
+ (std::abs(pp1.resolution.Height - pp2.resolution.Height) < FLT_EPSILON);
+ }
+ return equal;
+ }
+ friend bool operator != (PrintPageDesc pp1, PrintPageDesc pp2)
+ {
+ return !(pp1 == pp2);
+ }
+ };
+
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
@@ -73,10 +130,18 @@ namespace mupdf_cpp
Windows::ApplicationModel::Activation::FileActivatedEventArgs^ get() { return _fileEventArgs; }
void set(Windows::ApplicationModel::Activation::FileActivatedEventArgs^ value) { _fileEventArgs = value; }
}
+ void NotifyUser(String^ strMessage, int type);
protected:
virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
virtual void OnKeyDown(Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e) override;
+ property Windows::Graphics::Printing::IPrintDocumentSource^ PrintDocumentSource
+ {
+ Windows::Graphics::Printing::IPrintDocumentSource^ get()
+ {
+ return m_printdoc_source;
+ }
+ }
private:
Windows::Foundation::EventRegistrationToken _pageLoadedHandlerToken;
@@ -112,6 +177,19 @@ namespace mupdf_cpp
double m_Progress;
double m_doczoom;
+ /* Print related */
+ Vector<DocumentPage^>^ m_printpages;
+ concurrency::critical_section m_printlock;
+ EventRegistrationToken m_printTaskRequestedEventToken;
+ PrintDocument^ m_printdoc;
+ IPrintDocumentSource^ m_printdoc_source;
+ LONGLONG m_requestCount;
+ PrintPageDesc m_printpagedesc;
+ int m_printresolution;
+ bool m_printcrop;
+ bool m_pageRangeEditVisible;
+ std::vector<int> m_ppage_num_list;
+
void ReplaceImage(int page_num, InMemoryRandomAccessStream^ ras, Point ras_size, double zoom);
void Picker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void Searcher(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
@@ -154,7 +232,6 @@ namespace mupdf_cpp
void topAppBar_Loaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void UpdateAppBarButtonViewState();
bool EnsureUnsnapped();
- void NotifyUser(String^ strMessage, NotifyType_t type);
void ExitInvokedHandler(Windows::UI::Popups::IUICommand^ command);
void OKInvokedHandler(Windows::UI::Popups::IUICommand^ command);
Point ComputePageSize(spatial_info_t spatial_info, int page_num);
@@ -177,5 +254,22 @@ namespace mupdf_cpp
void Slider_Common();
void FlipView_Started(Platform::Object^ sender, Windows::UI::Xaml::Input::ManipulationStartedRoutedEventArgs^ e);
void UpdateZoom(int page_num, bool ignore_curr);
-};
+
+ /* Print Related */
+ void RegisterForPrinting();
+ void UnregisterForPrinting();
+ void PrintTaskRequested(PrintManager^ sender, PrintTaskRequestedEventArgs^ e);
+ void ClearPrintCollection();
+ void CreatePrintPreviewPages(Object^ sender, PaginateEventArgs^ e);
+ void GetPrintPreviewPages(Object^ sender, GetPreviewPageEventArgs^ e);
+ void UpdatePreview(int page_num, InMemoryRandomAccessStream^ ras,
+ Point ras_size, Page_Content_t content_type, double zoom_in);
+ void CleanUpPreview(int new_page);
+ void AddPrintPages(Object^ sender, AddPagesEventArgs^ e);
+ void PrintOptionsChanged(PrintTaskOptionDetails^ sender, PrintTaskOptionChangedEventArgs^ args);
+ void RefreshPreview();
+ void RemovePageRangeEdit(PrintTaskOptionDetails^ printTaskOptionDetails);
+ void SplitString(String^ string, wchar_t delimiter, std::vector<std::wstring>& words);
+ void GetPagesInRange(String^ pageRange);
+ };
}