summaryrefslogtreecommitdiff
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
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.
-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,