summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2013-06-09 12:28:15 -0700
committerRobin Watts <robin.watts@artifex.com>2013-06-14 21:18:04 +0100
commit5df70acc4e3ae23ed949d80b4c90d651765088ea (patch)
treefb5b50f82af8f4d8a1a9ddbd63ebe257753912a4
parentd581118e2d0ff407cfb918fcdd76b220d798725b (diff)
downloadmupdf-5df70acc4e3ae23ed949d80b4c90d651765088ea.tar.xz
Addition of display list rendering in WinRT library
The display list rendering is used when scaling within the current page to enable quicker response.
-rw-r--r--winrt/mupdf_cpp/MainPage.xaml.cpp31
-rw-r--r--winrt/mupdfwinrt/muctx.cpp67
-rw-r--r--winrt/mupdfwinrt/muctx.h6
-rw-r--r--winrt/mupdfwinrt/mudocument.cpp29
-rw-r--r--winrt/mupdfwinrt/mudocument.h4
5 files changed, 113 insertions, 24 deletions
diff --git a/winrt/mupdf_cpp/MainPage.xaml.cpp b/winrt/mupdf_cpp/MainPage.xaml.cpp
index a8dc1b3a..3c886339 100644
--- a/winrt/mupdf_cpp/MainPage.xaml.cpp
+++ b/winrt/mupdf_cpp/MainPage.xaml.cpp
@@ -429,10 +429,10 @@ void mupdf_cpp::MainPage::RenderThumbs()
cancellation_token_source cts;
auto token = cts.get_token();
m_ThumbCancel = cts;
+ auto ui = task_continuation_context::use_current();
this->m_ren_status = REN_THUMBS;
Vector<DocumentPage^>^ thumbnails = m_thumbnails;
- auto ui = task_continuation_context::use_current();
auto task_thumb = create_task([spatial_info, num_pages, thumbnails, this, ui, token]()-> int
{
spatial_info_t spatial_info_local = spatial_info;
@@ -441,7 +441,7 @@ void mupdf_cpp::MainPage::RenderThumbs()
for (int k = 0; k < num_pages; k++)
{
Point ras_size = ComputePageSize(spatial_info_local, k);
- auto task2 = create_task(mu_doc->RenderPageAsync(k, ras_size.X, ras_size.Y));
+ auto task2 = create_task(mu_doc->RenderPageAsync(k, ras_size.X, ras_size.Y, false));
task2.then([this, k, thumbnails, ras_size](InMemoryRandomAccessStream^ ras)
{
@@ -640,7 +640,7 @@ void mupdf_cpp::MainPage::InitialRender()
Point ras_size = ComputePageSize(spatial_info, k);
auto render_task =
- create_task(mu_doc->RenderPageAsync(k, ras_size.X, ras_size.Y));
+ create_task(mu_doc->RenderPageAsync(k, ras_size.X, ras_size.Y, false));
render_task.then([this, k, ras_size] (InMemoryRandomAccessStream^ ras)
{
@@ -687,7 +687,7 @@ void mupdf_cpp::MainPage::RenderRange(int curr_page)
{
Point ras_size = ComputePageSize(spatial_info, k);
auto render_task =
- create_task(mu_doc->RenderPageAsync(k, ras_size.X, ras_size.Y));
+ create_task(mu_doc->RenderPageAsync(k, ras_size.X, ras_size.Y, false));
render_task.then([this, k, ras_size] (InMemoryRandomAccessStream^ ras)
{
@@ -745,7 +745,7 @@ void mupdf_cpp::MainPage::Slider_ValueChanged(Platform::Object^ sender, Windows:
spatial_info_t spatial_info = InitSpatial(1);
Point ras_size = ComputePageSize(spatial_info, newValue);
auto render_task =
- create_task(mu_doc->RenderPageAsync(newValue, ras_size.X, ras_size.Y));
+ create_task(mu_doc->RenderPageAsync(newValue, ras_size.X, ras_size.Y, false));
render_task.then([this, newValue, ras_size] (InMemoryRandomAccessStream^ ras)
{
@@ -1321,17 +1321,26 @@ void mupdf_cpp::MainPage::ScrollChanged(Platform::Object^ sender,
{
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->RenderPageAsync(page, ras_size.X, ras_size.Y));
-
- render_task.then([this, page, ras_size] (InMemoryRandomAccessStream^ ras)
+ /* Go ahead and create display list if we dont have one for this page */
+ auto ui = task_continuation_context::use_current();
+ auto display_task = create_task(mu_doc->CreateDisplayList(page));
+ display_task.then([this, page, ras_size, ui] (int code)
{
- ReplaceImage(page, ras, ras_size);
- }, task_continuation_context::use_current());
+ if (code == S_ISOK)
+ {
+ auto render_task =
+ create_task(mu_doc->RenderPageAsync(page, ras_size.X, ras_size.Y, true));
+ render_task.then([this, page, ras_size] (InMemoryRandomAccessStream^ ras)
+ {
+ ReplaceImage(page, ras, ras_size);
+ }, ui);
+ }
+ });
}
}
diff --git a/winrt/mupdfwinrt/muctx.cpp b/winrt/mupdfwinrt/muctx.cpp
index 63f008cf..40849fb9 100644
--- a/winrt/mupdfwinrt/muctx.cpp
+++ b/winrt/mupdfwinrt/muctx.cpp
@@ -134,21 +134,23 @@ muctx::muctx(void)
this->mu_ctx = NULL;
this->mu_doc = NULL;
this->mu_outline = NULL;
+ this->mu_dlist = NULL;
+ this->dlist_pagenum = -1;
}
/* Destructor */
muctx::~muctx(void)
{
- if (mu_outline != NULL)
- fz_free_outline(mu_ctx, mu_outline);
- if (mu_doc != NULL)
- fz_close_document(mu_doc);
- if (mu_ctx != NULL)
- fz_free_context(mu_ctx);
+ fz_free_outline(mu_ctx, mu_outline);
+ fz_close_document(mu_doc);
+ fz_free_display_list(mu_ctx, mu_dlist);
+ fz_free_context(mu_ctx);
this->mu_ctx = NULL;
this->mu_doc = NULL;
this->mu_outline = NULL;
+ this->mu_dlist = NULL;
+ this->dlist_pagenum = -1;
}
/* Set up the stream access */
@@ -404,9 +406,52 @@ int muctx::GetLinks(int page_num, sh_vector_link links_vec)
return num_links;
}
+status_t muctx::CreateDisplayList(int page_num)
+{
+ fz_context *ctx_clone = NULL;
+ fz_device *dev = NULL;
+ fz_page *page = NULL;
+
+ ctx_clone = fz_clone_context(mu_ctx);
+
+ fz_var(dev);
+ fz_var(page);
+ fz_try(ctx_clone)
+ {
+ page = fz_load_page(mu_doc, page_num);
+
+ /* Free current list if we have one */
+ if (mu_dlist != NULL)
+ fz_free_display_list(ctx_clone, mu_dlist);
+
+ /* Create a new list */
+ mu_dlist = fz_new_display_list(ctx_clone);
+ dev = fz_new_list_device(ctx_clone, mu_dlist);
+ fz_run_page_contents(mu_doc, page, dev, &fz_identity, NULL);
+ }
+ fz_always(ctx_clone)
+ {
+ fz_free_device(dev);
+ fz_free_page(mu_doc, page);
+ }
+ fz_catch(ctx_clone)
+ {
+ fz_free_context(ctx_clone);
+ dlist_pagenum = -1;
+ return E_FAILURE;
+ }
+ dlist_pagenum = page_num;
+ return S_ISOK;
+}
+
+int muctx::GetDisplayListPage(void)
+{
+ return dlist_pagenum;
+}
+
/* Render page_num to size width by height into bmp_data buffer */
status_t muctx::RenderPage(int page_num, int width, int height,
- unsigned char *bmp_data)
+ unsigned char *bmp_data, bool use_dlist)
{
fz_device *dev = NULL;
fz_pixmap *pix = NULL;
@@ -415,6 +460,9 @@ status_t muctx::RenderPage(int page_num, int width, int height,
Point page_size;
fz_context *ctx_clone = NULL;
+ if (mu_dlist == NULL && use_dlist)
+ return E_FAILURE;
+
ctx_clone = fz_clone_context(mu_ctx);
fz_var(dev);
@@ -433,7 +481,10 @@ status_t muctx::RenderPage(int page_num, int width, int height,
pix = fz_new_pixmap_with_data(ctx_clone, fz_device_bgr(ctx_clone), 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);
+ if (use_dlist)
+ fz_run_display_list(mu_dlist, dev, pctm, NULL, NULL);
+ else
+ fz_run_page(mu_doc, page, dev, pctm, NULL);
}
fz_always(ctx_clone)
{
diff --git a/winrt/mupdfwinrt/muctx.h b/winrt/mupdfwinrt/muctx.h
index d35718d9..d22009a0 100644
--- a/winrt/mupdfwinrt/muctx.h
+++ b/winrt/mupdfwinrt/muctx.h
@@ -80,6 +80,8 @@ private:
fz_locks_context mu_locks;
fz_context *mu_ctx;
fz_document *mu_doc;
+ fz_display_list *mu_dlist;
+ int dlist_pagenum;
fz_outline *mu_outline;
fz_rect mu_hit_bbox[MAX_SEARCH];
void FlattenOutline(fz_outline *outline, int level,
@@ -92,7 +94,9 @@ public:
status_t InitializeStream(IRandomAccessStream^ readStream, char *ext);
int GetPageCount();
status_t InitializeContext();
- status_t RenderPage(int page_num, int width, int height, unsigned char *bmp_data);
+ status_t RenderPage(int page_num, int width, int height, unsigned char *bmp_data, bool use_dlist);
+ status_t CreateDisplayList(int page_num);
+ int GetDisplayListPage(void);
Point MeasurePage(int page_num);
Point MeasurePage(fz_page *page);
int GetLinks(int page_num, sh_vector_link links_vec);
diff --git a/winrt/mupdfwinrt/mudocument.cpp b/winrt/mupdfwinrt/mudocument.cpp
index fb227412..8688d520 100644
--- a/winrt/mupdfwinrt/mudocument.cpp
+++ b/winrt/mupdfwinrt/mudocument.cpp
@@ -162,11 +162,33 @@ Windows::Foundation::IAsyncOperationWithProgress<int, double>^
});
}
+/* Create the display list for this page */
+Windows::Foundation::IAsyncOperation<int>^ mudocument::CreateDisplayList(int page_num)
+{
+ return create_async([this, page_num](cancellation_token ct) -> int
+ {
+ if (mu_object.GetDisplayListPage() == page_num)
+ return S_ISOK;
+ std::lock_guard<std::mutex> lock(mutex_lock);
+ status_t code = mu_object.CreateDisplayList(page_num);
+ if (code != S_ISOK)
+ {
+ throw ref new FailureException("Display List Creation Failed");
+ }
+ return code;
+ });
+}
+
+int mudocument::GetDisplayListPage(void)
+{
+ return mu_object.GetDisplayListPage();
+}
+
/* Pack the page into a bmp stream */
Windows::Foundation::IAsyncOperation<InMemoryRandomAccessStream^>^
- mudocument::RenderPageAsync(int page_num, int width, int height)
+ mudocument::RenderPageAsync(int page_num, int width, int height, bool use_dlist)
{
- return create_async([this, width, height, page_num](cancellation_token ct) -> InMemoryRandomAccessStream^
+ return create_async([this, width, height, page_num, use_dlist](cancellation_token ct) -> InMemoryRandomAccessStream^
{
/* Allocate space for bmp */
Array<unsigned char>^ bmp_data = ref new Array<unsigned char>(height * 4 * width);
@@ -180,7 +202,8 @@ Windows::Foundation::IAsyncOperation<InMemoryRandomAccessStream^>^
std::lock_guard<std::mutex> lock(mutex_lock);
/* Get raster bitmap stream */
- status_t code = mu_object.RenderPage(page_num, width, height, &(bmp_data[0]));
+ status_t code = mu_object.RenderPage(page_num, width, height, &(bmp_data[0]),
+ use_dlist);
if (code != S_ISOK)
{
throw ref new FailureException("Page Rendering Failed");
diff --git a/winrt/mupdfwinrt/mudocument.h b/winrt/mupdfwinrt/mudocument.h
index f452f489..d90d2c9a 100644
--- a/winrt/mupdfwinrt/mudocument.h
+++ b/winrt/mupdfwinrt/mudocument.h
@@ -36,8 +36,9 @@ namespace mupdfwinrt
Windows::Foundation::IAsyncOperation<int>^ OpenFileAsync(StorageFile^ file);
int GetNumPages(void);
Point GetPageSize(int page_num);
+ Windows::Foundation::IAsyncOperation<int>^ mudocument::CreateDisplayList(int page_num);
Windows::Foundation::IAsyncOperation<InMemoryRandomAccessStream^>^
- RenderPageAsync(int page_num, int width, int height);
+ RenderPageAsync(int page_num, int width, int height, bool use_dlist);
Windows::Foundation::IAsyncOperationWithProgress<int, double>^
SearchDocumentWithProgressAsync(String^ textToFind, int dir, int start_page);
String^ ComputeHTML(int page_num);
@@ -47,6 +48,7 @@ namespace mupdfwinrt
int ComputeContents(void);
ContentItem^ GetContent(int k);
int ComputeLinks(int page_num);
+ int GetDisplayListPage(void);
Links^ GetLink(int k);
bool RequiresPassword();
bool ApplyPassword(String^ password);