diff options
Diffstat (limited to 'platform')
-rw-r--r-- | platform/winrt/libmupdf_winRT.vcxproj | 3 | ||||
-rw-r--r-- | platform/winrt/libmupdf_winRT.vcxproj.filters | 9 | ||||
-rw-r--r-- | platform/winrt/mupdf_cpp/App.xaml.cpp | 22 | ||||
-rw-r--r-- | platform/winrt/mupdf_cpp/MainPage.xaml.cpp | 221 | ||||
-rw-r--r-- | platform/winrt/mupdf_cpp/MainPage.xaml.h | 4 | ||||
-rw-r--r-- | platform/winrt/mupdfwinrt/muctx.cpp | 34 | ||||
-rw-r--r-- | platform/winrt/mupdfwinrt/muctx.h | 5 | ||||
-rw-r--r-- | platform/winrt/mupdfwinrt/mudocument.cpp | 25 | ||||
-rw-r--r-- | platform/winrt/mupdfwinrt/mudocument.h | 8 |
9 files changed, 239 insertions, 92 deletions
diff --git a/platform/winrt/libmupdf_winRT.vcxproj b/platform/winrt/libmupdf_winRT.vcxproj index 78fae974..dfb63142 100644 --- a/platform/winrt/libmupdf_winRT.vcxproj +++ b/platform/winrt/libmupdf_winRT.vcxproj @@ -51,6 +51,8 @@ <ClCompile Include="..\..\source\fitz\crypt-md5.c" /> <ClCompile Include="..\..\source\fitz\crypt-sha2.c" /> <ClCompile Include="..\..\source\fitz\device.c" /> + <ClCompile Include="..\..\source\fitz\document-all.c" /> + <ClCompile Include="..\..\source\fitz\document-no-run.c" /> <ClCompile Include="..\..\source\fitz\document.c" /> <ClCompile Include="..\..\source\fitz\draw-affine.c" /> <ClCompile Include="..\..\source\fitz\draw-blend.c" /> @@ -82,6 +84,7 @@ <ClCompile Include="..\..\source\fitz\list-device.c" /> <ClCompile Include="..\..\source\fitz\load-jpeg.c" /> <ClCompile Include="..\..\source\fitz\load-jpx.c" /> + <ClCompile Include="..\..\source\fitz\load-jxr.c" /> <ClCompile Include="..\..\source\fitz\load-png.c" /> <ClCompile Include="..\..\source\fitz\load-tiff.c" /> <ClCompile Include="..\..\source\fitz\memento.c" /> diff --git a/platform/winrt/libmupdf_winRT.vcxproj.filters b/platform/winrt/libmupdf_winRT.vcxproj.filters index fa87c591..be80fd15 100644 --- a/platform/winrt/libmupdf_winRT.vcxproj.filters +++ b/platform/winrt/libmupdf_winRT.vcxproj.filters @@ -381,6 +381,15 @@ <ClCompile Include="..\..\source\fitz\glyph.c"> <Filter>fitz</Filter> </ClCompile> + <ClCompile Include="..\..\source\fitz\document-all.c"> + <Filter>fitz</Filter> + </ClCompile> + <ClCompile Include="..\..\source\fitz\document-no-run.c"> + <Filter>!include\fitz</Filter> + </ClCompile> + <ClCompile Include="..\..\source\fitz\load-jxr.c"> + <Filter>fitz</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\source\fitz\ucdn.h"> diff --git a/platform/winrt/mupdf_cpp/App.xaml.cpp b/platform/winrt/mupdf_cpp/App.xaml.cpp index d0b9d8c7..4bb9614c 100644 --- a/platform/winrt/mupdf_cpp/App.xaml.cpp +++ b/platform/winrt/mupdf_cpp/App.xaml.cpp @@ -95,17 +95,23 @@ void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEvent } } -// Handle file activations. +/* Handle case where we do a association file opening and the app is already + running */ void App::OnFileActivated(Windows::ApplicationModel::Activation::FileActivatedEventArgs^ args) { - auto rootFrame = ref new Frame(); - TypeName pageType = { "mupdf_cpp.MainPage", TypeKind::Custom }; - rootFrame->Navigate(pageType, args); - Window::Current->Content = rootFrame; - auto rootPage = safe_cast<MainPage^>(rootFrame->Content); - rootPage->FileEvent = args; - rootPage->ProtocolEvent = nullptr; + auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content); + if (rootFrame->Content == nullptr) + { + if (!rootFrame->Navigate(TypeName(MainPage::typeid))) + { + throw ref new FailureException("Failed to create initial page"); + } + } + auto p = dynamic_cast<MainPage^>(rootFrame->Content); + p->FileEvent = args; + p->ProtocolEvent = nullptr; + p->FromFile(); Window::Current->Activate(); } diff --git a/platform/winrt/mupdf_cpp/MainPage.xaml.cpp b/platform/winrt/mupdf_cpp/MainPage.xaml.cpp index c3c8c576..fa717084 100644 --- a/platform/winrt/mupdf_cpp/MainPage.xaml.cpp +++ b/platform/winrt/mupdf_cpp/MainPage.xaml.cpp @@ -149,7 +149,8 @@ void MainPage::SetUpDirectX() m_d2d_factory->CreateDevice(dxgi_device.Get(), &m_d2d_device); } -/* Used during launch of application from file */ +/* Used during launch of application from file when application was not + already running */ void MainPage::Page_Loaded(Object^ sender, RoutedEventArgs^ e) { MainPage^ rootPage = dynamic_cast<MainPage^>(sender); @@ -166,6 +167,23 @@ void MainPage::Page_Loaded(Object^ sender, RoutedEventArgs^ e) } } +/* Used during launch of application from file when application was already + running */ +void MainPage::FromFile() +{ + if (this->FileEvent != nullptr) + { + /* Launched with an "open with", or as default app */ + if (this->FileEvent->Files->Size > 0) + { + IStorageItem ^file = this->FileEvent->Files->GetAt(0); + StorageFile ^sfile = safe_cast<StorageFile^>(file); + + OpenDocumentPrep(sfile); + } + } +} + /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> @@ -351,10 +369,10 @@ void MainPage::ReplaceImage(int page_num, InMemoryRandomAccessStream^ ras, } int MainPage::ComputePageSize(spatial_info_t spatial_info, int page_num, - Point *point) + Point *render_size, float *scale_factor) { Point screenSize; - Point pageSize; + Point renpageSize; Point size; try @@ -376,10 +394,12 @@ int MainPage::ComputePageSize(spatial_info_t spatial_info, int page_num, float hscale = screenSize.X / size.X; float vscale = screenSize.Y / size.Y; float scale = min(hscale, vscale); - pageSize.X = (float) (size.X * scale * spatial_info.scale_factor); - pageSize.Y = (float) (size.Y * scale * spatial_info.scale_factor); + renpageSize.X = (float)(size.X * scale * spatial_info.scale_factor); + renpageSize.Y = (float)(size.Y * scale * spatial_info.scale_factor); + + *scale_factor = (float) (scale * spatial_info.scale_factor); + *render_size = renpageSize; - *point = pageSize; return S_ISOK; } @@ -618,6 +638,7 @@ void MainPage::RenderThumbs() Point ras_size; Array<unsigned char>^ bmp_data; int code; + float scale_factor; /* The renderings run on a background thread */ assert(IsBackgroundThread()); @@ -625,10 +646,11 @@ void MainPage::RenderThumbs() for (int k = 0; k < num_pages; k++) { - if (ComputePageSize(spatial_info_local, k, &ras_size) == S_ISOK) + if (ComputePageSize(spatial_info_local, k, &ras_size, &scale_factor) == S_ISOK) { code = mu_doc->RenderPageBitmapSync(k, (int)ras_size.X, - (int)ras_size.Y, false, true, &bmp_data); + (int)ras_size.Y, scale_factor, false, true, false, { 0, 0 }, + { ras_size.X, ras_size.Y }, &bmp_data); DocumentPage^ doc_page = ref new DocumentPage(); doc_page->Height = (int)(ras_size.Y / SCALE_THUMB); @@ -809,9 +831,11 @@ void MainPage::InitialRender() if (m_num_pages > k ) { Point ras_size; - if (ComputePageSize(spatial_info, k, &ras_size) == S_ISOK) + float scale_factor; + + if (ComputePageSize(spatial_info, k, &ras_size, &scale_factor) == S_ISOK) { - auto render_task = create_task(mu_doc->RenderPageAsync(k, (int) ras_size.X, (int) ras_size.Y, true)); + auto render_task = create_task(mu_doc->RenderPageAsync(k, (int)ras_size.X, (int)ras_size.Y, true, scale_factor)); render_task.then([this, k, ras_size](InMemoryRandomAccessStream^ ras) { if (ras != nullptr) @@ -857,10 +881,11 @@ void MainPage::RenderRange(int curr_page) doc->PageZoom != m_doczoom) { Point ras_size; - if (ComputePageSize(spatial_info, k, &ras_size) == S_ISOK) + float scale_factor; + if (ComputePageSize(spatial_info, k, &ras_size, &scale_factor) == S_ISOK) { double zoom = m_doczoom; - auto render_task = create_task(mu_doc->RenderPageAsync(k, (int) ras_size.X, (int) ras_size.Y, true)); + auto render_task = create_task(mu_doc->RenderPageAsync(k, (int)ras_size.X, (int)ras_size.Y, true, scale_factor)); render_task.then([this, k, ras_size, zoom, curr_page](InMemoryRandomAccessStream^ ras) { if (ras != nullptr) @@ -1627,10 +1652,11 @@ void MainPage::ScrollChanged(Platform::Object^ sender, /* Render at new resolution. */ spatial_info_t spatial_info = InitSpatial(m_doczoom); Point ras_size; - if (ComputePageSize(spatial_info, page, &ras_size) == S_ISOK) + float scale_factor; + if (ComputePageSize(spatial_info, page, &ras_size, &scale_factor) == S_ISOK) { doc_page->PageZoom = m_doczoom; - auto render_task = create_task(mu_doc->RenderPageAsync(page, (int) ras_size.X, (int) ras_size.Y, true)); + auto render_task = create_task(mu_doc->RenderPageAsync(page, (int)ras_size.X, (int)ras_size.Y, true, scale_factor)); render_task.then([this, page, ras_size, scrollviewer](InMemoryRandomAccessStream^ ras) { if (ras != nullptr) @@ -2078,7 +2104,7 @@ void MainPage::DrawPreviewSurface(float width, float height, float scale_in, D2D1_BITMAP_PROPERTIES1 bitmap_properties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, - D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED)); + D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE)); // Create surface bitmap on which page content is drawn. ComPtr<ID2D1Bitmap1> d2d_surfacebitmap; @@ -2092,8 +2118,9 @@ void MainPage::DrawPreviewSurface(float width, float height, float scale_in, spatial_info.size.X = width; spatial_info.size.Y = height; Point ras_size; + float scale_factor; - if (ComputePageSize(spatial_info, ren_page_num, &ras_size) != S_ISOK) + if (ComputePageSize(spatial_info, ren_page_num, &ras_size, &scale_factor) != S_ISOK) return; ras_size.X = ceil(ras_size.X); @@ -2101,22 +2128,22 @@ void MainPage::DrawPreviewSurface(float width, float height, float scale_in, Array<unsigned char>^ bmp_data; int code = mu_doc->RenderPageBitmapSync(ren_page_num, (int) ras_size.X, - (int) ras_size.Y, true, false, - &bmp_data); + (int)ras_size.Y, scale_factor, true, false, false, { 0, 0 }, + { ras_size.X, ras_size.Y }, &bmp_data); if (bmp_data == nullptr) return; D2D1_SIZE_U bit_map_rect; bit_map_rect.width = (UINT32) (ras_size.X); bit_map_rect.height = (UINT32) (ras_size.Y); - D2D1_BITMAP_PROPERTIES1 bitmap_properties2 = + D2D1_BITMAP_PROPERTIES1 bitmap_prop = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_NONE, - D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED)); + D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE)); ID2D1Bitmap1 *bit_map; ThrowIfFailed(d2d_context->CreateBitmap(bit_map_rect, &(bmp_data[0]), (UINT32) (ras_size.X * 4), - &bitmap_properties2, &bit_map)); + &bitmap_prop, &bit_map)); D2D1_SIZE_F size = bit_map->GetSize(); /* Handle centering */ @@ -2141,12 +2168,19 @@ HRESULT MainPage::ClosePrintControl() return (m_d2d_printcontrol == nullptr) ? S_OK : m_d2d_printcontrol->Close(); } +/* To support high resolution printing, we tile renderings at the maxbitmap size + allowed with DirectX for this particular device. e.g the low end surface + will have a smaller maxbitmap size compared to a laptop or desktop. */ void MainPage::PrintPage(uint32 page_num, D2D1_RECT_F image_area, D2D1_SIZE_F page_area, float device_dpi, IStream* print_ticket) { int dpi = m_printresolution; int index_page_num = page_num - 1; int ren_page_num = index_page_num; + bool tile = false; + Point tile_count; + D2D1_SIZE_U bit_map_rect; + Array<unsigned char>^ bmp_data; if (index_page_num == 0) { @@ -2157,7 +2191,7 @@ void MainPage::PrintPage(uint32 page_num, D2D1_RECT_F image_area, D2D1_SIZE_F pa })); } - /* Windoze seems to hand me a bogus dpi */ + /* Windoze seems to hand me a bogus dpi. Need to follow up on this */ device_dpi = 96; if (m_ppage_num_list.size() > 0) @@ -2170,65 +2204,124 @@ void MainPage::PrintPage(uint32 page_num, D2D1_RECT_F image_area, D2D1_SIZE_F pa ComPtr<ID2D1DeviceContext> d2d_context; ThrowIfFailed(m_d2d_device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &d2d_context)); + + /* This should let us work in pixel dimensions but after much testing + it clearly has some issues. May investigate this further later. */ + //d2d_context->SetUnitMode(D2D1_UNIT_MODE_PIXELS); ComPtr<ID2D1CommandList> clist; ThrowIfFailed(d2d_context->CreateCommandList(&clist)); d2d_context->SetTarget(clist.Get()); - /* Figure out all the sizing. Width and height here are for device_dpi */ + /* Width and height here are at 96 dpi */ float width = image_area.right - image_area.left; float height = image_area.bottom - image_area.top; + /* MuPDF native resolution is 72dpi */ spatial_info_t spatial_info; spatial_info.scale_factor = 1.0; - /* width and height are based upon device dpi (96) and MuPDF native - resolution is 72dpi */ - spatial_info.size.X = (width /device_dpi) * (m_printresolution); + spatial_info.size.X = (width / device_dpi) * (m_printresolution); spatial_info.size.Y = (height /device_dpi) * (m_printresolution); Point ras_size; - if (ComputePageSize(spatial_info, ren_page_num, &ras_size) != S_ISOK) + float scale_factor; + + if (ComputePageSize(spatial_info, ren_page_num, &ras_size, &scale_factor) != S_ISOK) return; ras_size.X = ceil(ras_size.X); ras_size.Y = ceil(ras_size.Y); - Array<unsigned char>^ bmp_data; - int code = mu_doc->RenderPageBitmapSync(ren_page_num, (int) ras_size.X, - (int) ras_size.Y, true, false, - &bmp_data); - if (bmp_data == nullptr) - return; - D2D1_SIZE_U bit_map_rect; - bit_map_rect.width = (UINT32) (ras_size.X); - bit_map_rect.height = (UINT32) (ras_size.Y); - - D2D1_BITMAP_PROPERTIES1 bitmap_properties2 = - D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_NONE, - D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED)); - - ID2D1Bitmap1 *bit_map; - ThrowIfFailed(d2d_context->CreateBitmap(bit_map_rect, &(bmp_data[0]), - (UINT32)(ras_size.X * 4), &bitmap_properties2, &bit_map)); - D2D1_SIZE_F size = bit_map->GetSize(); + /* Determine if we need to do any tiling */ + int tile_size = d2d_context->GetMaximumBitmapSize(); + tile_count.Y = 1; + if (ras_size.X > tile_size) + { + tile = true; + tile_count.X = (float) ceil((float) ras_size.X / (float) tile_size); + bit_map_rect.width = (UINT32) (tile_size); + } + else + { + tile_count.X = 1; + bit_map_rect.width = (UINT32) (ras_size.X); + } + if (ras_size.Y > tile_size) + { + tile = true; + tile_count.Y = (float) ceil((float) ras_size.Y / (float) tile_size); + bit_map_rect.height = (UINT32) (tile_size); + } + else + { + tile_count.Y = 1; + bit_map_rect.height = (UINT32) (ras_size.Y); + } - /* Handle centering */ + /* Adjust for centering in media page */ float y_offset = 0; float x_offset = 0; - if (m_centerprint) + if (m_centerprint) { - /* Offsets need to be provided in the device dpi */ - y_offset = (float) ((page_area.height - (size.height * device_dpi / m_printresolution)) / 2.0); - x_offset = (float) ((page_area.width - (size.width * device_dpi / m_printresolution)) / 2.0); + y_offset = (float)round(((page_area.height - (ras_size.Y) * device_dpi / m_printresolution) / 2.0)); + x_offset = (float)round(((page_area.width - (ras_size.X) * device_dpi / m_printresolution) / 2.0)); } - float image_height = (bit_map_rect.height / m_printresolution) * device_dpi; - float image_width = (bit_map_rect.width / m_printresolution) * device_dpi; + D2D1_BITMAP_PROPERTIES1 bitmap_prop = + D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_NONE, + D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE), + (float) m_printresolution, (float) m_printresolution); + + ID2D1Bitmap1 *bit_map = NULL; + Point top_left, top_left_dip; + Point bottom_right, bottom_right_dip; + + /* Initialize X location */ + top_left.X = 0; + bottom_right.X = (float) bit_map_rect.width; d2d_context->BeginDraw(); - d2d_context->DrawBitmap(bit_map, D2D1::RectF(x_offset, y_offset, - image_width + x_offset, image_height + y_offset)); + /* Useful for debugging */ + //d2d_context->Clear(D2D1::ColorF(D2D1::ColorF::Coral)); + int total_tile = (int) (tile_count.X * tile_count.Y); + + for (int x = 0; x < tile_count.X; x++) + { + /* Reset Y location */ + top_left.Y = 0; + bottom_right.Y = (float) bit_map_rect.height; + + for (int y = 0; y < tile_count.Y; y++) + { + int code = mu_doc->RenderPageBitmapSync(ren_page_num, (int)bit_map_rect.width, + (int)bit_map_rect.height, scale_factor, true, false, tile, top_left, + bottom_right, &bmp_data); + if (bmp_data == nullptr || code != 0) + break; + + ThrowIfFailed(d2d_context->CreateBitmap(bit_map_rect, &(bmp_data[0]), + (UINT32)(bit_map_rect.width * 4), &bitmap_prop, &bit_map)); + + // This is where D2D1_UNIT_MODE_PIXELS fails to work. Essentially, + // DirectX ends up clipping based upon the origin still in DIPS + // instead of actual pixel positions. + top_left_dip.X = (float)((double) top_left.X * (double)device_dpi / (double)m_printresolution + x_offset - 0.5); + top_left_dip.Y = (float)((double)top_left.Y * (double)device_dpi / (double)m_printresolution + y_offset - 0.5); + bottom_right_dip.X = (float)((double)bottom_right.X * (double)device_dpi / (double)m_printresolution + x_offset + 0.5); + bottom_right_dip.Y = (float)((double)bottom_right.Y * (double)device_dpi / (double)m_printresolution + y_offset + 0.5); + d2d_context->DrawBitmap(bit_map, D2D1::RectF(top_left_dip.X, top_left_dip.Y, + bottom_right_dip.X, bottom_right_dip.Y)); + bit_map->Release(); + + /* Increment Y location */ + top_left.Y += (float) bit_map_rect.height; + bottom_right.Y += (float) bit_map_rect.height; + PrintProgressTile(total_tile); + } + /* Increment X location */ + top_left.X += (float) bit_map_rect.width; + bottom_right.X += (float) bit_map_rect.width; + } ThrowIfFailed(d2d_context->EndDraw()); ThrowIfFailed(clist->Close()); ThrowIfFailed(m_d2d_printcontrol->AddPage(clist.Get(), page_area, print_ticket)); - bit_map->Release(); } void MainPage::RefreshPreview() @@ -2260,6 +2353,23 @@ void MainPage::PrintProgress(PrintTask^ sender, PrintTaskProgressingEventArgs^ a })); } +void MainPage::PrintProgressTile(int total_tiles) +{ + assert(IsBackgroundThread()); + double step_size = 100.0 / ((double)GetPrintPageCount() * (double)total_tiles); + /* Update the progress bar if it is still active. The tiling of each + page can be slow on the surface if the resolution is high, hence + the need for this feedback */ + this->Dispatcher->RunAsync(CoreDispatcherPriority::Low, + ref new DispatchedHandler([this, step_size]() + { + if (this->xaml_PrintStack->Visibility != Windows::UI::Xaml::Visibility::Collapsed) + { + xaml_PrintProgress->Value += step_size; + } + })); +} + void MainPage::PrintCompleted(PrintTask^ sender, PrintTaskCompletedEventArgs^ args) { assert(IsBackgroundThread()); @@ -2268,6 +2378,7 @@ void MainPage::PrintCompleted(PrintTask^ sender, PrintTaskCompletedEventArgs^ ar ref new DispatchedHandler([this]() { xaml_PrintStack->Visibility = Windows::UI::Xaml::Visibility::Collapsed; + xaml_PrintProgress->Value = 0; })); } diff --git a/platform/winrt/mupdf_cpp/MainPage.xaml.h b/platform/winrt/mupdf_cpp/MainPage.xaml.h index c7b5e88b..1cf8dd97 100644 --- a/platform/winrt/mupdf_cpp/MainPage.xaml.h +++ b/platform/winrt/mupdf_cpp/MainPage.xaml.h @@ -152,6 +152,7 @@ namespace mupdf_cpp void set(Windows::ApplicationModel::Activation::FileActivatedEventArgs^ value) { _fileEventArgs = value; } } void NotifyUser(String^ strMessage, int type); + void FromFile(); /* For association cases when we are already running */ protected: virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override; @@ -264,7 +265,7 @@ namespace mupdf_cpp void UpdateAppBarButtonViewState(); void ExitInvokedHandler(Windows::UI::Popups::IUICommand^ command); void OKInvokedHandler(Windows::UI::Popups::IUICommand^ command); - int ComputePageSize(spatial_info_t spatial_info, int page_num, Point *Point); + int ComputePageSize(spatial_info_t spatial_info, int page_num, Point *ren_size, float *scale_factor); void ScrollChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::ScrollViewerViewChangedEventArgs^ e); void LinkTapped(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e); void SearchProgress(IAsyncOperationWithProgress<int, double>^ operation, double status); @@ -309,6 +310,7 @@ namespace mupdf_cpp int GetPrintPageCount(); void SetPrintTarget(void *print_struct); void PrintProgress(PrintTask^ sender, PrintTaskProgressingEventArgs^ args); + void PrintProgressTile(int total_tiles); void PrintCompleted(PrintTask^ sender, PrintTaskCompletedEventArgs^ args); private: void Testing(Platform::Object^ sender, Windows::UI::Xaml::Input::ManipulationCompletedRoutedEventArgs^ e); diff --git a/platform/winrt/mupdfwinrt/muctx.cpp b/platform/winrt/mupdfwinrt/muctx.cpp index 2c40a85d..4e8a4ad2 100644 --- a/platform/winrt/mupdfwinrt/muctx.cpp +++ b/platform/winrt/mupdfwinrt/muctx.cpp @@ -127,6 +127,7 @@ status_t muctx::InitializeContext() } else { + fz_register_document_handlers(this->mu_ctx); return S_ISOK; } } @@ -159,7 +160,7 @@ muctx::~muctx(void) status_t muctx::InitializeStream(IRandomAccessStream^ readStream, char *ext) { win_stream.stream = readStream; - fz_stream *mu_stream = fz_new_stream(mu_ctx, 0, win_read_file, win_close_file); + fz_stream *mu_stream = fz_new_stream(mu_ctx, 0, win_read_file, win_close_file, NULL); mu_stream->seek = win_seek_file; mu_stream->state = reinterpret_cast <void*> (&win_stream); @@ -442,9 +443,10 @@ fz_display_list * muctx::CreateDisplayList(int page_num, int *width, int *height } /* Render display list bmp_data buffer. No lock needed for this operation */ -status_t muctx::RenderPageMT(void *dlist, int page_width, int page_height, +status_t muctx::RenderPageMT(void *dlist, int page_width, int page_height, unsigned char *bmp_data, int bmp_width, int bmp_height, - bool flipy) + float scale, bool flipy, bool tile, Point top_left, + Point bottom_right) { fz_device *dev = NULL; fz_pixmap *pix = NULL; @@ -460,16 +462,22 @@ status_t muctx::RenderPageMT(void *dlist, int page_width, int page_height, fz_try(ctx_clone) { - /* Figure out scale factors so that we get the desired size */ - pctm = fz_scale(pctm, (float) bmp_width / page_width, (float) bmp_height / page_height); - /* Flip on Y */ + pctm = fz_scale(pctm, scale, scale); + /* Flip on Y. */ if (flipy) { - ctm.f = bmp_height; + ctm.f = (float) page_height * ctm.d; ctm.d = -ctm.d; + ctm.f += top_left.Y; } - pix = fz_new_pixmap_with_data(ctx_clone, fz_device_bgr(ctx_clone), bmp_width, - bmp_height, bmp_data); + else + { + ctm.f -= top_left.Y; + } + ctm.e -= top_left.X; + + pix = fz_new_pixmap_with_data(ctx_clone, fz_device_bgr(ctx_clone), + bmp_width, bmp_height, bmp_data); fz_clear_pixmap_with_value(ctx_clone, pix, 255); dev = fz_new_draw_device(ctx_clone, pix); fz_run_display_list(display_list, dev, pctm, NULL, NULL); @@ -485,14 +493,13 @@ status_t muctx::RenderPageMT(void *dlist, int page_width, int page_height, fz_free_context(ctx_clone); return E_FAILURE; } - fz_free_context(ctx_clone); return S_ISOK; } /* Render page_num to size width by height into bmp_data buffer. Lock needed. */ status_t muctx::RenderPage(int page_num, unsigned char *bmp_data, int bmp_width, - int bmp_height, bool flipy) + int bmp_height, float scale, bool flipy) { fz_device *dev = NULL; fz_pixmap *pix = NULL; @@ -508,10 +515,7 @@ status_t muctx::RenderPage(int page_num, unsigned char *bmp_data, int bmp_width, { page = fz_load_page(mu_doc, page_num); page_size = MeasurePage(page); - - /* Figure out scale factors so that we get the desired size */ - pctm = fz_scale(pctm, (float) bmp_width / page_size.X, - (float) bmp_height / page_size.Y); + pctm = fz_scale(pctm, scale, scale); /* Flip on Y */ if (flipy) { diff --git a/platform/winrt/mupdfwinrt/muctx.h b/platform/winrt/mupdfwinrt/muctx.h index 5c452155..80d165ed 100644 --- a/platform/winrt/mupdfwinrt/muctx.h +++ b/platform/winrt/mupdfwinrt/muctx.h @@ -86,10 +86,11 @@ public: int GetPageCount(); status_t InitializeContext(); status_t RenderPage(int page_num, unsigned char *bmp_data, int bmp_width, - int bmp_height, bool flipy); + int bmp_height, float scale, bool flipy); status_t RenderPageMT(void *dlist, int page_width, int page_height, unsigned char *bmp_data, int bmp_width, int bmp_height, - bool flipy); + float scale, bool flipy, bool tile, Point top_left, + Point bottom_right); fz_display_list* CreateDisplayList(int page_num, int *width, int *height); int MeasurePage(int page_num, Point *size); Point MeasurePage(fz_page *page); diff --git a/platform/winrt/mupdfwinrt/mudocument.cpp b/platform/winrt/mupdfwinrt/mudocument.cpp index 48093780..b37b45aa 100644 --- a/platform/winrt/mupdfwinrt/mudocument.cpp +++ b/platform/winrt/mupdfwinrt/mudocument.cpp @@ -173,7 +173,9 @@ Windows::Foundation::IAsyncOperationWithProgress<int, double>^ 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, bool flipy, Array<unsigned char>^* bit_map) + float scale, bool use_dlist, bool flipy, bool tile, + Point top_left, Point bottom_right, + Array<unsigned char>^* bit_map) { status_t code; /* Allocate space for bmp */ @@ -206,14 +208,20 @@ int mudocument::RenderPageBitmapSync(int page_num, int bmp_width, int bmp_height } code = mu_object.RenderPageMT(dlist, page_width, page_height, &(bmp_data[0]), bmp_width, bmp_height, - flipy); + scale, flipy, tile, top_left, bottom_right); } else { + /* Not dealing with the case of tiling and no display list at this time. */ + if (tile) + { + *bit_map = nullptr; + return E_FAILURE; + } /* Rendering in immediate mode. Keep lock in place */ mutex_lock.lock(); code = mu_object.RenderPage(page_num, &(bmp_data[0]), bmp_width, - bmp_height, flipy); + bmp_height, scale, flipy); mutex_lock.unlock(); } if (code != S_ISOK) @@ -229,9 +237,9 @@ int mudocument::RenderPageBitmapSync(int page_num, int bmp_width, int bmp_height /* Pack the page into a bmp stream */ Windows::Foundation::IAsyncOperation<InMemoryRandomAccessStream^>^ mudocument::RenderPageAsync(int page_num, int bmp_width, int bmp_height, - bool use_dlist) + bool use_dlist, float scale) { - return create_async([this, bmp_width, bmp_height, page_num, use_dlist] + return create_async([this, bmp_width, bmp_height, page_num, use_dlist, scale] (cancellation_token ct) -> InMemoryRandomAccessStream^ { /* Allocate space for bmp */ @@ -270,14 +278,15 @@ Windows::Foundation::IAsyncOperation<InMemoryRandomAccessStream^>^ /* 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); + scale, true, false, { 0.0, 0.0 }, + { (float) bmp_width, (float) bmp_height }); } 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, true); + bmp_height, scale, true); mutex_lock.unlock(); } if (code != S_ISOK) diff --git a/platform/winrt/mupdfwinrt/mudocument.h b/platform/winrt/mupdfwinrt/mudocument.h index 3e0b9fcf..9ab37ed7 100644 --- a/platform/winrt/mupdfwinrt/mudocument.h +++ b/platform/winrt/mupdfwinrt/mudocument.h @@ -33,9 +33,11 @@ namespace mupdfwinrt int GetNumPages(void); Point GetPageSize(int page_num); Windows::Foundation::IAsyncOperation<InMemoryRandomAccessStream^>^ - RenderPageAsync(int page_num, int width, int height, bool use_dlist); - int RenderPageBitmapSync(int page_num, int bmp_width, int bmp_height, - bool use_dlist, bool flipy, Array<unsigned char>^* bit_map); + RenderPageAsync(int page_num, int width, int height, + bool use_dlist, float scale); + int RenderPageBitmapSync(int page_num, int bmp_width, int bmp_height, + float scale, bool use_dlist, bool flipy, bool tiling, Point top_left, + Point bottom_right, Array<unsigned char>^* bit_map); Windows::Foundation::IAsyncOperationWithProgress<int, double>^ SearchDocumentWithProgressAsync(String^ textToFind, int dir, int start_page, int num_pages); |