From 510eb5217cac45c4009e287ede6aa92fbfb8b93d Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Thu, 16 May 2013 16:13:48 +0100 Subject: Miscellaneous tidying. Remove stray win32 changes. Update indentation style. --- winrt/README.txt | 2 +- winrt/mupdf_cpp/DocumentPage.cpp | 18 +- winrt/mupdf_cpp/DocumentPage.h | 330 ++++--- winrt/mupdf_cpp/MainPage.xaml.cpp | 1954 +++++++++++++++++++------------------ winrt/mupdf_cpp/MainPage.xaml.h | 182 ++-- winrt/mupdf_cpp/RectList.cpp | 13 +- winrt/mupdf_cpp/RectList.h | 250 +++-- winrt/mupdfwinrt/ContentItem.cpp | 6 +- winrt/mupdfwinrt/ContentItem.h | 105 +- winrt/mupdfwinrt/Links.cpp | 6 +- winrt/mupdfwinrt/Links.h | 127 +-- winrt/mupdfwinrt/muctx.cpp | 677 ++++++------- winrt/mupdfwinrt/muctx.h | 66 +- winrt/mupdfwinrt/mudocument.cpp | 348 +++---- winrt/mupdfwinrt/mudocument.h | 48 +- winrt/mupdfwinrt/utils.cpp | 34 +- winrt/mupdfwinrt/utils.h | 10 +- 17 files changed, 2124 insertions(+), 2052 deletions(-) (limited to 'winrt') diff --git a/winrt/README.txt b/winrt/README.txt index 52c1af9c..1ae59d2f 100644 --- a/winrt/README.txt +++ b/winrt/README.txt @@ -12,4 +12,4 @@ Still needs error checking Needs progress bar during text search -Help info needs to be populated \ No newline at end of file +Help info needs to be populated diff --git a/winrt/mupdf_cpp/DocumentPage.cpp b/winrt/mupdf_cpp/DocumentPage.cpp index 637a19a4..ace6138f 100644 --- a/winrt/mupdf_cpp/DocumentPage.cpp +++ b/winrt/mupdf_cpp/DocumentPage.cpp @@ -3,15 +3,15 @@ namespace mupdf_cpp { - DocumentPage::DocumentPage(void) - { - this->Image = nullptr; - this->Height = 0; - this->Width = 0; - this->Zoom = 1.0; - this->Content = NOTSET; - _isPropertyChangedObserved = false; - } + DocumentPage::DocumentPage(void) + { + this->Image = nullptr; + this->Height = 0; + this->Width = 0; + this->Zoom = 1.0; + this->Content = NOTSET; + _isPropertyChangedObserved = false; + } } diff --git a/winrt/mupdf_cpp/DocumentPage.h b/winrt/mupdf_cpp/DocumentPage.h index a7585410..3307ec3a 100644 --- a/winrt/mupdf_cpp/DocumentPage.h +++ b/winrt/mupdf_cpp/DocumentPage.h @@ -11,161 +11,187 @@ using namespace Windows::Foundation::Collections; using namespace Windows::UI::Xaml::Data; typedef enum { - FULL_RESOLUTION = 0, - THUMBNAIL, - DUMMY, - NOTSET + FULL_RESOLUTION = 0, + THUMBNAIL, + DUMMY, + NOTSET } Page_Content_t; - + namespace mupdf_cpp { - // enables data binding with this class - [Windows::UI::Xaml::Data::Bindable] - public ref class DocumentPage sealed : Windows::UI::Xaml::Data::INotifyPropertyChanged - { - private: - int height; - int width; - double zoom; - WriteableBitmap^ image; - Page_Content_t content; - IVector^ textbox; - IVector^ linkbox; - public: - DocumentPage(void); - - /* Note IVector needed for WinRT interface */ - property IVector^ TextBox - { - IVector^ get() { return (textbox); } - void set(IVector^ value) - { - textbox = value; - DocumentPage::OnPropertyChanged("TextBox"); - } - } - - property IVector^ LinkBox - { - IVector^ get() { return (linkbox); } - void set(IVector^ value) - { - linkbox = value; - DocumentPage::OnPropertyChanged("LinkBox"); - } - } - - property int Content - { - int get() { return ((int) content); } - void set(int value) - { - if (value > NOTSET) - { - throw ref new Platform::InvalidArgumentException(); - } - content = (Page_Content_t) value; - } - } - - property int Height - { - int get() { return height; } - void set(int value) - { - if (value < 0) - { - throw ref new Platform::InvalidArgumentException(); - } - height = value; - } - } - - property int Width - { - int get() { return width; } - void set(int value) - { - if (value < 0) - { - throw ref new Platform::InvalidArgumentException(); - } - width = value; - } - } - - property double Zoom - { - double get() { return zoom; } - void set(double value) - { - if (value < 0) - { - throw ref new Platform::InvalidArgumentException(); - } - zoom = value; - } - } - - property WriteableBitmap^ Image - { - WriteableBitmap^ get() { return image; } - void set(WriteableBitmap^ value) - { - image = value; - DocumentPage::OnPropertyChanged("Image"); - } - } - - private: - bool _isPropertyChangedObserved; - event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ _privatePropertyChanged; - - - protected: - /// - /// Notifies listeners that a property value has changed. - /// - /// Name of the property used to notify listeners. - void OnPropertyChanged(String^ propertyName) - { - if (_isPropertyChangedObserved) - { - PropertyChanged(this, ref new PropertyChangedEventArgs(propertyName)); - } - } - - public: - - // in c++, it is not neccessary to include definitions of add, remove, and raise. - // these definitions have been made explicitly here so that we can check if the - // event has listeners before firing the event - virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged - { - virtual Windows::Foundation::EventRegistrationToken add(Windows::UI::Xaml::Data::PropertyChangedEventHandler^ e) - { - _isPropertyChangedObserved = true; - return _privatePropertyChanged += e; - } - virtual void remove(Windows::Foundation::EventRegistrationToken t) - { - _privatePropertyChanged -= t; - } - - protected: - virtual void raise(Object^ sender, Windows::UI::Xaml::Data::PropertyChangedEventArgs^ e) - { - if (_isPropertyChangedObserved) - { - _privatePropertyChanged(sender, e); - } - } - } + // enables data binding with this class + [Windows::UI::Xaml::Data::Bindable] + public ref class DocumentPage sealed : Windows::UI::Xaml::Data::INotifyPropertyChanged + { + private: + int height; + int width; + double zoom; + WriteableBitmap^ image; + Page_Content_t content; + IVector^ textbox; + IVector^ linkbox; + public: + DocumentPage(void); + + /* Note IVector needed for WinRT interface */ + property IVector^ TextBox + { + IVector^ get() + { + return (textbox); + } + + void set(IVector^ value) + { + textbox = value; + DocumentPage::OnPropertyChanged("TextBox"); + } + } + + property IVector^ LinkBox + { + IVector^ get() + { + return (linkbox); + } + + void set(IVector^ value) + { + linkbox = value; + DocumentPage::OnPropertyChanged("LinkBox"); + } + } + + property int Content + { + int get() + { + return ((int) content); + } + + void set(int value) + { + if (value > NOTSET) + { + throw ref new Platform::InvalidArgumentException(); + } + content = (Page_Content_t) value; + } + } + + property int Height + { + int get() + { + return height; + } + + void set(int value) + { + if (value < 0) + { + throw ref new Platform::InvalidArgumentException(); + } + height = value; + } + } + + property int Width + { + int get() + { + return width; + } + + void set(int value) + { + if (value < 0) + { + throw ref new Platform::InvalidArgumentException(); + } + width = value; + } + } + + property double Zoom + { + double get() + { + return zoom; + } + + void set(double value) + { + if (value < 0) + { + throw ref new Platform::InvalidArgumentException(); + } + zoom = value; + } + } + + property WriteableBitmap^ Image + { + WriteableBitmap^ get() + { + return image; + } + + void set(WriteableBitmap^ value) + { + image = value; + DocumentPage::OnPropertyChanged("Image"); + } + } + + private: + bool _isPropertyChangedObserved; + event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ _privatePropertyChanged; + + + protected: + /// + /// Notifies listeners that a property value has changed. + /// + /// Name of the property used to notify listeners. + void OnPropertyChanged(String^ propertyName) + { + if (_isPropertyChangedObserved) + { + PropertyChanged(this, ref new PropertyChangedEventArgs(propertyName)); + } + } + + public: + + // in c++, it is not neccessary to include definitions + // of add, remove, and raise. These definitions have + // been made explicitly here so that we can check if + // the event has listeners before firing the event. + virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged + { + virtual Windows::Foundation::EventRegistrationToken add(Windows::UI::Xaml::Data::PropertyChangedEventHandler^ e) + { + _isPropertyChangedObserved = true; + return _privatePropertyChanged += e; + } + + virtual void remove(Windows::Foundation::EventRegistrationToken t) + { + _privatePropertyChanged -= t; + } + + protected: + virtual void raise(Object^ sender, Windows::UI::Xaml::Data::PropertyChangedEventArgs^ e) + { + if (_isPropertyChangedObserved) + { + _privatePropertyChanged(sender, e); + } + } + } #pragma endregion - - - - - }; + }; } diff --git a/winrt/mupdf_cpp/MainPage.xaml.cpp b/winrt/mupdf_cpp/MainPage.xaml.cpp index a4ceb070..76c0ecf3 100644 --- a/winrt/mupdf_cpp/MainPage.xaml.cpp +++ b/winrt/mupdf_cpp/MainPage.xaml.cpp @@ -47,23 +47,23 @@ unsigned int _mainThreadId = 0U; extern "C" { #endif - // The IsMainThread function returns true if the current thread is the app's main thread and false otherwise. - bool IsMainThread() - { - return (_mainThreadId == GetCurrentThreadId()); - } - - // The IsBackgroundThread function returns false if the current thread is the app's main thread and true otherwise. - bool IsBackgroundThread() - { - return (_mainThreadId != GetCurrentThreadId()); - } - - // The RecordMainThread function registers the main thread ID for use by the IsMainThread and IsBackgroundThread functions. - void RecordMainThread() - { - _mainThreadId = GetCurrentThreadId(); - } + // The IsMainThread function returns true if the current thread is the app's main thread and false otherwise. + bool IsMainThread() + { + return (_mainThreadId == GetCurrentThreadId()); + } + + // The IsBackgroundThread function returns false if the current thread is the app's main thread and true otherwise. + bool IsBackgroundThread() + { + return (_mainThreadId != GetCurrentThreadId()); + } + + // The RecordMainThread function registers the main thread ID for use by the IsMainThread and IsBackgroundThread functions. + void RecordMainThread() + { + _mainThreadId = GetCurrentThreadId(); + } #ifdef __cplusplus } @@ -74,16 +74,16 @@ extern "C" { MainPage::MainPage() { InitializeComponent(); - m_textcolor="#402572AC"; - m_linkcolor="#40AC7225"; - mu_doc = nullptr; - m_docPages = ref new Platform::Collections::Vector(); - m_thumbnails = ref new Platform::Collections::Vector(); - m_page_link_list = ref new Platform::Collections::Vector^>(); - m_text_list = ref new Platform::Collections::Vector(); - m_linkset = ref new Platform::Collections::Vector(); - CleanUp(); - RecordMainThread(); + m_textcolor="#402572AC"; + m_linkcolor="#40AC7225"; + mu_doc = nullptr; + m_docPages = ref new Platform::Collections::Vector(); + m_thumbnails = ref new Platform::Collections::Vector(); + m_page_link_list = ref new Platform::Collections::Vector^>(); + m_text_list = ref new Platform::Collections::Vector(); + m_linkset = ref new Platform::Collections::Vector(); + CleanUp(); + RecordMainThread(); } /// @@ -108,68 +108,68 @@ void mupdf_cpp::MainPage::OKInvokedHandler(Windows::UI::Popups::IUICommand^ comm void mupdf_cpp::MainPage::NotifyUser(String^ strMessage, NotifyType_t type) { - MessageDialog^ msg = ref new MessageDialog(strMessage); - UICommand^ ExitCommand = nullptr; - UICommand^ OKCommand = nullptr; - - switch (type) - { - case StatusMessage: - OKCommand = ref new UICommand("OK", - ref new UICommandInvokedHandler(this, &mupdf_cpp::MainPage::OKInvokedHandler)); - msg->Commands->Append(OKCommand); - /// Set the command that will be invoked by default - msg->DefaultCommandIndex = 0; - // Set the command to be invoked when escape is pressed - msg->CancelCommandIndex = 1; - break; - case ErrorMessage: - ExitCommand = ref new UICommand("Exit", - ref new UICommandInvokedHandler(this, &mupdf_cpp::MainPage::ExitInvokedHandler)); - msg->Commands->Append(ExitCommand); - /// Set the command that will be invoked by default - msg->DefaultCommandIndex = 0; - // Set the command to be invoked when escape is pressed - msg->CancelCommandIndex = 1; - break; - default: - break; - } - // Show the message dialog - msg->ShowAsync(); + MessageDialog^ msg = ref new MessageDialog(strMessage); + UICommand^ ExitCommand = nullptr; + UICommand^ OKCommand = nullptr; + + switch (type) + { + case StatusMessage: + OKCommand = ref new UICommand("OK", + ref new UICommandInvokedHandler(this, &mupdf_cpp::MainPage::OKInvokedHandler)); + msg->Commands->Append(OKCommand); + /// Set the command that will be invoked by default + msg->DefaultCommandIndex = 0; + // Set the command to be invoked when escape is pressed + msg->CancelCommandIndex = 1; + break; + case ErrorMessage: + ExitCommand = ref new UICommand("Exit", + ref new UICommandInvokedHandler(this, &mupdf_cpp::MainPage::ExitInvokedHandler)); + msg->Commands->Append(ExitCommand); + /// Set the command that will be invoked by default + msg->DefaultCommandIndex = 0; + // Set the command to be invoked when escape is pressed + msg->CancelCommandIndex = 1; + break; + default: + break; + } + // Show the message dialog + msg->ShowAsync(); } bool mupdf_cpp::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 - - bool unsnapped = (ApplicationView::Value != ApplicationViewState::Snapped || - ApplicationView::TryUnsnap()); - if (!unsnapped) - { - NotifyUser("Cannot unsnap the application", StatusMessage); - } - return unsnapped; + // 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 + + bool unsnapped = (ApplicationView::Value != ApplicationViewState::Snapped || + ApplicationView::TryUnsnap()); + if (!unsnapped) + { + NotifyUser("Cannot unsnap the application", StatusMessage); + } + return unsnapped; } void mupdf_cpp::MainPage::Picker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { - if (!EnsureUnsnapped()) - return; + if (!EnsureUnsnapped()) + return; - FileOpenPicker^ openPicker = ref new FileOpenPicker(); + FileOpenPicker^ openPicker = ref new FileOpenPicker(); openPicker->ViewMode = PickerViewMode::List; openPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary; - openPicker->FileTypeFilter->Append(".pdf"); - openPicker->FileTypeFilter->Append(".xps"); - openPicker->FileTypeFilter->Append(".oxps"); + openPicker->FileTypeFilter->Append(".pdf"); + openPicker->FileTypeFilter->Append(".xps"); + openPicker->FileTypeFilter->Append(".oxps"); create_task(openPicker->PickSingleFileAsync()).then([this](StorageFile^ file) { if (file) { - this->OpenDocumentPrep(file); + this->OpenDocumentPrep(file); } else { @@ -180,689 +180,691 @@ void mupdf_cpp::MainPage::Picker(Platform::Object^ sender, Windows::UI::Xaml::Ro /* Set the page with the new raster information */ void MainPage::UpdatePage(int page_num, InMemoryRandomAccessStream^ ras, - Point ras_size, Page_Content_t content_type) + Point ras_size, Page_Content_t content_type) { - 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; - - if (content_type == THUMBNAIL) - { - doc_page->Height = ras_size.Y / SCALE_THUMB; - doc_page->Width = ras_size.X / SCALE_THUMB; - } - else - { - doc_page->Height = ras_size.Y; - doc_page->Width = ras_size.X; - } - doc_page->Content = content_type; - - /* We do not want flipview change notification to occur for ourselves */ - m_page_update = true; - this->m_docPages->SetAt(page_num, doc_page); - m_page_update = false; + 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; + + if (content_type == THUMBNAIL) + { + doc_page->Height = ras_size.Y / SCALE_THUMB; + doc_page->Width = ras_size.X / SCALE_THUMB; + } + else + { + doc_page->Height = ras_size.Y; + doc_page->Width = ras_size.X; + } + doc_page->Content = content_type; + + /* We do not want flipview change notification to occur for ourselves */ + m_page_update = true; + this->m_docPages->SetAt(page_num, doc_page); + m_page_update = false; } /* Set the page with the new raster information but only the image data */ void MainPage::ReplaceImage(int page_num, InMemoryRandomAccessStream^ ras, - Point ras_size) + Point ras_size) { - assert(IsMainThread()); + assert(IsMainThread()); - WriteableBitmap ^bmp = ref new WriteableBitmap(ras_size.X, ras_size.Y); - bmp->SetSource(ras); + WriteableBitmap ^bmp = ref new WriteableBitmap(ras_size.X, ras_size.Y); + bmp->SetSource(ras); - DocumentPage^ doc_page = this->m_docPages->GetAt(page_num); - doc_page->Image = bmp; + DocumentPage^ doc_page = this->m_docPages->GetAt(page_num); + doc_page->Image = bmp; - doc_page->Height = ras_size.Y; - doc_page->Width = ras_size.X; + doc_page->Height = ras_size.Y; + doc_page->Width = ras_size.X; } Point MainPage::ComputePageSize(spatial_info_t spatial_info, int page_num) { - Point screenSize; - Point pageSize; - Point size = mu_doc->GetPageSize(page_num); + Point screenSize; + Point pageSize; + Point size = mu_doc->GetPageSize(page_num); - screenSize = spatial_info.size; + screenSize = spatial_info.size; screenSize.Y *= screenScale; screenSize.X *= screenScale; float hscale = screenSize.X / size.X; float vscale = screenSize.Y / size.Y; float scale = min(hscale, vscale); - pageSize.X = size.X * scale * spatial_info.scale_factor; - pageSize.Y = size.Y * scale * spatial_info.scale_factor; + pageSize.X = size.X * scale * spatial_info.scale_factor; + pageSize.Y = size.Y * scale * spatial_info.scale_factor; - return pageSize; + return pageSize; } static Point fitPageToScreen(Point page, Point screen) { - Point pageSize; + Point pageSize; float hscale = screen.X / page.X; float vscale = screen.Y / page.Y; float scale = min(hscale, vscale); - pageSize.X = floorf(page.X * scale) / page.X; + pageSize.X = floorf(page.X * scale) / page.X; pageSize.Y = floorf(page.Y * scale) / page.Y; + return pageSize; } spatial_info_t MainPage::InitSpatial(double scale) { - spatial_info_t value; + spatial_info_t value; - value.size.Y = this->ActualHeight; - value.size.X = this->ActualWidth; - value.scale_factor = scale; - return value; + value.size.Y = this->ActualHeight; + value.size.X = this->ActualWidth; + value.scale_factor = scale; + + return value; } void Prepare_bmp(int width, int height, DataWriter ^dw) { - int row_size = width * 4; - int bmp_size = row_size * height + 54; - - dw->WriteString("BM"); - dw->ByteOrder = ByteOrder::LittleEndian; - dw->WriteInt32(bmp_size); - dw->WriteInt16(0); - dw->WriteInt16(0); - dw->WriteInt32(54); - dw->WriteInt32(40); - dw->WriteInt32(width); - dw->WriteInt32(height); - dw->WriteInt16(1); - dw->WriteInt16(32); - dw->WriteInt32(0); - dw->WriteInt32(row_size * height); - dw->WriteInt32(2835); - dw->WriteInt32(2835); - dw->WriteInt32(0); - dw->WriteInt32(0); + int row_size = width * 4; + int bmp_size = row_size * height + 54; + + dw->WriteString("BM"); + dw->ByteOrder = ByteOrder::LittleEndian; + dw->WriteInt32(bmp_size); + dw->WriteInt16(0); + dw->WriteInt16(0); + dw->WriteInt32(54); + dw->WriteInt32(40); + dw->WriteInt32(width); + dw->WriteInt32(height); + dw->WriteInt16(1); + dw->WriteInt16(32); + dw->WriteInt32(0); + dw->WriteInt32(row_size * height); + dw->WriteInt32(2835); + dw->WriteInt32(2835); + dw->WriteInt32(0); + dw->WriteInt32(0); } void MainPage::ReleasePages(int old_page, int new_page) { - if (old_page == new_page) return; - /* To keep from having memory issue reset the page back to - the thumb if we are done rendering the thumbnails */ - for (int k = old_page - LOOK_AHEAD; k <= old_page + LOOK_AHEAD; k++) - { - if (k < new_page - LOOK_AHEAD || k > new_page + LOOK_AHEAD) - { - if (k >= 0 && k < this->m_num_pages) - { - SetThumb(k, true); - } - } - } + if (old_page == new_page) return; + /* To keep from having memory issue reset the page back to + the thumb if we are done rendering the thumbnails */ + for (int k = old_page - LOOK_AHEAD; k <= old_page + LOOK_AHEAD; k++) + { + if (k < new_page - LOOK_AHEAD || k > new_page + LOOK_AHEAD) + { + if (k >= 0 && k < this->m_num_pages) + { + SetThumb(k, true); + } + } + } } -/* Return this page from a full res image to the thumb image or only set to thumb - if it has not already been set */ +/* Return this page from a full res image to the thumb image or only set + to thumb if it has not already been set */ void MainPage::SetThumb(int page_num, bool replace) { - /* See what is there now */ - auto doc = this->m_docPages->GetAt(page_num); - if (doc->Content == THUMBNAIL) return; - if (doc->Content == FULL_RESOLUTION && replace == false) return; - - if (this->m_thumbnails->Size > page_num) - { - m_page_update = true; - this->m_docPages->SetAt(page_num, this->m_thumbnails->GetAt(page_num)); - m_page_update = false; - } + /* See what is there now */ + auto doc = this->m_docPages->GetAt(page_num); + if (doc->Content == THUMBNAIL) return; + if (doc->Content == FULL_RESOLUTION && replace == false) return; + + if (this->m_thumbnails->Size > page_num) + { + m_page_update = true; + this->m_docPages->SetAt(page_num, this->m_thumbnails->GetAt(page_num)); + m_page_update = false; + } } /* Create white image for us to use as place holder in large document for flip view filling instead of the thumbnail image */ void MainPage::CreateBlank(int width, int height) { - Array^ bmp_data = ref new Array(height * 4 * width); - /* Set up the memory stream */ - WriteableBitmap ^bmp = ref new WriteableBitmap(width, height); - InMemoryRandomAccessStream ^ras = ref new InMemoryRandomAccessStream(); - DataWriter ^dw = ref new DataWriter(ras->GetOutputStreamAt(0)); - /* Go ahead and write our header data into the memory stream */ - Prepare_bmp(width, height, dw); - - /* Set the data to all white */ - memset(bmp_data->Data, 255, height * 4 * width); - - /* Write the data */ - dw->WriteBytes(bmp_data); - - DataWriterStoreOperation^ result = dw->StoreAsync(); - /* Block on the Async call */ - while(result->Status != AsyncStatus::Completed) { - } - /* And store in a the image brush */ - bmp->SetSource(ras); - m_BlankBmp = bmp; + Array^ bmp_data = ref new Array(height * 4 * width); + /* Set up the memory stream */ + WriteableBitmap ^bmp = ref new WriteableBitmap(width, height); + InMemoryRandomAccessStream ^ras = ref new InMemoryRandomAccessStream(); + DataWriter ^dw = ref new DataWriter(ras->GetOutputStreamAt(0)); + /* Go ahead and write our header data into the memory stream */ + Prepare_bmp(width, height, dw); + + /* Set the data to all white */ + memset(bmp_data->Data, 255, height * 4 * width); + + /* Write the data */ + dw->WriteBytes(bmp_data); + + DataWriterStoreOperation^ result = dw->StoreAsync(); + /* Block on the Async call */ + while(result->Status != AsyncStatus::Completed) { + } + /* And store in a the image brush */ + bmp->SetSource(ras); + m_BlankBmp = bmp; } void mupdf_cpp::MainPage::SetFlipView() { - int height = this->ActualHeight; - int width = this->ActualWidth; - - CreateBlank(BLANK_WIDTH, BLANK_HEIGHT); - /* Set the current flip view mode */ - if (height > width) - this->m_curr_flipView = xaml_vert_flipView; - else - this->m_curr_flipView = xaml_horiz_flipView; + int height = this->ActualHeight; + int width = this->ActualWidth; + + CreateBlank(BLANK_WIDTH, BLANK_HEIGHT); + /* Set the current flip view mode */ + if (height > width) + this->m_curr_flipView = xaml_vert_flipView; + else + this->m_curr_flipView = xaml_horiz_flipView; } /* Clean up everything as we are opening a new document after having another one open */ void mupdf_cpp::MainPage::CleanUp() { - /* Remove current pages in the flipviews */ - if (m_docPages != nullptr && m_docPages->Size > 0) - m_docPages->Clear(); - if (m_thumbnails != nullptr && m_thumbnails->Size > 0) - m_thumbnails->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(); - if (m_linkset != nullptr && m_linkset->Size > 0) - m_linkset->Clear(); - - if (this->mu_doc != nullptr) - mu_doc->CleanUp(); - - mu_doc = ref new mudocument(); - if (mu_doc == nullptr) - throw ref new FailureException("Document allocation failed!"); - - this->m_curr_flipView = nullptr; - m_currpage = -1; - m_file_open = false; - m_slider_min = 0; - m_slider_max = 0; - m_init_done = false; - m_memory_use = 0; - m_insearch = false; - m_search_active = false; - m_sliderchange = false; - m_flip_from_searchlink = false; - m_num_pages = -1; - m_search_rect_count = 0; - m_ren_status = REN_AVAILABLE; - m_links_on = false; - m_rectlist_page = -1; - - this->xaml_PageSlider->Minimum = m_slider_min; - this->xaml_PageSlider->Maximum = m_slider_max; - this->xaml_PageSlider->IsEnabled = false; + /* Remove current pages in the flipviews */ + if (m_docPages != nullptr && m_docPages->Size > 0) + m_docPages->Clear(); + if (m_thumbnails != nullptr && m_thumbnails->Size > 0) + m_thumbnails->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(); + if (m_linkset != nullptr && m_linkset->Size > 0) + m_linkset->Clear(); + + if (this->mu_doc != nullptr) + mu_doc->CleanUp(); + + mu_doc = ref new mudocument(); + if (mu_doc == nullptr) + throw ref new FailureException("Document allocation failed!"); + + this->m_curr_flipView = nullptr; + m_currpage = -1; + m_file_open = false; + m_slider_min = 0; + m_slider_max = 0; + m_init_done = false; + m_memory_use = 0; + m_insearch = false; + m_search_active = false; + m_sliderchange = false; + m_flip_from_searchlink = false; + m_num_pages = -1; + m_search_rect_count = 0; + m_ren_status = REN_AVAILABLE; + m_links_on = false; + m_rectlist_page = -1; + + this->xaml_PageSlider->Minimum = m_slider_min; + this->xaml_PageSlider->Maximum = m_slider_max; + this->xaml_PageSlider->IsEnabled = false; } /* Create the thumbnail images */ void mupdf_cpp::MainPage::RenderThumbs() { - spatial_info_t spatial_info = this->InitSpatial(1); - int num_pages = this->m_num_pages; - cancellation_token_source cts; - auto token = cts.get_token(); - m_ThumbCancel = cts; - - this->m_ren_status = REN_THUMBS; - Vector^ thumbnails = m_thumbnails; - auto ui = task_continuation_context::use_current(); - create_task([spatial_info, num_pages, thumbnails, this, ui, token]()-> int - { - spatial_info_t spatial_info_local = spatial_info; - spatial_info_local.scale_factor = SCALE_THUMB; - - for (int k = 0; k < num_pages; k++) - { - Point ras_size = ComputePageSize(spatial_info_local, k); - bool done = false; - DWORD thread1_id = GetCurrentThreadId(); - auto task2 = create_task(mu_doc->RenderPage(k, ras_size.X, ras_size.Y)); - - task2.then([this, k, thumbnails, ras_size](InMemoryRandomAccessStream^ ras) - { - 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 / SCALE_THUMB; - doc_page->Width = ras_size.X / SCALE_THUMB; - doc_page->Content = THUMBNAIL; - doc_page->TextBox = nullptr; - doc_page->LinkBox = nullptr; - if (this->m_ren_status == REN_THUMBS) { - m_thumbnails->SetAt(k, doc_page); /* This avoids out of order returns from task */ - /* Flipview object gets overwhelmed unless I do this */ - if ((k < THUMB_PREADD)) - SetThumb(k, false); - } - }, ui).then([this] (task t) - { - try - { - t.get(); - } - catch(Platform::InvalidArgumentException^ e) - { - //TODO handle error. - } - }, token); //end task chain */ - - /* If cancelled then save the last one as the continuation will not - have occured. */ - if (is_task_cancellation_requested()) - { - cancel_current_task(); - } - } - return num_pages; /* all done with thumbnails! */ - }, token).then([this](task the_task) - { - /* Finish adding them, but not if we were cancelled. */ - bool is_cancelled = false; - try - { - the_task.get(); - } - catch (const task_canceled& e) - { - is_cancelled = true; - } - if (!is_cancelled) - { - for (int k = THUMB_PREADD; k < m_num_pages; k++) - SetThumb(k, false); - } - this->m_ren_status = REN_AVAILABLE; - }, task_continuation_context::use_current()); + spatial_info_t spatial_info = this->InitSpatial(1); + int num_pages = this->m_num_pages; + cancellation_token_source cts; + auto token = cts.get_token(); + m_ThumbCancel = cts; + + this->m_ren_status = REN_THUMBS; + Vector^ thumbnails = m_thumbnails; + auto ui = task_continuation_context::use_current(); + create_task([spatial_info, num_pages, thumbnails, this, ui, token]()-> int + { + spatial_info_t spatial_info_local = spatial_info; + spatial_info_local.scale_factor = SCALE_THUMB; + + for (int k = 0; k < num_pages; k++) + { + Point ras_size = ComputePageSize(spatial_info_local, k); + bool done = false; + DWORD thread1_id = GetCurrentThreadId(); + auto task2 = create_task(mu_doc->RenderPage(k, ras_size.X, ras_size.Y)); + + task2.then([this, k, thumbnails, ras_size](InMemoryRandomAccessStream^ ras) + { + 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 / SCALE_THUMB; + doc_page->Width = ras_size.X / SCALE_THUMB; + doc_page->Content = THUMBNAIL; + doc_page->TextBox = nullptr; + doc_page->LinkBox = nullptr; + if (this->m_ren_status == REN_THUMBS) { + m_thumbnails->SetAt(k, doc_page); /* This avoids out of order returns from task */ + /* Flipview object gets overwhelmed unless I do this */ + if ((k < THUMB_PREADD)) + SetThumb(k, false); + } + }, ui).then([this] (task t) + { + try + { + t.get(); + } + catch(Platform::InvalidArgumentException^ e) + { + //TODO handle error. + } + }, token); //end task chain */ + + /* If cancelled then save the last one as the continuation will not + have occured. */ + if (is_task_cancellation_requested()) + { + cancel_current_task(); + } + } + return num_pages; /* all done with thumbnails! */ + }, token).then([this](task the_task) + { + /* Finish adding them, but not if we were cancelled. */ + bool is_cancelled = false; + try + { + the_task.get(); + } + catch (const task_canceled& e) + { + is_cancelled = true; + } + if (!is_cancelled) + { + for (int k = THUMB_PREADD; k < m_num_pages; k++) + SetThumb(k, false); + } + this->m_ren_status = REN_AVAILABLE; + }, task_continuation_context::use_current()); } void mupdf_cpp::MainPage::OpenDocumentPrep(StorageFile^ file) { - if (this->m_num_pages != -1) - { - m_init_done = false; - - /* Set the index to the start of the document */ - this->xaml_vert_flipView->SelectedIndex = 0; - this->xaml_horiz_flipView->SelectedIndex = 0; - - /* If the thumbnail thread is running then we need to end that first */ - RenderingStatus_t *ren_status = &m_ren_status; - cancellation_token_source *ThumbCancel = &m_ThumbCancel; - - /* Create a task to wait until the renderer is available, then clean up then open */ - auto t = create_task([ren_status, ThumbCancel]()->int - { - if (*ren_status == REN_THUMBS) - ThumbCancel->cancel(); - while (*ren_status != REN_AVAILABLE) { - } - return 0; - }).then([this](task the_task) - { - CleanUp(); - return 0; - }, task_continuation_context::use_current()).then([this, file](task the_task) - { - OpenDocument(file); - }, task_continuation_context::use_current()); - } - else - { - OpenDocument(file); - } + if (this->m_num_pages != -1) + { + m_init_done = false; + + /* Set the index to the start of the document */ + this->xaml_vert_flipView->SelectedIndex = 0; + this->xaml_horiz_flipView->SelectedIndex = 0; + + /* If the thumbnail thread is running then we need to end that first */ + RenderingStatus_t *ren_status = &m_ren_status; + cancellation_token_source *ThumbCancel = &m_ThumbCancel; + + /* Create a task to wait until the renderer is available, then clean up then open */ + auto t = create_task([ren_status, ThumbCancel]()->int + { + if (*ren_status == REN_THUMBS) + ThumbCancel->cancel(); + while (*ren_status != REN_AVAILABLE) { + } + return 0; + }).then([this](task the_task) + { + CleanUp(); + return 0; + }, task_continuation_context::use_current()).then([this, file](task the_task) + { + OpenDocument(file); + }, task_continuation_context::use_current()); + } + else + { + OpenDocument(file); + } } void mupdf_cpp::MainPage::OpenDocument(StorageFile^ file) { - String^ path = file->Path; - const wchar_t *w = path->Data(); - int cb = WideCharToMultiByte(CP_UTF8, 0, w, -1, nullptr, 0, nullptr, nullptr); + String^ path = file->Path; + const wchar_t *w = path->Data(); + int cb = WideCharToMultiByte(CP_UTF8, 0, w, -1, nullptr, 0, nullptr, nullptr); char* name = new char[cb]; - WideCharToMultiByte(CP_UTF8, 0, w ,-1 ,name ,cb ,nullptr, nullptr); - char *ext = strrchr(name, '.'); - - this->SetFlipView(); - - /* Open document and when open, push on */ - auto open_task = create_task(mu_doc->OpenFile(file)); - - open_task.then([this] - { - assert(IsMainThread()); - - m_num_pages = mu_doc->GetNumPages(); - if ((m_currpage) >= m_num_pages) - { - m_currpage = m_num_pages - 1; - } - else if (m_currpage < 0) - { - m_currpage = 0; - } - - /* Initialize all the flipvew items with blanks and the thumbnails. */ - for (int k = 0; k < m_num_pages; k++) - { - /* Blank pages */ - DocumentPage^ doc_page = ref new DocumentPage(); - doc_page->Image = m_BlankBmp; - doc_page->Height = BLANK_HEIGHT; - doc_page->Width = BLANK_WIDTH; - doc_page->Content = DUMMY; - doc_page->TextBox = nullptr; - doc_page->LinkBox = nullptr; - m_docPages->Append(doc_page); - m_thumbnails->Append(doc_page); - /* Create empty lists for our links and specify that they have not - been computed for these pages */ - Vector^ temp_link = ref new Vector(); - m_page_link_list->Append(temp_link); - m_linkset->Append(false); - } - - this->xaml_horiz_flipView->ItemsSource = m_docPages; - this->xaml_vert_flipView->ItemsSource = m_docPages; - - /* Do the first few pages, then start the thumbs */ - spatial_info_t spatial_info = InitSpatial(1); - for (int k = 0; k < LOOK_AHEAD + 2; k++) - { - if (m_num_pages > k ) - { - Point ras_size = ComputePageSize(spatial_info, k); - - auto render_task = - create_task(mu_doc->RenderPage(k, ras_size.X, ras_size.Y)); - - render_task.then([this, k, ras_size] (InMemoryRandomAccessStream^ ras) - { - UpdatePage(k, ras, ras_size, FULL_RESOLUTION); - }, task_continuation_context::use_current()); - } - } - /* Update the slider settings, if more than one page */ - if (m_num_pages > 1) - { - this->xaml_PageSlider->Maximum = m_num_pages; - this->xaml_PageSlider->Minimum = 1; - this->xaml_PageSlider->IsEnabled = true; - } - else - { - this->xaml_PageSlider->Maximum = 0; - this->xaml_PageSlider->Minimum = 0; - this->xaml_PageSlider->IsEnabled = false; - } - /* All done with initial pages */ - this->m_init_done = true; - }).then([this] - { - this->RenderThumbs(); - }, task_continuation_context::use_current()); + WideCharToMultiByte(CP_UTF8, 0, w ,-1 ,name ,cb ,nullptr, nullptr); + char *ext = strrchr(name, '.'); + + this->SetFlipView(); + + /* Open document and when open, push on */ + auto open_task = create_task(mu_doc->OpenFile(file)); + + open_task.then([this] + { + assert(IsMainThread()); + + m_num_pages = mu_doc->GetNumPages(); + if ((m_currpage) >= m_num_pages) + { + m_currpage = m_num_pages - 1; + } + else if (m_currpage < 0) + { + m_currpage = 0; + } + + /* Initialize all the flipvew items with blanks and the thumbnails. */ + for (int k = 0; k < m_num_pages; k++) + { + /* Blank pages */ + DocumentPage^ doc_page = ref new DocumentPage(); + doc_page->Image = m_BlankBmp; + doc_page->Height = BLANK_HEIGHT; + doc_page->Width = BLANK_WIDTH; + doc_page->Content = DUMMY; + doc_page->TextBox = nullptr; + doc_page->LinkBox = nullptr; + m_docPages->Append(doc_page); + m_thumbnails->Append(doc_page); + /* Create empty lists for our links and specify that they have not + been computed for these pages */ + Vector^ temp_link = ref new Vector(); + m_page_link_list->Append(temp_link); + m_linkset->Append(false); + } + + this->xaml_horiz_flipView->ItemsSource = m_docPages; + this->xaml_vert_flipView->ItemsSource = m_docPages; + + /* Do the first few pages, then start the thumbs */ + spatial_info_t spatial_info = InitSpatial(1); + for (int k = 0; k < LOOK_AHEAD + 2; k++) + { + if (m_num_pages > k ) + { + Point ras_size = ComputePageSize(spatial_info, k); + + auto render_task = + create_task(mu_doc->RenderPage(k, ras_size.X, ras_size.Y)); + + render_task.then([this, k, ras_size] (InMemoryRandomAccessStream^ ras) + { + UpdatePage(k, ras, ras_size, FULL_RESOLUTION); + }, task_continuation_context::use_current()); + } + } + /* Update the slider settings, if more than one page */ + if (m_num_pages > 1) + { + this->xaml_PageSlider->Maximum = m_num_pages; + this->xaml_PageSlider->Minimum = 1; + this->xaml_PageSlider->IsEnabled = true; + } + else + { + this->xaml_PageSlider->Maximum = 0; + this->xaml_PageSlider->Minimum = 0; + this->xaml_PageSlider->IsEnabled = false; + } + /* All done with initial pages */ + this->m_init_done = true; + }).then([this] + { + this->RenderThumbs(); + }, task_continuation_context::use_current()); } void mupdf_cpp::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); - bool curr_page_rendered = true; - int range = LOOK_AHEAD; - - assert(IsMainThread()); - if (m_flip_from_searchlink) - range = 0; - for (int k = curr_page - LOOK_AHEAD; k <= curr_page + LOOK_AHEAD; k++) - { - if (k >= 0 && k < m_num_pages) - { - /* Check if page is already rendered */ - auto doc = this->m_docPages->GetAt(k); - if (doc->Content != FULL_RESOLUTION) - { - Point ras_size = ComputePageSize(spatial_info, k); - auto render_task = - create_task(mu_doc->RenderPage(k, ras_size.X, ras_size.Y)); - - render_task.then([this, k, ras_size] (InMemoryRandomAccessStream^ ras) - { - UpdatePage(k, ras, ras_size, FULL_RESOLUTION); - }, task_continuation_context::use_current()).then([this, k, curr_page]() - { - if (k == curr_page && this->m_links_on) - AddLinkCanvas(); - if (k == curr_page && this->m_text_list->Size > 0 && - m_flip_from_searchlink) - { - AddTextCanvas(); - m_flip_from_searchlink = false; - } - },task_continuation_context::use_current()); - } - else - { - /* We did not need to render the curr_page, so add links below if - needed. Otherwise, we need to wait for the task above to - complete before we add the links. */ - if (k == curr_page) - curr_page_rendered = false; - } - } - } - m_currpage = curr_page; - if (this->m_links_on && !curr_page_rendered) - AddLinkCanvas(); - if (this->m_text_list->Size > 0 && !curr_page_rendered && m_flip_from_searchlink) - { - AddTextCanvas(); - m_flip_from_searchlink = false; - } + /* Render +/- the look ahead from where we are if blank page is present */ + spatial_info_t spatial_info = InitSpatial(1); + bool curr_page_rendered = true; + int range = LOOK_AHEAD; + + assert(IsMainThread()); + if (m_flip_from_searchlink) + range = 0; + for (int k = curr_page - LOOK_AHEAD; k <= curr_page + LOOK_AHEAD; k++) + { + if (k >= 0 && k < m_num_pages) + { + /* Check if page is already rendered */ + auto doc = this->m_docPages->GetAt(k); + if (doc->Content != FULL_RESOLUTION) + { + Point ras_size = ComputePageSize(spatial_info, k); + auto render_task = + create_task(mu_doc->RenderPage(k, ras_size.X, ras_size.Y)); + + render_task.then([this, k, ras_size] (InMemoryRandomAccessStream^ ras) + { + UpdatePage(k, ras, ras_size, FULL_RESOLUTION); + }, task_continuation_context::use_current()).then([this, k, curr_page]() + { + if (k == curr_page && this->m_links_on) + AddLinkCanvas(); + if (k == curr_page && this->m_text_list->Size > 0 && + m_flip_from_searchlink) + { + AddTextCanvas(); + m_flip_from_searchlink = false; + } + },task_continuation_context::use_current()); + } + else + { + /* We did not need to render the curr_page, so add links below if + needed. Otherwise, we need to wait for the task above to + complete before we add the links. */ + if (k == curr_page) + curr_page_rendered = false; + } + } + } + m_currpage = curr_page; + if (this->m_links_on && !curr_page_rendered) + AddLinkCanvas(); + if (this->m_text_list->Size > 0 && !curr_page_rendered && m_flip_from_searchlink) + { + AddTextCanvas(); + m_flip_from_searchlink = false; + } } void mupdf_cpp::MainPage::Slider_ValueChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e) { - int newValue = (int) this->xaml_PageSlider->Value - 1; /* zero based */ - - if (m_update_flip) - { - m_update_flip = false; - return; - } - if (m_init_done && this->xaml_PageSlider->IsEnabled) - { - /* Make sure to clear any text search */ - auto doc_old = this->m_docPages->GetAt(m_currpage); - doc_old->TextBox = nullptr; - - auto doc = this->m_docPages->GetAt(newValue); - if (doc->Content != FULL_RESOLUTION) - { - spatial_info_t spatial_info = InitSpatial(1); - Point ras_size = ComputePageSize(spatial_info, newValue); - auto render_task = - create_task(mu_doc->RenderPage(newValue, ras_size.X, ras_size.Y)); - - render_task.then([this, newValue, ras_size] (InMemoryRandomAccessStream^ ras) - { - UpdatePage(newValue, ras, ras_size, FULL_RESOLUTION); - this->m_ren_status = REN_AVAILABLE; - this->m_currpage = newValue; - m_sliderchange = true; - this->m_curr_flipView->SelectedIndex = newValue; - }, task_continuation_context::use_current()); - } - } + int newValue = (int) this->xaml_PageSlider->Value - 1; /* zero based */ + + if (m_update_flip) + { + m_update_flip = false; + return; + } + if (m_init_done && this->xaml_PageSlider->IsEnabled) + { + /* Make sure to clear any text search */ + auto doc_old = this->m_docPages->GetAt(m_currpage); + doc_old->TextBox = nullptr; + + auto doc = this->m_docPages->GetAt(newValue); + if (doc->Content != FULL_RESOLUTION) + { + spatial_info_t spatial_info = InitSpatial(1); + Point ras_size = ComputePageSize(spatial_info, newValue); + auto render_task = + create_task(mu_doc->RenderPage(newValue, ras_size.X, ras_size.Y)); + + render_task.then([this, newValue, ras_size] (InMemoryRandomAccessStream^ ras) + { + UpdatePage(newValue, ras, ras_size, FULL_RESOLUTION); + this->m_ren_status = REN_AVAILABLE; + this->m_currpage = newValue; + m_sliderchange = true; + this->m_curr_flipView->SelectedIndex = newValue; + }, task_continuation_context::use_current()); + } + } } void mupdf_cpp::MainPage::FlipView_SelectionChanged(Object^ sender, SelectionChangedEventArgs^ e) { - if (m_init_done && !m_page_update) - { - int pos = this->m_curr_flipView->SelectedIndex; - - if (pos >= 0) - { - m_update_flip = true; - if (xaml_PageSlider->IsEnabled) - { - xaml_PageSlider->Value = pos; - } - if (m_sliderchange) - { - m_sliderchange = false; - return; - } - else - { - /* Make sure to clear any text search */ - auto doc_old = this->m_docPages->GetAt(m_currpage); - doc_old->TextBox = nullptr; - } - /* Get the current page */ - int curr_page = this->m_currpage; - this->RenderRange(pos); - this->ReleasePages(curr_page, pos); - } - } + if (m_init_done && !m_page_update) + { + int pos = this->m_curr_flipView->SelectedIndex; + + if (pos >= 0) + { + m_update_flip = true; + if (xaml_PageSlider->IsEnabled) + { + xaml_PageSlider->Value = pos; + } + if (m_sliderchange) + { + m_sliderchange = false; + return; + } + else + { + /* Make sure to clear any text search */ + auto doc_old = this->m_docPages->GetAt(m_currpage); + doc_old->TextBox = nullptr; + } + /* Get the current page */ + int curr_page = this->m_currpage; + this->RenderRange(pos); + this->ReleasePages(curr_page, pos); + } + } } /* Search Related Code */ void mupdf_cpp::MainPage::Searcher(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { - /* Update the app bar so that we can do the search */ - StackPanel^ leftPanel = (StackPanel^) this->TopAppBar->FindName("LeftPanel"); + /* Update the app bar so that we can do the search */ + StackPanel^ leftPanel = (StackPanel^) this->TopAppBar->FindName("LeftPanel"); if (leftPanel != nullptr && m_insearch) - { - m_insearch = false; - leftPanel->Children->RemoveAtEnd(); - leftPanel->Children->RemoveAtEnd(); - leftPanel->Children->RemoveAtEnd(); - } - else if (leftPanel != nullptr && !m_insearch) { - /* Search is not going to work in snapped view for now to simplify UI - in this cramped case. So see if we can get out of snapped mode. */ - - if (!EnsureUnsnapped()) - return; - - m_insearch = true; - Windows::UI::Xaml::Controls::Button^ PrevButton = ref new Button(); - PrevButton->Style = safe_cast(App::Current->Resources->Lookup("PreviousAppBarButtonStyle")); - PrevButton->Click += ref new RoutedEventHandler(this, &mupdf_cpp::MainPage::SearchPrev); - - Windows::UI::Xaml::Controls::Button^ NextButton = ref new Button(); - NextButton->Style = safe_cast(App::Current->Resources->Lookup("NextAppBarButtonStyle")); - NextButton->Click += ref new RoutedEventHandler(this, &mupdf_cpp::MainPage::SearchNext); - - Windows::UI::Xaml::Controls::TextBox^ SearchBox = ref new TextBox(); - SearchBox->Name = "findBox"; - SearchBox->Width = 200; - SearchBox->Height = 20; - - leftPanel->Children->Append(SearchBox); - leftPanel->Children->Append(PrevButton); - leftPanel->Children->Append(NextButton); + m_insearch = false; + leftPanel->Children->RemoveAtEnd(); + leftPanel->Children->RemoveAtEnd(); + leftPanel->Children->RemoveAtEnd(); + } + else if (leftPanel != nullptr && !m_insearch) + { + /* Search is not going to work in snapped view for now to simplify UI + in this cramped case. So see if we can get out of snapped mode. */ + + if (!EnsureUnsnapped()) + return; + + m_insearch = true; + Windows::UI::Xaml::Controls::Button^ PrevButton = ref new Button(); + PrevButton->Style = safe_cast(App::Current->Resources->Lookup("PreviousAppBarButtonStyle")); + PrevButton->Click += ref new RoutedEventHandler(this, &mupdf_cpp::MainPage::SearchPrev); + + Windows::UI::Xaml::Controls::Button^ NextButton = ref new Button(); + NextButton->Style = safe_cast(App::Current->Resources->Lookup("NextAppBarButtonStyle")); + NextButton->Click += ref new RoutedEventHandler(this, &mupdf_cpp::MainPage::SearchNext); + + Windows::UI::Xaml::Controls::TextBox^ SearchBox = ref new TextBox(); + SearchBox->Name = "findBox"; + SearchBox->Width = 200; + SearchBox->Height = 20; + + leftPanel->Children->Append(SearchBox); + leftPanel->Children->Append(PrevButton); + leftPanel->Children->Append(NextButton); } } void mupdf_cpp::MainPage::ClearTextSearch() { - /* Clear out any old search result */ - if (m_text_list->Size > 0) - m_text_list->Clear(); + /* Clear out any old search result */ + if (m_text_list->Size > 0) + m_text_list->Clear(); } void mupdf_cpp::MainPage::ShowSearchResults(SearchResult_t result) { - int old_page = this->m_currpage; - int new_page = result.page_num; - - ClearTextSearch(); - - /* Compute any scalings */ - Point screenSize; - Point pageSize; - Point scale; - - screenSize.Y = this->ActualHeight; - screenSize.X = this->ActualWidth; - screenSize.X *= screenScale; - screenSize.Y *= screenScale; - pageSize = mu_doc->GetPageSize(m_currpage); - scale = fitPageToScreen(pageSize, screenSize); - auto doc_page = this->m_docPages->GetAt(old_page); - - /* Construct our list of rectangles */ - for (int k = 0; k < result.box_count; k++) - { - RectList^ rect_item = ref new RectList(); - auto curr_box = mu_doc->GetTextSearch(k); - - rect_item->Color = m_textcolor; - rect_item->Height = curr_box->LowerRight.Y - curr_box->UpperLeft.Y; - rect_item->Width = curr_box->LowerRight.X - curr_box->UpperLeft.X; - rect_item->X = curr_box->UpperLeft.X * scale.X; - rect_item->Y = curr_box->UpperLeft.Y * scale.Y; - rect_item->Width *= (scale.X * doc_page->Zoom); + int old_page = this->m_currpage; + int new_page = result.page_num; + + ClearTextSearch(); + + /* Compute any scalings */ + Point screenSize; + Point pageSize; + Point scale; + + screenSize.Y = this->ActualHeight; + screenSize.X = this->ActualWidth; + screenSize.X *= screenScale; + screenSize.Y *= screenScale; + pageSize = mu_doc->GetPageSize(m_currpage); + scale = fitPageToScreen(pageSize, screenSize); + auto doc_page = this->m_docPages->GetAt(old_page); + + /* Construct our list of rectangles */ + for (int k = 0; k < result.box_count; k++) + { + RectList^ rect_item = ref new RectList(); + auto curr_box = mu_doc->GetTextSearch(k); + + rect_item->Color = m_textcolor; + rect_item->Height = curr_box->LowerRight.Y - curr_box->UpperLeft.Y; + rect_item->Width = curr_box->LowerRight.X - curr_box->UpperLeft.X; + rect_item->X = curr_box->UpperLeft.X * scale.X; + rect_item->Y = curr_box->UpperLeft.Y * scale.Y; + rect_item->Width *= (scale.X * doc_page->Zoom); rect_item->Height *= (scale.Y * doc_page->Zoom); - rect_item->Index = k.ToString(); - m_text_list->Append(rect_item); - } - /* Make sure the current page has its text results cleared */ - doc_page->TextBox = nullptr; - - /* Go ahead and set our doc item to this in the vertical and horizontal view */ - m_searchpage = new_page; - m_flip_from_searchlink = true; - - if (old_page == new_page) - { - FlipView_SelectionChanged(nullptr, nullptr); - } - else - { - this->m_curr_flipView->SelectedIndex = new_page; - } - return; + rect_item->Index = k.ToString(); + m_text_list->Append(rect_item); + } + /* Make sure the current page has its text results cleared */ + doc_page->TextBox = nullptr; + + /* Go ahead and set our doc item to this in the vertical and horizontal view */ + m_searchpage = new_page; + m_flip_from_searchlink = true; + + if (old_page == new_page) + { + FlipView_SelectionChanged(nullptr, nullptr); + } + else + { + this->m_curr_flipView->SelectedIndex = new_page; + } + return; } void mupdf_cpp::MainPage::SearchNext(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { - StackPanel^ leftPanel = (StackPanel^) this->TopAppBar->FindName("LeftPanel"); - TextBox^ findBox = (TextBox^) leftPanel->FindName("findBox"); - String^ textToFind = findBox->Text; + StackPanel^ leftPanel = (StackPanel^) this->TopAppBar->FindName("LeftPanel"); + TextBox^ findBox = (TextBox^) leftPanel->FindName("findBox"); + String^ textToFind = findBox->Text; - if (this->m_search_active == false) - SearchInDirection(1, textToFind); + if (this->m_search_active == false) + SearchInDirection(1, textToFind); } void mupdf_cpp::MainPage::SearchPrev(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { - StackPanel^ leftPanel = (StackPanel^) this->TopAppBar->FindName("LeftPanel"); - TextBox^ findBox = (TextBox^) leftPanel->FindName("findBox"); - String^ textToFind = findBox->Text; + StackPanel^ leftPanel = (StackPanel^) this->TopAppBar->FindName("LeftPanel"); + TextBox^ findBox = (TextBox^) leftPanel->FindName("findBox"); + String^ textToFind = findBox->Text; - if (this->m_search_active == false) - SearchInDirection(-1, textToFind); + if (this->m_search_active == false) + SearchInDirection(-1, textToFind); } void mupdf_cpp::MainPage::CancelSearch(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) @@ -872,412 +874,412 @@ void mupdf_cpp::MainPage::CancelSearch(Platform::Object^ sender, Windows::UI::Xa void mupdf_cpp::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); - assert(doc_page->Content == FULL_RESOLUTION); - if (doc_page->Content == FULL_RESOLUTION) // We should not be doing links for thumbnails - { - doc_page->TextBox = m_text_list; - } - this->m_search_active = false; + /* Go ahead and set our doc item to this in the vertical and horizontal view */ + auto doc_page = this->m_docPages->GetAt(m_currpage); + assert(doc_page->Content == FULL_RESOLUTION); + if (doc_page->Content == FULL_RESOLUTION) // We should not be doing links for thumbnails + { + doc_page->TextBox = m_text_list; + } + this->m_search_active = false; } void mupdf_cpp::MainPage::SearchInDirection(int dir, String^ textToFind) { - cancellation_token_source cts; - auto token = cts.get_token(); - m_searchcts = cts; - int pos = m_currpage; - int start; - SearchResult_t result; + cancellation_token_source cts; + auto token = cts.get_token(); + m_searchcts = cts; + int pos = m_currpage; + int start; + SearchResult_t result; - result.box_count = 0; - result.page_num = -1; + result.box_count = 0; + result.page_num = -1; if (m_searchpage == pos) start = pos + dir; else start = pos; - /* ProgressBar^ my_xaml_Progress = (ProgressBar^) (this->FindName("xaml_Progress")); - my_xaml_Progress->Value = start; - my_xaml_Progress->IsEnabled = true; - my_xaml_Progress->Opacity = 1.0; */ + /* ProgressBar^ my_xaml_Progress = (ProgressBar^) (this->FindName("xaml_Progress")); + my_xaml_Progress->Value = start; + my_xaml_Progress->IsEnabled = true; + my_xaml_Progress->Opacity = 1.0; */ - if (start < 0) - return; - if (start > this->m_num_pages - 1) - return; - this->m_search_active = true; + if (start < 0) + return; + if (start > this->m_num_pages - 1) + return; + this->m_search_active = true; - /* Do task lambdas here to avoid UI blocking issues */ - auto search_task = create_task([this, textToFind, dir, start, &result]()->SearchResult_t - { + /* Do task lambdas here to avoid UI blocking issues */ + auto search_task = create_task([this, textToFind, dir, start, &result]()->SearchResult_t + { for (int i = start; i >= 0 && i < this->m_num_pages; i += dir) - { - result.box_count = this->mu_doc->ComputeTextSearch(textToFind, i); - result.page_num = i; + { + result.box_count = this->mu_doc->ComputeTextSearch(textToFind, i); + result.page_num = i; - // my_xaml_Progress->Value = i; + // my_xaml_Progress->Value = i; - if (result.box_count > 0) - { - return result; + if (result.box_count > 0) + { + return result; } - if (is_task_cancellation_requested()) - { - } - } - /* Todo no matches found alert */ - return result; - }, token); - /* Do the continuation on the ui thread */ - search_task.then([this](task the_task) - { - SearchResult_t the_result = the_task.get(); - if (the_result.box_count > 0) - { - this->ShowSearchResults(the_result); - } - }, task_continuation_context::use_current()); + if (is_task_cancellation_requested()) + { + } + } + /* Todo no matches found alert */ + return result; + }, token); + /* Do the continuation on the ui thread */ + search_task.then([this](task the_task) + { + SearchResult_t the_result = the_task.get(); + if (the_result.box_count > 0) + { + this->ShowSearchResults(the_result); + } + }, task_continuation_context::use_current()); } /* This is here to handle when we rotate or go into the snapview mode */ void mupdf_cpp::MainPage::GridSizeChanged() { - int height = this->ActualHeight; - int width = this->ActualWidth; - FlipView^ old_flip = m_curr_flipView; - - if (TopAppBar1->IsOpen) - { - UpdateAppBarButtonViewState(); - } - - if (height > width) - { - m_curr_flipView = this->xaml_vert_flipView; - if (!m_zoom_mode) - { - this->xaml_zoomCanvas->Height = height; - this->xaml_zoomCanvas->Width = width; - this->m_curr_flipView->Height = height; - this->m_curr_flipView->Width = width; - } - xaml_vert_flipView->IsEnabled = true; - xaml_vert_flipView->Opacity = 1; - xaml_horiz_flipView->IsEnabled = false; - xaml_horiz_flipView->Opacity = 0; } - else - { - m_curr_flipView = this->xaml_horiz_flipView; - if (!m_zoom_mode) - { - this->xaml_zoomCanvas->Height = height; - this->xaml_zoomCanvas->Width = width; - this->m_curr_flipView->Height = height; - this->m_curr_flipView->Width = width; - } - xaml_horiz_flipView->IsEnabled = true; - xaml_horiz_flipView->Opacity = 1; - xaml_vert_flipView->IsEnabled = false; - xaml_vert_flipView->Opacity = 0; - } - - if (xaml_WebView->Visibility == Windows::UI::Xaml::Visibility::Visible) - { - int height = xaml_OutsideGrid->ActualHeight; - int height_app = TopAppBar1->ActualHeight; + int height = this->ActualHeight; + int width = this->ActualWidth; + FlipView^ old_flip = m_curr_flipView; + + if (TopAppBar1->IsOpen) + { + UpdateAppBarButtonViewState(); + } + + if (height > width) + { + m_curr_flipView = this->xaml_vert_flipView; + if (!m_zoom_mode) + { + this->xaml_zoomCanvas->Height = height; + this->xaml_zoomCanvas->Width = width; + this->m_curr_flipView->Height = height; + this->m_curr_flipView->Width = width; + } + xaml_vert_flipView->IsEnabled = true; + xaml_vert_flipView->Opacity = 1; + xaml_horiz_flipView->IsEnabled = false; + xaml_horiz_flipView->Opacity = 0; } + else + { + m_curr_flipView = this->xaml_horiz_flipView; + if (!m_zoom_mode) + { + this->xaml_zoomCanvas->Height = height; + this->xaml_zoomCanvas->Width = width; + this->m_curr_flipView->Height = height; + this->m_curr_flipView->Width = width; + } + xaml_horiz_flipView->IsEnabled = true; + xaml_horiz_flipView->Opacity = 1; + xaml_vert_flipView->IsEnabled = false; + xaml_vert_flipView->Opacity = 0; + } + + if (xaml_WebView->Visibility == Windows::UI::Xaml::Visibility::Visible) + { + int height = xaml_OutsideGrid->ActualHeight; + int height_app = TopAppBar1->ActualHeight; - xaml_WebView->Height = height - height_app; - } - - UpDatePageSizes(); - - if (m_num_pages > 0 && old_flip != m_curr_flipView && old_flip != nullptr) - { - if ((this->m_curr_flipView->SelectedIndex == this->m_currpage) && this->m_links_on) - FlipView_SelectionChanged(nullptr, nullptr); - else - this->m_curr_flipView->SelectedIndex = this->m_currpage; - } + xaml_WebView->Height = height - height_app; + } + + UpDatePageSizes(); + + if (m_num_pages > 0 && old_flip != m_curr_flipView && old_flip != nullptr) + { + if ((this->m_curr_flipView->SelectedIndex == this->m_currpage) && this->m_links_on) + FlipView_SelectionChanged(nullptr, nullptr); + else + this->m_curr_flipView->SelectedIndex = this->m_currpage; + } } void mupdf_cpp::MainPage::UpDatePageSizes() { - /* Reset the thumb view scaling value */ - if (m_num_pages > 0) - { - int num_items = m_thumbnails->Size; - for (int i = 0; i < num_items; i++) - { - DocumentPage ^thumb_page = m_thumbnails->GetAt(i); - if (thumb_page != nullptr && thumb_page->Image != nullptr) - { - int curr_height = thumb_page->Height; - int curr_width = thumb_page->Width; - - double scale_x = (double) curr_height / (double) this->xaml_zoomCanvas->Height; - double scale_y = (double) curr_width / (double) this->xaml_zoomCanvas->Width; - - double min_scale = max(scale_x, scale_y); - thumb_page->Height = curr_height / min_scale; - thumb_page->Width = curr_width / min_scale; - } - } - } + /* Reset the thumb view scaling value */ + if (m_num_pages > 0) + { + int num_items = m_thumbnails->Size; + for (int i = 0; i < num_items; i++) + { + DocumentPage ^thumb_page = m_thumbnails->GetAt(i); + if (thumb_page != nullptr && thumb_page->Image != nullptr) + { + int curr_height = thumb_page->Height; + int curr_width = thumb_page->Width; + + double scale_x = (double) curr_height / (double) this->xaml_zoomCanvas->Height; + double scale_y = (double) curr_width / (double) this->xaml_zoomCanvas->Width; + + double min_scale = max(scale_x, scale_y); + thumb_page->Height = curr_height / min_scale; + thumb_page->Width = curr_width / min_scale; + } + } + } }; /* Link related code */ void mupdf_cpp::MainPage::Linker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { - m_links_on = !m_links_on; - - if (m_links_on) - AddLinkCanvas(); - else - { - /* Make sure surrounding render pages lose their links */ - for (int k = m_currpage - LOOK_AHEAD; k <= m_currpage + LOOK_AHEAD; k++) - { - if (k >= 0 && k < m_num_pages) - { - auto doc_page = this->m_docPages->GetAt(k); - if (doc_page->Content == FULL_RESOLUTION) - { - doc_page->LinkBox = nullptr; - } - } - } - } + m_links_on = !m_links_on; + + if (m_links_on) + AddLinkCanvas(); + else + { + /* Make sure surrounding render pages lose their links */ + for (int k = m_currpage - LOOK_AHEAD; k <= m_currpage + LOOK_AHEAD; k++) + { + if (k >= 0 && k < m_num_pages) + { + auto doc_page = this->m_docPages->GetAt(k); + if (doc_page->Content == FULL_RESOLUTION) + { + doc_page->LinkBox = nullptr; + } + } + } + } } /* Add in the link rects. If we have not already computed them then do that now */ void mupdf_cpp::MainPage::AddLinkCanvas() { - /* See if the link object for this page has already been computed */ - int link_page = m_linkset->GetAt(m_currpage); - auto doc_page = this->m_docPages->GetAt(m_currpage); - - if (!link_page) - { - m_linkset->SetAt(m_currpage, true); - int num_links = mu_doc->ComputeLinks(m_currpage); - if (num_links == 0) return; - - Point screenSize; - Point pageSize; - Point scale; - - screenSize.Y = this->ActualHeight; - screenSize.X = this->ActualWidth; - screenSize.X *= screenScale; - screenSize.Y *= screenScale; - pageSize = mu_doc->GetPageSize(m_currpage); - scale = fitPageToScreen(pageSize, screenSize); - - /* Create a new RectList collection */ - auto link_list = ref new Platform::Collections::Vector(); - - /* Now add the rects */ - for (int k = 0; k < num_links; k++) - { - auto curr_link = mu_doc->GetLink(k); - if (curr_link->Type != NOT_SET) - { - RectList^ rect_item = ref new RectList(); - rect_item->Color = m_linkcolor; - rect_item->Height = curr_link->LowerRight.Y - curr_link->UpperLeft.Y; - rect_item->Width = curr_link->LowerRight.X - curr_link->UpperLeft.X; - rect_item->X = curr_link->UpperLeft.X * scale.X; - rect_item->Y = curr_link->UpperLeft.Y * scale.Y; - rect_item->Width *= (scale.X * doc_page->Zoom); - rect_item->Height *= (scale.Y * doc_page->Zoom); - rect_item->Type = curr_link->Type; - rect_item->Urilink = curr_link->Uri; - rect_item->PageNum = curr_link->PageNum; - rect_item->Index = k.ToString(); - link_list->Append(rect_item); - } - } - /* Now set it in our list of links */ - m_page_link_list->SetAt(m_currpage, link_list); - } - /* Go ahead and set our doc item to this in the vertical and horizontal view */ - if (doc_page->LinkBox == nullptr) - { - if (doc_page->Content == FULL_RESOLUTION) // We should not be doing links for thumbnails - { - doc_page->LinkBox = m_page_link_list->GetAt(m_currpage); - } - } + /* See if the link object for this page has already been computed */ + int link_page = m_linkset->GetAt(m_currpage); + auto doc_page = this->m_docPages->GetAt(m_currpage); + + if (!link_page) + { + m_linkset->SetAt(m_currpage, true); + int num_links = mu_doc->ComputeLinks(m_currpage); + if (num_links == 0) return; + + Point screenSize; + Point pageSize; + Point scale; + + screenSize.Y = this->ActualHeight; + screenSize.X = this->ActualWidth; + screenSize.X *= screenScale; + screenSize.Y *= screenScale; + pageSize = mu_doc->GetPageSize(m_currpage); + scale = fitPageToScreen(pageSize, screenSize); + + /* Create a new RectList collection */ + auto link_list = ref new Platform::Collections::Vector(); + + /* Now add the rects */ + for (int k = 0; k < num_links; k++) + { + auto curr_link = mu_doc->GetLink(k); + if (curr_link->Type != NOT_SET) + { + RectList^ rect_item = ref new RectList(); + rect_item->Color = m_linkcolor; + rect_item->Height = curr_link->LowerRight.Y - curr_link->UpperLeft.Y; + rect_item->Width = curr_link->LowerRight.X - curr_link->UpperLeft.X; + rect_item->X = curr_link->UpperLeft.X * scale.X; + rect_item->Y = curr_link->UpperLeft.Y * scale.Y; + rect_item->Width *= (scale.X * doc_page->Zoom); + rect_item->Height *= (scale.Y * doc_page->Zoom); + rect_item->Type = curr_link->Type; + rect_item->Urilink = curr_link->Uri; + rect_item->PageNum = curr_link->PageNum; + rect_item->Index = k.ToString(); + link_list->Append(rect_item); + } + } + /* Now set it in our list of links */ + m_page_link_list->SetAt(m_currpage, link_list); + } + /* Go ahead and set our doc item to this in the vertical and horizontal view */ + if (doc_page->LinkBox == nullptr) + { + if (doc_page->Content == FULL_RESOLUTION) // We should not be doing links for thumbnails + { + doc_page->LinkBox = m_page_link_list->GetAt(m_currpage); + } + } } /* A link was tapped */ void mupdf_cpp::MainPage::LinkTapped(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e) { - Rectangle^ rect = safe_cast(e->OriginalSource); - String^ str_index = safe_cast(rect->Tag); - int index = _wtof(str_index->Data()); - - if (index >= 0 && index < m_num_pages) - { - auto link_list = m_page_link_list->GetAt(m_currpage); - auto link = link_list->GetAt(index); - - if (link->Type == LINK_GOTO) - { - this->m_curr_flipView->SelectedIndex = link->PageNum; - } - else if (link->Type == LINK_URI) - { - // Set the option to show a warning - auto launchOptions = ref new Windows::System::LauncherOptions(); - launchOptions->TreatAsUntrusted = true; - - // Launch the URI with a warning prompt - concurrency::task launchUriOperation(Windows::System::Launcher::LaunchUriAsync(link->Urilink, launchOptions)); - launchUriOperation.then([](bool success) - { - if (success) - { - // URI launched - } - else - { - // URI launch failed - } - }); - } - } + Rectangle^ rect = safe_cast(e->OriginalSource); + String^ str_index = safe_cast(rect->Tag); + int index = _wtof(str_index->Data()); + + if (index >= 0 && index < m_num_pages) + { + auto link_list = m_page_link_list->GetAt(m_currpage); + auto link = link_list->GetAt(index); + + if (link->Type == LINK_GOTO) + { + this->m_curr_flipView->SelectedIndex = link->PageNum; + } + else if (link->Type == LINK_URI) + { + // Set the option to show a warning + auto launchOptions = ref new Windows::System::LauncherOptions(); + launchOptions->TreatAsUntrusted = true; + + // Launch the URI with a warning prompt + concurrency::task launchUriOperation(Windows::System::Launcher::LaunchUriAsync(link->Urilink, launchOptions)); + launchUriOperation.then([](bool success) + { + if (success) + { + // URI launched + } + else + { + // URI launch failed + } + }); + } + } } /* Bring up the contents */ void mupdf_cpp::MainPage::ContentDisplay(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { - if (this->m_num_pages < 0) - return; - - if (this->xaml_ListView->IsEnabled) - { - this->xaml_ListView->Opacity = 0.0; - this->xaml_ListView->IsEnabled = false; - this->m_curr_flipView->Opacity = 1.0; - this->m_curr_flipView->IsEnabled = true; - } - else - { - if (xaml_ListView->Items->Size == 0) - { - int size_content = mu_doc->ComputeContents(); - /* Bring up the content now */ - for (int k = 0; k < size_content; k++) - { - ContentItem^ item = mu_doc->GetContent(k); - this->xaml_ListView->Items->Append(item); - } - if (size_content > 0) - { - this->xaml_ListView->Opacity = 1.0; - this->xaml_ListView->IsEnabled = true; - this->m_curr_flipView->Opacity = 0.0; - this->m_curr_flipView->IsEnabled = false; - } - } - else - { - this->xaml_ListView->Opacity = 1.0; - this->xaml_ListView->IsEnabled = true; - this->m_curr_flipView->Opacity = 0.0; - this->m_curr_flipView->IsEnabled = false; - } - } + if (this->m_num_pages < 0) + return; + + if (this->xaml_ListView->IsEnabled) + { + this->xaml_ListView->Opacity = 0.0; + this->xaml_ListView->IsEnabled = false; + this->m_curr_flipView->Opacity = 1.0; + this->m_curr_flipView->IsEnabled = true; + } + else + { + if (xaml_ListView->Items->Size == 0) + { + int size_content = mu_doc->ComputeContents(); + /* Bring up the content now */ + for (int k = 0; k < size_content; k++) + { + ContentItem^ item = mu_doc->GetContent(k); + this->xaml_ListView->Items->Append(item); + } + if (size_content > 0) + { + this->xaml_ListView->Opacity = 1.0; + this->xaml_ListView->IsEnabled = true; + this->m_curr_flipView->Opacity = 0.0; + this->m_curr_flipView->IsEnabled = false; + } + } + else + { + this->xaml_ListView->Opacity = 1.0; + this->xaml_ListView->IsEnabled = true; + this->m_curr_flipView->Opacity = 0.0; + this->m_curr_flipView->IsEnabled = false; + } + } } void mupdf_cpp::MainPage::ContentSelected(Platform::Object^ sender, Windows::UI::Xaml::Controls::ItemClickEventArgs^ e) { - ContentItem^ b = safe_cast(e->ClickedItem); - int newpage = b->Page; - - if (newpage > -1 && newpage < this->m_num_pages) - { - this->xaml_ListView->Opacity = 0.0; - this->xaml_ListView->IsEnabled = false; - this->m_curr_flipView->Opacity = 1.0; - this->m_curr_flipView->IsEnabled = true; - - int old_page = this->m_currpage; - this->m_curr_flipView->SelectedIndex = newpage; - this->m_currpage = newpage; - } + ContentItem^ b = safe_cast(e->ClickedItem); + int newpage = b->Page; + + if (newpage > -1 && newpage < this->m_num_pages) + { + this->xaml_ListView->Opacity = 0.0; + this->xaml_ListView->IsEnabled = false; + this->m_curr_flipView->Opacity = 1.0; + this->m_curr_flipView->IsEnabled = true; + + int old_page = this->m_currpage; + this->m_curr_flipView->SelectedIndex = newpage; + this->m_currpage = newpage; + } } void mupdf_cpp::MainPage::Reflower(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { - if (this->m_num_pages < 0) return; - - if (xaml_WebView->Visibility == Windows::UI::Xaml::Visibility::Visible) - { - /* Go back to flip view */ - xaml_WebView->Visibility = Windows::UI::Xaml::Visibility::Collapsed; - this->xaml_MainGrid->Opacity = 1.0; - this->m_curr_flipView->IsEnabled = true; - xaml_WebView->Visibility = Windows::UI::Xaml::Visibility::Collapsed; - xaml_WebView->Opacity = 0.0; - - } - else if (this->m_curr_flipView->IsEnabled) - { - String^ html_string = mu_doc->ComputeHTML(this->m_currpage); - xaml_WebView->Visibility = Windows::UI::Xaml::Visibility::Visible; - this->xaml_MainGrid->Opacity = 0.0; - this->m_curr_flipView->IsEnabled = false; - this->xaml_WebView->NavigateToString(html_string); - this->xaml_WebView->Height = this->ActualHeight - 2 * this->BottomAppBar->ActualHeight; - /* Check if thumb rendering is done. If not then restart */ - } + if (this->m_num_pages < 0) return; + + if (xaml_WebView->Visibility == Windows::UI::Xaml::Visibility::Visible) + { + /* Go back to flip view */ + xaml_WebView->Visibility = Windows::UI::Xaml::Visibility::Collapsed; + this->xaml_MainGrid->Opacity = 1.0; + this->m_curr_flipView->IsEnabled = true; + xaml_WebView->Visibility = Windows::UI::Xaml::Visibility::Collapsed; + xaml_WebView->Opacity = 0.0; + + } + else if (this->m_curr_flipView->IsEnabled) + { + String^ html_string = mu_doc->ComputeHTML(this->m_currpage); + xaml_WebView->Visibility = Windows::UI::Xaml::Visibility::Visible; + this->xaml_MainGrid->Opacity = 0.0; + this->m_curr_flipView->IsEnabled = false; + this->xaml_WebView->NavigateToString(html_string); + this->xaml_WebView->Height = this->ActualHeight - 2 * this->BottomAppBar->ActualHeight; + /* Check if thumb rendering is done. If not then restart */ + } } /* 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) { - UpdateAppBarButtonViewState(); + UpdateAppBarButtonViewState(); } void mupdf_cpp::MainPage::UpdateAppBarButtonViewState() { - String ^viewState = Windows::UI::ViewManagement::ApplicationView::Value.ToString(); - VisualStateManager::GoToState(Search, viewState, true); - VisualStateManager::GoToState(Contents, viewState, true); - VisualStateManager::GoToState(Links, viewState, true); - VisualStateManager::GoToState(Reflow, viewState, true); - VisualStateManager::GoToState(Help, viewState, true); + String ^viewState = Windows::UI::ViewManagement::ApplicationView::Value.ToString(); + VisualStateManager::GoToState(Search, viewState, true); + VisualStateManager::GoToState(Contents, viewState, true); + VisualStateManager::GoToState(Links, viewState, true); + VisualStateManager::GoToState(Reflow, viewState, true); + VisualStateManager::GoToState(Help, viewState, true); } void mupdf_cpp::MainPage::ScrollChanged(Platform::Object^ sender, - Windows::UI::Xaml::Controls::ScrollViewerViewChangedEventArgs^ e) + Windows::UI::Xaml::Controls::ScrollViewerViewChangedEventArgs^ e) { - ScrollViewer^ scrollviewer = safe_cast (sender); - auto doc_page = this->m_docPages->GetAt(m_currpage); - - if (scrollviewer->ZoomFactor == doc_page->Zoom) - return; - - if (!e->IsIntermediate) - { - doc_page->Zoom = scrollviewer->ZoomFactor; - int page = m_currpage; - /* Render at new resolution */ - spatial_info_t spatial_info = InitSpatial(doc_page->Zoom); - Point ras_size = ComputePageSize(spatial_info, page); - - auto render_task = - create_task(mu_doc->RenderPage(page, ras_size.X, ras_size.Y)); - - render_task.then([this, page, ras_size] (InMemoryRandomAccessStream^ ras) - { - ReplaceImage(page, ras, ras_size); - }, task_continuation_context::use_current()); - } + ScrollViewer^ scrollviewer = safe_cast (sender); + auto doc_page = this->m_docPages->GetAt(m_currpage); + + if (scrollviewer->ZoomFactor == doc_page->Zoom) + return; + + if (!e->IsIntermediate) + { + doc_page->Zoom = scrollviewer->ZoomFactor; + int page = m_currpage; + /* Render at new resolution */ + spatial_info_t spatial_info = InitSpatial(doc_page->Zoom); + Point ras_size = ComputePageSize(spatial_info, page); + + auto render_task = + create_task(mu_doc->RenderPage(page, ras_size.X, ras_size.Y)); + + render_task.then([this, page, ras_size] (InMemoryRandomAccessStream^ ras) + { + ReplaceImage(page, ras, ras_size); + }, task_continuation_context::use_current()); + } } diff --git a/winrt/mupdf_cpp/MainPage.xaml.h b/winrt/mupdf_cpp/MainPage.xaml.h index e3f9a782..869297f4 100644 --- a/winrt/mupdf_cpp/MainPage.xaml.h +++ b/winrt/mupdf_cpp/MainPage.xaml.h @@ -33,27 +33,27 @@ using namespace mupdfwinrt; typedef enum { - StatusMessage, - ErrorMessage + StatusMessage, + ErrorMessage } NotifyType_t; typedef enum { - REN_AVAILABLE = 0, - REN_THUMBS, - REN_UPDATE_THUMB_CANVAS, - REN_PAGE /* Used to ignore value when source based setting */ + REN_AVAILABLE = 0, + REN_THUMBS, + REN_UPDATE_THUMB_CANVAS, + REN_PAGE /* Used to ignore value when source based setting */ } RenderingStatus_t; typedef struct SearchResult_s { - int box_count; - int page_num; + int box_count; + int page_num; } SearchResult_t; typedef struct spatial_info_s { - Point size; - double scale_factor; + Point size; + double scale_factor; } spatial_info_t; namespace mupdf_cpp @@ -69,87 +69,87 @@ namespace mupdf_cpp protected: virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override; - /* added */ - private: - Vector^ m_docPages; - Vector^ m_thumbnails; - Vector^>^ m_page_link_list; - Vector^ m_linkset; - Vector^ m_text_list; - int m_rectlist_page; - mudocument^ mu_doc; - bool m_file_open; - int m_currpage; - int m_searchpage; - int m_num_pages; - int m_slider_min; - int m_slider_max; - bool m_init_done; - bool m_flip_from_searchlink; - bool m_links_on; - int m_search_rect_count; - cancellation_token_source m_searchcts; - bool m_page_update; - long long m_memory_use; - WriteableBitmap ^m_BlankBmp; - String^ m_textcolor; - String^ m_linkcolor; - FlipView^ m_curr_flipView; - RenderingStatus_t m_ren_status; - cancellation_token_source m_ThumbCancel; - bool m_zoom_mode; // remove - bool m_insearch; /* Used for UI display */ - bool m_search_active; /* Used to avoid multiple UI clicks */ - bool m_sliderchange; - bool m_update_flip; + /* added */ + private: + Vector^ m_docPages; + Vector^ m_thumbnails; + Vector^>^ m_page_link_list; + Vector^ m_linkset; + Vector^ m_text_list; + int m_rectlist_page; + mudocument^ mu_doc; + bool m_file_open; + int m_currpage; + int m_searchpage; + int m_num_pages; + int m_slider_min; + int m_slider_max; + bool m_init_done; + bool m_flip_from_searchlink; + bool m_links_on; + int m_search_rect_count; + cancellation_token_source m_searchcts; + bool m_page_update; + long long m_memory_use; + WriteableBitmap ^m_BlankBmp; + String^ m_textcolor; + String^ m_linkcolor; + FlipView^ m_curr_flipView; + RenderingStatus_t m_ren_status; + cancellation_token_source m_ThumbCancel; + bool m_zoom_mode; // remove + bool m_insearch; /* Used for UI display */ + bool m_search_active; /* Used to avoid multiple UI clicks */ + bool m_sliderchange; + bool m_update_flip; - void ReplaceImage(int page_num, InMemoryRandomAccessStream^ ras, Point ras_size); + void ReplaceImage(int page_num, InMemoryRandomAccessStream^ ras, Point ras_size); void Picker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - void Searcher(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - void OpenDocumentPrep(StorageFile^ file); - void OpenDocument(StorageFile^ file); - void RenderRange(int curr_page); - void CleanUp(); - void UpdatePage(int page_num, InMemoryRandomAccessStream^ ras, Point ras_size, Page_Content_t content_type); - void CreateBlank(int width, int height); - void HandleFileNotFoundException(Platform::COMException^ e); - void NotifyUserFileNotExist(); - void SetFlipView(); - void Slider_ValueChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e); - void Slider_Released(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e); - void FlipView_SelectionChanged(Object^ sender, SelectionChangedEventArgs^ e); - void SearchNext(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - void SearchPrev(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - void CancelSearch(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - void SearchInDirection(int dir, String^ textToFind); - void ShowSearchResults(SearchResult_t result); - void ClearTextSearch(); - void AddTextCanvas(); - void GridSizeChanged(); - void UpDatePageSizes(); - void ShowThumbnail(); - void Canvas_ManipulationCompleted(Platform::Object^ sender, Windows::UI::Xaml::Input::ManipulationCompletedRoutedEventArgs^ e); - void AddThumbNail(int page_num, FlipView^ flip_view); - spatial_info_t InitSpatial(double scale); - void RenderThumbs(); - void SetThumb(int page_num, bool replace); - void ReleasePages(int old_page, int new_page); - void Linker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - void AddLinkCanvas(); - void ContentDisplay(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - void FlattenOutline(fz_outline *outline, int level); - void ListView_Single_Tap(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e); - void ContentSelected(Platform::Object^ sender, Windows::UI::Xaml::Controls::ItemClickEventArgs^ e); - void ContentChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e); - void Reflower(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - 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); - void ScrollChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::ScrollViewerViewChangedEventArgs^ e); - void LinkTapped(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e); - }; + void Searcher(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); + void OpenDocumentPrep(StorageFile^ file); + void OpenDocument(StorageFile^ file); + void RenderRange(int curr_page); + void CleanUp(); + void UpdatePage(int page_num, InMemoryRandomAccessStream^ ras, Point ras_size, Page_Content_t content_type); + void CreateBlank(int width, int height); + void HandleFileNotFoundException(Platform::COMException^ e); + void NotifyUserFileNotExist(); + void SetFlipView(); + void Slider_ValueChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e); + void Slider_Released(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e); + void FlipView_SelectionChanged(Object^ sender, SelectionChangedEventArgs^ e); + void SearchNext(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); + void SearchPrev(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); + void CancelSearch(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); + void SearchInDirection(int dir, String^ textToFind); + void ShowSearchResults(SearchResult_t result); + void ClearTextSearch(); + void AddTextCanvas(); + void GridSizeChanged(); + void UpDatePageSizes(); + void ShowThumbnail(); + void Canvas_ManipulationCompleted(Platform::Object^ sender, Windows::UI::Xaml::Input::ManipulationCompletedRoutedEventArgs^ e); + void AddThumbNail(int page_num, FlipView^ flip_view); + spatial_info_t InitSpatial(double scale); + void RenderThumbs(); + void SetThumb(int page_num, bool replace); + void ReleasePages(int old_page, int new_page); + void Linker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); + void AddLinkCanvas(); + void ContentDisplay(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); + void FlattenOutline(fz_outline *outline, int level); + void ListView_Single_Tap(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e); + void ContentSelected(Platform::Object^ sender, Windows::UI::Xaml::Controls::ItemClickEventArgs^ e); + void ContentChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e); + void Reflower(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); + 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); + void ScrollChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::ScrollViewerViewChangedEventArgs^ e); + void LinkTapped(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e); + }; } diff --git a/winrt/mupdf_cpp/RectList.cpp b/winrt/mupdf_cpp/RectList.cpp index 0095af3b..b9c1560d 100644 --- a/winrt/mupdf_cpp/RectList.cpp +++ b/winrt/mupdf_cpp/RectList.cpp @@ -3,14 +3,7 @@ namespace mupdf_cpp { - RectList::RectList(void) - { - - - - - } - + RectList::RectList(void) + { + } } - - diff --git a/winrt/mupdf_cpp/RectList.h b/winrt/mupdf_cpp/RectList.h index d3f0527f..5d802327 100644 --- a/winrt/mupdf_cpp/RectList.h +++ b/winrt/mupdf_cpp/RectList.h @@ -7,111 +7,147 @@ using namespace Platform; /* For String */ namespace mupdf_cpp { - [Windows::UI::Xaml::Data::Bindable] // in c++, adding this attribute to ref classes enables data binding for more info search for 'Bindable' on the page http://go.microsoft.com/fwlink/?LinkId=254639 - - public ref class RectList sealed - { - private: - int height; - int width; - int x; - int y; - String^ color; - /* These are used to store the link infomation */ - int type; - int pagenum; - Windows::Foundation::Uri ^uri; - String^ index; // For identify which rectangle was tapped - public: - RectList(void); - - property String^ Index - { - String^ get() { return ((String^) index); } - void set(String^ value) - { - index = value; - } - } - - property String^ Color - { - String^ get() { return (color); } - void set(String^ value) - { - color = value; - } - } - - property int Height - { - int get() { return ((int) height); } - void set(int value) - { - if (value < 0) - { - throw ref new Platform::InvalidArgumentException(); - } - height = value; - } - } - - property int Width - { - int get() { return width; } - void set(int value) - { - if (value < 0) - { - throw ref new Platform::InvalidArgumentException(); - } - width = value; - } - } - - property int X - { - int get() { return x; } - void set(int value) - { - x = value; - } - } - - property int Y - { - int get() { return y; } - void set(int value) - { - y = value; - } - } - - property int Type - { - int get() { return type; } - void set(int value) - { - type = value; - } - } - - property int PageNum - { - int get() { return pagenum; } - void set(int value) - { - pagenum = value; - } - } - - property Windows::Foundation::Uri^ Urilink - { - Windows::Foundation::Uri^ get() { return uri; } - void set(Windows::Foundation::Uri^ value) - { - uri = value; - } - } - }; + [Windows::UI::Xaml::Data::Bindable] // in c++, adding this attribute to ref classes enables data binding for more info search for 'Bindable' on the page http://go.microsoft.com/fwlink/?LinkId=254639 + + public ref class RectList sealed + { + private: + int height; + int width; + int x; + int y; + String^ color; + /* These are used to store the link infomation */ + int type; + int pagenum; + Windows::Foundation::Uri ^uri; + String^ index; // For identify which rectangle was tapped + public: + RectList(void); + + property String^ Index + { + String^ get() + { + return ((String^) index); + } + + void set(String^ value) + { + index = value; + } + } + + property String^ Color + { + String^ get() + { + return (color); + } + + void set(String^ value) + { + color = value; + } + } + + property int Height + { + int get() + { + return ((int) height); + } + + void set(int value) + { + if (value < 0) + { + throw ref new Platform::InvalidArgumentException(); + } + height = value; + } + } + + property int Width + { + int get() + { + return width; + } + + void set(int value) + { + if (value < 0) + { + throw ref new Platform::InvalidArgumentException(); + } + width = value; + } + } + + property int X + { + int get() + { + return x; + } + + void set(int value) + { + x = value; + } + } + + property int Y + { + int get() + { + return y; + } + + void set(int value) + { + y = value; + } + } + + property int Type + { + int get() + { + return type; + } + + void set(int value) + { + type = value; + } + } + + property int PageNum + { + int get() + { + return pagenum; + } + + void set(int value) + { + pagenum = value; + } + } + + property Windows::Foundation::Uri^ Urilink + { + Windows::Foundation::Uri^ get() + { + return uri; + } + + void set(Windows::Foundation::Uri^ value) + { + uri = value; + } + } + }; } diff --git a/winrt/mupdfwinrt/ContentItem.cpp b/winrt/mupdfwinrt/ContentItem.cpp index 7bb264db..eff1f58b 100644 --- a/winrt/mupdfwinrt/ContentItem.cpp +++ b/winrt/mupdfwinrt/ContentItem.cpp @@ -5,7 +5,7 @@ using namespace mupdfwinrt; ContentItem::ContentItem(void) { - StringOrig = nullptr; - StringMargin = nullptr; - Page = 0; + StringOrig = nullptr; + StringMargin = nullptr; + Page = 0; } diff --git a/winrt/mupdfwinrt/ContentItem.h b/winrt/mupdfwinrt/ContentItem.h index 69dd89fe..ec2e2121 100644 --- a/winrt/mupdfwinrt/ContentItem.h +++ b/winrt/mupdfwinrt/ContentItem.h @@ -3,57 +3,56 @@ using namespace Platform; /* For String */ namespace mupdfwinrt { - [Windows::UI::Xaml::Data::Bindable] - public ref class ContentItem sealed - { - private: - int page; - String^ string_orig; - String^ string_margin; - - public: - ContentItem(void); - - property int Page - { - int get() { return (page); } - void set(int value) - { - if (value < 0) - { - throw ref new Platform::InvalidArgumentException(); - } - page = value; - } - } - - property String^ StringOrig - { - String^ get() { return (string_orig); } - void set(String^ value) - { - string_orig = value; - } - } - - property String^ StringMargin - { - String^ get() { return (string_margin); } - void set(String^ value) - { - string_margin = value; - } - } - - - - - - - }; + [Windows::UI::Xaml::Data::Bindable] + public ref class ContentItem sealed + { + private: + int page; + String^ string_orig; + String^ string_margin; + + public: + ContentItem(void); + + property int Page + { + int get() + { + return (page); + } + + void set(int value) + { + if (value < 0) + throw ref new Platform::InvalidArgumentException(); + page = value; + } + } + + property String^ StringOrig + { + String^ get() + { + return (string_orig); + } + + void set(String^ value) + { + string_orig = value; + } + } + + property String^ StringMargin + { + String^ get() + { + return (string_margin); + } + + void set(String^ value) + { + string_margin = value; + } + } + }; } - - - - - diff --git a/winrt/mupdfwinrt/Links.cpp b/winrt/mupdfwinrt/Links.cpp index eb8dfac7..6169e77c 100644 --- a/winrt/mupdfwinrt/Links.cpp +++ b/winrt/mupdfwinrt/Links.cpp @@ -5,7 +5,7 @@ using namespace mupdfwinrt; Links::Links(void) { - this->uri = nullptr; - this->page_num = -1; - this->type = NOT_SET; + this->uri = nullptr; + this->page_num = -1; + this->type = NOT_SET; } diff --git a/winrt/mupdfwinrt/Links.h b/winrt/mupdfwinrt/Links.h index 64072e35..00a08f73 100644 --- a/winrt/mupdfwinrt/Links.h +++ b/winrt/mupdfwinrt/Links.h @@ -6,67 +6,82 @@ using namespace Windows::Foundation; namespace mupdfwinrt { - public ref class Links sealed - { - private: - int type; - Point upper_left; - Point lower_right; - Windows::Foundation::Uri ^uri; - int page_num; - public: - Links(void); + public ref class Links sealed + { + private: + int type; + Point upper_left; + Point lower_right; + Windows::Foundation::Uri ^uri; + int page_num; + public: + Links(void); - property int Type - { - int get() { return (type); } - void set(int value) - { - if (value > NOT_SET) - { - throw ref new Platform::InvalidArgumentException(); - } - type = value; - } - } + property int Type + { + int get() + { + return (type); + } - property Point UpperLeft - { - Point get() { return upper_left; } - void set(Point value) - { - upper_left = value; - } - } + void set(int value) + { + if (value > NOT_SET) + throw ref new Platform::InvalidArgumentException(); + type = value; + } + } - property Point LowerRight - { - Point get() { return lower_right; } - void set(Point value) - { - lower_right = value; - } - } + property Point UpperLeft + { + Point get() + { + return upper_left; + } - property int PageNum - { - int get() { return page_num; } - void set(int value) - { - page_num = value; - } - } + void set(Point value) + { + upper_left = value; + } + } - property Windows::Foundation::Uri^ Uri - { - Windows::Foundation::Uri^ get() { return uri; } - void set(Windows::Foundation::Uri^ value) - { - uri = value; - } - } - }; -} + property Point LowerRight + { + Point get() + { + return lower_right; + } + + void set(Point value) + { + lower_right = value; + } + } + property int PageNum + { + int get() + { + return page_num; + } + void set(int value) + { + page_num = value; + } + } + property Windows::Foundation::Uri^ Uri + { + Windows::Foundation::Uri^ get() + { + return uri; + } + + void set(Windows::Foundation::Uri^ value) + { + uri = value; + } + } + }; +} diff --git a/winrt/mupdfwinrt/muctx.cpp b/winrt/mupdfwinrt/muctx.cpp index 091846e7..5b9d2464 100644 --- a/winrt/mupdfwinrt/muctx.cpp +++ b/winrt/mupdfwinrt/muctx.cpp @@ -4,77 +4,78 @@ #include "muctx.h" #include "Links.h" -/* This class interfaces to mupdf API with minimal windows objects (other than - the file streaming stuff) */ +/* This class interfaces to mupdf API with minimal windows objects + * (other than the file streaming stuff) */ /* File streaming set up for mupdf */ -/* win_read_file etc. Reading of windows managed stream. This is not ideal as I have - to read into a managed buffer and then transfer to the actual buffer I want. I - would like a more direct approach. Alternate approach is to push this off - outside the winrt and read from a memory buffer. */ +/* win_read_file etc. Reading of windows managed stream. This is + * not ideal as I have to read into a managed buffer and then transfer + * to the actual buffer I want. I would like a more direct approach. + * Alternate approach is to push this off outside the winrt and read + * from a memory buffer. */ static int win_read_file(fz_stream *stm, unsigned char *buf, int len) { - void *temp = stm->state; - win_stream_struct *stream = reinterpret_cast (temp); - IRandomAccessStream^ Stream = stream->stream; - unsigned long long curr_pos = Stream->Position; - unsigned long long length = Stream->Size; - DataReader^ local_reader = ref new DataReader(Stream); - DataReaderLoadOperation^ result = local_reader->LoadAsync(len); + void *temp = stm->state; + win_stream_struct *stream = reinterpret_cast (temp); + IRandomAccessStream^ Stream = stream->stream; + unsigned long long curr_pos = Stream->Position; + unsigned long long length = Stream->Size; + DataReader^ local_reader = ref new DataReader(Stream); + DataReaderLoadOperation^ result = local_reader->LoadAsync(len); - /* Block on the Async call */ - while(result->Status != AsyncStatus::Completed) { + /* Block on the Async call */ + while(result->Status != AsyncStatus::Completed) { - } + } - result->GetResults(); - int curr_len2 = local_reader->UnconsumedBufferLength; - if (curr_len2 < len) - len = curr_len2; + result->GetResults(); + int curr_len2 = local_reader->UnconsumedBufferLength; + if (curr_len2 < len) + len = curr_len2; - Platform::Array^ arrByte = ref new Platform::Array(len); - local_reader->ReadBytes(arrByte); + Platform::Array^ arrByte = ref new Platform::Array(len); + local_reader->ReadBytes(arrByte); - memcpy(buf, arrByte->Data, len); - local_reader->DetachStream(); + memcpy(buf, arrByte->Data, len); + local_reader->DetachStream(); return len; } static void win_seek_file(fz_stream *stm, int offset, int whence) { - void *temp = stm->state; - win_stream_struct *stream = reinterpret_cast (temp); - IRandomAccessStream^ Stream = stream->stream; - unsigned long long curr_pos = Stream->Position; - unsigned long long length = Stream->Size; - unsigned long long n; - - if (whence == SEEK_END) - { - n = length + offset; - } - else if (whence == SEEK_CUR) - { - n = curr_pos + offset; - } - else if (whence == SEEK_SET) - { - n = offset; - } - Stream->Seek(n); - curr_pos = Stream->Position; - stm->pos = n; + void *temp = stm->state; + win_stream_struct *stream = reinterpret_cast (temp); + IRandomAccessStream^ Stream = stream->stream; + unsigned long long curr_pos = Stream->Position; + unsigned long long length = Stream->Size; + unsigned long long n; + + if (whence == SEEK_END) + { + n = length + offset; + } + else if (whence == SEEK_CUR) + { + n = curr_pos + offset; + } + else if (whence == SEEK_SET) + { + n = offset; + } + Stream->Seek(n); + curr_pos = Stream->Position; + stm->pos = n; stm->rp = stm->bp; stm->wp = stm->bp; } static void win_close_file(fz_context *ctx, void *state) { - DataReader^ dataReader = reinterpret_cast (state); + DataReader^ dataReader = reinterpret_cast (state); - delete dataReader; + delete dataReader; } /* mutext functions see mupdf readme for details */ @@ -90,113 +91,113 @@ static void unlock_mutex(void *user, int lock) void muctx::CleanUp(void) { - free(this->mu_cookie); - if (mu_outline != NULL) + free(this->mu_cookie); + if (mu_outline != NULL) fz_free_outline(mu_ctx, mu_outline); - if (mu_doc != NULL) + if (mu_doc != NULL) fz_close_document(mu_doc); - if (mu_ctx != NULL) + if (mu_ctx != NULL) fz_free_context(mu_ctx); - this->mu_cookie = NULL; - this->mu_ctx = NULL; - this->mu_doc = NULL; - this->mu_outline = NULL; - this->mu_stream = NULL; + this->mu_cookie = NULL; + this->mu_ctx = NULL; + this->mu_doc = NULL; + this->mu_outline = NULL; + this->mu_stream = NULL; } /* Set up the context, mutex and cookie */ HRESULT muctx::InitializeContext() { - /* Get the mutex set up */ + /* Get the mutex set up */ InitializeCriticalSectionEx(&mu_criticalsec, 0, 0); mu_locks.user = &mu_criticalsec; mu_locks.lock = lock_mutex; mu_locks.unlock = unlock_mutex; - /* Allocate the context */ - this->mu_ctx = fz_new_context(NULL, &mu_locks, FZ_STORE_DEFAULT); + /* Allocate the context */ + this->mu_ctx = fz_new_context(NULL, &mu_locks, FZ_STORE_DEFAULT); if (this->mu_ctx == NULL) { return E_OUTOFMEMORY; } else { - /* If we are fine, allocate the cookie for progress etc. */ + /* If we are fine, allocate the cookie for progress etc. */ this->mu_cookie = (fz_cookie*)malloc(sizeof(fz_cookie)); - if (this->mu_cookie == NULL) { - fz_free_context(this->mu_ctx); - return E_OUTOFMEMORY; - } - else - return S_OK; + if (this->mu_cookie == NULL) { + fz_free_context(this->mu_ctx); + return E_OUTOFMEMORY; + } + else + return S_OK; } } /* Initializer */ muctx::muctx(void) { - this->mu_cookie = NULL; - this->mu_ctx = NULL; - this->mu_doc = NULL; - this->mu_outline = NULL; - this->mu_stream = NULL; + this->mu_cookie = NULL; + this->mu_ctx = NULL; + this->mu_doc = NULL; + this->mu_outline = NULL; + this->mu_stream = NULL; } /* Destructor */ muctx::~muctx(void) { - free(this->mu_cookie); - if (mu_outline != NULL) + free(this->mu_cookie); + if (mu_outline != NULL) fz_free_outline(mu_ctx, mu_outline); - if (mu_doc != NULL) + if (mu_doc != NULL) fz_close_document(mu_doc); - if (mu_ctx != NULL) + if (mu_ctx != NULL) fz_free_context(mu_ctx); - this->mu_cookie = NULL; - this->mu_ctx = NULL; - this->mu_doc = NULL; - this->mu_outline = NULL; - this->mu_stream = NULL; + this->mu_cookie = NULL; + this->mu_ctx = NULL; + this->mu_doc = NULL; + this->mu_outline = NULL; + this->mu_stream = NULL; } /* Set up the stream access */ HRESULT muctx::InitializeStream(IRandomAccessStream^ readStream, char *ext) { - win_stream.stream = readStream; - this->mu_stream = fz_new_stream(mu_ctx, 0, win_read_file, win_close_file); - this->mu_stream->seek = win_seek_file; - this->mu_stream->state = reinterpret_cast (&win_stream); - - /* Now lets see if we can open the file */ - mu_doc = fz_open_document_with_stream(mu_ctx, ext, this->mu_stream); - - if (mu_doc == NULL) - return E_FAIL; - else - return S_OK; + win_stream.stream = readStream; + this->mu_stream = fz_new_stream(mu_ctx, 0, win_read_file, win_close_file); + this->mu_stream->seek = win_seek_file; + this->mu_stream->state = reinterpret_cast (&win_stream); + + /* Now lets see if we can open the file */ + mu_doc = fz_open_document_with_stream(mu_ctx, ext, this->mu_stream); + + if (mu_doc == NULL) + return E_FAIL; + else + return S_OK; } /* Return the documents page count */ int muctx::GetPageCount() { - if (this->mu_doc == NULL) - return -1; - else - return this->mu_doc->count_pages(this->mu_doc); + if (this->mu_doc == NULL) + return -1; + else + return this->mu_doc->count_pages(this->mu_doc); } /* Get page size */ Point muctx::MeasurePage(int page_num) { Point pageSize; - fz_rect rect; - fz_page *page; - fz_rect *bounds; + fz_rect rect; + fz_page *page; + fz_rect *bounds; - page = fz_load_page(mu_doc, page_num); - bounds = fz_bound_page(mu_doc, page, &rect); + page = fz_load_page(mu_doc, page_num); + bounds = fz_bound_page(mu_doc, page, &rect); pageSize.X = bounds->x1 - bounds->x0; pageSize.Y = bounds->y1 - bounds->y0; @@ -207,10 +208,10 @@ Point muctx::MeasurePage(int page_num) Point muctx::MeasurePage(fz_page *page) { Point pageSize; - fz_rect rect; - fz_rect *bounds; + fz_rect rect; + fz_rect *bounds; - bounds = fz_bound_page(mu_doc, page, &rect); + bounds = fz_bound_page(mu_doc, page, &rect); pageSize.X = bounds->x1 - bounds->x0; pageSize.Y = bounds->y1 - bounds->y0; @@ -218,7 +219,7 @@ Point muctx::MeasurePage(fz_page *page) } void muctx::FlattenOutline(fz_outline *outline, int level, - sh_vector_content contents_vec) + sh_vector_content contents_vec) { char indent[8*4+1]; if (level > 8) @@ -226,8 +227,8 @@ void muctx::FlattenOutline(fz_outline *outline, int level, memset(indent, ' ', level * 4); indent[level * 4] = 0; - String^ indent_str = char_to_String(indent); - String^ str_indent; + String^ indent_str = char_to_String(indent); + String^ str_indent; while (outline) { @@ -236,15 +237,15 @@ void muctx::FlattenOutline(fz_outline *outline, int level, int page = outline->dest.ld.gotor.page; if (page >= 0 && outline->title) { - /* Add to the contents std:vec */ - sh_content content_item(new content_t()); - content_item->page = page; - content_item->string_orig = char_to_String(outline->title); - content_item->string_margin = - str_indent->Concat(indent_str, content_item->string_orig); - contents_vec->push_back(content_item); - } - } + /* Add to the contents std:vec */ + sh_content content_item(new content_t()); + content_item->page = page; + content_item->string_orig = char_to_String(outline->title); + content_item->string_margin = + str_indent->Concat(indent_str, content_item->string_orig); + contents_vec->push_back(content_item); + } + } FlattenOutline(outline->down, level + 1, contents_vec); outline = outline->next; } @@ -252,243 +253,243 @@ void muctx::FlattenOutline(fz_outline *outline, int level, int muctx::GetContents(sh_vector_content contents_vec) { - fz_outline *root = NULL; - fz_context *ctx_clone = NULL; - int has_content = 0; + fz_outline *root = NULL; + fz_context *ctx_clone = NULL; + int has_content = 0; - if (mu_cookie->abort == 1) - return has_content; + if (mu_cookie->abort == 1) + return has_content; - ctx_clone = fz_clone_context(mu_ctx); + ctx_clone = fz_clone_context(mu_ctx); - fz_var(root); + fz_var(root); fz_try(ctx_clone) { - root = fz_load_outline(mu_doc); - if (root != NULL) - { - has_content = 1; - FlattenOutline(root, 0, contents_vec); - } - } + root = fz_load_outline(mu_doc); + if (root != NULL) + { + has_content = 1; + FlattenOutline(root, 0, contents_vec); + } + } fz_always(ctx_clone) { - if (root != NULL) - { - fz_free_outline(ctx_clone, root); - } - } + if (root != NULL) + { + fz_free_outline(ctx_clone, root); + } + } fz_catch(ctx_clone) { - fz_free_context(ctx_clone); + fz_free_context(ctx_clone); return E_FAIL; } - fz_free_context(ctx_clone); - return has_content; + fz_free_context(ctx_clone); + return has_content; } int muctx::GetTextSearch(int page_num, char* needle, sh_vector_text texts_vec) { - fz_page *page = NULL; - fz_text_sheet *sheet = NULL; - fz_device *dev = NULL; - fz_context *ctx_clone = NULL; - fz_text_page *text = NULL; - int hit_count = 0; - int k; - - if (mu_cookie->abort == 1) - return hit_count; - - ctx_clone = fz_clone_context(mu_ctx); - - fz_var(page); - fz_var(sheet); - fz_var(dev); + fz_page *page = NULL; + fz_text_sheet *sheet = NULL; + fz_device *dev = NULL; + fz_context *ctx_clone = NULL; + fz_text_page *text = NULL; + int hit_count = 0; + int k; + + if (mu_cookie->abort == 1) + return hit_count; + + ctx_clone = fz_clone_context(mu_ctx); + + fz_var(page); + fz_var(sheet); + fz_var(dev); fz_try(ctx_clone) { - page = fz_load_page(mu_doc, page_num); - sheet = fz_new_text_sheet(ctx_clone); - text = fz_new_text_page(ctx_clone, &fz_empty_rect); // Free? - dev = fz_new_text_device(ctx_clone, sheet, text); - fz_run_page(mu_doc, page, dev, &fz_identity, NULL); - fz_free_device(dev); /* Why does this need to be done here? Seems odd */ - dev = NULL; - hit_count = fz_search_text_page(ctx_clone, text, needle, mu_hit_bbox, nelem(mu_hit_bbox)); - - for (k = 0; k < hit_count; k++) - { - sh_text text_search(new text_search_t()); - text_search->upper_left.X = mu_hit_bbox[k].x0; - text_search->upper_left.Y = mu_hit_bbox[k].y0; - text_search->lower_right.X = mu_hit_bbox[k].x1; - text_search->lower_right.Y = mu_hit_bbox[k].y1; - texts_vec->push_back(text_search); - } - } + page = fz_load_page(mu_doc, page_num); + sheet = fz_new_text_sheet(ctx_clone); + text = fz_new_text_page(ctx_clone, &fz_empty_rect); // Free? + dev = fz_new_text_device(ctx_clone, sheet, text); + fz_run_page(mu_doc, page, dev, &fz_identity, NULL); + fz_free_device(dev); /* Why does this need to be done here? Seems odd */ + dev = NULL; + hit_count = fz_search_text_page(ctx_clone, text, needle, mu_hit_bbox, nelem(mu_hit_bbox)); + + for (k = 0; k < hit_count; k++) + { + sh_text text_search(new text_search_t()); + text_search->upper_left.X = mu_hit_bbox[k].x0; + text_search->upper_left.Y = mu_hit_bbox[k].y0; + text_search->lower_right.X = mu_hit_bbox[k].x1; + text_search->lower_right.Y = mu_hit_bbox[k].y1; + texts_vec->push_back(text_search); + } + } fz_always(ctx_clone) { - if (page != NULL) - { - fz_free_page(mu_doc, page); - } - if (dev != NULL) - { - fz_free_device(dev); - } - if (sheet != NULL) - { - fz_free_text_sheet(ctx_clone, sheet); - } - if (text != NULL) - { - fz_free_text_page(ctx_clone, text); - } - } + if (page != NULL) + { + fz_free_page(mu_doc, page); + } + if (dev != NULL) + { + fz_free_device(dev); + } + if (sheet != NULL) + { + fz_free_text_sheet(ctx_clone, sheet); + } + if (text != NULL) + { + fz_free_text_page(ctx_clone, text); + } + } fz_catch(ctx_clone) { - fz_free_context(ctx_clone); - return E_FAIL; + fz_free_context(ctx_clone); + return E_FAIL; } - fz_free_context(ctx_clone); - return hit_count; + fz_free_context(ctx_clone); + return hit_count; } /* Get the links and pack into a smart pointer structure */ int muctx::GetLinks(int page_num, sh_vector_link links_vec) { - fz_page *page = NULL; - fz_link *links = NULL; - fz_context *ctx_clone = NULL; - int k = 0; - int num_links = 0; + fz_page *page = NULL; + fz_link *links = NULL; + fz_context *ctx_clone = NULL; + int k = 0; + int num_links = 0; - if (mu_cookie->abort == 1) - return num_links; + if (mu_cookie->abort == 1) + return num_links; - ctx_clone = fz_clone_context(mu_ctx); + ctx_clone = fz_clone_context(mu_ctx); - fz_var(page); - fz_var(links); + fz_var(page); + fz_var(links); fz_try(ctx_clone) { - page = fz_load_page(mu_doc, page_num); - links = fz_load_links(mu_doc, page); - - fz_link *curr_link = links; - if (curr_link != NULL) - { - /* Get our smart pointer structure filled */ - while (curr_link != NULL) - { - fz_rect curr_rect = curr_link->rect; - sh_link link(new document_link_t()); - - link->upper_left.X = curr_rect.x0; - link->upper_left.Y = curr_rect.y0; - link->lower_right.X = curr_rect.x1; - link->lower_right.Y = curr_rect.y1; - - switch (curr_link->dest.kind) - { - case FZ_LINK_GOTO: - - link->type = LINK_GOTO; - link->page_num = curr_link->dest.ld.gotor.page; - break; - - case FZ_LINK_URI: - { - int lenstr = strlen(curr_link->dest.ld.uri.uri); - std::unique_ptr uri(new char[lenstr + 1]); - strcpy_s(uri.get(), lenstr + 1, curr_link->dest.ld.uri.uri); - link->uri.swap(uri); - link->type = LINK_URI; - break; - } - - default: - link->type = NOT_SET; - - } - links_vec->push_back(link); - curr_link = curr_link->next; - num_links += 1; - } - } - } + page = fz_load_page(mu_doc, page_num); + links = fz_load_links(mu_doc, page); + + fz_link *curr_link = links; + if (curr_link != NULL) + { + /* Get our smart pointer structure filled */ + while (curr_link != NULL) + { + fz_rect curr_rect = curr_link->rect; + sh_link link(new document_link_t()); + + link->upper_left.X = curr_rect.x0; + link->upper_left.Y = curr_rect.y0; + link->lower_right.X = curr_rect.x1; + link->lower_right.Y = curr_rect.y1; + + switch (curr_link->dest.kind) + { + case FZ_LINK_GOTO: + + link->type = LINK_GOTO; + link->page_num = curr_link->dest.ld.gotor.page; + break; + + case FZ_LINK_URI: + { + int lenstr = strlen(curr_link->dest.ld.uri.uri); + std::unique_ptr uri(new char[lenstr + 1]); + strcpy_s(uri.get(), lenstr + 1, curr_link->dest.ld.uri.uri); + link->uri.swap(uri); + link->type = LINK_URI; + break; + } + + default: + link->type = NOT_SET; + + } + links_vec->push_back(link); + curr_link = curr_link->next; + num_links += 1; + } + } + } fz_always(ctx_clone) { - if (page != NULL) - { - fz_free_page(mu_doc, page); - } - if (links != NULL) - { - fz_drop_link(ctx_clone, links); - } + if (page != NULL) + { + fz_free_page(mu_doc, page); + } + if (links != NULL) + { + fz_drop_link(ctx_clone, links); + } } fz_catch(ctx_clone) { - fz_free_context(ctx_clone); + fz_free_context(ctx_clone); return E_FAIL; } - fz_free_context(ctx_clone); - return num_links; + fz_free_context(ctx_clone); + return num_links; } /* Render page_num to size width by height into bmp_data buffer */ HRESULT muctx::RenderPage(int page_num, int width, int height, - unsigned char *bmp_data) + unsigned char *bmp_data) { - fz_device *dev = NULL; - fz_pixmap *pix = NULL; - fz_page *page = NULL; + fz_device *dev = NULL; + fz_pixmap *pix = NULL; + fz_page *page = NULL; fz_matrix ctm, *pctm = &ctm; - Point page_size; - fz_context *ctx_clone = NULL; + Point page_size; + fz_context *ctx_clone = NULL; - if (mu_cookie->abort == 1) - return S_OK; + if (mu_cookie->abort == 1) + return S_OK; - ctx_clone = fz_clone_context(mu_ctx); + ctx_clone = fz_clone_context(mu_ctx); - fz_var(dev); + fz_var(dev); fz_var(pix); - fz_var(page); + fz_var(page); fz_try(ctx_clone) { - page = fz_load_page(mu_doc, page_num); - page_size = MeasurePage(page); - - /* Figure out scale factors so that we get the desired size */ - pctm = fz_scale(pctm, (float) width / page_size.X, (float) height / page_size.Y); - /* Flip on Y */ - ctm.f = height; - ctm.d = -ctm.d; - pix = fz_new_pixmap_with_data(ctx_clone, fz_device_bgr, width, height, bmp_data); - fz_clear_pixmap_with_value(ctx_clone, pix, 255); - dev = fz_new_draw_device(ctx_clone, pix); - fz_run_page(mu_doc, page, dev, pctm, NULL); + page = fz_load_page(mu_doc, page_num); + page_size = MeasurePage(page); + + /* Figure out scale factors so that we get the desired size */ + pctm = fz_scale(pctm, (float) width / page_size.X, (float) height / page_size.Y); + /* Flip on Y */ + ctm.f = height; + ctm.d = -ctm.d; + pix = fz_new_pixmap_with_data(ctx_clone, fz_device_bgr, width, height, bmp_data); + fz_clear_pixmap_with_value(ctx_clone, pix, 255); + dev = fz_new_draw_device(ctx_clone, pix); + fz_run_page(mu_doc, page, dev, pctm, NULL); } fz_always(ctx_clone) { - if (dev != NULL) - { + if (dev != NULL) + { fz_free_device(dev); } if (pix != NULL) { fz_drop_pixmap(ctx_clone, pix); } - if (page != NULL) - { - fz_free_page(mu_doc, page); - } + if (page != NULL) + { + fz_free_page(mu_doc, page); + } } fz_catch(ctx_clone) { - fz_free_context(ctx_clone); + fz_free_context(ctx_clone); return E_FAIL; } @@ -498,61 +499,61 @@ HRESULT muctx::RenderPage(int page_num, int width, int height, String^ muctx::GetHTML(int page_num) { - fz_output *out = NULL; - fz_device *dev = NULL; - fz_page *page = NULL; - fz_text_sheet *sheet = NULL; - fz_text_page *text = NULL; - fz_context *ctx_clone = NULL; - fz_buffer *buf = NULL; - String^ html; - - if (mu_cookie->abort == 1) - return nullptr; - - ctx_clone = fz_clone_context(mu_ctx); - - fz_var(dev); - fz_var(page); - fz_var(sheet); - fz_var(text); // Free? - fz_var(buf); // Free? + fz_output *out = NULL; + fz_device *dev = NULL; + fz_page *page = NULL; + fz_text_sheet *sheet = NULL; + fz_text_page *text = NULL; + fz_context *ctx_clone = NULL; + fz_buffer *buf = NULL; + String^ html; + + if (mu_cookie->abort == 1) + return nullptr; + + ctx_clone = fz_clone_context(mu_ctx); + + fz_var(dev); + fz_var(page); + fz_var(sheet); + fz_var(text); // Free? + fz_var(buf); // Free? fz_try(ctx_clone) { - page = fz_load_page(mu_doc, page_num); - sheet = fz_new_text_sheet(ctx_clone); - text = fz_new_text_page(ctx_clone, &fz_empty_rect); - dev = fz_new_text_device(ctx_clone, sheet, text); - fz_run_page(mu_doc, page, dev, &fz_identity, NULL); - fz_free_device(dev); - dev = NULL; - fz_analyze_text(ctx_clone, sheet, text); - buf = fz_new_buffer(ctx_clone, 256); - out = fz_new_output_with_buffer(ctx_clone, buf); - fz_print_text_page_html(ctx_clone, out, text); - html = char_to_String((char*) buf->data); - } + page = fz_load_page(mu_doc, page_num); + sheet = fz_new_text_sheet(ctx_clone); + text = fz_new_text_page(ctx_clone, &fz_empty_rect); + dev = fz_new_text_device(ctx_clone, sheet, text); + fz_run_page(mu_doc, page, dev, &fz_identity, NULL); + fz_free_device(dev); + dev = NULL; + fz_analyze_text(ctx_clone, sheet, text); + buf = fz_new_buffer(ctx_clone, 256); + out = fz_new_output_with_buffer(ctx_clone, buf); + fz_print_text_page_html(ctx_clone, out, text); + html = char_to_String((char*) buf->data); + } fz_always(ctx_clone) { - if (dev != NULL) - { + if (dev != NULL) + { fz_free_device(dev); } - if (page != NULL) - { - fz_free_page(mu_doc, page); - } - if (sheet != NULL) - { - fz_free_text_sheet(ctx_clone, sheet); - } - } + if (page != NULL) + { + fz_free_page(mu_doc, page); + } + if (sheet != NULL) + { + fz_free_text_sheet(ctx_clone, sheet); + } + } fz_catch(ctx_clone) { - fz_free_context(ctx_clone); - return nullptr; - } + fz_free_context(ctx_clone); + return nullptr; + } fz_free_context(ctx_clone); - return html; + return html; } diff --git a/winrt/mupdfwinrt/muctx.h b/winrt/mupdfwinrt/muctx.h index c738593f..333a1902 100644 --- a/winrt/mupdfwinrt/muctx.h +++ b/winrt/mupdfwinrt/muctx.h @@ -9,10 +9,10 @@ #include "utils.h" extern "C" { - #include "fitz.h" - #include "fitz-internal.h" - #include "muxps.h" - #include "mupdf.h" + #include "fitz.h" + #include "fitz-internal.h" + #include "muxps.h" + #include "mupdf.h" } #define MAX_SEARCH 500 @@ -27,10 +27,10 @@ using namespace Windows::Foundation; /* For Point */ typedef struct document_link_s { link_t type; - Point upper_left; - Point lower_right; - std::unique_ptr uri; - int page_num; + Point upper_left; + Point lower_right; + std::unique_ptr uri; + int page_num; } document_link_t; #define sh_link std::shared_ptr #define sh_vector_link std::shared_ptr> @@ -38,8 +38,8 @@ typedef struct document_link_s /* Text Search */ typedef struct text_search_s { - Point upper_left; - Point lower_right; + Point upper_left; + Point lower_right; } text_search_t; #define sh_text std::shared_ptr #define sh_vector_text std::shared_ptr> @@ -47,9 +47,9 @@ typedef struct text_search_s /* Content Results */ typedef struct content_s { - int page; - String^ string_orig; - String^ string_margin; + int page; + String^ string_orig; + String^ string_margin; } content_t; #define sh_content std::shared_ptr #define sh_vector_content std::shared_ptr> @@ -63,36 +63,36 @@ using namespace Windows::Foundation; typedef struct win_stream_struct_s { - IRandomAccessStream^ stream; + IRandomAccessStream^ stream; } win_stream_struct; class muctx { private: CRITICAL_SECTION mu_criticalsec; - win_stream_struct win_stream; - fz_locks_context mu_locks; + win_stream_struct win_stream; + fz_locks_context mu_locks; fz_context *mu_ctx; fz_document *mu_doc; fz_outline *mu_outline; - fz_rect mu_hit_bbox[MAX_SEARCH]; + fz_rect mu_hit_bbox[MAX_SEARCH]; fz_cookie *mu_cookie; - fz_stream *mu_stream; - void FlattenOutline(fz_outline *outline, int level, - sh_vector_content contents_vec); + fz_stream *mu_stream; + void FlattenOutline(fz_outline *outline, int level, + sh_vector_content contents_vec); public: - muctx(void); - ~muctx(void); - void CleanUp(void); - HRESULT InitializeStream(IRandomAccessStream^ readStream, char *ext); - int GetPageCount(); - HRESULT InitializeContext(); - HRESULT RenderPage(int page_num, int width, int height, unsigned char *bmp_data); - Point MeasurePage(int page_num); - Point MeasurePage(fz_page *page); - int GetLinks(int page_num, sh_vector_link links_vec); - int GetTextSearch(int page_num, char* needle, sh_vector_text texts_vec); - int GetContents(sh_vector_content contents_vec); - String^ GetHTML(int page_num); + muctx(void); + ~muctx(void); + void CleanUp(void); + HRESULT InitializeStream(IRandomAccessStream^ readStream, char *ext); + int GetPageCount(); + HRESULT InitializeContext(); + HRESULT RenderPage(int page_num, int width, int height, unsigned char *bmp_data); + Point MeasurePage(int page_num); + Point MeasurePage(fz_page *page); + int GetLinks(int page_num, sh_vector_link links_vec); + int GetTextSearch(int page_num, char* needle, sh_vector_text texts_vec); + int GetContents(sh_vector_content contents_vec); + String^ GetHTML(int page_num); }; diff --git a/winrt/mupdfwinrt/mudocument.cpp b/winrt/mupdfwinrt/mudocument.cpp index bc21a994..c3003e96 100644 --- a/winrt/mupdfwinrt/mudocument.cpp +++ b/winrt/mupdfwinrt/mudocument.cpp @@ -13,233 +13,233 @@ using namespace Platform::Collections; mudocument::mudocument() { - this->mu_object.InitializeContext(); - this->links = nullptr; + this->mu_object.InitializeContext(); + this->links = nullptr; } void mudocument::CleanUp() { - this->mu_object.CleanUp(); + this->mu_object.CleanUp(); } int mudocument::GetNumPages() { - return this->mu_object.GetPageCount(); + return this->mu_object.GetPageCount(); } Point mudocument::GetPageSize(int page_num) { - std::lock_guard lock(mutex_lock); - return this->mu_object.MeasurePage(page_num); + std::lock_guard lock(mutex_lock); + return this->mu_object.MeasurePage(page_num); } Windows::Foundation::IAsyncAction^ mudocument::OpenFile(StorageFile^ file) { - return create_async([this, file]() - { - String^ path = file->Path; - const wchar_t *w = path->Data(); - int cb = WideCharToMultiByte(CP_UTF8, 0, w, -1, nullptr, 0, nullptr, nullptr); - char* name = new char[cb]; - - WideCharToMultiByte(CP_UTF8, 0, w ,-1 ,name ,cb ,nullptr, nullptr); - char *ext = strrchr(name, '.'); - - auto t = create_task(file->OpenAsync(FileAccessMode::Read)); - - return t.then([this, file, ext](task task) - { - try - { - IRandomAccessStream^ readStream = task.get(); - UINT64 const size = readStream->Size; - - if (size <= MAXUINT32) - { - HRESULT code = this->mu_object.InitializeStream(readStream, ext); - return; - } - else - { - delete readStream; - return; - } - } - catch(COMException^ ex) { - /* Need to do something useful here */ - throw ex; - } - }); - }); + return create_async([this, file]() + { + String^ path = file->Path; + const wchar_t *w = path->Data(); + int cb = WideCharToMultiByte(CP_UTF8, 0, w, -1, nullptr, 0, nullptr, nullptr); + char* name = new char[cb]; + + WideCharToMultiByte(CP_UTF8, 0, w ,-1 ,name ,cb ,nullptr, nullptr); + char *ext = strrchr(name, '.'); + + auto t = create_task(file->OpenAsync(FileAccessMode::Read)); + + return t.then([this, file, ext](task task) + { + try + { + IRandomAccessStream^ readStream = task.get(); + UINT64 const size = readStream->Size; + + if (size <= MAXUINT32) + { + HRESULT code = this->mu_object.InitializeStream(readStream, ext); + return; + } + else + { + delete readStream; + return; + } + } + catch(COMException^ ex) { + /* Need to do something useful here */ + throw ex; + } + }); + }); } /* Header info for bmp stream so that we can use the image brush */ static void Prepare_bmp(int width, int height, DataWriter ^dw) { - int row_size = width * 4; - int bmp_size = row_size * height + 54; - - dw->WriteString("BM"); - dw->ByteOrder = ByteOrder::LittleEndian; - dw->WriteInt32(bmp_size); - dw->WriteInt16(0); - dw->WriteInt16(0); - dw->WriteInt32(54); - dw->WriteInt32(40); - dw->WriteInt32(width); - dw->WriteInt32(height); - dw->WriteInt16(1); - dw->WriteInt16(32); - dw->WriteInt32(0); - dw->WriteInt32(row_size * height); - dw->WriteInt32(2835); - dw->WriteInt32(2835); - dw->WriteInt32(0); - dw->WriteInt32(0); + int row_size = width * 4; + int bmp_size = row_size * height + 54; + + dw->WriteString("BM"); + dw->ByteOrder = ByteOrder::LittleEndian; + dw->WriteInt32(bmp_size); + dw->WriteInt16(0); + dw->WriteInt16(0); + dw->WriteInt32(54); + dw->WriteInt32(40); + dw->WriteInt32(width); + dw->WriteInt32(height); + dw->WriteInt16(1); + dw->WriteInt16(32); + dw->WriteInt32(0); + dw->WriteInt32(row_size * height); + dw->WriteInt32(2835); + dw->WriteInt32(2835); + dw->WriteInt32(0); + dw->WriteInt32(0); } /* Pack the page into a bmp stream so that we can use it with an image brush */ Windows::Foundation::IAsyncOperation^ - mudocument::RenderPage(int page_num, int width, int height) + mudocument::RenderPage(int page_num, int width, int height) { - return create_async([this, width, height, page_num](cancellation_token ct) -> InMemoryRandomAccessStream^ - { - /* Allocate space for bmp */ - Array^ bmp_data = ref new Array(height * 4 * width); - /* Set up the memory stream */ - InMemoryRandomAccessStream ^ras = ref new InMemoryRandomAccessStream(); - DataWriter ^dw = ref new DataWriter(ras->GetOutputStreamAt(0)); - - /* Go ahead and write our header data into the memory stream */ - Prepare_bmp(width, height, dw); - - std::lock_guard lock(mutex_lock); - - /* Get raster bitmap stream */ - HRESULT code = mu_object.RenderPage(page_num, width, height, &(bmp_data[0])); - if (code != S_OK) - { - throw ref new FailureException("Page Rendering Failed"); - } - /* Now the data into the memory stream */ - dw->WriteBytes(bmp_data); - DataWriterStoreOperation^ result = dw->StoreAsync(); - /* Block on this Async call? */ - while(result->Status != AsyncStatus::Completed) { - } - /* Return raster stream */ - return ras; - }); + return create_async([this, width, height, page_num](cancellation_token ct) -> InMemoryRandomAccessStream^ + { + /* Allocate space for bmp */ + Array^ bmp_data = ref new Array(height * 4 * width); + /* Set up the memory stream */ + InMemoryRandomAccessStream ^ras = ref new InMemoryRandomAccessStream(); + DataWriter ^dw = ref new DataWriter(ras->GetOutputStreamAt(0)); + + /* Go ahead and write our header data into the memory stream */ + Prepare_bmp(width, height, dw); + + std::lock_guard lock(mutex_lock); + + /* Get raster bitmap stream */ + HRESULT code = mu_object.RenderPage(page_num, width, height, &(bmp_data[0])); + if (code != S_OK) + { + throw ref new FailureException("Page Rendering Failed"); + } + /* Now the data into the memory stream */ + dw->WriteBytes(bmp_data); + DataWriterStoreOperation^ result = dw->StoreAsync(); + /* Block on this Async call? */ + while(result->Status != AsyncStatus::Completed) { + } + /* Return raster stream */ + return ras; + }); } int mudocument::ComputeLinks(int page_num) { - std::lock_guard lock(mutex_lock); - /* We get back a standard smart pointer from muctx interface and go to WinRT - type here */ - sh_vector_link link_smart_ptr_vec(new std::vector()); - int num_items = mu_object.GetLinks(page_num, link_smart_ptr_vec); - if (num_items == 0) - return 0; - /* Pack into winRT type*/ - this->links = ref new Platform::Collections::Vector(); - for (int k = 0; k < num_items; k++) - { - auto new_link = ref new Links(); - sh_link muctx_link = link_smart_ptr_vec->at(k); - new_link->LowerRight = muctx_link->lower_right; - new_link->UpperLeft = muctx_link->upper_left; - new_link->PageNum = muctx_link->page_num; - new_link->Type = muctx_link->type; - if (new_link->Type == LINK_URI) - { - String^ str = char_to_String(muctx_link->uri.get()); - // The URI to launch - new_link->Uri = ref new Windows::Foundation::Uri(str); - } - this->links->Append(new_link); - } - return num_items; + std::lock_guard lock(mutex_lock); + /* We get back a standard smart pointer from muctx interface and go to WinRT + type here */ + sh_vector_link link_smart_ptr_vec(new std::vector()); + int num_items = mu_object.GetLinks(page_num, link_smart_ptr_vec); + if (num_items == 0) + return 0; + /* Pack into winRT type*/ + this->links = ref new Platform::Collections::Vector(); + for (int k = 0; k < num_items; k++) + { + auto new_link = ref new Links(); + sh_link muctx_link = link_smart_ptr_vec->at(k); + new_link->LowerRight = muctx_link->lower_right; + new_link->UpperLeft = muctx_link->upper_left; + new_link->PageNum = muctx_link->page_num; + new_link->Type = muctx_link->type; + if (new_link->Type == LINK_URI) + { + String^ str = char_to_String(muctx_link->uri.get()); + // The URI to launch + new_link->Uri = ref new Windows::Foundation::Uri(str); + } + this->links->Append(new_link); + } + return num_items; } Links^ mudocument::GetLink(int k) { - if (k >= this->links->Size) - return nullptr; - return this->links->GetAt(k); + if (k >= this->links->Size) + return nullptr; + return this->links->GetAt(k); } int mudocument::ComputeTextSearch(String^ text, int page_num) { - std::lock_guard lock(mutex_lock); - /* We get back a standard smart pointer from muctx interface and go to WinRT - type here */ - char* text_char = String_to_char(text); - sh_vector_text text_smart_ptr_vec(new std::vector()); - - int num_items = mu_object.GetTextSearch(page_num, text_char, text_smart_ptr_vec); - if (num_items == 0) - return 0; - /* Pack into winRT type*/ - this->textsearch = ref new Platform::Collections::Vector(); - for (int k = 0; k < num_items; k++) - { - auto new_link = ref new Links(); - sh_text muctx_text = text_smart_ptr_vec->at(k); - new_link->LowerRight = muctx_text->lower_right; - new_link->UpperLeft = muctx_text->upper_left; - new_link->Type = TEXTBOX; - this->textsearch->Append(new_link); - } - delete []text_char; - return num_items; + std::lock_guard lock(mutex_lock); + /* We get back a standard smart pointer from muctx interface and go to + * WinRT type here */ + char* text_char = String_to_char(text); + sh_vector_text text_smart_ptr_vec(new std::vector()); + + int num_items = mu_object.GetTextSearch(page_num, text_char, text_smart_ptr_vec); + if (num_items == 0) + return 0; + /* Pack into winRT type*/ + this->textsearch = ref new Platform::Collections::Vector(); + for (int k = 0; k < num_items; k++) + { + auto new_link = ref new Links(); + sh_text muctx_text = text_smart_ptr_vec->at(k); + new_link->LowerRight = muctx_text->lower_right; + new_link->UpperLeft = muctx_text->upper_left; + new_link->Type = TEXTBOX; + this->textsearch->Append(new_link); + } + delete []text_char; + return num_items; } /* Returns the kth item for a page after a text search query */ Links^ mudocument::GetTextSearch(int k) { - if (k >= this->textsearch->Size) - return nullptr; - return this->textsearch->GetAt(k); + if (k >= this->textsearch->Size) + return nullptr; + return this->textsearch->GetAt(k); } int mudocument::ComputeContents() { - std::lock_guard lock(mutex_lock); - /* We get back a standard smart pointer from muctx interface and go to WinRT - type here */ - - sh_vector_content content_smart_ptr_vec(new std::vector()); - - int has_content = mu_object.GetContents(content_smart_ptr_vec); - - if (!has_content) - return 0; - /* Pack into winRT type*/ - this->contents = ref new Platform::Collections::Vector(); - int num_items = content_smart_ptr_vec->size(); - - for (int k = 0; k < num_items; k++) - { - auto new_content = ref new ContentItem(); - sh_content muctx_content = content_smart_ptr_vec->at(k); - new_content->Page = muctx_content->page; - new_content->StringMargin = muctx_content->string_margin; - new_content->StringOrig = muctx_content->string_orig; - this->contents->Append(new_content); - } - return num_items; + std::lock_guard lock(mutex_lock); + /* We get back a standard smart pointer from muctx interface and go to + * WinRT type here */ + + sh_vector_content content_smart_ptr_vec(new std::vector()); + + int has_content = mu_object.GetContents(content_smart_ptr_vec); + + if (!has_content) + return 0; + /* Pack into winRT type*/ + this->contents = ref new Platform::Collections::Vector(); + int num_items = content_smart_ptr_vec->size(); + + for (int k = 0; k < num_items; k++) + { + auto new_content = ref new ContentItem(); + sh_content muctx_content = content_smart_ptr_vec->at(k); + new_content->Page = muctx_content->page; + new_content->StringMargin = muctx_content->string_margin; + new_content->StringOrig = muctx_content->string_orig; + this->contents->Append(new_content); + } + return num_items; } ContentItem^ mudocument::GetContent(int k) { - if (k >= this->contents->Size) - return nullptr; - return this->contents->GetAt(k); + if (k >= this->contents->Size) + return nullptr; + return this->contents->GetAt(k); } String^ mudocument::ComputeHTML(int page_num) { - std::lock_guard lock(mutex_lock); - return mu_object.GetHTML(page_num); + std::lock_guard lock(mutex_lock); + return mu_object.GetHTML(page_num); } diff --git a/winrt/mupdfwinrt/mudocument.h b/winrt/mupdfwinrt/mudocument.h index 48b8c301..a271d74c 100644 --- a/winrt/mupdfwinrt/mudocument.h +++ b/winrt/mupdfwinrt/mudocument.h @@ -18,28 +18,28 @@ using namespace Platform::Collections; namespace mupdfwinrt { - public ref class mudocument sealed - { - private: - muctx mu_object; - std::mutex mutex_lock; - Platform::Collections::Vector^ links; - Platform::Collections::Vector^ textsearch; - Platform::Collections::Vector^ contents; - public: - mudocument(); - void CleanUp(); - Windows::Foundation::IAsyncAction^ OpenFile(StorageFile^ file); - int GetNumPages(void); - Point GetPageSize(int page_num); - Windows::Foundation::IAsyncOperation^ - RenderPage(int page_num, int width, int height); - String^ ComputeHTML(int page_num); - int ComputeTextSearch(String^ text, int page_num); - Links^ GetTextSearch(int k); - int ComputeContents(void); - ContentItem^ GetContent(int k); - int ComputeLinks(int page_num); - Links^ GetLink(int k); - }; + public ref class mudocument sealed + { + private: + muctx mu_object; + std::mutex mutex_lock; + Platform::Collections::Vector^ links; + Platform::Collections::Vector^ textsearch; + Platform::Collections::Vector^ contents; + public: + mudocument(); + void CleanUp(); + Windows::Foundation::IAsyncAction^ OpenFile(StorageFile^ file); + int GetNumPages(void); + Point GetPageSize(int page_num); + Windows::Foundation::IAsyncOperation^ + RenderPage(int page_num, int width, int height); + String^ ComputeHTML(int page_num); + int ComputeTextSearch(String^ text, int page_num); + Links^ GetTextSearch(int k); + int ComputeContents(void); + ContentItem^ GetContent(int k); + int ComputeLinks(int page_num); + Links^ GetLink(int k); + }; } diff --git a/winrt/mupdfwinrt/utils.cpp b/winrt/mupdfwinrt/utils.cpp index a046ec90..38e11ada 100644 --- a/winrt/mupdfwinrt/utils.cpp +++ b/winrt/mupdfwinrt/utils.cpp @@ -4,25 +4,25 @@ /* Window string hurdles.... */ String^ char_to_String(char *char_in) { - size_t size = MultiByteToWideChar(CP_UTF8, 0, char_in, -1, NULL, 0); - wchar_t *pw; - pw = new wchar_t[size]; - if (!pw) - { - delete []pw; - return nullptr; - } - MultiByteToWideChar(CP_UTF8, 0, char_in, -1, pw, size ); - String^ str_out = ref new String(pw); - delete []pw; - return str_out; + size_t size = MultiByteToWideChar(CP_UTF8, 0, char_in, -1, NULL, 0); + wchar_t *pw; + pw = new wchar_t[size]; + if (!pw) + { + delete []pw; + return nullptr; + } + MultiByteToWideChar(CP_UTF8, 0, char_in, -1, pw, size ); + String^ str_out = ref new String(pw); + delete []pw; + return str_out; } char* String_to_char(String^ text) { - const wchar_t *w = text->Data(); - int cb = WideCharToMultiByte(CP_UTF8, 0, text->Data(), -1, nullptr, 0, nullptr, nullptr); + const wchar_t *w = text->Data(); + int cb = WideCharToMultiByte(CP_UTF8, 0, text->Data(), -1, nullptr, 0, nullptr, nullptr); char* charout = new char[cb]; - WideCharToMultiByte(CP_UTF8, 0, text->Data() ,-1 ,charout ,cb ,nullptr, nullptr); - return charout; -} \ No newline at end of file + WideCharToMultiByte(CP_UTF8, 0, text->Data() ,-1 ,charout ,cb ,nullptr, nullptr); + return charout; +} diff --git a/winrt/mupdfwinrt/utils.h b/winrt/mupdfwinrt/utils.h index 33513b21..a1237097 100644 --- a/winrt/mupdfwinrt/utils.h +++ b/winrt/mupdfwinrt/utils.h @@ -4,11 +4,11 @@ using namespace Platform; typedef enum { - LINK_GOTO = 0, - LINK_URI, - TEXTBOX, /* Do double duty with this class */ - NOT_SET, + LINK_GOTO = 0, + LINK_URI, + TEXTBOX, /* Do double duty with this class */ + NOT_SET, } link_t; String^ char_to_String(char *char_in); -char* String_to_char(String^ text); \ No newline at end of file +char* String_to_char(String^ text); -- cgit v1.2.3