summaryrefslogtreecommitdiff
path: root/platform/winrt
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2014-03-20 11:54:03 -0700
committerMichael Vrhel <michael.vrhel@artifex.com>2014-09-09 16:39:33 -0700
commit67a1b4e6cf4b45059b32de420892bf9d90c01042 (patch)
treecf283df06579b6299d53a027e77adb9cbbe65033 /platform/winrt
parent7e24e989fbc54d16a8ca3171f1795b158c888aca (diff)
downloadmupdf-67a1b4e6cf4b45059b32de420892bf9d90c01042.tar.xz
Initial work toward getting link navigation in place for gsview.
Also several fixes to the navigation of pages and managing thumbnail replacement of pages that are out of view.
Diffstat (limited to 'platform/winrt')
-rw-r--r--platform/winrt/gsview/DocPage.cs1
-rw-r--r--platform/winrt/gsview/MainWindow.xaml4
-rw-r--r--platform/winrt/gsview/MainWindow.xaml.cs309
-rw-r--r--platform/winrt/gsview/RectList.cs10
-rw-r--r--platform/winrt/gsview/mudocument.cs60
-rw-r--r--platform/winrt/libmupdf_winRT.vcxproj1
-rw-r--r--platform/winrt/libmupdf_winRT.vcxproj.filters3
-rw-r--r--platform/winrt/mupdfnet/mupdfnet.cpp47
-rw-r--r--platform/winrt/mupdfnet/mupdfnet.h6
9 files changed, 365 insertions, 76 deletions
diff --git a/platform/winrt/gsview/DocPage.cs b/platform/winrt/gsview/DocPage.cs
index 1cf55112..3e4943b0 100644
--- a/platform/winrt/gsview/DocPage.cs
+++ b/platform/winrt/gsview/DocPage.cs
@@ -89,6 +89,7 @@ namespace gsview
PropertyChanged(this, new PropertyChangedEventArgs("Height"));
PropertyChanged(this, new PropertyChangedEventArgs("Width"));
PropertyChanged(this, new PropertyChangedEventArgs("TextBox"));
+ PropertyChanged(this, new PropertyChangedEventArgs("LinkBox"));
}
}
diff --git a/platform/winrt/gsview/MainWindow.xaml b/platform/winrt/gsview/MainWindow.xaml
index 959e4eb0..55424d1a 100644
--- a/platform/winrt/gsview/MainWindow.xaml
+++ b/platform/winrt/gsview/MainWindow.xaml
@@ -49,7 +49,7 @@
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
- <Rectangle Tag="{Binding Path=Index}" Width="{Binding Path=Width}" Height="{Binding Path=Height}" Fill="{Binding Path=Color}">
+ <Rectangle Tag="{Binding Path=Index}" Width="{Binding Path=Width}" Height="{Binding Path=Height}" Fill="{Binding Path=Color}" IsEnabled="True" MouseDown="LinkClick">
<Rectangle.RenderTransform>
<TranslateTransform X="{Binding Path=X}" Y="{Binding Path=Y}"/>
</Rectangle.RenderTransform>
@@ -557,7 +557,7 @@
ScrollViewer.CanContentScroll="False"
Background="DarkGray" ScrollViewer.PanningMode="Both"
ScrollViewer.ScrollChanged="ListViewScrollChanged"
- PreviewMouseLeftButtonUp="PageSelected" MouseDoubleClick="PageDoubleClick"
+ MouseDoubleClick="PageDoubleClick"
>
<!-- This keeps the pages in the center of the panel -->
<ListView.ItemContainerStyle>
diff --git a/platform/winrt/gsview/MainWindow.xaml.cs b/platform/winrt/gsview/MainWindow.xaml.cs
index 0e31df8e..9fe3a2a4 100644
--- a/platform/winrt/gsview/MainWindow.xaml.cs
+++ b/platform/winrt/gsview/MainWindow.xaml.cs
@@ -171,10 +171,9 @@ namespace gsview
mudocument mu_doc;
public Pages m_docPages;
List<DocPage> m_thumbnails;
- List<List<RectList>> m_page_link_list;
+ List<List<RectList>> m_page_link_list = null;
int m_contents_size;
int m_content_item;
- List<bool> m_linkset;
List<RectList> m_text_list = null;
private int m_rectlist_page;
private List<ContentEntry> m_content_list;
@@ -185,7 +184,6 @@ namespace gsview
private bool m_init_done;
private bool m_links_on;
private int m_search_rect_count;
- private bool m_page_update;
String m_textcolor = "#402572AC";
String m_linkcolor = "#40AC7225";
RenderingStatus_t m_ren_status;
@@ -205,6 +203,7 @@ namespace gsview
bool m_zoomhandled;
BackgroundWorker m_thumbworker = null;
BackgroundWorker m_textsearch = null;
+ BackgroundWorker m_linksearch = null;
String m_document_type;
Info m_infowindow;
OutputIntent m_outputintents;
@@ -212,6 +211,7 @@ namespace gsview
private Point startPoint;
private Rectangle rect;
String m_prevsearch = null;
+ int m_numpagesvisible;
public MainWindow()
{
@@ -225,8 +225,6 @@ namespace gsview
{
m_docPages = new Pages();
m_thumbnails = new List<DocPage>();
- m_page_link_list = new List<List<RectList>>();
- m_linkset = new List<bool>();
m_ghostscript = new ghostsharp();
m_ghostscript.gsUpdateMain += new ghostsharp.gsCallBackMain(gsProgress);
m_gsoutput = new gsOutput();
@@ -284,15 +282,15 @@ namespace gsview
if (m_thumbnails != null && m_thumbnails.Count > 0)
m_thumbnails.Clear();
if (m_page_link_list != null && m_page_link_list.Count > 0)
+ {
m_page_link_list.Clear();
+ m_page_link_list = null;
+ }
if (m_text_list != null && m_text_list.Count > 0)
{
m_text_list.Clear();
m_text_list = null;
}
- if (m_linkset != null && m_linkset.Count > 0)
- m_linkset.Clear();
-
if (mu_doc != null)
mu_doc.CleanUp();
try
@@ -328,6 +326,7 @@ namespace gsview
m_currpage = 0;
m_document_type = DocumentTypes.UNKNOWN;
EnabletoPDF();
+ m_numpagesvisible = 3;
return result;
}
@@ -642,11 +641,6 @@ namespace gsview
m_docPages.Add(InitDocPage());
m_docPages[k].PageNum = k;
m_thumbnails.Add(InitDocPage());
- /* Create empty lists for our links and specify that they have
- not been computed for these pages */
- List<RectList> temp_link = new List<RectList>();
- m_page_link_list.Add(temp_link);
- m_linkset.Add(false);
}
/* Do the first few full res pages */
@@ -688,17 +682,13 @@ namespace gsview
private void OnBackPageClick(object sender, RoutedEventArgs e)
{
if (m_currpage == 0 || !m_init_done) return;
-
- m_currpage = m_currpage - 1;
- xaml_PageList.ScrollIntoView(m_docPages[m_currpage]);
+ RenderRange(m_currpage - 1, true);
}
private void OnForwardPageClick(object sender, RoutedEventArgs e)
{
if (m_currpage == m_num_pages - 1 || !m_init_done) return;
-
- m_currpage = m_currpage + 1;
- xaml_PageList.ScrollIntoView(m_docPages[m_currpage]);
+ RenderRange(m_currpage + 1, true);
}
private void CancelLoadClick(object sender, RoutedEventArgs e)
@@ -753,8 +743,7 @@ namespace gsview
{
if (item.PageNum < 0)
return;
- m_currpage = item.PageNum;
- xaml_PageList.ScrollIntoView(m_docPages[item.PageNum]);
+ RenderRange(item.PageNum, true);
}
}
@@ -763,8 +752,9 @@ namespace gsview
var item = ((FrameworkElement)e.OriginalSource).DataContext as ContentItem;
if (item != null && item.Page < m_num_pages)
{
- m_currpage = m_docPages[item.Page].PageNum;
- xaml_PageList.ScrollIntoView(m_docPages[item.Page]);
+ int page = m_docPages[item.Page].PageNum;
+ if (page >= 0 && page < m_num_pages)
+ RenderRange(page, true);
}
}
@@ -781,7 +771,6 @@ namespace gsview
if (found != null)
{
var Item = (DocPage)found;
- m_currpage = Item.PageNum;
RenderRange(Item.PageNum, false);
}
return;
@@ -790,11 +779,11 @@ namespace gsview
}
/* Render +/- the look ahead from where we are if blank page is present */
- async private void RenderRange(int curr_page, bool scrollto)
+ async private void RenderRange(int new_page, bool scrollto)
{
- int range = Constants.LOOK_AHEAD;
+ int range = (int) Math.Ceiling(((double) m_numpagesvisible - 1.0) / 2.0);
- for (int k = curr_page - range; k <= curr_page + range; k++)
+ for (int k = new_page - range; k <= new_page + range; k++)
{
if (k >= 0 && k < m_num_pages)
{
@@ -822,9 +811,19 @@ namespace gsview
{
if (m_docPages[k].TextBox != null)
ScaleTextBox(k);
+ if (m_links_on && m_page_link_list != null)
+ {
+ m_docPages[k].LinkBox = m_page_link_list[k];
+ if (m_docPages[k].LinkBox != null)
+ ScaleLinkBox(k);
+ }
+ else
+ {
+ m_docPages[k].LinkBox = null;
+ }
UpdatePage(k, bitmap, ras_size, Page_Content_t.FULL_RESOLUTION, m_doczoom);
m_docPages[k].PageRefresh();
- if (k == curr_page && scrollto)
+ if (k == new_page && scrollto)
xaml_PageList.ScrollIntoView(m_docPages[k]);
}
}, TaskScheduler.FromCurrentSynchronizationContext());
@@ -836,8 +835,18 @@ namespace gsview
}
}
}
+ else
+ {
+ /* We did not have to render the page but we may need to
+ * scroll to it */
+ if (k == new_page && scrollto)
+ xaml_PageList.ScrollIntoView(m_docPages[k]);
+ }
}
}
+ /* Release old range and set new page */
+ ReleasePages(m_currpage, new_page, range);
+ m_currpage = new_page;
}
private bool Visible(FrameworkElement elem, FrameworkElement cont)
@@ -850,14 +859,14 @@ namespace gsview
return rect.Contains(bounds2.TopLeft) || rect.Contains(bounds2.BottomRight);
}
- private void ReleasePages(int old_page, int new_page)
+ private void ReleasePages(int old_page, int new_page, int range)
{
if (old_page == new_page) return;
/* To keep from having memory issue reset the page back to
the thumb if we are done rendering the thumbnails */
- for (int k = old_page - Constants.LOOK_AHEAD; k <= old_page + Constants.LOOK_AHEAD; k++)
+ for (int k = old_page - range; k <= old_page + range; k++)
{
- if (k < new_page - Constants.LOOK_AHEAD || k > new_page + Constants.LOOK_AHEAD)
+ if (k < new_page - range || k > new_page + range)
{
if (k >= 0 && k < m_num_pages)
{
@@ -867,29 +876,29 @@ namespace gsview
}
}
- /* Return this page from a full res image to the thumb image or only set
- to thumb if it has not already been set */
+ /* Return this page from a full res image to the thumb image */
private void SetThumb(int page_num)
{
/* See what is there now */
- var doc = m_docPages[page_num];
- if (doc.Content == Page_Content_t.THUMBNAIL && doc.Zoom == m_doczoom) return;
+ var doc_page = m_docPages[page_num];
+ if (doc_page.Content == Page_Content_t.THUMBNAIL &&
+ doc_page.Zoom == m_doczoom) return;
if (m_thumbnails.Count > page_num)
{
- m_page_update = true;
- var thumb_page = m_thumbnails[page_num];
- thumb_page.Height = (int)(thumb_page.NativeHeight * m_doczoom);
- thumb_page.Width = (int)(thumb_page.NativeWidth * m_doczoom);
- thumb_page.Zoom = 1.0;
- m_docPages[page_num] = thumb_page;
- m_page_update = false;
- }
- }
-
- private void LinksToggle(object sender, RoutedEventArgs e)
- {
+ doc_page.Content = Page_Content_t.THUMBNAIL;
+ doc_page.Zoom = m_doczoom;
+ doc_page.BitMap = m_thumbnails[page_num].BitMap;
+ doc_page.Width = (int)(m_doczoom * doc_page.BitMap.PixelWidth / Constants.SCALE_THUMB);
+ doc_page.Height = (int)(m_doczoom * doc_page.BitMap.PixelHeight / Constants.SCALE_THUMB);
+ doc_page.PageNum = page_num;
+ doc_page.LinkBox = null;
+ doc_page.TextBox = null;
+ /* No need to refresh unless it just occurs during other stuff
+ * we just want to make sure we can release the bitmaps */
+ //doc_page.PageRefresh();
+ }
}
private void ZoomOut(object sender, RoutedEventArgs e)
@@ -898,6 +907,7 @@ namespace gsview
if (m_doczoom < Constants.ZOOM_MIN)
m_doczoom = Constants.ZOOM_MIN;
xaml_ZoomSlider.Value = m_doczoom * 100.0;
+ m_numpagesvisible = (int)(Math.Ceiling((1.0 / m_doczoom) + 2));
RenderRange(m_currpage, false);
}
@@ -907,6 +917,7 @@ namespace gsview
if (m_doczoom > Constants.ZOOM_MAX)
m_doczoom = Constants.ZOOM_MAX;
xaml_ZoomSlider.Value = m_doczoom * 100.0;
+ m_numpagesvisible = (int) (Math.Ceiling((1.0 / m_doczoom) + 2));
RenderRange(m_currpage, false);
}
@@ -1191,18 +1202,6 @@ namespace gsview
xaml_FooterControl.Visibility = System.Windows.Visibility.Collapsed;
}
- private void PageSelected(object sender, MouseButtonEventArgs e)
- {
- var item = ((FrameworkElement)e.OriginalSource).DataContext as DocPage;
- if (item != null)
- {
- if (item.PageNum < 0)
- return;
- m_currpage = item.PageNum;
- xaml_PageList.ScrollIntoView(m_docPages[item.PageNum]);
- }
- }
-
private void ZoomReleased(object sender, MouseButtonEventArgs e)
{
if (m_init_done)
@@ -1220,10 +1219,7 @@ namespace gsview
m_doczoom = 1.0;
var item = ((FrameworkElement)e.OriginalSource).DataContext as DocPage;
if (item != null)
- {
- m_currpage = item.PageNum;
- RenderRange(m_currpage, true);
- }
+ RenderRange(item.PageNum, true);
}
}
@@ -1660,6 +1656,7 @@ namespace gsview
m_outputintents.Show();
}
+#region Search Code
/* Search related code */
private void Search(object sender, RoutedEventArgs e)
{
@@ -1672,6 +1669,7 @@ namespace gsview
else
{
xaml_SearchControl.Visibility = System.Windows.Visibility.Collapsed;
+ xaml_SearchProgress.Visibility = System.Windows.Visibility.Collapsed;
ClearTextSearch();
}
}
@@ -1729,6 +1727,8 @@ namespace gsview
var rect = new Rect(top_left, size);
results.rectangles.Add(rect);
}
+ /* Reset global smart pointer once we have everything */
+ mu_doc.ReleaseTextSearch();
worker.ReportProgress(percent, results);
break;
}
@@ -1862,13 +1862,12 @@ namespace gsview
in_text_search = 1;
m_textsearch = null;
}
-
if (m_prevsearch != null && needle != m_prevsearch)
{
in_text_search = 0;
ClearTextSearch();
}
-
+
if (m_textsearch == null)
{
m_prevsearch = needle;
@@ -1892,5 +1891,185 @@ namespace gsview
ShowMessage(NotifyType_t.MESS_ERROR, "Out of memory: " + e.Message);
}
}
+#endregion Search Code
+
+#region Link Code
+ private void LinksToggle(object sender, RoutedEventArgs e)
+ {
+ if (!m_init_done)
+ return;
+
+ m_links_on = !m_links_on;
+
+ if (m_page_link_list == null)
+ {
+ if (m_linksearch != null && m_linksearch.IsBusy)
+ return;
+
+ m_page_link_list = new List<List<RectList>>();
+ m_linksearch = new BackgroundWorker();
+ m_linksearch.WorkerReportsProgress = false;
+ m_linksearch.WorkerSupportsCancellation = true;
+ m_linksearch.DoWork += new DoWorkEventHandler(LinkWork);
+ m_linksearch.RunWorkerCompleted += new RunWorkerCompletedEventHandler(LinkCompleted);
+ m_linksearch.RunWorkerAsync();
+ }
+ else
+ {
+ if (m_links_on)
+ LinksOn();
+ else
+ LinksOff();
+ }
+ }
+
+ private void LinkWork(object sender, DoWorkEventArgs e)
+ {
+ BackgroundWorker worker = sender as BackgroundWorker;
+
+ for (int k = 0; k < m_num_pages; k++)
+ {
+ int box_count = mu_doc.GetLinksPage(k);
+ List<RectList> links = new List<RectList>();
+ if (box_count > 0)
+ {
+ var rectlist = new RectList();
+ for (int j = 0; j < box_count; j++)
+ {
+ Point top_left;
+ Size size;
+ String uri;
+ int type;
+ int topage;
+
+ mu_doc.GetLinkItem(j, out top_left, out size, out uri,
+ out topage, out type);
+ rectlist.Height = size.Height * m_doczoom;
+ rectlist.Width = size.Width * m_doczoom;
+ rectlist.X = top_left.X * m_doczoom;
+ rectlist.Y = top_left.Y * m_doczoom;
+ rectlist.Color = m_linkcolor;
+ rectlist.Index = k.ToString() + "." + j.ToString();
+ rectlist.PageNum = topage;
+ rectlist.Scale = m_doczoom;
+ if (uri != null)
+ rectlist.Urilink = new Uri(uri);
+ rectlist.Type = (Link_t) type;
+ links.Add(rectlist);
+ }
+ }
+ mu_doc.ReleaseLink();
+ m_page_link_list.Add(links);
+
+ if (worker.CancellationPending == true)
+ {
+ e.Cancel = true;
+ break;
+ }
+ }
+ }
+
+ private void LinkCompleted(object sender, RunWorkerCompletedEventArgs e)
+ {
+ LinksOn();
+ }
+
+ private void ScaleLinkBox(int pagenum)
+ {
+ var temp = m_docPages[pagenum].LinkBox;
+ for (int kk = 0; kk < temp.Count; kk++)
+ {
+ var rect_item = temp[kk];
+ double factor = m_doczoom / temp[kk].Scale;
+
+ temp[kk].Height = temp[kk].Height * factor;
+ temp[kk].Width = temp[kk].Width * factor;
+ temp[kk].X = temp[kk].X * factor;
+ temp[kk].Y = temp[kk].Y * factor;
+
+ temp[kk].Scale = m_doczoom;
+ temp[kk].PageRefresh();
+ }
+ m_docPages[pagenum].LinkBox = temp;
+ }
+
+ /* Only visible pages */
+ private void LinksOff()
+ {
+ int range = (int)Math.Ceiling(((double)m_numpagesvisible - 1.0) / 2.0);
+
+ for (int kk = m_currpage - range; kk <= m_currpage + range; kk++)
+ {
+ var temp = m_docPages[kk].LinkBox;
+ if (temp != null)
+ {
+ m_docPages[kk].LinkBox = null;
+ m_docPages[kk].PageRefresh();
+ }
+ }
+ }
+
+ /* Only visible pages */
+ private void LinksOn()
+ {
+ int range = (int)Math.Ceiling(((double)m_numpagesvisible - 1.0) / 2.0);
+
+ for (int kk = m_currpage - range; kk <= m_currpage + range; kk++)
+ {
+ var temp = m_docPages[kk].LinkBox;
+ if (temp == null)
+ {
+ m_docPages[kk].LinkBox = m_page_link_list[kk];
+ m_docPages[kk].PageRefresh();
+ }
+ }
+ }
+
+ private void LinkClick(object sender, MouseButtonEventArgs e)
+ {
+ var item = (Rectangle)sender;
+
+ if (item == null)
+ return;
+
+ String tag = (String)item.Tag;
+ int page = 0;
+ int index = 0;
+
+ if (tag == null || tag.Length < 3 || !(tag.Contains('.')))
+ return;
+
+ String[] parts = tag.Split('.');
+ try
+ {
+ page = System.Convert.ToInt32(parts[0]);
+ index = System.Convert.ToInt32(parts[1]);
+
+ }
+ catch (FormatException e1)
+ {
+ Console.WriteLine("String is not a sequence of digits.");
+ }
+ catch (OverflowException e2)
+ {
+ Console.WriteLine("The number cannot fit in an Int32.");
+ }
+
+ if (index >= 0 && index < m_num_pages && page >= 0 && page < m_num_pages)
+ {
+ var link_list = m_page_link_list[page];
+ var link = link_list[index];
+
+ if (link.Type == Link_t.LINK_GOTO)
+ {
+ if (m_currpage != link.PageNum && link.PageNum >= 0 &&
+ link.PageNum < m_num_pages)
+ RenderRange(link.PageNum, true);
+ }
+ else if (link.Type == Link_t.LINK_URI)
+ System.Diagnostics.Process.Start(link.Urilink.AbsoluteUri);
+ }
+ }
+#endregion Link Code
}
} \ No newline at end of file
diff --git a/platform/winrt/gsview/RectList.cs b/platform/winrt/gsview/RectList.cs
index 0cdba66d..880f1a37 100644
--- a/platform/winrt/gsview/RectList.cs
+++ b/platform/winrt/gsview/RectList.cs
@@ -7,6 +7,14 @@ using System.ComponentModel;
namespace gsview
{
+ public enum Link_t
+ {
+ LINK_GOTO,
+ LINK_URI,
+ TEXTBOX,
+ NOT_SET
+ };
+
public class RectList : INotifyPropertyChanged
{
public String Index
@@ -51,7 +59,7 @@ namespace gsview
set;
}
- public int Type
+ public Link_t Type
{
get;
set;
diff --git a/platform/winrt/gsview/mudocument.cs b/platform/winrt/gsview/mudocument.cs
index 35b4d8b9..9e7353d2 100644
--- a/platform/winrt/gsview/mudocument.cs
+++ b/platform/winrt/gsview/mudocument.cs
@@ -25,8 +25,6 @@ namespace gsview
{
IntPtr mu_object;
private System.Object m_lock = new System.Object();
- List<Links> links;
- List<Links> textsearch;
public List<ContentItem> contents;
/* The list of functions that we use to call into C interface of muctx.
@@ -100,25 +98,35 @@ namespace gsview
[DllImport("mupdfnet.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
- public static extern bool mGetTextSearchItem(int k, ref double top_x,
+ public static extern bool mGetTextSearchItem(int item_num, ref double top_x,
ref double top_y, ref double height, ref double width);
[DllImport("mupdfnet.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
public static extern void mReleaseTextSearch();
-/*
- [DllImport("mugs.dll", CharSet = CharSet.Auto,
- CallingConvention = CallingConvention.StdCall)]
- public static extern void GetLinks(IntPtr ctx);
+ [DllImport("mupdfnet.dll", CharSet = CharSet.Auto,
+ CallingConvention = CallingConvention.StdCall)]
+ public static extern int mGetLinksPage(IntPtr ctx, int page_num);
+ /* The managed code Marshal actually releases the allocated string from C */
+ [DllImport("mupdfnet.dll", CharSet = CharSet.Ansi,
+ CallingConvention = CallingConvention.StdCall)]
+ [return: MarshalAs(UnmanagedType.LPStr)]
+ public static extern string mGetLinkItem(int item_num, ref double top_x,
+ ref double top_y, ref double height, ref double width, ref int topage,
+ ref int type);
+
+ [DllImport("mupdfnet.dll", CharSet = CharSet.Auto,
+ CallingConvention = CallingConvention.StdCall)]
+ public static extern void mReleaseLink();
+ /*
[DllImport("mugs.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
public static extern void GetHTML(IntPtr ctx);
~muctx(void);
- unsigned int GetLinks(int page_num, sh_vector_link links_vec);
std::string GetHTML(int page_num);
*/
@@ -274,5 +282,41 @@ namespace gsview
{
mReleaseTextSearch();
}
+
+ public int GetLinksPage(int page_num)
+ {
+ int num_found;
+ lock (m_lock)
+ {
+ num_found = mGetLinksPage(mu_object, page_num);
+ }
+ return num_found;
+ }
+
+ public void GetLinkItem(int k, out Point top_left, out Size size_rect,
+ out String uri, out int topage, out int typea)
+ {
+ double top_x = 0, top_y = 0, height = 0, width = 0;
+ int typeb = 0;
+ int linkpage = 0;
+
+ uri = mGetLinkItem(k, ref top_x, ref top_y, ref height, ref width,
+ ref linkpage, ref typeb);
+
+ topage = linkpage;
+ typea = typeb;
+ top_left = new Point();
+ size_rect = new Size();
+
+ top_left.X = top_x;
+ top_left.Y = top_y;
+ size_rect.Width = width;
+ size_rect.Height = height;
+ }
+
+ public void ReleaseLink()
+ {
+ mReleaseLink();
+ }
}
}
diff --git a/platform/winrt/libmupdf_winRT.vcxproj b/platform/winrt/libmupdf_winRT.vcxproj
index 9b12992b..d75558aa 100644
--- a/platform/winrt/libmupdf_winRT.vcxproj
+++ b/platform/winrt/libmupdf_winRT.vcxproj
@@ -157,6 +157,7 @@
<ClCompile Include="..\..\source\pdf\pdf-xref-aux.c" />
<ClCompile Include="..\..\source\pdf\pdf-xref.c" />
<ClCompile Include="..\..\source\tiff\mutiff.c" />
+ <ClCompile Include="..\..\source\tools\pdfclean.c" />
<ClCompile Include="..\..\source\xps\xps-common.c" />
<ClCompile Include="..\..\source\xps\xps-doc.c" />
<ClCompile Include="..\..\source\xps\xps-glyphs.c" />
diff --git a/platform/winrt/libmupdf_winRT.vcxproj.filters b/platform/winrt/libmupdf_winRT.vcxproj.filters
index 8ed107bb..912f91ff 100644
--- a/platform/winrt/libmupdf_winRT.vcxproj.filters
+++ b/platform/winrt/libmupdf_winRT.vcxproj.filters
@@ -423,6 +423,9 @@
<ClCompile Include="..\..\source\pdf\pdf-clean.c">
<Filter>pdf</Filter>
</ClCompile>
+ <ClCompile Include="..\..\source\tools\pdfclean.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\source\fitz\ucdn.h">
diff --git a/platform/winrt/mupdfnet/mupdfnet.cpp b/platform/winrt/mupdfnet/mupdfnet.cpp
index 621762a2..e886113c 100644
--- a/platform/winrt/mupdfnet/mupdfnet.cpp
+++ b/platform/winrt/mupdfnet/mupdfnet.cpp
@@ -17,6 +17,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser
std::shared_ptr<std::vector<sh_content>> gContents;
std::shared_ptr<std::vector<sh_text>> gTextResults;
+std::shared_ptr<std::vector<sh_link>> gLinkResults;
char* String_to_char(PCWSTR text)
{
@@ -178,6 +179,52 @@ SYMBOL_DECLSPEC void __stdcall mReleaseTextSearch()
gTextResults.reset();
}
+SYMBOL_DECLSPEC int __stdcall mGetLinksPage(void *ctx, int page_num)
+{
+ muctx *mu_ctx = static_cast<muctx*>(ctx);
+
+ sh_vector_link link_smart_ptr_vec(new std::vector<sh_link>());
+ gLinkResults = link_smart_ptr_vec;
+
+ return mu_ctx->GetLinks(page_num, gLinkResults);
+}
+
+SYMBOL_DECLSPEC char* __stdcall mGetLinkItem(int k, double *top_x, double
+ *top_y, double *height, double *width, int *topage, int *type)
+{
+ char* retstr = NULL;
+
+ if (k < 0 || k > gLinkResults->size())
+ return false;
+ sh_link muctx_link = gLinkResults->at(k);
+ *top_x = muctx_link->upper_left.X;
+ *top_y = muctx_link->upper_left.Y;
+ *width = muctx_link->lower_right.X - muctx_link->upper_left.X;
+ *height = muctx_link->lower_right.Y - muctx_link->upper_left.Y;
+ *topage = muctx_link->page_num;
+ *type = (int) muctx_link->type;
+
+ if (muctx_link->type == LINK_URI)
+ {
+ const char* str = muctx_link->uri.get();
+ int len = strlen(str);
+ if (len > 0)
+ {
+ /* This allocation ensures that Marshal will release in the managed code */
+ retstr = (char*)::CoTaskMemAlloc(len + 1);
+ strcpy(retstr, str);
+ }
+ muctx_link->uri.release();
+ }
+ return retstr;
+}
+
+SYMBOL_DECLSPEC void __stdcall mReleaseLink()
+{
+ if (gTextResults != nullptr)
+ gTextResults.reset();
+}
+
SYMBOL_DECLSPEC void* __stdcall mCreateDisplayList(void *ctx, int page_num,
int *page_width, int *page_height)
{
diff --git a/platform/winrt/mupdfnet/mupdfnet.h b/platform/winrt/mupdfnet/mupdfnet.h
index d16a50f8..c9c8a369 100644
--- a/platform/winrt/mupdfnet/mupdfnet.h
+++ b/platform/winrt/mupdfnet/mupdfnet.h
@@ -36,6 +36,12 @@ EXTERN_C SYMBOL_DECLSPEC int __stdcall mTextSearchPage(void *ctx, int page_num,
EXTERN_C SYMBOL_DECLSPEC bool __stdcall mGetTextSearchItem(int k, double *top_x, double
*top_y, double *height, double *width);
EXTERN_C SYMBOL_DECLSPEC void __stdcall mReleaseTextSearch();
+
+EXTERN_C SYMBOL_DECLSPEC int __stdcall mGetLinksPage(void *ctx, int page_num);
+EXTERN_C SYMBOL_DECLSPEC char* __stdcall mGetLinkItem(int k, double *top_x, double
+ *top_y, double *height, double *width, int *topage, int *type);
+EXTERN_C SYMBOL_DECLSPEC void __stdcall mReleaseLink();
+
EXTERN_C SYMBOL_DECLSPEC void* __stdcall mCreateDisplayList(void *ctx, int page_num,
int *page_width, int *page_height);
EXTERN_C SYMBOL_DECLSPEC int __stdcall mRenderPageMT(void *ctx, void *dlist,