diff options
Diffstat (limited to 'platform/winrt/mupdfwinrt/mudocument.cpp')
-rw-r--r-- | platform/winrt/mupdfwinrt/mudocument.cpp | 103 |
1 files changed, 75 insertions, 28 deletions
diff --git a/platform/winrt/mupdfwinrt/mudocument.cpp b/platform/winrt/mupdfwinrt/mudocument.cpp index d4855dd9..48093780 100644 --- a/platform/winrt/mupdfwinrt/mudocument.cpp +++ b/platform/winrt/mupdfwinrt/mudocument.cpp @@ -1,8 +1,8 @@ // mudocument.cpp /* This file contains the interface between the muctx class, which - implements the mupdf calls and the WinRT objects enabling calling from - C#, C++, Visual Basic, JavaScript applications */ + implements the mupdf calls and the WinRT objects enabling calling from + C#, C++, Visual Basic, JavaScript applications */ #include "pch.h" #include "mudocument.h" @@ -46,8 +46,10 @@ Point mudocument::GetPageSize(int page_num) Point size; mutex_lock.lock(); - size = this->mu_object.MeasurePage(page_num); + int code = this->mu_object.MeasurePage(page_num, &size); mutex_lock.unlock(); + if (code < 0) + throw ref new Exception(code, ref new String(L"Get Page Size Failed")); return size; } @@ -86,8 +88,7 @@ Windows::Foundation::IAsyncOperation<int>^ mudocument::OpenFileAsync(StorageFile } } catch(COMException^ ex) { - /* Need to do something useful here */ - throw ex; + throw ref new FailureException("Open File Failed"); } }); }); @@ -168,15 +169,23 @@ Windows::Foundation::IAsyncOperationWithProgress<int, double>^ } /* Pack the page into a bitmap. This is used in the DirectX code for printing - not in the xaml related code. */ + not in the xaml related code. It is also used by the thumbnail creation + thread to ensure that the thumbs are created in order and we don't create + thousands of threads */ int mudocument::RenderPageBitmapSync(int page_num, int bmp_width, int bmp_height, - bool use_dlist, Array<unsigned char>^* bit_map) + bool use_dlist, bool flipy, Array<unsigned char>^* bit_map) { status_t code; /* Allocate space for bmp */ Array<unsigned char>^ bmp_data = ref new Array<unsigned char>(bmp_height * 4 * bmp_width); + if (bmp_data == nullptr) + { + *bit_map = nullptr; + return E_OUTOFMEM; + } + if (use_dlist) { void *dlist; @@ -190,21 +199,27 @@ int mudocument::RenderPageBitmapSync(int page_num, int bmp_width, int bmp_height &page_height); /* Rendering of display list can occur with other threads so unlock */ mutex_lock.unlock(); + if (dlist == NULL) + { + *bit_map = nullptr; + return E_FAILURE; + } code = mu_object.RenderPageMT(dlist, page_width, page_height, &(bmp_data[0]), bmp_width, bmp_height, - false); + flipy); } else { /* Rendering in immediate mode. Keep lock in place */ mutex_lock.lock(); code = mu_object.RenderPage(page_num, &(bmp_data[0]), bmp_width, - bmp_height, false); + bmp_height, flipy); mutex_lock.unlock(); } if (code != S_ISOK) { - throw ref new FailureException("Page Rendering Failed"); + *bit_map = nullptr; + return E_FAILURE; } *bit_map = bmp_data; @@ -222,9 +237,17 @@ Windows::Foundation::IAsyncOperation<InMemoryRandomAccessStream^>^ /* Allocate space for bmp */ Array<unsigned char>^ bmp_data = ref new Array<unsigned char>(bmp_height * 4 * bmp_width); + if (bmp_data == nullptr) + return nullptr; + /* Set up the memory stream */ InMemoryRandomAccessStream ^ras = ref new InMemoryRandomAccessStream(); + if (ras == nullptr) + return nullptr; DataWriter ^dw = ref new DataWriter(ras->GetOutputStreamAt(0)); + if (dw == nullptr) + return nullptr; + status_t code; /* Go ahead and write our header data into the memory stream */ @@ -241,8 +264,10 @@ Windows::Foundation::IAsyncOperation<InMemoryRandomAccessStream^>^ in the page cache */ dlist = (void*) mu_object.CreateDisplayList(page_num, &page_width, &page_height); - /* Rendering of display list can occur with other threads so unlock */ mutex_lock.unlock(); + if (dlist == NULL) + return nullptr; + /* Rendering of display list can occur with other threads so unlock */ code = mu_object.RenderPageMT(dlist, page_width, page_height, &(bmp_data[0]), bmp_width, bmp_height, true); @@ -256,35 +281,38 @@ Windows::Foundation::IAsyncOperation<InMemoryRandomAccessStream^>^ mutex_lock.unlock(); } if (code != S_ISOK) - { - throw ref new FailureException("Page Rendering Failed"); - } + return nullptr; /* 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) { - } + auto t = create_task(dw->StoreAsync()); + t.wait(); /* Return raster stream */ return ras; }); } -int mudocument::ComputeLinks(int page_num) +unsigned int mudocument::ComputeLinks(int page_num) { /* 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<sh_link>()); mutex_lock.lock(); - int num_items = mu_object.GetLinks(page_num, link_smart_ptr_vec); + unsigned int num_items = mu_object.GetLinks(page_num, link_smart_ptr_vec); mutex_lock.unlock(); - if (num_items == 0) + if (num_items == 0 || num_items == E_FAIL) return 0; /* Pack into winRT type*/ this->links = ref new Platform::Collections::Vector<Links^>(); - for (int k = 0; k < num_items; k++) + if (this->links == nullptr) + return 0; + for (unsigned int k = 0; k < num_items; k++) { auto new_link = ref new Links(); + if (new_link == nullptr) + { + this->links = nullptr; + return 0; + } sh_link muctx_link = link_smart_ptr_vec->at(k); new_link->LowerRight = muctx_link->lower_right; new_link->UpperLeft = muctx_link->upper_left; @@ -295,13 +323,18 @@ int mudocument::ComputeLinks(int page_num) String^ str = char_to_String(muctx_link->uri.get()); // The URI to launch new_link->Uri = ref new Windows::Foundation::Uri(str); + if (new_link->Uri == nullptr) + { + this->links = nullptr; + return 0; + } } this->links->Append(new_link); } return num_items; } -Links^ mudocument::GetLink(int k) +Links^ mudocument::GetLink(unsigned int k) { if (k >= this->links->Size) return nullptr; @@ -324,9 +357,16 @@ int mudocument::ComputeTextSearch(String^ text, int page_num) return 0; /* Pack into winRT type*/ this->textsearch = ref new Platform::Collections::Vector<Links^>(); + if (this->textsearch == nullptr) + return 0; for (int k = 0; k < num_items; k++) { auto new_link = ref new Links(); + if (new_link == nullptr) + { + this->textsearch = nullptr; + return 0; + } sh_text muctx_text = text_smart_ptr_vec->at(k); new_link->LowerRight = muctx_text->lower_right; new_link->UpperLeft = muctx_text->upper_left; @@ -347,14 +387,14 @@ int mudocument::TextSearchCount(void) } /* Returns the kth item for a page after a text search query */ -Links^ mudocument::GetTextSearch(int k) +Links^ mudocument::GetTextSearch(unsigned int k) { if (k >= this->textsearch->Size) return nullptr; return this->textsearch->GetAt(k); } -int mudocument::ComputeContents() +unsigned int mudocument::ComputeContents() { /* We get back a standard smart pointer from muctx interface and go to * WinRT type here */ @@ -369,11 +409,18 @@ int mudocument::ComputeContents() return 0; /* Pack into winRT type*/ this->contents = ref new Platform::Collections::Vector<ContentItem^>(); - int num_items = content_smart_ptr_vec->size(); + if (this->contents == nullptr) + return 0; + unsigned int num_items = content_smart_ptr_vec->size(); - for (int k = 0; k < num_items; k++) + for (unsigned int k = 0; k < num_items; k++) { auto new_content = ref new ContentItem(); + if (new_content == nullptr) + { + this->contents = nullptr; + return 0; + } sh_content muctx_content = content_smart_ptr_vec->at(k); new_content->Page = muctx_content->page; new_content->StringMargin = muctx_content->string_margin; @@ -383,7 +430,7 @@ int mudocument::ComputeContents() return num_items; } -ContentItem^ mudocument::GetContent(int k) +ContentItem^ mudocument::GetContent(unsigned int k) { if (k >= this->contents->Size) return nullptr; |