public class Pdf2Pcl { public static byte[] ConvertPcl2Pdf(string pdfFileName) { byte[] rawDocumentData = null; var gsPipedOutput = new GhostscriptPipedOutput(); var outputPipeHandle = "%handle%" + int.Parse(gsPipedOutput.ClientHandle).ToString("X2"); using (var processor = new GhostscriptProcessor()) { var switches = new List<string>(); switches.Add("-dQUIET"); switches.Add("-dSAFER"); switches.Add("-dBATCH"); switches.Add("-dNOPAUSE"); switches.Add("-dNOPROMPT"); switches.Add("-sDEVICE=pxlmono"); switches.Add("-dNumRenderingThreads=20"); switches.Add("-o" + outputPipeHandle); switches.Add("-f"); switches.Add(pdfFileName); try { processor.StartProcessing(switches.ToArray(), new GsIoHandler()); rawDocumentData = gsPipedOutput.Data; } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { gsPipedOutput.Dispose(); gsPipedOutput = null; } } return rawDocumentData; } public class GsIoHandler : GhostscriptStdIO { public GsIoHandler() : base(true, true, true) { } public override void StdIn(out string input, int count) { input = string.Empty; } public override void StdOut(string output) { if (string.IsNullOrWhiteSpace(output)) return; output = output.Trim(); Console.WriteLine("GS: {0}",output); } public override void StdError(string error) { if (string.IsNullOrWhiteSpace(error)) return; error = error.Trim(); Console.WriteLine("GS: {0}", error); } } }
private const byte SkipTheByte = 0xff; private const byte UByte = 0xc0; private const byte AttrUByte = 0xf8; private const byte Orientation = 0x28; private const byte MediaSize = 0x25; private const byte MediaSource = 0x26; private const byte SimplexPageMode = 0x34; private const byte DuplexPageMode = 0x35; private const byte DuplexHorizontalBinding = 0x00; private const byte SimplexFrontSide = 0x00; private const byte DuplexVerticalBinding = 0x01; private const byte BeginPage = 0x43;
var pagePattern = new byte[] { UByte, SkipTheByte, AttrUByte, Orientation, UByte, SkipTheByte, AttrUByte, MediaSize, UByte, SkipTheByte, AttrUByte, MediaSource, UByte, SkipTheByte, AttrUByte, SimplexPageMode, BeginPage };
static int[] PatternMatching(byte[] data, byte[] pattern) { var pageShiftLst = new List<int>(); for (var i = 0; i < data.Count(); i++) { if (IsOnPattern(data, i, pattern)) { pageShiftLst.Add(i); Console.Write("{0:X8} | ", i); for (var j = 0; j < pattern.Count(); j++) { Console.Write("{0:X} ", data[i + j]); } Console.WriteLine(""); i += pattern.Count() - 1; } } return pageShiftLst.ToArray(); } static bool IsOnPattern(byte[] data, int shift, byte[] pattern) { for (var i = 0; i < pattern.Count() ; i++) { if (!((shift + i) < data.Count())) return false; if (pattern[i] != SkipTheByte) { if (pattern[i] != data[shift + i]) { return false; } } } return true; }
private const int MediaSourceValueShift = 9; private const int DuplexBindingShift = 13; private const int PageModeShift = 15;
static byte[] ApplyPattern(byte[] data, int[] pageIndexes, byte[] extraPattern, bool isDuplex) { for (int i = 0; i < pageIndexes.Length; i++) { var pageIndex = pageIndexes[i]; data[pageIndex + PageModeShift] = isDuplex ? DuplexPageMode : SimplexPageMode; data[pageIndex + DuplexBindingShift] = isDuplex ? DuplexVerticalBinding : SimplexFrontSide; data[pageIndex + MediaSourceValueShift] = extraPattern[i]; } return data; }
public static bool SendRawDataToPrinter(string szPrinterName, byte[] data, string docName) { bool bSuccess = false; IntPtr pUnmanagedBytes = new IntPtr(0); pUnmanagedBytes = Marshal.AllocCoTaskMem(data.Length); Marshal.Copy(data, 0, pUnmanagedBytes, data.Length); bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, data.Length, docName); Marshal.FreeCoTaskMem(pUnmanagedBytes); return bSuccess; }
using System; using System.Collections.Generic; using System.Drawing.Printing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PCL_processing { class Program { private const byte SkipTheByte = 0xff; // 0xfc - 0xff Reserved for future use. private const byte UByte = 0xc0; private const byte AttrUByte = 0xf8; private const byte Orientation = 0x28; private const byte MediaSize = 0x25; private const byte MediaSource = 0x26; private const byte SimplexPageMode = 0x34; private const byte DuplexPageMode = 0x35; private const byte DuplexHorizontalBinding = 0x00; private const byte SimplexFrontSide = 0x00; private const byte DuplexVerticalBinding = 0x01; private const byte BeginPage = 0x43; private const int MediaSourceValueShift = 9; private const int DuplexBindingShift = 13; private const int PageModeShift = 15; static void Main(string[] args) { var pagePattern = new byte[] { UByte, SkipTheByte, AttrUByte, Orientation, UByte, SkipTheByte, AttrUByte, MediaSize, UByte, SkipTheByte, AttrUByte, MediaSource, UByte, SkipTheByte, AttrUByte, SimplexPageMode, BeginPage }; var fileName = ""; if (!args.Any()) { while (true) { Console.WriteLine("Please write pdf file name:"); fileName = Console.ReadLine(); if (string.IsNullOrWhiteSpace(fileName)) { Console.WriteLine("You have wrote empty string"); continue; } break; } } else { fileName = args[0]; } if (!File.Exists(fileName)) { Console.WriteLine("File \"{0}\" not found", fileName); return; } var data = Pdf2Pcl.ConvertPcl2Pdf(fileName); var pageIndexes = PatternMatching(data, pagePattern); Console.WriteLine("Found {0} pages", pageIndexes.Length); var printPattern = GetSourecPattern(); var isDuplex = Menu(new[] {"Simplex", "Duplex"}, "Selec mode:") > 0; var extraPattern = ExtractPattern(printPattern, pageIndexes.Length, isDuplex); data = ApplyPattern(data, pageIndexes, extraPattern, isDuplex); for (int i = 0; i < pageIndexes.Length; i++) { Console.Write("{0:X8} | ", pageIndexes[i]); for (var j = 0; j < pagePattern.Count(); j++) { Console.Write("{0:X} ", data[pageIndexes[i] + j]); } Console.WriteLine(""); } var printer = GetPrinter(); RawPrinter.SendRawDataToPrinter(printer, data, fileName); Console.WriteLine("*** DONE ***"); Console.ReadLine(); } static byte[] ApplyPattern(byte[] data, int[] pageIndexes, byte[] extraPattern, bool isDuplex) { for (int i = 0; i < pageIndexes.Length; i++) { var pageIndex = pageIndexes[i]; data[pageIndex + PageModeShift] = isDuplex ? DuplexPageMode : SimplexPageMode; data[pageIndex + DuplexBindingShift] = isDuplex ? DuplexVerticalBinding : SimplexFrontSide; data[pageIndex + MediaSourceValueShift] = extraPattern[i]; } return data; } static int[] PatternMatching(byte[] data, byte[] pattern) { var pageShiftLst = new List<int>(); for (var i = 0; i < data.Count(); i++) { if (IsOnPattern(data, i, pattern)) { pageShiftLst.Add(i); Console.Write("{0:X8} | ", i); for (var j = 0; j < pattern.Count(); j++) { Console.Write("{0:X} ", data[i + j]); } Console.WriteLine(""); i += pattern.Count() - 1; } } return pageShiftLst.ToArray(); } static bool IsOnPattern(byte[] data, int shift, byte[] pattern) { for (var i = 0; i < pattern.Count() ; i++) { if (!((shift + i) < data.Count())) return false; if (pattern[i] != SkipTheByte) { if (pattern[i] != data[shift + i]) { return false; } } } return true; } private static byte[] ExtractPattern(int[] pattern, int pageCount, bool isDublex) { var srcPoint = 0; var expandedPattern = new List<byte>(); for (var pageNumber = 0; pageNumber < pageCount; pageNumber++) { // expand-pattern expandedPattern.Add((byte)pattern[srcPoint]); if (isDublex) { if (pageNumber % 2 != 0) { srcPoint++; } } else { srcPoint++; } srcPoint = srcPoint < pattern.Count() ? srcPoint : 0; } return expandedPattern.ToArray(); } private static int[] GetSourecPattern() { var bindingsFile = "source-bindings.kv"; var patternsFile = "patterns.csv"; var Bindings = GetBindings(bindingsFile); var Patterns = GetPatterns(patternsFile, Bindings); var patternindex = Menu(Patterns.Keys.ToArray(), "Please select pattern:"); var pattern = Patterns.ElementAt(patternindex).Value; var srcPattern = pattern.Select(i => Bindings[i]).ToList(); return srcPattern.ToArray(); } private static int Menu(string[] items, string message) { var selectedIndex = -1; while (true) { Console.WriteLine(message); for (int i = 0; i < items.Length; i++) { Console.WriteLine("[{0}] -- \"{1}\"", i, items[i]); } var str = Console.ReadLine(); if (Int32.TryParse(str, out selectedIndex)) { if (selectedIndex >= 0 && selectedIndex < items.Length) { break; } } } return selectedIndex; } private static Dictionary<int, int> GetBindings(string fileName) { if (!File.Exists(fileName)) { Console.WriteLine(" \"{0}\"", fileName); return new Dictionary<int, int>(); } var res = new Dictionary<int, int>(); var lines = File.ReadAllLines(fileName, Encoding.Default); foreach (var line in lines) { var kv = line.Split('='); if (kv.Count() != 2) { Console.WriteLine(" : \"{0}\"", line); return new Dictionary<int, int>(); } int k = 0; int v = 0; if (!int.TryParse(kv[0], out k)) { Console.WriteLine(" : \"{0}\"", line); return new Dictionary<int, int>(); } if (!int.TryParse(kv[1], out v)) { Console.WriteLine(" : \"{0}\"", line); return new Dictionary<int, int>(); } res[k] = v; } return res; } private static Dictionary<string, int[]> GetPatterns(string fileName, Dictionary<int, int> bindings) { if (!File.Exists(fileName)) { Console.WriteLine(" \"{0}\"", fileName); return new Dictionary<string, int[]>(); } var lines = File.ReadAllLines(fileName, Encoding.Default); var res = new Dictionary<string, int[]>(); foreach (var line in lines) { var splt = line.Split(';'); if (!splt.Any()) { Console.WriteLine(" \"{0}\"", line); return new Dictionary<string, int[]>(); } var patternName = splt[0]; var patternBody = new List<int>(); for (var i = 1; i < splt.Count(); i++) { int item = 0; if (!int.TryParse(splt[i], out item)) { Console.WriteLine(" \"{0}\"", line); break; } if (!bindings.ContainsKey(item)) { Console.WriteLine(" \"{0}\"", line); break; } patternBody.Add(item); } res[patternName] = patternBody.ToArray(); } return res; } static string GetPrinter() { var printers = new string[PrinterSettings.InstalledPrinters.Count]; PrinterSettings.InstalledPrinters.CopyTo(printers, 0); var printerIndex = Menu(printers, "Please select printer:"); return printers[printerIndex]; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Ghostscript.NET; using Ghostscript.NET.Processor; namespace PCL_processing { public class Pdf2Pcl { public static byte[] ConvertPcl2Pdf(string pdfFileName) { byte[] rawDocumentData = null; var gsPipedOutput = new GhostscriptPipedOutput(); var outputPipeHandle = "%handle%" + int.Parse(gsPipedOutput.ClientHandle).ToString("X2"); using (var processor = new GhostscriptProcessor()) { var switches = new List<string>(); switches.Add("-dQUIET"); switches.Add("-dSAFER"); switches.Add("-dBATCH"); switches.Add("-dNOPAUSE"); switches.Add("-dNOPROMPT"); switches.Add("-sDEVICE=pxlmono"); switches.Add("-o" + outputPipeHandle); switches.Add("-f"); switches.Add(pdfFileName); try { processor.StartProcessing(switches.ToArray(), new GsIoHandler()); rawDocumentData = gsPipedOutput.Data; } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { gsPipedOutput.Dispose(); gsPipedOutput = null; } } return rawDocumentData; } public class GsIoHandler : GhostscriptStdIO { public GsIoHandler() : base(true, true, true) { } public override void StdIn(out string input, int count) { input = string.Empty; } public override void StdOut(string output) { if (string.IsNullOrWhiteSpace(output)) return; output = output.Trim(); Console.WriteLine("GS: {0}",output); } public override void StdError(string error) { if (string.IsNullOrWhiteSpace(error)) return; error = error.Trim(); Console.WriteLine("GS: {0}", error); } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace PCL_processing { class RawPrinter { // Structure and API declarions: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] private class DOCINFOA { [MarshalAs(UnmanagedType.LPStr)] public string pDocName; [MarshalAs(UnmanagedType.LPStr)] public string pOutputFile; [MarshalAs(UnmanagedType.LPStr)] public string pDataType; } [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd); [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool ClosePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di); [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool EndDocPrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool StartPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool EndPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten); private static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount, string docName) { Int32 dwError = 0, dwWritten = 0; IntPtr hPrinter = new IntPtr(0); DOCINFOA di = new DOCINFOA(); bool bSuccess = false; // Assume failure unless you specifically succeed. di.pDocName = docName; di.pDataType = "RAW"; // Open the printer. if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)) { // Start a document. if (StartDocPrinter(hPrinter, 1, di)) { // Start a page. if (StartPagePrinter(hPrinter)) { // Write your bytes. bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten); EndPagePrinter(hPrinter); } EndDocPrinter(hPrinter); } ClosePrinter(hPrinter); } // If you did not succeed, GetLastError may give more information // about why not. if (bSuccess == false) { dwError = Marshal.GetLastWin32Error(); } return bSuccess; } public static bool SendRawDataToPrinter(string szPrinterName, byte[] data, string docName) { bool bSuccess = false; // Your unmanaged pointer. IntPtr pUnmanagedBytes = new IntPtr(0); // Allocate some unmanaged memory for those bytes. pUnmanagedBytes = Marshal.AllocCoTaskMem(data.Length); // Copy the managed byte array into the unmanaged array. Marshal.Copy(data, 0, pUnmanagedBytes, data.Length); // Send the unmanaged bytes to the printer. bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, data.Length, docName); // Free the unmanaged memory that you allocated earlier. Marshal.FreeCoTaskMem(pUnmanagedBytes); return bSuccess; } } }
;2;3;3;4;4
;2;3;4
;2;3;3;4
;2;4
;2
1=3
2=4
3=5
4=7
Source: https://habr.com/ru/post/302062/
All Articles