diff options
author | Michael Vrhel <michael.vrhel@artifex.com> | 2013-06-09 12:28:15 -0700 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2013-06-14 21:18:04 +0100 |
commit | 5df70acc4e3ae23ed949d80b4c90d651765088ea (patch) | |
tree | fb5b50f82af8f4d8a1a9ddbd63ebe257753912a4 /winrt | |
parent | d581118e2d0ff407cfb918fcdd76b220d798725b (diff) | |
download | mupdf-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.
Diffstat (limited to 'winrt')
-rw-r--r-- | winrt/mupdf_cpp/MainPage.xaml.cpp | 31 | ||||
-rw-r--r-- | winrt/mupdfwinrt/muctx.cpp | 67 | ||||
-rw-r--r-- | winrt/mupdfwinrt/muctx.h | 6 | ||||
-rw-r--r-- | winrt/mupdfwinrt/mudocument.cpp | 29 | ||||
-rw-r--r-- | winrt/mupdfwinrt/mudocument.h | 4 |
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); |