summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2013-03-27 14:43:05 -0700
committerRobin Watts <robin.watts@artifex.com>2013-05-16 19:25:35 +0100
commitf344b6104db737954080e5e97676e6945708fcf9 (patch)
tree3dcbd4fe9dedf8c148c84e08b5013b4f7f04f1c3
parentaa0c80c1bd70cff8727e83996fc555461ef68278 (diff)
downloadmupdf-f344b6104db737954080e5e97676e6945708fcf9.tar.xz
Fix issues related to search, new project open, rendered image freeing, and more task fixes
-rw-r--r--winRT/winapp/MainPage.xaml.cpp213
-rw-r--r--winRT/winapp/MainPage.xaml.h2
2 files changed, 157 insertions, 58 deletions
diff --git a/winRT/winapp/MainPage.xaml.cpp b/winRT/winapp/MainPage.xaml.cpp
index 2f9a1c7d..7e257e49 100644
--- a/winRT/winapp/MainPage.xaml.cpp
+++ b/winRT/winapp/MainPage.xaml.cpp
@@ -54,13 +54,13 @@ extern "C" {
// The IsMainThread function returns true if the current thread is the app's main thread and false otherwise.
bool IsMainThread()
{
- return (_mainThreadId == 0U || _mainThreadId == GetCurrentThreadId());
+ 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 == 0U || _mainThreadId != GetCurrentThreadId());
+ return (_mainThreadId != GetCurrentThreadId());
}
// The RecordMainThread function registers the main thread ID for use by the IsMainThread and IsBackgroundThread functions.
@@ -132,9 +132,7 @@ void winapp::MainPage::Picker(Platform::Object^ sender, Windows::UI::Xaml::Route
{
if (file)
{
- this->OpenDocument(file);
- /* File selected. Start rendering and switch view. */
- //txtBlockOutput->Text = "Picked photo: " + file->Name;
+ this->OpenDocumentPrep(file);
}
else
{
@@ -228,6 +226,25 @@ void Prepare_bmp(int width, int height, DataWriter ^dw)
dw->WriteInt32(0);
}
+void MainPage::ReleasePages(int old_page, int new_page)
+{
+ /* To keep from having memory issue reset the page back to
+ the thumb if we are done rendering the thumbnails */
+ if (this->m_thumb_page_start == this->m_num_pages)
+ {
+ 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);
+ }
+ }
+ }
+ }
+}
+
void MainPage::InitThumbnails()
{
this->m_thumbnails.raster = ref new Array<InMemoryRandomAccessStream^>(m_num_pages);
@@ -469,6 +486,54 @@ InMemoryRandomAccessStream^ RenderBitMap(fz_document *doc, fz_page *page, int *w
return ras;
}
+task<Canvas^> RenderPage_Task(fz_document *doc, int page_num, int *width, int *height,
+ spatial_info_t spatial_info, ImageBrush^ *renderedImage)
+{
+ fz_page *page = fz_load_page(doc, page_num);
+ int width_val, height_val;
+ auto p = std::make_shared<std::pair<int,int>>(-1,-1);
+
+ /* This will launch rendering on another thread */
+ auto t = create_task([spatial_info, page_num, doc, page, width, height, p]()-> InMemoryRandomAccessStream^
+ {
+ InMemoryRandomAccessStream^ ras;
+
+ /* Get raster bitmap stream */
+ ras = RenderBitMap(doc, page, &(p->first), &(p->second), spatial_info);
+ *width = p->first;
+ *height = p->second;
+
+ return ras;
+ });
+ return t.then([renderedImage, doc, page, p](task<InMemoryRandomAccessStream^> the_task)
+ {
+ /* And store in a new image brush. Note: creation of WriteableBitmap
+ MUST be done by the UI thread. */
+ InMemoryRandomAccessStream^ ras;
+
+ assert(IsMainThread);
+ try
+ {
+ ras = the_task.get();
+ }
+ catch (const task_canceled& e)
+ {
+ return (Canvas^) nullptr;
+ }
+ WriteableBitmap ^bmp = ref new WriteableBitmap(p->first, p->second);
+ bmp->SetSource(ras);
+ *renderedImage = ref new ImageBrush();
+ (*renderedImage)->Stretch = Windows::UI::Xaml::Media::Stretch::None;
+ (*renderedImage)->ImageSource = bmp;
+ Canvas^ ret_Canvas = ref new Canvas();
+ ret_Canvas->Width = p->first;
+ ret_Canvas->Height = p->second;
+ ret_Canvas->Background = *renderedImage;
+ fz_free_page(doc, page);
+ return ret_Canvas;
+ }, task_continuation_context::use_current());
+}
+
Canvas^ RenderPage(fz_document *doc, fz_page *page, int *width, int *height,
spatial_info_t spatial_info, ImageBrush^ *renderedImage)
{
@@ -629,7 +694,9 @@ void winapp::MainPage::RenderThumbs()
from race conditions. Creation of bmp has to be done in ui thread */
FlipViewItem ^flipview_temp_v = (FlipViewItem^) xaml_vert_flipView->Items->GetAt(k);
FlipViewItem ^flipview_temp_h = (FlipViewItem^) xaml_horiz_flipView->Items->GetAt(k);
- if (flipview_temp_h->Background != nullptr)
+ FlipViewItem ^flipview_temp_curr = (FlipViewItem^) m_curr_flipView->Items->GetAt(k);
+
+ if (flipview_temp_curr->Background != nullptr)
{
WriteableBitmap ^bmp = ref new WriteableBitmap(m_thumbnails.size[k].Y, m_thumbnails.size[k].X);
bmp->SetSource(m_thumbnails.raster[k]);
@@ -653,23 +720,15 @@ void winapp::MainPage::RenderThumbs()
}, task_continuation_context::use_current());
}
-void winapp::MainPage::OpenDocument(StorageFile^ file)
+void winapp::MainPage::OpenDocumentPrep(StorageFile^ 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, '.');
-
if (this->m_num_pages != -1)
{
/* 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 */
+ /* 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) {
@@ -678,13 +737,30 @@ void winapp::MainPage::OpenDocument(StorageFile^ file)
}
}
return 0;
- });
-
- t.then([this](task<int> the_task)
+ }).then([this](task<int> the_task)
{
CleanUp();
+ return 0;
+ }, task_continuation_context::use_current()).then([this, file](task<int> the_task)
+ {
+ OpenDocument(file);
}, task_continuation_context::use_current());
}
+ else
+ {
+ OpenDocument(file);
+ }
+}
+
+void winapp::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);
+ char* name = new char[cb];
+
+ WideCharToMultiByte(CP_UTF8, 0, w ,-1 ,name ,cb ,nullptr, nullptr);
+ char *ext = strrchr(name, '.');
this->SetupZoomCanvas();
auto ui = task_continuation_context::use_current();
@@ -826,7 +902,7 @@ task<int> winapp::MainPage::RenderRange(int curr_page, int *height, int *width)
/* Check if thumb rendering is done. If not then restart */
if (this->m_num_pages != this->m_thumb_page_start)
- this->RenderThumbs();
+ // this->RenderThumbs();
return val;
}, task_continuation_context::use_current());
}
@@ -917,21 +993,7 @@ void winapp::MainPage::FlipView_SelectionChanged(Object^ sender, SelectionChange
task<int> task = this->RenderRange(pos, &height, &width);
task.then([this, curr_page, pos](int val)
{
- /* To keep from having memory issue reset the page back to
- the thumb if we are done rendering the thumbnails */
- if (this->m_thumb_page_start == this->m_num_pages)
- {
- for (int k = curr_page - LOOK_AHEAD; k <= curr_page + LOOK_AHEAD; k++)
- {
- if (k < pos - LOOK_AHEAD || k > pos + LOOK_AHEAD)
- {
- if (k >= 0 && k < this->m_num_pages)
- {
- SetThumb(k);
- }
- }
- }
- }
+ this->ReleasePages(curr_page, pos);
}, task_continuation_context::use_current());
}
}
@@ -1035,26 +1097,40 @@ void winapp::MainPage::FlipView_Double(Object^ sender, DoubleTappedRoutedEventAr
{
if (!m_zoom_mode && this->m_num_pages != -1)
{
- m_zoom_mode = true;
- int pos = this->m_curr_flipView->SelectedIndex;
- int width, height;
- fz_page *page = fz_load_page(m_doc, pos);
- spatial_info_t spatial_info = InitSpatial(1);
+ RenderingStatus_t *ren_status = &m_ren_status;
+ cancellation_token_source *ThumbCancel = &m_ThumbCancel;
- m_renderedCanvas = RenderPage(m_doc, page, &width, &height, spatial_info,
- &m_renderedImage);
- m_renderedImage->Stretch = Windows::UI::Xaml::Media::Stretch::None;
- this->xaml_zoomCanvas->Background = m_renderedImage;
+ /* Create a task to wait until the renderer is available */
+ auto t = create_task([ren_status, ThumbCancel]()
+ {
+ if (*ren_status == REN_THUMBS) {
+ ThumbCancel->cancel();
+ while (*ren_status == REN_THUMBS) {
+ }
+ }
+ }).then([this]()
+ {
+ m_zoom_mode = true;
+ int pos = this->m_curr_flipView->SelectedIndex;
+ int width, height;
+ fz_page *page = fz_load_page(m_doc, pos);
+ spatial_info_t spatial_info = InitSpatial(1);
- this->xaml_zoomCanvas->Width = width;
- this->xaml_zoomCanvas->Height = height;
+ m_renderedCanvas = RenderPage(m_doc, page, &width, &height, spatial_info,
+ &m_renderedImage);
+ m_renderedImage->Stretch = Windows::UI::Xaml::Media::Stretch::None;
+ this->xaml_zoomCanvas->Background = m_renderedImage;
- m_curr_flipView->IsEnabled = false;
- this->xaml_zoomCanvas->Background->Opacity = 1;
- this->m_curr_flipView->Opacity = 0.0;
- m_first_time = true;
- m_from_doubleflip = true;
- m_curr_zoom = 1.0;
+ this->xaml_zoomCanvas->Width = width;
+ this->xaml_zoomCanvas->Height = height;
+
+ m_curr_flipView->IsEnabled = false;
+ this->xaml_zoomCanvas->Background->Opacity = 1;
+ this->m_curr_flipView->Opacity = 0.0;
+ m_first_time = true;
+ m_from_doubleflip = true;
+ m_curr_zoom = 1.0;
+ }, task_continuation_context::use_current());
}
}
@@ -1149,11 +1225,33 @@ void winapp::MainPage::Searcher(Platform::Object^ sender, Windows::UI::Xaml::Rou
void winapp::MainPage::ShowSearchResults(SearchResult_t result)
{
int height, width;
- task<int> task = this->RenderRange(result.page_num, &height, &width);
+ int old_page = this->m_currpage;
+ int new_page = result.page_num;
+ spatial_info_t spatial_info = InitSpatial(1);
- /* Once the rendering is done launch this task to show the result */
- task.then([this, result](int val)
+ //task<int> task = this->RenderRange(new_page, &height, &width);
+ this->m_ren_status = REN_PAGE;
+ task<Canvas^> the_task = RenderPage_Task(m_doc, new_page, &width, &height,
+ spatial_info, &m_renderedImage);
+ the_task.then([this, old_page, new_page](task<Canvas^> the_task)
{
+ assert(IsMainThread);
+
+ try
+ {
+ this->m_renderedCanvas = the_task.get();
+ }
+ catch (const task_canceled& e)
+ {
+ this->m_renderedCanvas = nullptr;
+ }
+ ReplacePage(new_page);
+ this->m_ren_status = REN_AVAILABLE;
+ this->ReleasePages(old_page, new_page);
+ }, task_continuation_context::use_current()).then([this, result]()
+
+ {
+ /* Once the rendering is done launch this task to show the result */
RectSize screenSize;
RectSize pageSize;
RectSize scale;
@@ -1194,6 +1292,7 @@ void winapp::MainPage::ShowSearchResults(SearchResult_t result)
{
m_flip_from_search = true;
this->m_curr_flipView->SelectedIndex = result.page_num;
+ m_currpage = result.page_num;
}
}, task_continuation_context::use_current());
}
@@ -1318,8 +1417,6 @@ void winapp::MainPage::SearchInDirection(int dir, String^ textToFind)
{
my_bar->Value = start;
} */
- /* Get the ui thread */
- auto ui = task_continuation_context::use_current();
this->m_search_active = true;
/* Do task lambdas here to avoid UI blocking issues */
@@ -1357,7 +1454,7 @@ void winapp::MainPage::SearchInDirection(int dir, String^ textToFind)
this->ShowSearchResults(the_result);
this->m_search_active = false;
}
- }, ui);
+ }, task_continuation_context::use_current());
}
/* This is here to handle when we rotate or go into the snapview mode
diff --git a/winRT/winapp/MainPage.xaml.h b/winRT/winapp/MainPage.xaml.h
index 3678f4fc..4b187e25 100644
--- a/winRT/winapp/MainPage.xaml.h
+++ b/winRT/winapp/MainPage.xaml.h
@@ -112,6 +112,7 @@ namespace winapp
bool m_update_flip;
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);
task<int> RenderRange(int curr_page, int *height, int *width);
void CleanUp();
@@ -147,5 +148,6 @@ namespace winapp
void InitThumbnails();
void RenderThumbs();
void SetThumb(int page_num);
+ void ReleasePages(int old_page, int new_page);
};
}