summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2014-01-08 22:42:10 -0800
committerMichael Vrhel <michael.vrhel@artifex.com>2014-01-09 14:25:57 -0800
commitcd84c92e68a7a3131895c469294235159ffab4dd (patch)
treec2f3b00708a583e8b6666f2131aab026b7f108e5 /platform
parent5249664dd8178e985b4ef47af6e1772b4c7665e7 (diff)
downloadmupdf-cd84c92e68a7a3131895c469294235159ffab4dd.tar.xz
Add tiling into the DirectX printing code.
The tiling in x and y is needed to ensure that we can print at high resolutions with devices that have smaller bit map sizes (e.g. the surface). Banding only in the y dimension like we often do is not sufficient. Also fix an open with file association bug that must of occurred with the transition to 8.1 And update WinRT solution for recent changes in mupdf code. This includes the addition of a few new files and the document type registration.
Diffstat (limited to 'platform')
-rw-r--r--platform/winrt/libmupdf_winRT.vcxproj3
-rw-r--r--platform/winrt/libmupdf_winRT.vcxproj.filters9
-rw-r--r--platform/winrt/mupdf_cpp/App.xaml.cpp22
-rw-r--r--platform/winrt/mupdf_cpp/MainPage.xaml.cpp221
-rw-r--r--platform/winrt/mupdf_cpp/MainPage.xaml.h4
-rw-r--r--platform/winrt/mupdfwinrt/muctx.cpp34
-rw-r--r--platform/winrt/mupdfwinrt/muctx.h5
-rw-r--r--platform/winrt/mupdfwinrt/mudocument.cpp25
-rw-r--r--platform/winrt/mupdfwinrt/mudocument.h8
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);