diff options
Diffstat (limited to 'platform/windows/gsview/mudocument.cs')
-rw-r--r-- | platform/windows/gsview/mudocument.cs | 1747 |
1 files changed, 1747 insertions, 0 deletions
diff --git a/platform/windows/gsview/mudocument.cs b/platform/windows/gsview/mudocument.cs new file mode 100644 index 00000000..291a424e --- /dev/null +++ b/platform/windows/gsview/mudocument.cs @@ -0,0 +1,1747 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +//using System.Threading.Tasks; +using System.Threading; +using System.Runtime.InteropServices; +using System.Security; +using System.Windows; +using System.ComponentModel; +using System.Windows.Forms; + +/* This file contains the interface between the muctx cpp class, which + implements the mupdf calls and the .net managed code */ + +namespace gsview +{ + /* Parameters for conversion */ + public struct ConvertParams_t + { + public int resolution; + public gsDevice_t device; + public String outputfile; + public int num_pages; + public System.Collections.IList pages; + public int currpage; + public GS_Result_t result; + }; + + /* Must match enum in muctx.h */ + enum mudevice_t + { + SVG_OUT, + PNM_OUT, + PCL_OUT, + PWG_OUT, + }; + + public class muPDFEventArgs : EventArgs + { + private bool m_completed; + private int m_progress; + private ConvertParams_t m_param; + + public bool Completed + { + get { return m_completed; } + } + + public ConvertParams_t Params + { + get { return m_param; } + } + + public int Progress + { + get { return m_progress; } + } + + public muPDFEventArgs(bool completed, int progress, ConvertParams_t param) + { + m_completed = completed; + m_progress = progress; + m_param = param; + } + } + + public struct content_s + { + public int page; + public IntPtr string_margin; + } + + [SuppressUnmanagedCodeSecurity] + class mudocument + { + public bool is64bit; + IntPtr mu_object; + BackgroundWorker m_worker; + ConvertParams_t m_params; + /* Callbacks to Main */ + internal delegate void mupdfDLLProblem(object muObject, String mess); + internal event mupdfDLLProblem mupdfDLLProblemMain; + internal delegate void mupdfCallBackMain(object muObject, muPDFEventArgs info); + internal event mupdfCallBackMain mupdfUpdateMain; + + private System.Object m_lock = new System.Object(); + public List<ContentItem> contents; + + #region DLLInterface + /* The list of functions that we use to call into C interface of muctx. + * Calling into C++ code from managed code is complex. Since CLR + * compiling is needed and that does not support mutex. Hence the C + * interface */ + [DllImport("mupdfnet64.dll", EntryPoint = "mInitialize", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mInitialize64(); + + [DllImport("mupdfnet64.dll", EntryPoint = "mOpenDocument", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern status_t mOpenDocument64(IntPtr ctx, string filename); + + [DllImport("mupdfnet64.dll", EntryPoint = "mCleanUp", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mCleanUp64(IntPtr ctx); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetPageCount", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetPageCount64(IntPtr ctx); + + [DllImport("mupdfnet64.dll", EntryPoint = "mRequiresPassword", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern bool mRequiresPassword64(IntPtr ctx); + + [DllImport("mupdfnet64.dll", EntryPoint = "mApplyPassword", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern bool mApplyPassword64(IntPtr ctx, string password); + + [DllImport("mupdfnet64.dll", EntryPoint = "mRenderPage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mRenderPage64(IntPtr ctx, int page_num, + Byte[] bmp_data, int bmp_width, int bmp_height, double scale, + bool flipy); + + [DllImport("mupdfnet64.dll", EntryPoint = "mMeasurePage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mMeasurePage64(IntPtr ctx, int page_num, + ref double width, ref double height); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetContents", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetContents64(IntPtr ctx); + + [DllImport("mupdfnet64.dll", EntryPoint = "mReleaseContents", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseContents64(); + + [DllImport("mupdfnet64.dll", EntryPoint = "mSetAA", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mSetAA64(IntPtr ctx, int level); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet64.dll", EntryPoint = "mGetContentsItem", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetContentsItem64(int k, ref int len, ref int page); + + [DllImport("mupdfnet64.dll", EntryPoint = "mCreateDisplayList", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mCreateDisplayList64(IntPtr ctx, int page_num, + ref int page_width, ref int page_height); + + [DllImport("mupdfnet64.dll", EntryPoint = "mCreateDisplayListAnnot", + CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mCreateDisplayListAnnot64(IntPtr ctx, int page_num); + + [DllImport("mupdfnet64.dll", EntryPoint = "mCreateDisplayListText", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mCreateDisplayListText64(IntPtr ctx, int page_num, + ref int page_width, ref int page_height, ref IntPtr text, ref int length); + + [DllImport("mupdfnet64.dll", EntryPoint = "mRenderPageMT", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mRenderPageMT64(IntPtr ctx, IntPtr dlist, + IntPtr annot_dlist, int page_width, int page_height, Byte[] bmp_data, + int bmp_width, int bmp_height, double scale, bool flipy); + + [DllImport("mupdfnet64.dll", EntryPoint = "mTextSearchPage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mTextSearchPage64(IntPtr ctx, int page_num, + string needle); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetTextSearchItem", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern bool mGetTextSearchItem64(int item_num, ref double top_x, + ref double top_y, ref double height, ref double width); + + [DllImport("mupdfnet64.dll", EntryPoint = "mReleaseTextSearch", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseTextSearch64(); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetLinksPage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetLinksPage64(IntPtr ctx, int page_num); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet64.dll", EntryPoint = "mGetLinkItem", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetLinkItem64(int item_num, ref double top_x, + ref double top_y, ref double height, ref double width, ref int topage, + ref int type); + + [DllImport("mupdfnet64.dll", EntryPoint = "mReleaseLink", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseLink64(); + + [DllImport("mupdfnet64.dll", EntryPoint = "mReleaseText", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseText64(IntPtr ctx, IntPtr textpage); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetTextBlock", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetTextBlock64(IntPtr textpage, int block_num, + ref double top_x,ref double top_y, ref double height, ref double width); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetTextLine", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetTextLine64(IntPtr textpage, int block_num, + int line_num, ref double top_x, ref double top_y, ref double height, + ref double width); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetTextCharacter", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetTextCharacter64(IntPtr textpage, int block_num, + int line_num, int item_num, ref double top_x, + ref double top_y, ref double height, ref double width); + + [DllImport("mupdfnet64.dll", EntryPoint = "mExtractPages", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mExtractPages64(String infile, String outfile, + String password, bool has_password, bool linearize, int num_pages, + IntPtr pages); + + [DllImport("mupdfnet64.dll", EntryPoint = "mSavePage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mSavePage64(IntPtr ctx, String outfile, + int page_num, int res, int type, bool append); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet64.dll", EntryPoint = "mGetVers", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetVers64(); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet64.dll", EntryPoint = "mGetText", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetText64(IntPtr ctx, int pagenum, int type); + + /* And the 32bit version */ + [DllImport("mupdfnet32.dll", EntryPoint = "mInitialize", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mInitialize32(); + + [DllImport("mupdfnet32.dll", EntryPoint = "mOpenDocument", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern status_t mOpenDocument32(IntPtr ctx, string filename); + + [DllImport("mupdfnet32.dll", EntryPoint = "mCleanUp", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mCleanUp32(IntPtr ctx); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetPageCount", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetPageCount32(IntPtr ctx); + + [DllImport("mupdfnet32.dll", EntryPoint = "mRequiresPassword", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern bool mRequiresPassword32(IntPtr ctx); + + [DllImport("mupdfnet32.dll", EntryPoint = "mApplyPassword", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern bool mApplyPassword32(IntPtr ctx, string password); + + [DllImport("mupdfnet32.dll", EntryPoint = "mRenderPage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mRenderPage32(IntPtr ctx, int page_num, + Byte[] bmp_data, int bmp_width, int bmp_height, double scale, + bool flipy); + + [DllImport("mupdfnet32.dll", EntryPoint = "mMeasurePage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mMeasurePage32(IntPtr ctx, int page_num, + ref double width, ref double height); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetContents", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetContents32(IntPtr ctx); + + [DllImport("mupdfnet32.dll", EntryPoint = "mReleaseContents", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseContents32(); + + [DllImport("mupdfnet32.dll", EntryPoint = "mSetAA", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mSetAA32(IntPtr ctx, int level); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet32.dll", EntryPoint = "mGetContentsItem", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetContentsItem32(int k, ref int len, ref int page); + + [DllImport("mupdfnet32.dll", EntryPoint = "mCreateDisplayList", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mCreateDisplayList32(IntPtr ctx, int page_num, + ref int page_width, ref int page_height); + + [DllImport("mupdfnet32.dll", EntryPoint = "mCreateDisplayListAnnot", + CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mCreateDisplayListAnnot32(IntPtr ctx, int page_num); + + + [DllImport("mupdfnet32.dll", EntryPoint = "mCreateDisplayListText", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mCreateDisplayListText32(IntPtr ctx, int page_num, + ref int page_width, ref int page_height, ref IntPtr text, ref int length); + + [DllImport("mupdfnet32.dll", EntryPoint = "mRenderPageMT", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mRenderPageMT32(IntPtr ctx, IntPtr dlist, + IntPtr annot_dlist, int page_width, int page_height, Byte[] bmp_data, + int bmp_width, int bmp_height, double scale, bool flipy); + + [DllImport("mupdfnet32.dll", EntryPoint = "mTextSearchPage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mTextSearchPage32(IntPtr ctx, int page_num, + string needle); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetTextSearchItem", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern bool mGetTextSearchItem32(int item_num, ref double top_x, + ref double top_y, ref double height, ref double width); + + [DllImport("mupdfnet32.dll", EntryPoint = "mReleaseTextSearch", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseTextSearch32(); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetLinksPage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetLinksPage32(IntPtr ctx, int page_num); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet32.dll", EntryPoint = "mGetLinkItem", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetLinkItem32(int item_num, ref double top_x, + ref double top_y, ref double height, ref double width, ref int topage, + ref int type); + + [DllImport("mupdfnet32.dll", EntryPoint = "mReleaseLink", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseLink32(); + + [DllImport("mupdfnet32.dll", EntryPoint = "mReleaseText", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseText32(IntPtr ctx, IntPtr textpage); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetTextBlock", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetTextBlock32(IntPtr textpage, int block_num, + ref double top_x, ref double top_y, ref double height, ref double width); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetTextLine", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetTextLine32(IntPtr textpage, int block_num, + int line_num, ref double top_x, ref double top_y, ref double height, + ref double width); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetTextCharacter", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetTextCharacter32(IntPtr textpage, int block_num, + int line_num, int item_num, ref double top_x, + ref double top_y, ref double height, ref double width); + + [DllImport("mupdfnet32.dll", EntryPoint = "mExtractPages", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mExtractPages32(String infile, String outfile, + String password, bool has_password, bool linearize, int num_pages, + IntPtr pages); + + [DllImport("mupdfnet32.dll", EntryPoint = "mSavePage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mSavePage32(IntPtr ctx, String outfile, + int page_num, int res, int type, bool append); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet32.dll", EntryPoint = "mGetVers", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetVers32(); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet32.dll", EntryPoint = "mGetText", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetText32(IntPtr ctx, int pagenum, int type); + + #endregion DLLInterface + + #region DLLErrorTrap + /* And make sure we can catch any issues in finding the DLL or if we have + * a 32bit 64bit issue */ + private IntPtr tc_mInitialize() + { + IntPtr output; + try + { + if (is64bit) + output = mInitialize64(); + else + output = mInitialize32(); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 1"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + return output; + } + + private status_t tc_mOpenDocument(IntPtr ctx, string filename) + { + status_t output; + try + { + if (is64bit) + output = mOpenDocument64(ctx, filename); + else + output = mOpenDocument32(ctx, filename); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 2"; + mupdfDLLProblemMain(this, err); + return status_t.E_FAILURE; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return status_t.E_FAILURE; + } + return output; + } + + private int tc_mCleanUp(IntPtr ctx) + { + try + { + if (is64bit) + mCleanUp64(ctx); + else + mCleanUp32(ctx); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 3"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return 0; + } + + private int tc_mGetPageCount(IntPtr ctx) + { + int output; + try + { + if (is64bit) + output = mGetPageCount64(ctx); + else + output = mGetPageCount32(ctx); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 4"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private bool tc_mRequiresPassword(IntPtr ctx) + { + bool output; + try + { + if (is64bit) + output = mRequiresPassword64(ctx); + else + output = mRequiresPassword32(ctx); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 5"; + mupdfDLLProblemMain(this, err); + return false; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return false; + } + return output; + } + + private bool tc_mApplyPassword(IntPtr ctx, string password) + { + bool output; + try + { + if (is64bit) + output = mApplyPassword64(ctx, password); + else + output = mApplyPassword32(ctx, password); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 6"; + mupdfDLLProblemMain(this, err); + return false; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return false; + } + return output; + } + + private int tc_mRenderPage(IntPtr ctx, int page_num, Byte[] bmp_data, + int bmp_width, int bmp_height, double scale, bool flipy) + { + int output; + try + { + if (is64bit) + output = mRenderPage64(ctx, page_num, bmp_data, bmp_width, + bmp_height, scale, flipy); + else + output = mRenderPage32(ctx, page_num, bmp_data, bmp_width, + bmp_height, scale, flipy); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 7"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mMeasurePage(IntPtr ctx, int page_num, ref double width, + ref double height) + { + int output; + try + { + if (is64bit) + output = mMeasurePage64(ctx, page_num, ref width, ref height); + else + output = mMeasurePage32(ctx, page_num, ref width, ref height); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 8"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mGetContents(IntPtr ctx) + { + int output; + try + { + if (is64bit) + output = mGetContents64(ctx); + else + output = mGetContents32(ctx); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 9"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mReleaseContents() + { + try + { + if (is64bit) + mReleaseContents64(); + else + mReleaseContents32(); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 10"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return 0; + } + + private string tc_mGetContentsItem(int k, ref int len, ref int page) + { + String output; + try + { + if (is64bit) + output = mGetContentsItem64(k, ref len, ref page); + else + output = mGetContentsItem32(k, ref len, ref page); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 11"; + mupdfDLLProblemMain(this, err); + return null; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return null; + } + return output; + } + + private IntPtr tc_mCreateDisplayListAnnot(IntPtr ctx, int page_num) + { + IntPtr output; + try + { + if (is64bit) + output = mCreateDisplayListAnnot64(ctx, page_num); + else + output = mCreateDisplayListAnnot32(ctx, page_num); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 12"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + return output; + } + + private IntPtr tc_mCreateDisplayList(IntPtr ctx, int page_num, + ref int page_width, ref int page_height) + { + IntPtr output; + try + { + if (is64bit) + output = mCreateDisplayList64(ctx, page_num, ref page_width, + ref page_height); + else + output = mCreateDisplayList32(ctx, page_num, ref page_width, + ref page_height); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 13"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + return output; + } + + private int tc_mSetAA(IntPtr ctx, int level) + { + try + { + if (is64bit) + mSetAA64(ctx, level); + else + mSetAA32(ctx, level); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 14"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return 0; + } + + private IntPtr tc_mCreateDisplayListText(IntPtr ctx, int page_num, + ref int page_width, ref int page_height, ref IntPtr text, ref int length) + { + IntPtr output; + try + { + if (is64bit) + output = mCreateDisplayListText64(ctx, page_num, ref page_width, + ref page_height, ref text, ref length); + else + output = mCreateDisplayListText32(ctx, page_num, ref page_width, + ref page_height, ref text, ref length); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 15"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + return output; + } + + private int tc_mRenderPageMT(IntPtr ctx, IntPtr dlist, IntPtr annot_dlist, + int page_width, int page_height, Byte[] bmp_data, int bmp_width, + int bmp_height, double scale, bool flipy) + { + int output; + try + { + if (is64bit) + output = mRenderPageMT64(ctx, dlist, annot_dlist, page_width, + page_height, bmp_data, bmp_width, bmp_height, scale, flipy); + else + output = mRenderPageMT32(ctx, dlist, annot_dlist, page_width, + page_height, bmp_data, bmp_width, bmp_height, scale, flipy); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 16"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mTextSearchPage(IntPtr ctx, int page_num, string needle) + { + int output; + try + { + if (is64bit) + output = mTextSearchPage64(ctx, page_num, needle); + else + output = mTextSearchPage32(ctx, page_num, needle); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 17"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private bool tc_mGetTextSearchItem(int item_num, ref double top_x, + ref double top_y, ref double height, ref double width) + { + bool output; + try + { + if (is64bit) + output = mGetTextSearchItem64(item_num, ref top_x, ref top_y, + ref height, ref width); + else + output = mGetTextSearchItem32(item_num, ref top_x, ref top_y, + ref height, ref width); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 18"; + mupdfDLLProblemMain(this, err); + return false; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return false; + } + return output; + } + + private int tc_mReleaseTextSearch() + { + try + { + if (is64bit) + mReleaseTextSearch64(); + else + mReleaseTextSearch32(); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 18"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return 0; + } + + private int tc_mGetLinksPage(IntPtr ctx, int page_num) + { + int output; + try + { + if (is64bit) + output = mGetLinksPage64(ctx, page_num); + else + output = mGetLinksPage32(ctx, page_num); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 19"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private string tc_mGetLinkItem(int item_num, ref double top_x, + ref double top_y, ref double height, ref double width, ref int topage, + ref int type) + { + String output; + try + { + if (is64bit) + output = mGetLinkItem64(item_num, ref top_x, ref top_y, ref height, + ref width, ref topage, ref type); + else + output = mGetLinkItem32(item_num, ref top_x, ref top_y, ref height, + ref width, ref topage, ref type); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 20"; + mupdfDLLProblemMain(this, err); + return null; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return null; + } + return output; + } + + private int tc_mReleaseLink() + { + try + { + if (is64bit) + mReleaseLink64(); + else + mReleaseLink32(); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 21"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return 0; + } + + private int tc_mReleaseText(IntPtr ctx, IntPtr textpage) + { + try + { + if (is64bit) + mReleaseText64(ctx, textpage); + else + mReleaseText32(ctx, textpage); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 22"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return 0; + } + + private int tc_mGetTextBlock(IntPtr textpage, int block_num, + ref double top_x, ref double top_y, ref double height, ref double width) + { + int output; + try + { + if (is64bit) + output = mGetTextBlock64(textpage, block_num, ref top_x, + ref top_y, ref height, ref width); + else + output = mGetTextBlock32(textpage, block_num, ref top_x, + ref top_y, ref height, ref width); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 23"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mGetTextLine(IntPtr textpage, int block_num, + int line_num, ref double top_x, ref double top_y, ref double height, + ref double width) + { + int output; + try + { + if (is64bit) + output = mGetTextLine64(textpage, block_num, line_num, + ref top_x, ref top_y, ref height, ref width); + else + output = mGetTextLine32(textpage, block_num, line_num, + ref top_x, ref top_y, ref height, ref width); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 24"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mGetTextCharacter(IntPtr textpage, int block_num, + int line_num, int item_num, ref double top_x, + ref double top_y, ref double height, ref double width) + { + int output; + try + { + if (is64bit) + output = mGetTextCharacter64(textpage, block_num, line_num, + item_num, ref top_x, ref top_y, ref height, ref width); + else + output = mGetTextCharacter32(textpage, block_num, line_num, + item_num, ref top_x, ref top_y, ref height, ref width); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 25"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mExtractPages(String infile, String outfile, + String password, bool has_password, bool linearize, int num_pages, + IntPtr pages) + { + int output; + try + { + if (is64bit) + output = mExtractPages64(infile, outfile, password, has_password, + linearize, num_pages, pages); + else + output = mExtractPages32(infile, outfile, password, has_password, + linearize, num_pages, pages); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 26"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private string tc_mGetVers() + { + String output; + try + { + if (is64bit) + output = mGetVers64(); + else + output = mGetVers32(); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 27"; + mupdfDLLProblemMain(this, err); + return null; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return null; + } + return output; + } + + private string tc_mGetText(IntPtr ctx, int pagenum, textout_t type) + { + String output; + try + { + if (is64bit) + output = mGetText64(ctx, pagenum, (int) type); + else + output = mGetText32(ctx, pagenum, (int) type); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 28"; + mupdfDLLProblemMain(this, err); + return null; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return null; + } + return output; + } + + private int tc_mSavePage(IntPtr ctx, String outfile, int page_num, + int res, int type, bool append) + { + int output; + try + { + if (is64bit) + output = mSavePage64(ctx, outfile, page_num, res, type, append); + else + output = mSavePage32(ctx, outfile, page_num, res, type, append); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 29"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + #endregion DLLErrorTrap + + /* Now the actual code that does some work */ + public status_t Initialize() + { + is64bit = Environment.Is64BitOperatingSystem && + Environment.Is64BitProcess; + + mu_object = tc_mInitialize(); + if (mu_object == null) + return status_t.E_FAILURE; + else + return status_t.S_ISOK; + } + + public void CleanUp() + { + if (mu_object != null) + { + lock(m_lock) + tc_mCleanUp(mu_object); + } + } + + public String GetText(int page_num, textout_t type) + { + return tc_mGetText(mu_object, page_num, type); + } + + public void GetVersion(out String vers) + { + vers = tc_mGetVers(); + } + + public int GetPageCount() + { + return tc_mGetPageCount(mu_object); + } + + public bool RequiresPassword() + { + return tc_mRequiresPassword(mu_object); + } + + public bool ApplyPassword(String password) + { + return tc_mApplyPassword(mu_object, password); + } + + public void SetAA(AA_t AAlevel) + { + lock (m_lock) + { + tc_mSetAA(mu_object, (int)AAlevel); + } + } + + public int RenderPage(int page_num, Byte[] bmp_data, int bmp_width, + int bmp_height, double scale, bool flipy, bool use_dlist, bool + get_text, out BlocksText blocks, bool annotation, + out Annotate_t annot_type) + { + int code; + blocks = null; + String blockcolor = "#00FFFFFF"; + String linecolor = "#402572AC"; + /* Debug */ + //blockcolor = "#20FFFF00"; + + annot_type = Annotate_t.UNKNOWN; + if (use_dlist) + { + IntPtr dlist = IntPtr.Zero; + IntPtr annot_dlist = IntPtr.Zero; + IntPtr text = IntPtr.Zero; + int num_blocks = 0; + + int page_height = 0; + int page_width = 0; + + if (get_text) + { + lock (m_lock) + { + dlist = tc_mCreateDisplayListText(mu_object, page_num, + ref page_width, ref page_height, ref text, ref num_blocks); + } + /* If we have some text go ahead and get the bounding boxes + * now. There is likely a better way to do this with passing + * a structure across the boundary in a single call. ToDO */ + /* Length here is the number of blocks. mupdf splits block + * into lines (spans) and then these into text characters + * Our goal here is to get them into a structure that we + * can rapidly use in our ui display. Maintaining the block + * and span stucture so that we can minimize the number of + * rects that are introduced */ + if (num_blocks > 0) + { + blocks = new BlocksText(); + for (int kk = 0; kk < num_blocks; kk++) + { + double top_x = 0, top_y = 0, height = 0, width = 0; + var block = new TextBlock(); + + int num_lines = tc_mGetTextBlock(text, kk, ref top_x, + ref top_y, ref height, ref width); + + block.X = top_x; + block.Y = top_y; + block.Width = width; + block.Height = height; + block.Color = blockcolor; + block.Scale = 1.0; + block.PageNumber = page_num; + blocks.Add(block); + + blocks[kk].TextLines = new List<TextLine>(); + for (int jj = 0; jj < num_lines; jj++) + { + var line = new TextLine(); + int num_chars = tc_mGetTextLine(text, kk, jj, ref top_x, + ref top_y, ref height, ref width); + line.X = top_x; + line.Y = top_y; + line.Width = width; + line.Height = height; + line.Scale = 1.0; + line.Color = linecolor; + blocks[kk].TextLines.Add(line); + + blocks[kk].TextLines[jj].TextCharacters = new List<TextCharacter>(); + for (int mm = 0; mm < num_chars; mm++) + { + var textchars = new TextCharacter(); + int character = tc_mGetTextCharacter(text, kk, jj, mm, ref top_x, + ref top_y, ref height, ref width); + textchars.X = top_x; + textchars.Y = top_y; + textchars.Width = width; + textchars.Height = height; + textchars.Scale = 1.0; + textchars.Color = linecolor; + textchars.character = System.Convert.ToChar(character).ToString(); + blocks[kk].TextLines[jj].TextCharacters.Add(textchars); + } + } + } + /* We are done with the text object */ + tc_mReleaseText(mu_object, text); + } + } + else + lock (m_lock) + { + dlist = tc_mCreateDisplayList(mu_object, page_num, + ref page_width, ref page_height); + } + if (annotation) + { + lock (m_lock) + { + annot_dlist = tc_mCreateDisplayListAnnot(mu_object, page_num); + if (annot_dlist == IntPtr.Zero) + annot_type = Annotate_t.NO_ANNOTATE; + else + annot_type = Annotate_t.HAS_ANNOTATE; + } + } + + /* Rendering of display list can occur with other threads so unlock */ + if (dlist == null) + { + return (int) status_t.E_FAILURE; + } + code = tc_mRenderPageMT(mu_object, dlist, annot_dlist, page_width, + page_height, bmp_data, bmp_width, bmp_height, scale, flipy); + } + else + { + lock(m_lock) + { + code = tc_mRenderPage(mu_object, page_num, bmp_data, bmp_width, + bmp_height, scale, flipy); + } + } + return code; + } + + public status_t OpenFile(string filename) + { + return tc_mOpenDocument(mu_object, filename); + } + + public int GetPageSize(int page_num, out Point size_out) + { + int code; + double height = 0, width = 0; + + size_out = new Point(); + + lock(m_lock) + { + code = tc_mMeasurePage(mu_object, page_num, ref width, ref height); + } + + size_out.X = width; + size_out.Y = height; + return code; + } + + public int ComputeContents() + { + int num_items; + int len = 0, page = 0; + + lock(m_lock) + { + num_items = tc_mGetContents(mu_object); + } + + if (contents == null) + contents = new List<ContentItem>(); + + for (int k = 0; k < num_items; k++) + { + ContentItem item = new ContentItem(); + item.StringMargin = tc_mGetContentsItem(k, ref len, ref page); + item.Page = page; + contents.Add(item); + } + return num_items; + } + + public void ReleaseContents() + { + tc_mReleaseContents(); + } + + public int TextSearchPage(int page_num, String needle) + { + int num_found; + lock (m_lock) + { + num_found = tc_mTextSearchPage(mu_object, page_num, needle); + } + return num_found; + } + + public bool GetTextSearchItem(int k, out Point top_left, out Size size_rect) + { + double top_x = 0, top_y = 0 , height = 0, width = 0; + bool found = tc_mGetTextSearchItem(k, ref top_x, ref top_y, ref height, ref width); + + 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; + + return found; + } + + public void ReleaseTextSearch() + { + tc_mReleaseTextSearch(); + } + + public int GetLinksPage(int page_num) + { + int num_found; + lock (m_lock) + { + num_found = tc_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 = tc_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() + { + tc_mReleaseLink(); + } + + public void ReleaseText(IntPtr textpage) + { + tc_mReleaseText(mu_object, textpage); + } + + public void HTMLSaveAs(String infile, String outfile, String password, + bool has_password, bool linearize, int num_pages, System.Collections.IList pages) + { + if (num_pages > 0) + { + /* We need to do an allocation for our array of page numbers and + * perform pinning to avoid GC while in the c++ code */ + GCHandle pagesPtrStable; + int[] page_list; + page_list = new int[pages.Count]; + + for (int kk = 0; kk < pages.Count; kk++) + { + SelectPage currpage = (SelectPage)pages[kk]; + page_list[kk] = currpage.Page; + } + pagesPtrStable = GCHandle.Alloc(page_list, GCHandleType.Pinned); + tc_mExtractPages(infile, outfile, password, has_password, linearize, + num_pages, pagesPtrStable.AddrOfPinnedObject()); + pagesPtrStable.Free(); + } + else + { + tc_mExtractPages(infile, outfile, password, has_password, linearize, + num_pages, IntPtr.Zero); + } + } + + public void PDFExtract(String infile, String outfile, String password, + bool has_password, bool linearize, int num_pages, System.Collections.IList pages) + { + if (num_pages > 0) + { + /* We need to do an allocation for our array of page numbers and + * perform pinning to avoid GC while in the c++ code */ + GCHandle pagesPtrStable; + int[] page_list; + page_list = new int[pages.Count]; + + for (int kk = 0; kk < pages.Count; kk++) + { + SelectPage currpage = (SelectPage)pages[kk]; + page_list[kk] = currpage.Page; + } + pagesPtrStable = GCHandle.Alloc(page_list, GCHandleType.Pinned); + tc_mExtractPages(infile, outfile, password, has_password, linearize, + num_pages, pagesPtrStable.AddrOfPinnedObject()); + pagesPtrStable.Free(); + } + else + { + tc_mExtractPages(infile, outfile, password, has_password, linearize, + num_pages, IntPtr.Zero); + } + } + + public gsStatus ConvertSave(gsDevice_t device, String outputFile, int num_pages, + System.Collections.IList pages, int resolution) + { + ConvertParams_t convertparams = new ConvertParams_t(); + + convertparams.device = device; + convertparams.outputfile = outputFile; + convertparams.num_pages = num_pages; + convertparams.resolution = resolution; + convertparams.pages = pages; + convertparams.currpage = 1; + return ConvertMuPDF(convertparams); + } + + /* Render page by page in background with progress call back */ + private gsStatus ConvertMuPDF(ConvertParams_t Params) + { + try + { + if (m_worker != null && m_worker.IsBusy) + { + m_worker.CancelAsync(); + return gsStatus.GS_BUSY; + } + if (m_worker == null) + { + m_worker = new BackgroundWorker(); + m_worker.WorkerReportsProgress = true; + m_worker.WorkerSupportsCancellation = true; + m_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(MuPDFCompleted); + m_worker.ProgressChanged += new ProgressChangedEventHandler(MuPDFProgressChanged); + m_worker.DoWork += new DoWorkEventHandler(MuPDFWork); + } + + m_params = Params; + m_worker.RunWorkerAsync(Params); + return gsStatus.GS_READY; + } + catch (OutOfMemoryException e) + { + Console.WriteLine("Memory allocation failed during mupdf rendering\n"); + return gsStatus.GS_ERROR; + } + } + + private void MuPDFCompleted(object sender, RunWorkerCompletedEventArgs e) + { + ConvertParams_t Value; + muPDFEventArgs info; + + if (e.Cancelled) + { + Value = new ConvertParams_t(); + Value.result = GS_Result_t.gsCANCELLED; + info = new muPDFEventArgs(true, 100, Value); + } + else + { + Value = (ConvertParams_t)e.Result; + info = new muPDFEventArgs(true, 100, Value); + } + mupdfUpdateMain(this, info); + } + + private void MuPDFProgressChanged(object sender, ProgressChangedEventArgs e) + { + /* Callback with progress */ + ConvertParams_t Value = new ConvertParams_t(); + muPDFEventArgs info = new muPDFEventArgs(false, e.ProgressPercentage, Value); + mupdfUpdateMain(this, info); + } + + public void Cancel() + { + m_worker.CancelAsync(); + } + + /* ToDo: do we report pages that failed? or just push on */ + private void MuPDFWork(object sender, DoWorkEventArgs e) + { + ConvertParams_t muparams = (ConvertParams_t)e.Argument; + String out_file = muparams.outputfile; + int num_pages = muparams.num_pages; + int resolution = muparams.resolution; + var pages = muparams.pages; + BackgroundWorker worker = sender as BackgroundWorker; + + muparams.result = GS_Result_t.gsOK; + + int result; + + for (int kk = 0; kk < num_pages; kk++) + { + SelectPage curr_page = (SelectPage)pages[kk]; + int page_num = curr_page.Page; + bool append = (kk != 0); + + /* Look for file extension. */ + string extension = System.IO.Path.GetExtension(out_file); + int len = extension.Length; + String new_out_file = out_file.Substring(0, out_file.Length - len); + String out_file_name = new_out_file + "_" + page_num + extension; + + /* Question: is lock valid when done from this worker thread? */ + switch (muparams.device) + { + case gsDevice_t.svg: + lock (this.m_lock) /* Single-page format */ + result = tc_mSavePage(mu_object, out_file_name, + page_num - 1, resolution, (int) mudevice_t.SVG_OUT, + false); + break; + case gsDevice_t.pnm: + lock (this.m_lock) /* Single-page format */ + result = tc_mSavePage(mu_object, out_file_name, + page_num - 1, resolution, (int)mudevice_t.PNM_OUT, + false); + break; + case gsDevice_t.pclbitmap: /* Multi-page format */ + lock (this.m_lock) + result = tc_mSavePage(mu_object, out_file, + page_num - 1, resolution, (int)mudevice_t.PCL_OUT, + append); + break; + case gsDevice_t.pwg: /* Multi-page format */ + lock (this.m_lock) + result = tc_mSavePage(mu_object, out_file, + page_num - 1, resolution, (int)mudevice_t.PWG_OUT, + append); + break; + } + double prog = (double) (kk+1.0)/((double) num_pages) * 100.0; + worker.ReportProgress((int)prog); + + if (worker.CancellationPending == true) + { + e.Cancel = true; + muparams.result = GS_Result_t.gsCANCELLED; + break; + } + } + e.Result = muparams; + return; + } + } +} |