/* Close the display device and delete the instance */ public gsParamState_t DisplayDeviceClose() { int code = 0; gsParamState_t out_params = new gsParamState_t(); out_params.result = GS_Result_t.gsOK; try { int code1 = ghostapi.gsapi_exit(dispInstance); if ((code == 0) || (code == gsConstants.E_QUIT)) { code = code1; } ghostapi.gsapi_delete_instance(dispInstance); dispInstance = IntPtr.Zero; } catch (Exception except) { gsDLLProblemMain("Exception: " + except.Message); out_params.result = GS_Result_t.gsFAILED; } return(out_params); }
/* Launch a thread rendering a set of pages with the display device. For use with languages * that can be indexed via pages which include PDF and XPS */ public gsStatus gsDisplayDeviceRenderPages(String fileName, int first_page, int last_page, double zoom) { gsParamState_t gsparams = new gsParamState_t(); int format = (gsConstants.DISPLAY_COLORS_RGB | gsConstants.DISPLAY_DEPTH_8 | gsConstants.DISPLAY_LITTLEENDIAN); int resolution = (int)(72.0 * zoom + 0.5); gsparams.args = new List <string>(); gsparams.args.Add("gs"); gsparams.args.Add("-dNOPAUSE"); gsparams.args.Add("-dBATCH"); gsparams.args.Add("-I%rom%Resource/Init/"); gsparams.args.Add("-dSAFER"); gsparams.args.Add("-r" + resolution); gsparams.args.Add("-sDEVICE=display"); gsparams.args.Add("-dDisplayFormat=" + format); gsparams.args.Add("-dFirstPage=" + first_page); gsparams.args.Add("-dLastPage=" + last_page); gsparams.args.Add("-f"); gsparams.args.Add(fileName); gsparams.task = GS_Task_t.DISPLAY_DEV_PDF; gsparams.currpage = first_page - 1; return(RunGhostscriptAsync(gsparams)); }
/* Launch a thread rendering all the pages with the display device * to collect thumbnail images or full resolution. */ public gsStatus gsDisplayDeviceRenderAll(String fileName, double zoom, bool aa, GS_Task_t task) { gsParamState_t gsparams = new gsParamState_t(); int format = (gsConstants.DISPLAY_COLORS_RGB | gsConstants.DISPLAY_DEPTH_8 | gsConstants.DISPLAY_LITTLEENDIAN); int resolution = (int)(72.0 * zoom + 0.5); gsparams.args = new List <string>(); gsparams.args.Add("gs"); gsparams.args.Add("-dNOPAUSE"); gsparams.args.Add("-dBATCH"); gsparams.args.Add("-I%rom%Resource/Init/"); gsparams.args.Add("-dSAFER"); gsparams.args.Add("-r" + resolution); if (aa) { gsparams.args.Add("-dTextAlphaBits=4"); gsparams.args.Add("-dGraphicsAlphaBits=4"); } gsparams.args.Add("-sDEVICE=display"); gsparams.args.Add("-dDisplayFormat=" + format); gsparams.args.Add("-f"); gsparams.args.Add(fileName); gsparams.task = task; gsparams.currpage = 0; return(RunGhostscriptAsync(gsparams)); }
/* Use syncronous call to ghostscript to get the * number of pages in a PDF file */ public int GetPageCount(String fileName) { gsParamState_t gsparams = new gsParamState_t(); gsParamState_t result; gsparams.args = new List <string>(); gsparams.args.Add("gs"); gsparams.args.Add("-dNODISPLAY"); gsparams.args.Add("-dNOPAUSE"); gsparams.args.Add("-dBATCH"); gsparams.args.Add("-I%rom%Resource/Init/"); //gsparams.args.Add("-q"); gsparams.args.Add("-sFile=\"" + fileName + "\""); gsparams.args.Add("--permit-file-read=\"" + fileName + "\""); gsparams.args.Add("-c"); gsparams.args.Add("\"File (r) file runpdfbegin pdfpagecount = quit\""); gsparams.task = GS_Task_t.GET_PAGE_COUNT; m_params = gsparams; result = gsFileSync(gsparams); if (result.result == GS_Result_t.gsOK) { return(m_params.num_pages); } else { return(-1); } }
/* Callback as worker progresses */ private void gsProgressChanged(object sender, ProgressChangedEventArgs e) { /* Callback with progress */ gsParamState_t Value = new gsParamState_t(); gsEventArgs info = new gsEventArgs(false, e.ProgressPercentage, Value); gsUpdateMain(info); }
/* Launch a thread to create XPS document for windows printing */ public gsStatus CreateXPS(String fileName, int resolution, int num_pages, Print printsettings, int firstpage, int lastpage) { gsParamState_t gsparams = new gsParamState_t(); gsparams.args = new List <string>(); gsparams.inputfile = fileName; gsparams.args.Add("gs"); gsparams.args.Add("-dNOPAUSE"); gsparams.args.Add("-dBATCH"); gsparams.args.Add("-I%rom%Resource/Init/"); gsparams.args.Add("-dSAFER"); gsparams.args.Add("-r" + resolution.ToString()); gsparams.args.Add("-dNOCACHE"); gsparams.args.Add("-sDEVICE=xpswrite"); gsparams.args.Add("-dFirstPage=" + firstpage.ToString()); gsparams.args.Add("-dLastPage=" + lastpage.ToString()); if (printsettings != null) { double paperheight; double paperwidth; if (printsettings.m_pagedetails.Landscape == true) { paperheight = printsettings.m_pagedetails.PrintableArea.Width; paperwidth = printsettings.m_pagedetails.PrintableArea.Height; } else { paperheight = printsettings.m_pagedetails.PrintableArea.Height; paperwidth = printsettings.m_pagedetails.PrintableArea.Width; } double width = paperwidth * 72.0 / 100.0; double height = paperheight * 72.0 / 100.0; gsparams.args.Add("-dDEVICEWIDTHPOINTS=" + width); gsparams.args.Add("-dDEVICEHEIGHTPOINTS=" + height); gsparams.args.Add("-dFIXEDMEDIA"); /* Scale and translate and rotate if needed */ if (printsettings.xaml_autofit.IsChecked == true) { gsparams.args.Add("-dFitPage"); } } gsparams.outputfile = Path.GetTempFileName(); gsparams.args.Add("-o"); gsparams.args.Add(gsparams.outputfile); gsparams.args.Add("-f"); gsparams.args.Add(fileName); gsparams.task = GS_Task_t.CREATE_XPS; return(RunGhostscriptAsync(gsparams)); }
/* Call the appropriate worker thread based upon the task * that we have to do */ private gsStatus RunGhostscriptAsync(gsParamState_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(gsCompleted); m_worker.ProgressChanged += new ProgressChangedEventHandler(gsProgressChanged); } switch (Params.task) { case GS_Task_t.PS_DISTILL: m_worker.DoWork += new DoWorkEventHandler(gsBytesAsync); break; case GS_Task_t.DISPLAY_DEV_NON_PDF: case GS_Task_t.DISPLAY_DEV_PDF: case GS_Task_t.DISPLAY_DEV_THUMBS_NON_PDF: case GS_Task_t.DISPLAY_DEV_THUMBS_PDF: m_worker.DoWork += new DoWorkEventHandler(DisplayDeviceAsync); break; case GS_Task_t.SAVE_RESULT: case GS_Task_t.CREATE_XPS: default: m_worker.DoWork += new DoWorkEventHandler(gsFileAsync); break; } m_params = Params; m_worker.RunWorkerAsync(Params); return(gsStatus.GS_READY); } catch (OutOfMemoryException) { Console.WriteLine("Memory allocation failed during gs rendering\n"); return(gsStatus.GS_ERROR); } }
/* Launch a thread rendering all the pages with the display device * to distill an input PS file and save as a PDF. */ public gsStatus DistillPS(String fileName, int resolution) { gsParamState_t gsparams = new gsParamState_t(); gsparams.args = new List <string>(); gsparams.inputfile = fileName; gsparams.args.Add("gs"); gsparams.args.Add("-dNOPAUSE"); gsparams.args.Add("-dBATCH"); gsparams.args.Add("-I%rom%Resource/Init/"); gsparams.args.Add("-dSAFER"); gsparams.args.Add("-sDEVICE=pdfwrite"); gsparams.outputfile = Path.GetTempFileName(); gsparams.args.Add("-o" + gsparams.outputfile); gsparams.task = GS_Task_t.PS_DISTILL; return(RunGhostscriptAsync(gsparams)); }
/* Worker task for using display device */ private void DisplayDeviceAsync(object sender, DoWorkEventArgs e) { int code = 0; gsParamState_t gsparams = (gsParamState_t)e.Argument; GCHandle argPtrsStable = new GCHandle(); int num_params = gsparams.args.Count; var argParam = new GCHandle[num_params]; var argPtrs = new IntPtr[num_params]; List <byte[]> CharacterArray = new List <byte[]>(num_params); bool cleanup = true; gsparams.result = GS_Result_t.gsOK; try { code = ghostapi.gsapi_new_instance(out dispInstance, IntPtr.Zero); if (code < 0) { throw new GhostscriptException("DisplayDeviceAsync: gsapi_new_instance error"); } code = ghostapi.gsapi_set_stdio(dispInstance, stdin_callback, stdout_callback, stderr_callback); if (code < 0) { throw new GhostscriptException("DisplayDeviceAsync: gsapi_set_stdio error"); } code = ghostapi.gsapi_set_arg_encoding(dispInstance, (int)gsEncoding.GS_ARG_ENCODING_UTF8); if (code < 0) { throw new GhostscriptException("DisplayDeviceAsync: gsapi_set_arg_encoding error"); } code = ghostapi.gsapi_set_display_callback(dispInstance, ptr_display_struct); if (code < 0) { throw new GhostscriptException("DisplayDeviceAsync: gsapi_set_display_callback error"); } String fullcommand = ""; for (int k = 0; k < num_params; k++) { CharacterArray.Add(System.Text.Encoding.UTF8.GetBytes((gsparams.args[k] + "\0").ToCharArray())); argParam[k] = GCHandle.Alloc(CharacterArray[k], GCHandleType.Pinned); argPtrs[k] = argParam[k].AddrOfPinnedObject(); fullcommand = fullcommand + " " + gsparams.args[k]; } argPtrsStable = GCHandle.Alloc(argPtrs, GCHandleType.Pinned); fullcommand = "Command Line: " + fullcommand + "\n"; gsIOUpdateMain(fullcommand, fullcommand.Length); code = ghostapi.gsapi_init_with_args(dispInstance, num_params, argPtrsStable.AddrOfPinnedObject()); if (code < 0) { throw new GhostscriptException("DisplayDeviceAsync: gsapi_init_with_args error"); } } catch (DllNotFoundException except) { gsDLLProblemMain("Exception: " + except.Message); gsparams.result = GS_Result_t.gsFAILED; cleanup = false; e.Result = gsparams; } catch (BadImageFormatException except) { gsDLLProblemMain("Exception: " + except.Message); gsparams.result = GS_Result_t.gsFAILED; cleanup = false; e.Result = gsparams; } catch (GhostscriptException except) { gsDLLProblemMain("Exception: " + except.Message); gsparams.result = GS_Result_t.gsFAILED; if (dispInstance != IntPtr.Zero) { ghostapi.gsapi_delete_instance(dispInstance); } dispInstance = IntPtr.Zero; } catch (Exception except) { gsDLLProblemMain("Exception: " + except.Message); gsparams.result = GS_Result_t.gsFAILED; if (dispInstance != IntPtr.Zero) { ghostapi.gsapi_delete_instance(dispInstance); } dispInstance = IntPtr.Zero; } finally { if (cleanup) { for (int k = 0; k < num_params; k++) { argParam[k].Free(); } argPtrsStable.Free(); e.Result = gsparams; if (gsparams.result == GS_Result_t.gsOK && (gsparams.task == GS_Task_t.DISPLAY_DEV_NON_PDF || gsparams.task == GS_Task_t.DISPLAY_DEV_THUMBS_NON_PDF)) { gsParamState_t result = DisplayDeviceClose(); if (gsparams.result == 0) { gsparams.result = result.result; } } } } return; }
public gsEventArgs(bool completed, int progress, gsParamState_t param) { m_completed = completed; m_progress = progress; m_param = param; }
/* Processing with gsapi_run_string for callback progress */ private void gsBytesAsync(object sender, DoWorkEventArgs e) { gsParamState_t Params = (gsParamState_t)e.Argument; int num_params = Params.args.Count; var argParam = new GCHandle[num_params]; var argPtrs = new IntPtr[num_params]; List <byte[]> CharacterArray = new List <byte[]>(num_params); GCHandle argPtrsStable = new GCHandle(); Byte[] Buffer = new Byte[gsConstants.GS_READ_BUFFER]; BackgroundWorker worker = sender as BackgroundWorker; int code = 0; int exitcode = 0; var Feed = new GCHandle(); var FeedPtr = new IntPtr(); String[] strParams = new String[num_params]; FileStream fs = null; bool cleanup = true; try { /* Open the file */ fs = new FileStream(Params.inputfile, FileMode.Open); var len = (int)fs.Length; code = ghostapi.gsapi_new_instance(out gsInstance, IntPtr.Zero); if (code < 0) { throw new GhostscriptException("gsBytesAsync: gsapi_new_instance error"); } code = ghostapi.gsapi_set_stdio(gsInstance, stdin_callback, stdout_callback, stderr_callback); if (code < 0) { throw new GhostscriptException("gsBytesAsync: gsapi_set_stdio error"); } code = ghostapi.gsapi_set_arg_encoding(gsInstance, (int)gsEncoding.GS_ARG_ENCODING_UTF8); if (code < 0) { throw new GhostscriptException("gsBytesAsync: gsapi_set_arg_encoding error"); } /* Now convert our Strings to char* and get pinned handles to these. * This keeps the c# GC from moving stuff around on us */ String fullcommand = ""; for (int k = 0; k < num_params; k++) { CharacterArray.Add(System.Text.Encoding.UTF8.GetBytes((Params.args[k] + "\0").ToCharArray())); argParam[k] = GCHandle.Alloc(CharacterArray[k], GCHandleType.Pinned); argPtrs[k] = argParam[k].AddrOfPinnedObject(); fullcommand = fullcommand + " " + Params.args[k]; } /* Also stick the array of pointers into memory that will not be GCd */ argPtrsStable = GCHandle.Alloc(argPtrs, GCHandleType.Pinned); fullcommand = "Command Line: " + fullcommand + "\n"; gsIOUpdateMain(fullcommand, fullcommand.Length); code = ghostapi.gsapi_init_with_args(gsInstance, num_params, argPtrsStable.AddrOfPinnedObject()); if (code < 0) { throw new GhostscriptException("gsBytesAsync: gsapi_init_with_args error"); } /* Pin data buffer */ Feed = GCHandle.Alloc(Buffer, GCHandleType.Pinned); FeedPtr = Feed.AddrOfPinnedObject(); /* Now start feeding the input piece meal and do a call back * with our progress */ if (code == 0) { int count; double perc; int total = 0; int ret_code; ret_code = ghostapi.gsapi_run_string_begin(gsInstance, 0, ref exitcode); if (exitcode < 0) { code = exitcode; throw new GhostscriptException("gsBytesAsync: gsapi_run_string_begin error"); } while ((count = fs.Read(Buffer, 0, gsConstants.GS_READ_BUFFER)) > 0) { ret_code = ghostapi.gsapi_run_string_continue(gsInstance, FeedPtr, count, 0, ref exitcode); if (exitcode < 0) { code = exitcode; throw new GhostscriptException("gsBytesAsync: gsapi_run_string_continue error"); } total = total + count; perc = 100.0 * (double)total / (double)len; worker.ReportProgress((int)perc); if (worker.CancellationPending == true) { e.Cancel = true; break; } } ret_code = ghostapi.gsapi_run_string_end(gsInstance, 0, ref exitcode); if (exitcode < 0) { code = exitcode; throw new GhostscriptException("gsBytesAsync: gsapi_run_string_end error"); } } } catch (DllNotFoundException except) { gsDLLProblemMain("Exception: " + except.Message); Params.result = GS_Result_t.gsFAILED; cleanup = false; e.Result = Params; } catch (BadImageFormatException except) { gsDLLProblemMain("Exception: " + except.Message); Params.result = GS_Result_t.gsFAILED; cleanup = false; e.Result = Params; } catch (GhostscriptException except) { gsDLLProblemMain("Exception: " + except.Message); } catch (Exception except) { /* Could be a file io issue */ gsDLLProblemMain("Exception: " + except.Message); Params.result = GS_Result_t.gsFAILED; cleanup = false; e.Result = Params; } finally { if (cleanup) { fs.Close(); /* Free pinned items */ for (int k = 0; k < num_params; k++) { argParam[k].Free(); } argPtrsStable.Free(); Feed.Free(); /* gs clean up */ int code1 = ghostapi.gsapi_exit(gsInstance); if ((code == 0) || (code == gsConstants.E_QUIT)) { code = code1; } ghostapi.gsapi_delete_instance(gsInstance); Params.return_code = code; if ((code == 0) || (code == gsConstants.E_QUIT)) { Params.result = GS_Result_t.gsOK; e.Result = Params; } else { Params.result = GS_Result_t.gsFAILED; e.Result = Params; } gsInstance = IntPtr.Zero; } } return; }
/* Process command line with gsapi_init_with_args */ private void gsFileAsync(object sender, DoWorkEventArgs e) { gsParamState_t Params = (gsParamState_t)e.Argument; int num_params = Params.args.Count; var argParam = new GCHandle[num_params]; var argPtrs = new IntPtr[num_params]; List <byte[]> CharacterArray = new List <byte[]>(num_params); GCHandle argPtrsStable = new GCHandle(); int code = 0; bool cleanup = true; try { code = ghostapi.gsapi_new_instance(out gsInstance, IntPtr.Zero); if (code < 0) { throw new GhostscriptException("gsFileAsync: gsapi_new_instance error"); } code = ghostapi.gsapi_set_stdio(gsInstance, stdin_callback, stdout_callback, stderr_callback); if (code < 0) { throw new GhostscriptException("gsFileAsync: gsapi_set_stdio error"); } code = ghostapi.gsapi_set_arg_encoding(gsInstance, (int)gsEncoding.GS_ARG_ENCODING_UTF8); if (code < 0) { throw new GhostscriptException("gsFileAsync: gsapi_set_arg_encoding error"); } /* Now convert our Strings to char* and get pinned handles to these. * This keeps the c# GC from moving stuff around on us */ String fullcommand = ""; for (int k = 0; k < num_params; k++) { CharacterArray.Add(System.Text.Encoding.UTF8.GetBytes((Params.args[k] + "\0").ToCharArray())); argParam[k] = GCHandle.Alloc(CharacterArray[k], GCHandleType.Pinned); argPtrs[k] = argParam[k].AddrOfPinnedObject(); fullcommand = fullcommand + " " + Params.args[k]; } /* Also stick the array of pointers into memory that will not be GCd */ argPtrsStable = GCHandle.Alloc(argPtrs, GCHandleType.Pinned); fullcommand = "Command Line: " + fullcommand + "\n"; gsIOUpdateMain(fullcommand, fullcommand.Length); code = ghostapi.gsapi_init_with_args(gsInstance, num_params, argPtrsStable.AddrOfPinnedObject()); if (code < 0) { throw new GhostscriptException("gsFileAsync: gsapi_init_with_args error"); } } catch (DllNotFoundException except) { gsDLLProblemMain("Exception: " + except.Message); Params.result = GS_Result_t.gsFAILED; cleanup = false; e.Result = Params; } catch (BadImageFormatException except) { gsDLLProblemMain("Exception: " + except.Message); Params.result = GS_Result_t.gsFAILED; cleanup = false; e.Result = Params; } catch (GhostscriptException except) { gsDLLProblemMain("Exception: " + except.Message); } catch (Exception except) { gsDLLProblemMain("Exception: " + except.Message); } finally { if (cleanup) { /* All the pinned items need to be freed so the GC can do its job */ for (int k = 0; k < num_params; k++) { argParam[k].Free(); } argPtrsStable.Free(); int code1 = ghostapi.gsapi_exit(gsInstance); if ((code == 0) || (code == gsConstants.E_QUIT)) { code = code1; } ghostapi.gsapi_delete_instance(gsInstance); Params.return_code = code; if ((code == 0) || (code == gsConstants.E_QUIT)) { Params.result = GS_Result_t.gsOK; e.Result = Params; } else { Params.result = GS_Result_t.gsFAILED; e.Result = Params; } gsInstance = IntPtr.Zero; } } return; }
/* Callback upon worker all done */ private void gsCompleted(object sender, RunWorkerCompletedEventArgs e) { gsParamState_t Value; gsEventArgs info; gsParamState_t Params; try { Params = (gsParamState_t)e.Result; } catch (System.Reflection.TargetInvocationException) { /* Something went VERY wrong with GS */ /* Following is to help debug these issues */ /* var inner = ee.InnerException; * var message = ee.Message; * var inner_message = inner.Message; * String bound = "\n************\n"; * gsIOUpdateMain(this, bound, bound.Length); * gsIOUpdateMain(this, message, message.Length); * gsIOUpdateMain(this, bound, bound.Length); * gsIOUpdateMain(this, inner_message, inner_message.Length); * gsIOUpdateMain(this, bound, bound.Length); * var temp = inner.Source; * gsIOUpdateMain(this, bound, bound.Length); * gsIOUpdateMain(this, temp, temp.Length); * var method = inner.TargetSite; * gsIOUpdateMain(this, bound, bound.Length); * var method_name = method.Name; * gsIOUpdateMain(this, method_name, method_name.Length); * var stack = inner.StackTrace; * gsIOUpdateMain(this, bound, bound.Length); * gsIOUpdateMain(this, stack, stack.Length); */ String output = "Ghostscript DLL Invalid Access."; gsDLLProblemMain(output); return; } switch (Params.task) { case GS_Task_t.PS_DISTILL: m_worker.DoWork -= new DoWorkEventHandler(gsBytesAsync); break; case GS_Task_t.DISPLAY_DEV_NON_PDF: case GS_Task_t.DISPLAY_DEV_PDF: case GS_Task_t.DISPLAY_DEV_THUMBS_NON_PDF: case GS_Task_t.DISPLAY_DEV_THUMBS_PDF: m_worker.DoWork -= new DoWorkEventHandler(DisplayDeviceAsync); break; default: m_worker.DoWork -= new DoWorkEventHandler(gsFileAsync); break; } if (e.Cancelled) { Value = new gsParamState_t(); Value.result = GS_Result_t.gsCANCELLED; info = new gsEventArgs(true, 100, Value); } else { Value = (gsParamState_t)e.Result; info = new gsEventArgs(true, 100, Value); } gsUpdateMain(info); }