summaryrefslogtreecommitdiff
path: root/platform/winrt/mupdfwinrt/mudocument.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/winrt/mupdfwinrt/mudocument.cpp')
-rw-r--r--platform/winrt/mupdfwinrt/mudocument.cpp103
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;