diff options
author | Michael Vrhel <michael.vrhel@artifex.com> | 2014-03-20 11:54:03 -0700 |
---|---|---|
committer | Michael Vrhel <michael.vrhel@artifex.com> | 2014-09-09 16:39:33 -0700 |
commit | 67a1b4e6cf4b45059b32de420892bf9d90c01042 (patch) | |
tree | cf283df06579b6299d53a027e77adb9cbbe65033 | |
parent | 7e24e989fbc54d16a8ca3171f1795b158c888aca (diff) | |
download | mupdf-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.cs | 1 | ||||
-rw-r--r-- | platform/winrt/gsview/MainWindow.xaml | 4 | ||||
-rw-r--r-- | platform/winrt/gsview/MainWindow.xaml.cs | 309 | ||||
-rw-r--r-- | platform/winrt/gsview/RectList.cs | 10 | ||||
-rw-r--r-- | platform/winrt/gsview/mudocument.cs | 60 | ||||
-rw-r--r-- | platform/winrt/libmupdf_winRT.vcxproj | 1 | ||||
-rw-r--r-- | platform/winrt/libmupdf_winRT.vcxproj.filters | 3 | ||||
-rw-r--r-- | platform/winrt/mupdfnet/mupdfnet.cpp | 47 | ||||
-rw-r--r-- | platform/winrt/mupdfnet/mupdfnet.h | 6 |
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, |