MuPDFCore 1.8.0
Multiplatform .NET bindings for MuPDF
Loading...
Searching...
No Matches
MuPDF.cs
1/*
2 MuPDFCore - A set of multiplatform .NET Core bindings for MuPDF.
3 Copyright (C) 2020 Giorgio Bianchini
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Affero General Public License as
7 published by the Free Software Foundation, version 3.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Affero General Public License for more details.
13
14 You should have received a copy of the GNU Affero General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>
16*/
17
18using System;
19using System.IO;
20using System.IO.Pipes;
21using System.Runtime.InteropServices;
22using System.Text;
23using System.Threading.Tasks;
24
25[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100d18d076ff369e4fb7295f51bbfedc5974e626236cec589265dca9183dd03ac869402b455337d976594875fb1993db7971bce4c6326bf5b6497ed50fe64629147cbe6ba727baf462fb9fcd2abb2db58feb93c754c92c107d6d57d9e099e8654ddc949d4622f13e01ef079351bc83c73988218218f3e67909ee75d225d6e9d78a7")]
26namespace MuPDFCore
27{
28 /// <summary>
29 /// Exit codes returned by native methods describing various errors that can occur.
30 /// </summary>
31 public enum ExitCodes
32 {
33 /// <summary>
34 /// An error occurred while creating the context object.
35 /// </summary>
36 ERR_CANNOT_CREATE_CONTEXT = 129,
37
38 /// <summary>
39 /// An error occurred while registering the default document handlers with the context.
40 /// </summary>
41 ERR_CANNOT_REGISTER_HANDLERS = 130,
42
43 /// <summary>
44 /// An error occurred while opening a file.
45 /// </summary>
46 ERR_CANNOT_OPEN_FILE = 131,
47
48 /// <summary>
49 /// An error occurred while determining the total number of pages in the document.
50 /// </summary>
51 ERR_CANNOT_COUNT_PAGES = 132,
52
53 /// <summary>
54 /// An error occurred while rendering the page.
55 /// </summary>
56 ERR_CANNOT_RENDER = 134,
57
58 /// <summary>
59 /// An error occurred while opening the stream.
60 /// </summary>
61 ERR_CANNOT_OPEN_STREAM = 135,
62
63 /// <summary>
64 /// An error occurred while loading the page.
65 /// </summary>
66 ERR_CANNOT_LOAD_PAGE = 136,
67
68 /// <summary>
69 /// An error occurred while computing the page bounds.
70 /// </summary>
71 ERR_CANNOT_COMPUTE_BOUNDS = 137,
72
73 /// <summary>
74 /// An error occurred while initialising the mutexes for the lock mechanism.
75 /// </summary>
76 ERR_CANNOT_INIT_MUTEX = 138,
77
78 /// <summary>
79 /// An error occurred while cloning the context.
80 /// </summary>
81 ERR_CANNOT_CLONE_CONTEXT = 139,
82
83 /// <summary>
84 /// An error occurred while saving the page to a raster image file.
85 /// </summary>
86 ERR_CANNOT_SAVE = 140,
87
88 /// <summary>
89 /// An error occurred while creating the output buffer.
90 /// </summary>
91 ERR_CANNOT_CREATE_BUFFER = 141,
92
93 /// <summary>
94 /// An error occurred while creating the document writer.
95 /// </summary>
96 ERR_CANNOT_CREATE_WRITER = 142,
97
98 /// <summary>
99 /// An error occurred while finalising the document file.
100 /// </summary>
101 ERR_CANNOT_CLOSE_DOCUMENT = 143,
102
103 /// <summary>
104 /// An error occurred while creating an empty structured text page.
105 /// </summary>
106 ERR_CANNOT_CREATE_PAGE = 144,
107
108 /// <summary>
109 /// An error occurred while populating the structured text page
110 /// </summary>
111 ERR_CANNOT_POPULATE_PAGE = 145,
112
113 /// <summary>
114 /// No error occurred. All is well.
115 /// </summary>
116 EXIT_SUCCESS = 0
117 }
118
119 /// <summary>
120 /// File types supported in input by the library.
121 /// </summary>
122 public enum InputFileTypes
123 {
124 /// <summary>
125 /// Portable Document Format.
126 /// </summary>
127 PDF = 0,
128
129 /// <summary>
130 /// XML Paper Specification document.
131 /// </summary>
132 XPS = 1,
133
134 /// <summary>
135 /// Comic book archive file (ZIP archive containing page scans).
136 /// </summary>
137 CBZ = 2,
138
139 /// <summary>
140 /// Portable Network Graphics format.
141 /// </summary>
142 PNG = 3,
143
144 /// <summary>
145 /// Joint Photographic Experts Group image.
146 /// </summary>
147 JPEG = 4,
148
149 /// <summary>
150 /// Bitmap image.
151 /// </summary>
152 BMP = 5,
153
154 /// <summary>
155 /// Graphics Interchange Format.
156 /// </summary>
157 GIF = 6,
158
159 /// <summary>
160 /// Tagged Image File Format.
161 /// </summary>
162 TIFF = 7,
163
164 /// <summary>
165 /// Portable aNyMap graphics format.
166 /// </summary>
167 PNM = 8,
168
169 /// <summary>
170 /// Portable Arbitrary Map graphics format.
171 /// </summary>
172 PAM = 9,
173
174 /// <summary>
175 /// Electronic PUBlication document.
176 /// </summary>
177 EPUB = 10,
178
179 /// <summary>
180 /// FictionBook document.
181 /// </summary>
182 FB2 = 11,
183
184 /// <summary>
185 /// Mobipocket e-book document.
186 /// </summary>
187 MOBI = 12,
188
189 /// <summary>
190 /// HTML document.
191 /// </summary>
192 HTML = 13,
193 }
194
195 /// <summary>
196 /// Raster image file types supported in output by the library.
197 /// </summary>
199 {
200 /// <summary>
201 /// Portable aNyMap graphics format.
202 /// </summary>
203 PNM = 0,
204
205 /// <summary>
206 /// Portable Arbitrary Map graphics format.
207 /// </summary>
208 PAM = 1,
209
210 /// <summary>
211 /// Portable Network Graphics format.
212 /// </summary>
213 PNG = 2,
214
215 /// <summary>
216 /// PhotoShop Document format.
217 /// </summary>
218 PSD = 3,
219
220 /// <summary>
221 /// Joint Photographic Experts Group format, with quality level 90.
222 /// </summary>
223 JPEG = 4
224 };
225
226 /// <summary>
227 /// Document file types supported in output by the library.
228 /// </summary>
230 {
231 /// <summary>
232 /// Portable Document Format.
233 /// </summary>
234 PDF = 0,
235
236 /// <summary>
237 /// Scalable Vector Graphics.
238 /// </summary>
239 SVG = 1,
240
241 /// <summary>
242 /// Comic book archive format.
243 /// </summary>
244 CBZ = 2
245 };
246
247 /// <summary>
248 /// Pixel formats supported by the library.
249 /// </summary>
250 public enum PixelFormats
251 {
252 /// <summary>
253 /// 24bpp RGB format.
254 /// </summary>
255 RGB = 0,
256
257 /// <summary>
258 /// 32bpp RGBA format.
259 /// </summary>
260 RGBA = 1,
261
262 /// <summary>
263 /// 24bpp BGR format.
264 /// </summary>
265 BGR = 2,
266
267 /// <summary>
268 /// 32bpp BGRA format.
269 /// </summary>
270 BGRA = 3
271 }
272
273 /// <summary>
274 /// Possible document encryption states.
275 /// </summary>
276 public enum EncryptionState
277 {
278 /// <summary>
279 /// The document is not encrypted.
280 /// </summary>
281 Unencrypted = 0,
282
283 /// <summary>
284 /// The document is encrypted and a user password is necessary to render it.
285 /// </summary>
286 Encrypted = 1,
287
288 /// <summary>
289 /// The document is encrypted and the correct user password has been supplied.
290 /// </summary>
291 Unlocked = 2
292 }
293
294 /// <summary>
295 /// Possible document restriction states.
296 /// </summary>
298 {
299 /// <summary>
300 /// The document does not have any restrictions associated to it.
301 /// </summary>
302 Unrestricted = 0,
303
304 /// <summary>
305 /// Some restrictions apply to the document. An owner password is required to remove these restrictions.
306 /// </summary>
307 Restricted = 1,
308
309 /// <summary>
310 /// The document had some restrictions and the correct owner password has been supplied.
311 /// </summary>
312 Unlocked = 2
313 }
314
315 /// <summary>
316 /// Document restrictions.
317 /// </summary>
319 {
320 /// <summary>
321 /// No operation is restricted.
322 /// </summary>
323 None = 0,
324
325 /// <summary>
326 /// Printing the document is restricted.
327 /// </summary>
328 Print = 1,
329
330 /// <summary>
331 /// Copying the document is restricted.
332 /// </summary>
333 Copy = 2,
334
335 /// <summary>
336 /// Editing the document is restricted.
337 /// </summary>
338 Edit = 4,
339
340 /// <summary>
341 /// Annotating the document is restricted.
342 /// </summary>
343 Annotate = 8
344 }
345
346 /// <summary>
347 /// Password types.
348 /// </summary>
349 public enum PasswordTypes
350 {
351 /// <summary>
352 /// No password.
353 /// </summary>
354 None = 0,
355
356 /// <summary>
357 /// The password corresponds to the user password.
358 /// </summary>
359 User = 1,
360
361 /// <summary>
362 /// The password corresponds to the owner password.
363 /// </summary>
364 Owner = 2
365 }
366
367 /// <summary>
368 /// A struct to hold information about the current rendering process and to abort rendering as needed.
369 /// </summary>
370 [StructLayout(LayoutKind.Sequential)]
371 internal struct Cookie
372 {
373 public int abort;
374 public int progress;
375 public ulong progress_max;
376 public int errors;
377 public int incomplete;
378 }
379
380 /// <summary>
381 /// Holds a summary of the progress of the current rendering operation.
382 /// </summary>
383 public class RenderProgress
384 {
385 /// <summary>
386 /// Holds the progress of a single thread.
387 /// </summary>
389 {
390 /// <summary>
391 /// The current progress.
392 /// </summary>
393 public int Progress;
394
395 /// <summary>
396 /// The maximum progress. If this is 0, this value could not be determined (yet).
397 /// </summary>
398 public long MaxProgress;
399
400 internal ThreadRenderProgress(int progress, ulong maxProgress)
401 {
402 this.Progress = progress;
403 this.MaxProgress = (long)maxProgress;
404 }
405 }
406
407 /// <summary>
408 /// Contains the progress of all the threads used in rendering the document.
409 /// </summary>
410 public ThreadRenderProgress[] ThreadRenderProgresses { get; private set; }
411
412 internal RenderProgress(ThreadRenderProgress[] threadRenderProgresses)
413 {
414 ThreadRenderProgresses = threadRenderProgresses;
415 }
416 }
417
418 /// <summary>
419 /// An <see cref="IDisposable"/> wrapper around an <see cref="IntPtr"/> that frees the allocated memory when it is disposed.
420 /// </summary>
421 public class DisposableIntPtr : IDisposable
422 {
423 /// <summary>
424 /// The pointer to the unmanaged memory.
425 /// </summary>
426 private readonly IntPtr InternalPointer;
427
428 /// <summary>
429 /// The number of bytes that have been allocated, for adding memory pressure.
430 /// </summary>
431 private readonly long BytesAllocated = -1;
432
433 /// <summary>
434 /// Create a new DisposableIntPtr.
435 /// </summary>
436 /// <param name="pointer">The pointer that should be freed upon disposing of this object.</param>
437 public DisposableIntPtr(IntPtr pointer)
438 {
439 this.InternalPointer = pointer;
440 }
441
442 /// <summary>
443 /// Create a new DisposableIntPtr, adding memory pressure to the GC to account for the allocation of unmanaged memory.
444 /// </summary>
445 /// <param name="pointer">The pointer that should be freed upon disposing of this object.</param>
446 /// <param name="bytesAllocated">The number of bytes that have been allocated, for adding memory pressure.</param>
447 public DisposableIntPtr(IntPtr pointer, long bytesAllocated)
448 {
449 this.InternalPointer = pointer;
450 this.BytesAllocated = bytesAllocated;
451
452 if (BytesAllocated > 0)
453 {
454 GC.AddMemoryPressure(bytesAllocated);
455 }
456 }
457
458 private bool disposedValue;
459
460 ///<inheritdoc/>
461 protected virtual void Dispose(bool disposing)
462 {
463 if (!disposedValue)
464 {
465 Marshal.FreeHGlobal(InternalPointer);
466
467 if (BytesAllocated > 0)
468 {
469 GC.RemoveMemoryPressure(BytesAllocated);
470 }
471
472 disposedValue = true;
473 }
474 }
475
476 ///<inheritdoc/>
477 ~DisposableIntPtr()
478 {
479 Dispose(disposing: false);
480 }
481
482 ///<inheritdoc/>
483 public void Dispose()
484 {
485 Dispose(disposing: true);
486 GC.SuppressFinalize(this);
487 }
488 }
489
490 /// <summary>
491 /// The exception that is thrown when a MuPDF operation fails.
492 /// </summary>
493 public class MuPDFException : Exception
494 {
495 /// <summary>
496 /// The <see cref="ExitCodes"/> returned by the native function.
497 /// </summary>
498 public readonly ExitCodes ErrorCode;
499
500 internal MuPDFException(string message, ExitCodes errorCode) : base(message)
501 {
502 this.ErrorCode = errorCode;
503 }
504 }
505
506 /// <summary>
507 /// The exception that is thrown when an attempt is made to render an encrypted document without supplying the required password.
508 /// </summary>
509 public class DocumentLockedException : Exception
510 {
511 internal DocumentLockedException(string message) : base(message) { }
512 }
513
514 /// <summary>
515 /// A class to simplify passing a string to the MuPDF C library with the correct encoding.
516 /// </summary>
517 internal class UTF8EncodedString : IDisposable
518 {
519 private bool disposedValue;
520
521 /// <summary>
522 /// The address of the bytes encoding the string in unmanaged memory.
523 /// </summary>
524 public IntPtr Address { get; }
525
526 /// <summary>
527 /// Create a null-terminated, UTF-8 encoded string in unmanaged memory.
528 /// </summary>
529 /// <param name="text"></param>
530 public UTF8EncodedString(string text)
531 {
532 byte[] data = System.Text.Encoding.UTF8.GetBytes(text);
533
534 IntPtr dataHolder = Marshal.AllocHGlobal(data.Length + 1);
535 Marshal.Copy(data, 0, dataHolder, data.Length);
536 Marshal.WriteByte(dataHolder, data.Length, 0);
537
538 this.Address = dataHolder;
539 }
540
541 protected virtual void Dispose(bool disposing)
542 {
543 if (!disposedValue)
544 {
545 Marshal.FreeHGlobal(Address);
546 disposedValue = true;
547 }
548 }
549
550 ~UTF8EncodedString()
551 {
552 Dispose(disposing: false);
553 }
554
555 public void Dispose()
556 {
557 Dispose(disposing: true);
558 GC.SuppressFinalize(this);
559 }
560 }
561
562 /// <summary>
563 /// EventArgs for the <see cref="MuPDF.StandardOutputMessage"/> and <see cref="MuPDF.StandardErrorMessage"/> events.
564 /// </summary>
565 public class MessageEventArgs : EventArgs
566 {
567 /// <summary>
568 /// The message that has been logged.
569 /// </summary>
570 public string Message { get; }
571
572 /// <summary>
573 /// Create a new <see cref="MessageEventArgs"/> instance.
574 /// </summary>
575 /// <param name="message">The message that has been logged.</param>
576 public MessageEventArgs(string message)
577 {
578 this.Message = message;
579 }
580 }
581
582 /// <summary>
583 /// Contains static methods to perform setup operations.
584 /// </summary>
585 public static class MuPDF
586 {
587 private static int StdOutFD = -1;
588 private static int StdErrFD = -1;
589
590 private static TextWriter ConsoleOut;
591 private static TextWriter ConsoleErr;
592
593 private static ConsoleColor DefaultForeground;
594 private static ConsoleColor DefaultBackground;
595
596 private static string PipeName;
597 private static bool CleanupRegistered = false;
598 private static object CleanupLock = new object();
599
600 /// <summary>
601 /// This event is invoked when <see cref="RedirectOutput"/> has been called and the native MuPDF library writes to the standard output stream.
602 /// </summary>
603 public static event EventHandler<MessageEventArgs> StandardOutputMessage;
604
605 /// <summary>
606 /// This event is invoked when <see cref="RedirectOutput"/> has been called and the native MuPDF library writes to the standard error stream.
607 /// </summary>
608 public static event EventHandler<MessageEventArgs> StandardErrorMessage;
609
610 /// <summary>
611 /// Redirects output messages from the native MuPDF library to the <see cref="StandardOutputMessage"/> and <see cref="StandardErrorMessage"/> events. Note that this has side-effects.
612 /// </summary>
613 /// <returns>A <see cref="Task"/> that finishes when the output streams have been redirected.</returns>
614 public static async Task RedirectOutput()
615 {
616 if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows))
617 {
618 await RedirectOutputWindows();
619 }
620 else
621 {
622 await RedirectOutputUnix();
623 }
624
625 if (!CleanupRegistered)
626 {
627 AppDomain.CurrentDomain.ProcessExit += (s, e) =>
628 {
629 ResetOutput();
630 };
631 }
632 }
633
634 const int UnixMaxPipeLength = 107;
635
636 private static async Task RedirectOutputUnix()
637 {
638 if (StdOutFD < 0 && StdErrFD < 0)
639 {
640 string tempPath = Path.GetTempPath();
641
642 string pipeName = "MuPDFCore-" + Guid.NewGuid().ToString();
643
644 pipeName = pipeName.Substring(0, Math.Min(pipeName.Length, UnixMaxPipeLength - tempPath.Length - 4));
645 pipeName = Path.Combine(tempPath, pipeName);
646
647 PipeName = pipeName;
648
649 Task redirectOutputTask = System.Threading.Tasks.Task.Run(() =>
650 {
651 NativeMethods.RedirectOutput(out StdOutFD, out StdErrFD, pipeName + "-out", pipeName + "-err");
652 });
653
654 // Start stdout pipe (this is actually a socket)
655 _ = Task.Run(() =>
656 {
657 using (NamedPipeClientStream client = new NamedPipeClientStream(pipeName + "-out"))
658 {
659 while (true)
660 {
661 try
662 {
663 client.Connect(100);
664 break;
665 }
666 catch { }
667 }
668
669 using (StreamReader reader = new StreamReader(client))
670 {
671 while (true)
672 {
673 string message = reader.ReadLine();
674
675 if (!string.IsNullOrEmpty(message))
676 {
677 StandardOutputMessage?.Invoke(null, new MessageEventArgs(message));
678 }
679 }
680 }
681 }
682
683 });
684
685 // Start stderr pipe (this is actually a socket)
686 _ = Task.Run(() =>
687 {
688 using (NamedPipeClientStream client = new NamedPipeClientStream(pipeName + "-err"))
689 {
690 while (true)
691 {
692 try
693 {
694 client.Connect(100);
695 break;
696 }
697 catch { }
698 }
699
700 using (StreamReader reader = new StreamReader(client))
701 {
702 while (true)
703 {
704 string message = reader.ReadLine();
705
706 if (!string.IsNullOrEmpty(message))
707 {
708 StandardErrorMessage?.Invoke(null, new MessageEventArgs(message));
709 }
710 }
711 }
712 }
713
714 });
715
716 await redirectOutputTask;
717
718 ConsoleOut = Console.Out;
719 ConsoleErr = Console.Error;
720
721 ConsoleColor fg = Console.ForegroundColor;
722 ConsoleColor bg = Console.BackgroundColor;
723
724 Console.ResetColor();
725
726 DefaultForeground = Console.ForegroundColor;
727 DefaultBackground = Console.BackgroundColor;
728
729 Console.ForegroundColor = fg;
730 Console.BackgroundColor = bg;
731
732 Console.SetOut(new FileDescriptorTextWriter(Console.Out.Encoding, StdOutFD));
733 Console.SetError(new FileDescriptorTextWriter(Console.Error.Encoding, StdErrFD));
734 }
735 }
736
737 private static async Task RedirectOutputWindows()
738 {
739 if (StdOutFD < 0 && StdErrFD < 0)
740 {
741 string pipeName = "MuPDFCore-" + Guid.NewGuid().ToString();
742
743 Task redirectOutputTask = System.Threading.Tasks.Task.Run(() =>
744 {
745 NativeMethods.RedirectOutput(out StdOutFD, out StdErrFD, "\\\\.\\pipe\\" + pipeName + "-out", "\\\\.\\pipe\\" + pipeName + "-err");
746 });
747
748 // Start stdout pipe
749 _ = Task.Run(() =>
750 {
751 using (NamedPipeClientStream client = new NamedPipeClientStream(pipeName + "-out"))
752 {
753 while (true)
754 {
755 try
756 {
757 client.Connect(100);
758 break;
759 }
760 catch { }
761 }
762
763 using (StreamReader reader = new StreamReader(client))
764 {
765 while (true)
766 {
767 string message = reader.ReadLine();
768
769 if (!string.IsNullOrEmpty(message))
770 {
771 StandardOutputMessage?.Invoke(null, new MessageEventArgs(message));
772 }
773 }
774 }
775 }
776
777 });
778
779 // Start stderr pipe
780 _ = Task.Run(() =>
781 {
782 using (NamedPipeClientStream client = new NamedPipeClientStream(pipeName + "-err"))
783 {
784 while (true)
785 {
786 try
787 {
788 client.Connect(100);
789 break;
790 }
791 catch { }
792 }
793
794 using (StreamReader reader = new StreamReader(client))
795 {
796 while (true)
797 {
798 string message = reader.ReadLine();
799
800 if (!string.IsNullOrEmpty(message))
801 {
802 StandardErrorMessage?.Invoke(null, new MessageEventArgs(message));
803 }
804 }
805 }
806 }
807
808 });
809
810 await redirectOutputTask;
811
812 ConsoleOut = Console.Out;
813 ConsoleErr = Console.Error;
814
815 ConsoleColor fg = Console.ForegroundColor;
816 ConsoleColor bg = Console.BackgroundColor;
817
818 Console.ResetColor();
819
820 DefaultForeground = Console.ForegroundColor;
821 DefaultBackground = Console.BackgroundColor;
822
823 Console.ForegroundColor = fg;
824 Console.BackgroundColor = bg;
825
826 Console.SetOut(new FileDescriptorTextWriter(Console.Out.Encoding, StdOutFD));
827 Console.SetError(new FileDescriptorTextWriter(Console.Error.Encoding, StdErrFD));
828 }
829 }
830
831 /// <summary>
832 /// Reset the default standard output and error streams for the native MuPDF library.
833 /// </summary>
834 public static void ResetOutput()
835 {
836 lock (CleanupLock)
837 {
838 if (StdOutFD >= 0 && StdErrFD >= 0)
839 {
840 NativeMethods.ResetOutput(StdOutFD, StdErrFD);
841
842 Console.SetOut(ConsoleOut);
843 Console.SetError(ConsoleErr);
844
845 StdOutFD = -1;
846 StdErrFD = -1;
847
848 if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
849 {
850 File.Delete(PipeName + "-out");
851 File.Delete(PipeName + "-err");
852 }
853 }
854 }
855 }
856
857 internal class FileDescriptorTextWriter : TextWriter
858 {
859 public override Encoding Encoding { get; }
860 private int FileDescriptor { get; }
861
862 public FileDescriptorTextWriter(Encoding encoding, int fileDescriptor)
863 {
864 this.Encoding = encoding;
865 this.FileDescriptor = fileDescriptor;
866 }
867
868 public override void Write(string value)
869 {
870 StringBuilder sb = new StringBuilder();
871
872 if (Console.ForegroundColor != DefaultForeground || Console.BackgroundColor != DefaultBackground)
873 {
874 sb.Append("␛[");
875 }
876
877 if (Console.ForegroundColor != DefaultForeground)
878 {
879 switch (Console.ForegroundColor)
880 {
881 case ConsoleColor.Black:
882 sb.Append("30");
883 break;
884 case ConsoleColor.DarkRed:
885 sb.Append("31");
886 break;
887 case ConsoleColor.DarkGreen:
888 sb.Append("32");
889 break;
890 case ConsoleColor.DarkYellow:
891 sb.Append("33");
892 break;
893 case ConsoleColor.DarkBlue:
894 sb.Append("34");
895 break;
896 case ConsoleColor.DarkMagenta:
897 sb.Append("35");
898 break;
899 case ConsoleColor.DarkCyan:
900 sb.Append("36");
901 break;
902 case ConsoleColor.Gray:
903 sb.Append("37");
904 break;
905 case ConsoleColor.DarkGray:
906 sb.Append("90");
907 break;
908 case ConsoleColor.Red:
909 sb.Append("91");
910 break;
911 case ConsoleColor.Green:
912 sb.Append("92");
913 break;
914 case ConsoleColor.Yellow:
915 sb.Append("93");
916 break;
917 case ConsoleColor.Blue:
918 sb.Append("94");
919 break;
920 case ConsoleColor.Magenta:
921 sb.Append("95");
922 break;
923 case ConsoleColor.Cyan:
924 sb.Append("96");
925 break;
926 case ConsoleColor.White:
927 sb.Append("97");
928 break;
929 }
930 }
931
932 if (Console.ForegroundColor != DefaultForeground && Console.BackgroundColor != DefaultBackground)
933 {
934 sb.Append(";");
935 }
936
937 if (Console.BackgroundColor != DefaultBackground)
938 {
939 switch (Console.BackgroundColor)
940 {
941 case ConsoleColor.Black:
942 sb.Append("40");
943 break;
944 case ConsoleColor.DarkRed:
945 sb.Append("41");
946 break;
947 case ConsoleColor.DarkGreen:
948 sb.Append("42");
949 break;
950 case ConsoleColor.DarkYellow:
951 sb.Append("43");
952 break;
953 case ConsoleColor.DarkBlue:
954 sb.Append("44");
955 break;
956 case ConsoleColor.DarkMagenta:
957 sb.Append("45");
958 break;
959 case ConsoleColor.DarkCyan:
960 sb.Append("46");
961 break;
962 case ConsoleColor.Gray:
963 sb.Append("47");
964 break;
965 case ConsoleColor.DarkGray:
966 sb.Append("100");
967 break;
968 case ConsoleColor.Red:
969 sb.Append("101");
970 break;
971 case ConsoleColor.Green:
972 sb.Append("102");
973 break;
974 case ConsoleColor.Yellow:
975 sb.Append("103");
976 break;
977 case ConsoleColor.Blue:
978 sb.Append("104");
979 break;
980 case ConsoleColor.Magenta:
981 sb.Append("105");
982 break;
983 case ConsoleColor.Cyan:
984 sb.Append("106");
985 break;
986 case ConsoleColor.White:
987 sb.Append("107");
988 break;
989 }
990 }
991
992 if (Console.ForegroundColor != DefaultForeground || Console.BackgroundColor != DefaultBackground)
993 {
994 sb.Append("m");
995 }
996
997 sb.Append(value);
998
999 if (Console.ForegroundColor != DefaultForeground || Console.BackgroundColor != DefaultBackground)
1000 {
1001 sb.Append("␛[");
1002 }
1003
1004 if (Console.ForegroundColor != DefaultForeground)
1005 {
1006 sb.Append("39");
1007 }
1008
1009 if (Console.ForegroundColor != DefaultForeground && Console.BackgroundColor != DefaultBackground)
1010 {
1011 sb.Append(";");
1012 }
1013
1014 if (Console.BackgroundColor != DefaultBackground)
1015 {
1016 sb.Append("49");
1017 }
1018
1019 if (Console.ForegroundColor != DefaultForeground || Console.BackgroundColor != DefaultBackground)
1020 {
1021 sb.Append("m");
1022 }
1023
1024 NativeMethods.WriteToFileDescriptor(FileDescriptor, sb.ToString(), sb.Length);
1025 }
1026
1027 public override void Write(char value)
1028 {
1029 Write(value.ToString());
1030 }
1031
1032 public override void Write(char[] buffer)
1033 {
1034 Write(new string(buffer));
1035 }
1036
1037 public override void Write(char[] buffer, int index, int count)
1038 {
1039 Write(new string(buffer, index, count));
1040 }
1041
1042 public override void WriteLine(string value)
1043 {
1044 Write(value);
1045 WriteLine();
1046 }
1047 }
1048 }
1049
1050 /// <summary>
1051 /// Native methods.
1052 /// </summary>
1053 internal static class NativeMethods
1054 {
1055 /// <summary>
1056 /// Create a MuPDF context object with the specified store size.
1057 /// </summary>
1058 /// <param name="store_size">Maximum size in bytes of the resource store.</param>
1059 /// <param name="out_ctx">A pointer to the native context object.</param>
1060 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1061 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1062 internal static extern int CreateContext(ulong store_size, ref IntPtr out_ctx);
1063
1064 /// <summary>
1065 /// Free a context and its global store.
1066 /// </summary>
1067 /// <param name="ctx">A pointer to the native context to free.</param>
1068 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1069 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1070 internal static extern int DisposeContext(IntPtr ctx);
1071
1072 /// <summary>
1073 /// Evict items from the store until the total size of the objects in the store is reduced to a given percentage of its current size.
1074 /// </summary>
1075 /// <param name="ctx">The context whose store should be shrunk.</param>
1076 /// <param name="perc">Fraction of current size to reduce the store to.</param>
1077 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1078 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1079 internal static extern int ShrinkStore(IntPtr ctx, uint perc);
1080
1081 /// <summary>
1082 /// Evict every item from the store.
1083 /// </summary>
1084 /// <param name="ctx">The context whose store should be emptied.</param>
1085 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1086 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1087 internal static extern void EmptyStore(IntPtr ctx);
1088
1089 /// <summary>
1090 /// Get the current size of the store.
1091 /// </summary>
1092 /// <param name="ctx">The context whose store's size should be determined.</param>
1093 /// <returns>The current size in bytes of the store.</returns>
1094 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1095 internal static extern ulong GetCurrentStoreSize(IntPtr ctx);
1096
1097 /// <summary>
1098 /// Get the maximum size of the store.
1099 /// </summary>
1100 /// <param name="ctx">The context whose store's maximum size should be determined.</param>
1101 /// <returns>The maximum size in bytes of the store.</returns>
1102 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1103 internal static extern ulong GetMaxStoreSize(IntPtr ctx);
1104
1105 /// <summary>
1106 /// Set the current antialiasing levels.
1107 /// </summary>
1108 /// <param name="ctx">The context whose antialiasing levels should be set.</param>
1109 /// <param name="aa">The overall antialiasing level. Ignored if &lt; 0.</param>
1110 /// <param name="graphics_aa">The graphics antialiasing level. Ignored if &lt; 0.</param>
1111 /// <param name="text_aa">The text antialiasing level. Ignored if &lt; 0.</param>
1112 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1113 internal static extern void SetAALevel(IntPtr ctx, int aa, int graphics_aa, int text_aa);
1114
1115 /// <summary>
1116 /// Get the current antialiasing levels.
1117 /// </summary>
1118 /// <param name="ctx">The context whose antialiasing levels should be retrieved.</param>
1119 /// <param name="out_aa">The overall antialiasing level.</param>
1120 /// <param name="out_graphics_aa">The graphics antialiasing level.</param>
1121 /// <param name="out_text_aa">The text antialiasing level.</param>
1122 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1123 internal static extern void GetAALevel(IntPtr ctx, out int out_aa, out int out_graphics_aa, out int out_text_aa);
1124
1125 /// <summary>
1126 /// Create a display list from a page.
1127 /// </summary>
1128 /// <param name="ctx">A pointer to the context used to create the document.</param>
1129 /// <param name="page">A pointer to the page that should be used to create the display list.</param>
1130 /// <param name="annotations">An integer indicating whether annotations should be included in the display list (1) or not (any other value).</param>
1131 /// <param name="out_display_list">A pointer to the newly-created display list.</param>
1132 /// <param name="out_x0">The left coordinate of the display list's bounds.</param>
1133 /// <param name="out_y0">The top coordinate of the display list's bounds.</param>
1134 /// <param name="out_x1">The right coordinate of the display list's bounds.</param>
1135 /// <param name="out_y1">The bottom coordinate of the display list's bounds.</param>
1136 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1137 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1138 internal static extern int GetDisplayList(IntPtr ctx, IntPtr page, int annotations, ref IntPtr out_display_list, ref float out_x0, ref float out_y0, ref float out_x1, ref float out_y1);
1139
1140 /// <summary>
1141 /// Free a display list.
1142 /// </summary>
1143 /// <param name="ctx">The context that was used to create the display list.</param>
1144 /// <param name="list">The display list to dispose.</param>
1145 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1146 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1147 internal static extern int DisposeDisplayList(IntPtr ctx, IntPtr list);
1148
1149 /// <summary>
1150 /// Create a new document from a stream.
1151 /// </summary>
1152 /// <param name="ctx">The context to which the document will belong.</param>
1153 /// <param name="data">A pointer to a byte array containing the data that makes up the document.</param>
1154 /// <param name="data_length">The length in bytes of the data that makes up the document.</param>
1155 /// <param name="file_type">The type (extension) of the document.</param>
1156 /// <param name="get_image_resolution">If this is not 0, try opening the stream as an image and return the actual resolution (in DPI) of the image. Otherwise (or if trying to open the stream as an image fails), the returned resolution will be -1.</param>
1157 /// <param name="out_doc">The newly created document.</param>
1158 /// <param name="out_str">The newly created stream (so that it can be disposed later).</param>
1159 /// <param name="out_page_count">The number of pages in the document.</param>
1160 /// <param name="out_image_xres">If the document is an image file, the horizontal resolution of the image.</param>
1161 /// <param name="out_image_yres">If the document is an image file, the vertical resolution of the image.</param>
1162 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1163 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1164 internal static extern int CreateDocumentFromStream(IntPtr ctx, IntPtr data, ulong data_length, string file_type, int get_image_resolution, ref IntPtr out_doc, ref IntPtr out_str, ref int out_page_count, ref float out_image_xres, ref float out_image_yres);
1165
1166 /// <summary>
1167 /// Create a new document from a file name.
1168 /// </summary>
1169 /// <param name="ctx">The context to which the document will belong.</param>
1170 /// <param name="file_name">The path of the file to open, UTF-8 encoded.</param>
1171 /// <param name="get_image_resolution">If this is not 0, try opening the file as an image and return the actual resolution (in DPI) of the image. Otherwise (or if trying to open the file as an image fails), the returned resolution will be -1.</param>
1172 /// <param name="out_doc">The newly created document.</param>
1173 /// <param name="out_page_count">The number of pages in the document.</param>
1174 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1175 /// <param name="out_image_xres">If the document is an image file, the horizontal resolution of the image.</param>
1176 /// <param name="out_image_yres">If the document is an image file, the vertical resolution of the image.</param>
1177 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1178 internal static extern int CreateDocumentFromFile(IntPtr ctx, IntPtr file_name, int get_image_resolution, ref IntPtr out_doc, ref int out_page_count, ref float out_image_xres, ref float out_image_yres);
1179
1180 /// <summary>
1181 /// Free a stream and its associated resources.
1182 /// </summary>
1183 /// <param name="ctx">The context that was used while creating the stream.</param>
1184 /// <param name="str">The stream to free.</param>
1185 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1186 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1187 internal static extern int DisposeStream(IntPtr ctx, IntPtr str);
1188
1189 /// <summary>
1190 /// Free a document and its associated resources.
1191 /// </summary>
1192 /// <param name="ctx">The context that was used in creating the document.</param>
1193 /// <param name="doc">The document to free.</param>
1194 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1195 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1196 internal static extern int DisposeDocument(IntPtr ctx, IntPtr doc);
1197
1198 /// <summary>
1199 /// Render (part of) a display list to an array of bytes starting at the specified pointer.
1200 /// </summary>
1201 /// <param name="ctx">A context to hold the exception stack and the cached resources.</param>
1202 /// <param name="list">The display list to render.</param>
1203 /// <param name="x0">The left coordinate in page units of the region of the display list that should be rendererd.</param>
1204 /// <param name="y0">The top coordinate in page units of the region of the display list that should be rendererd.</param>
1205 /// <param name="x1">The right coordinate in page units of the region of the display list that should be rendererd.</param>
1206 /// <param name="y1">The bottom coordinate in page units of the region of the display list that should be rendererd.</param>
1207 /// <param name="zoom">How much the specified region should be scaled when rendering. This determines the size in pixels of the rendered image.</param>
1208 /// <param name="colorFormat">The pixel data format.</param>
1209 /// <param name="pixel_storage">A pointer indicating where the pixel bytes will be written. There must be enough space available!</param>
1210 /// <param name="cookie">A pointer to a cookie object that can be used to track progress and/or abort rendering. Can be null.</param>
1211 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1212 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1213 internal static extern int RenderSubDisplayList(IntPtr ctx, IntPtr list, float x0, float y0, float x1, float y1, float zoom, int colorFormat, IntPtr pixel_storage, IntPtr cookie);
1214
1215 /// <summary>
1216 /// Load a page from a document.
1217 /// </summary>
1218 /// <param name="ctx">The context to which the document belongs.</param>
1219 /// <param name="doc">The document from which the page should be extracted.</param>
1220 /// <param name="page_number">The page number.</param>
1221 /// <param name="out_page">The newly extracted page.</param>
1222 /// <param name="out_x">The left coordinate of the page's bounds.</param>
1223 /// <param name="out_y">The top coordinate of the page's bounds.</param>
1224 /// <param name="out_w">The width of the page.</param>
1225 /// <param name="out_h">The height of the page.</param>
1226 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1227 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1228 internal static extern int LoadPage(IntPtr ctx, IntPtr doc, int page_number, ref IntPtr out_page, ref float out_x, ref float out_y, ref float out_w, ref float out_h);
1229
1230 /// <summary>
1231 /// Free a page and its associated resources.
1232 /// </summary>
1233 /// <param name="ctx">The context to which the document containing the page belongs.</param>
1234 /// <param name="page">The page to free.</param>
1235 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1236 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1237 internal static extern int DisposePage(IntPtr ctx, IntPtr page);
1238
1239 /// <summary>
1240 /// Layout reflowable document types.
1241 /// </summary>
1242 /// <param name="ctx">The context to which the document belongs.</param>
1243 /// <param name="doc">The document to layout.</param>
1244 /// <param name="width">The page width.</param>
1245 /// <param name="height">The page height.</param>
1246 /// <param name="em">The default font size, in points.</param>
1247 /// <param name="out_page_count">The number of pages in the document, after the layout.</param>
1248 /// <returns>An integer detailing whether any errors occurred.</returns>
1249 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1250 internal static extern int LayoutDocument(IntPtr ctx, IntPtr doc, float width, float height, float em, out int out_page_count);
1251
1252 /// <summary>
1253 /// Create cloned contexts that can be used in multithreaded rendering.
1254 /// </summary>
1255 /// <param name="ctx">The original context to clone.</param>
1256 /// <param name="count">The number of cloned contexts to create.</param>
1257 /// <param name="out_contexts">An array of pointers to the cloned contexts.</param>
1258 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1259 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1260 internal static extern int CloneContext(IntPtr ctx, int count, IntPtr out_contexts);
1261
1262 /// <summary>
1263 /// Save (part of) a display list to an image file in the specified format.
1264 /// </summary>
1265 /// <param name="ctx">A context to hold the exception stack and the cached resources.</param>
1266 /// <param name="list">The display list to render.</param>
1267 /// <param name="x0">The left coordinate in page units of the region of the display list that should be rendererd.</param>
1268 /// <param name="y0">The top coordinate in page units of the region of the display list that should be rendererd.</param>
1269 /// <param name="x1">The right coordinate in page units of the region of the display list that should be rendererd.</param>
1270 /// <param name="y1">The bottom coordinate in page units of the region of the display list that should be rendererd.</param>
1271 /// <param name="zoom">How much the specified region should be scaled when rendering. This determines the size in pixels of the rendered image.</param>
1272 /// <param name="colorFormat">The pixel data format.</param>
1273 /// <param name="file_name">The path to the output file, UTF-8 encoded.</param>
1274 /// <param name="output_format">An integer equivalent to <see cref="RasterOutputFileTypes"/> specifying the output format.</param>
1275 /// <param name="quality">Quality level for the output format (where applicable).</param>
1276 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1277 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1278 internal static extern int SaveImage(IntPtr ctx, IntPtr list, float x0, float y0, float x1, float y1, float zoom, int colorFormat, IntPtr file_name, int output_format, int quality);
1279
1280 /// <summary>
1281 /// Write (part of) a display list to an image buffer in the specified format.
1282 /// </summary>
1283 /// <param name="ctx">A context to hold the exception stack and the cached resources.</param>
1284 /// <param name="list">The display list to render.</param>
1285 /// <param name="x0">The left coordinate in page units of the region of the display list that should be rendererd.</param>
1286 /// <param name="y0">The top coordinate in page units of the region of the display list that should be rendererd.</param>
1287 /// <param name="x1">The right coordinate in page units of the region of the display list that should be rendererd.</param>
1288 /// <param name="y1">The bottom coordinate in page units of the region of the display list that should be rendererd.</param>
1289 /// <param name="zoom">How much the specified region should be scaled when rendering. This determines the size in pixels of the rendered image.</param>
1290 /// <param name="colorFormat">The pixel data format.</param>
1291 /// <param name="output_format">An integer equivalent to <see cref="RasterOutputFileTypes"/> specifying the output format.</param>
1292 /// <param name="quality">Quality level for the output format (where applicable).</param>
1293 /// <param name="out_buffer">The address of the buffer on which the data has been written (only useful for disposing the buffer later).</param>
1294 /// <param name="out_data">The address of the byte array where the data has been actually written.</param>
1295 /// <param name="out_length">The length in bytes of the image data.</param>
1296 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1297 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1298 internal static extern int WriteImage(IntPtr ctx, IntPtr list, float x0, float y0, float x1, float y1, float zoom, int colorFormat, int output_format, int quality, ref IntPtr out_buffer, ref IntPtr out_data, ref ulong out_length);
1299
1300 /// <summary>
1301 /// Free a native buffer and its associated resources.
1302 /// </summary>
1303 /// <param name="ctx">A context to hold the exception stack and the cached resources.</param>
1304 /// <param name="buf">The buffer to free.</param>
1305 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1306 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1307 internal static extern int DisposeBuffer(IntPtr ctx, IntPtr buf);
1308
1309 /// <summary>
1310 /// Create a new document writer object.
1311 /// </summary>
1312 /// <param name="ctx">A context to hold the exception stack and the cached resources.</param>
1313 /// <param name="file_name">The name of file that will hold the writer's output, UTF-8 encoded.</param>
1314 /// <param name="format">An integer equivalent to <see cref="DocumentOutputFileTypes"/> specifying the output format.</param>
1315 /// <param name="out_document_writer">A pointer to the new document writer object.</param>
1316 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1317 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1318 internal static extern int CreateDocumentWriter(IntPtr ctx, IntPtr file_name, int format, ref IntPtr out_document_writer);
1319
1320 /// <summary>
1321 /// Render (part of) a display list as a page in the specified document writer.
1322 /// </summary>
1323 /// <param name="ctx">A context to hold the exception stack and the cached resources.</param>
1324 /// <param name="list">The display list to render.</param>
1325 /// <param name="x0">The left coordinate in page units of the region of the display list that should be rendererd.</param>
1326 /// <param name="y0">The top coordinate in page units of the region of the display list that should be rendererd.</param>
1327 /// <param name="x1">The right coordinate in page units of the region of the display list that should be rendererd.</param>
1328 /// <param name="y1">The bottom coordinate in page units of the region of the display list that should be rendererd.</param>
1329 /// <param name="zoom">How much the specified region should be scaled when rendering. This will determine the final size of the page.</param>
1330 /// <param name="writ">The document writer on which the page should be written.</param>
1331 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1332 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1333 internal static extern int WriteSubDisplayListAsPage(IntPtr ctx, IntPtr list, float x0, float y0, float x1, float y1, float zoom, IntPtr writ);
1334
1335 /// <summary>
1336 /// Finalise a document writer, closing the file and freeing all resources.
1337 /// </summary>
1338 /// <param name="ctx">The context that was used to create the document writer.</param>
1339 /// <param name="writ">The document writer to finalise.</param>
1340 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1341 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1342 internal static extern int FinalizeDocumentWriter(IntPtr ctx, IntPtr writ);
1343
1344 /// <summary>
1345 /// Get the contents of a structured text character.
1346 /// </summary>
1347 /// <param name="character">The address of the character.</param>
1348 /// <param name="out_c">Unicode code point of the character.</param>
1349 /// <param name="out_color">An sRGB hex representation of the colour of the character.</param>
1350 /// <param name="out_origin_x">The x coordinate of the baseline origin of the character.</param>
1351 /// <param name="out_origin_y">The y coordinate of the baseline origin of the character.</param>
1352 /// <param name="out_size">The size in points of the character.</param>
1353 /// <param name="out_ll_x">The x coordinate of the lower left corner of the bounding quad.</param>
1354 /// <param name="out_ll_y">The y coordinate of the lower left corner of the bounding quad.</param>
1355 /// <param name="out_ul_x">The x coordinate of the upper left corner of the bounding quad.</param>
1356 /// <param name="out_ul_y">The y coordinate of the upper left corner of the bounding quad.</param>
1357 /// <param name="out_ur_x">The x coordinate of the upper right corner of the bounding quad.</param>
1358 /// <param name="out_ur_y">The y coordinate of the upper right corner of the bounding quad.</param>
1359 /// <param name="out_lr_x">The x coordinate of the lower right corner of the bounding quad.</param>
1360 /// <param name="out_lr_y">The y coordinate of the lower right corner of the bounding quad.</param>
1361 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1362 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1363 internal static extern int GetStructuredTextChar(IntPtr character, ref int out_c, ref int out_color, ref float out_origin_x, ref float out_origin_y, ref float out_size, ref float out_ll_x, ref float out_ll_y, ref float out_ul_x, ref float out_ul_y, ref float out_ur_x, ref float out_ur_y, ref float out_lr_x, ref float out_lr_y);
1364
1365 /// <summary>
1366 /// Get an array of structured text characters from a structured text line.
1367 /// </summary>
1368 /// <param name="line">The structured text line from which the characters should be extracted.</param>
1369 /// <param name="out_chars">An array of pointers to the structured text characters.</param>
1370 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1371 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1372 internal static extern int GetStructuredTextChars(IntPtr line, IntPtr out_chars);
1373
1374 /// <summary>
1375 /// Get the contents of a structured text line.
1376 /// </summary>
1377 /// <param name="line">The address of the line.</param>
1378 /// <param name="out_wmode">An integer equivalent to <see cref="MuPDFStructuredTextLine"/> representing the writing mode of the line.</param>
1379 /// <param name="out_x0">The left coordinate in page units of the bounding box of the line.</param>
1380 /// <param name="out_y0">The top coordinate in page units of the bounding box of the line.</param>
1381 /// <param name="out_x1">The right coordinate in page units of the bounding box of the line.</param>
1382 /// <param name="out_y1">The bottom coordinate in page units of the bounding box of the line.</param>
1383 /// <param name="out_x">The x component of the normalised direction of the baseline.</param>
1384 /// <param name="out_y">The y component of the normalised direction of the baseline.</param>
1385 /// <param name="out_char_count">The number of characters in the line.</param>
1386 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1387 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1388 internal static extern int GetStructuredTextLine(IntPtr line, ref int out_wmode, ref float out_x0, ref float out_y0, ref float out_x1, ref float out_y1, ref float out_x, ref float out_y, ref int out_char_count);
1389
1390 /// <summary>
1391 /// Get an array of structured text lines from a structured text block.
1392 /// </summary>
1393 /// <param name="block">The structured text block from which the lines should be extracted.</param>
1394 /// <param name="out_lines">An array of pointers to the structured text lines.</param>
1395 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1396 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1397 internal static extern int GetStructuredTextLines(IntPtr block, IntPtr out_lines);
1398
1399 /// <summary>
1400 /// Get the contents of a structured text block.
1401 /// </summary>
1402 /// <param name="block">The address of the block.</param>
1403 /// <param name="out_type">An integer equivalent to <see cref="MuPDFStructuredTextBlock.Types"/> representing the type of the block.</param>
1404 /// <param name="out_x0">The left coordinate in page units of the bounding box of the block.</param>
1405 /// <param name="out_y0">The top coordinate in page units of the bounding box of the block.</param>
1406 /// <param name="out_x1">The right coordinate in page units of the bounding box of the block.</param>
1407 /// <param name="out_y1">The bottom coordinate in page units of the bounding box of the block.</param>
1408 /// <param name="out_line_count">The number of lines in the block.</param>
1409 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1410 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1411 internal static extern int GetStructuredTextBlock(IntPtr block, ref int out_type, ref float out_x0, ref float out_y0, ref float out_x1, ref float out_y1, ref int out_line_count);
1412
1413 /// <summary>
1414 /// Get an array of structured text blocks from a structured text page.
1415 /// </summary>
1416 /// <param name="page">The structured text page from which the blocks should be extracted.</param>
1417 /// <param name="out_blocks">An array of pointers to the structured text blocks.</param>
1418 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1419 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1420 internal static extern int GetStructuredTextBlocks(IntPtr page, IntPtr out_blocks);
1421
1422 /// <summary>
1423 /// Get a structured text representation of a display list.
1424 /// </summary>
1425 /// <param name="ctx">A context to hold the exception stack and the cached resources.</param>
1426 /// <param name="list">The display list whose structured text representation is sought.</param>
1427 /// <param name="out_page">The address of the structured text page.</param>
1428 /// <param name="out_stext_block_count">The number of structured text blocks in the page.</param>
1429 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1430 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1431 internal static extern int GetStructuredTextPage(IntPtr ctx, IntPtr list, ref IntPtr out_page, ref int out_stext_block_count);
1432
1433 /// <summary>
1434 /// Delegate defining a callback function that is invoked by the unmanaged MuPDF library to indicate OCR progress.
1435 /// </summary>
1436 /// <param name="progress">The current progress, ranging from 0 to 100.</param>
1437 /// <returns>This function should return 0 to indicate that the OCR process should continue, or 1 to indicate that it should be stopped.</returns>
1438 internal delegate int ProgressCallback(int progress);
1439
1440 /// <summary>
1441 /// Get a structured text representation of a display list, using the Tesseract OCR engine.
1442 /// </summary>
1443 /// <param name="ctx">A context to hold the exception stack and the cached resources.</param>
1444 /// <param name="list">The display list whose structured text representation is sought.</param>
1445 /// <param name="out_page">The address of the structured text page.</param>
1446 /// <param name="out_stext_block_count">The number of structured text blocks in the page.</param>
1447 /// <param name="zoom">How much the specified region should be scaled when rendering. This determines the size in pixels of the image that is passed to Tesseract.</param>
1448 /// <param name="x0">The left coordinate in page units of the region of the display list that should be analysed.</param>
1449 /// <param name="y0">The top coordinate in page units of the region of the display list that should be analysed.</param>
1450 /// <param name="x1">The right coordinate in page units of the region of the display list that should be analysed.</param>
1451 /// <param name="y1">The bottom coordinate in page units of the region of the display list that should be analysed.</param>
1452 /// <param name="prefix">A string value that will be used as an argument for the <c>putenv</c> function. If this is <see langword="null"/>, the <c>putenv</c> function is not invoked. Usually used to set the value of the <c>TESSDATA_PREFIX</c> environment variable.</param>
1453 /// <param name="language">The name of the language model file to use for the OCR.</param>
1454 /// <param name="callback">A progress callback function. This function will be called with an integer parameter ranging from 0 to 100 to indicate OCR progress, and should return 0 to continue or 1 to abort the OCR process.</param>
1455 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1456 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1457 internal static extern int GetStructuredTextPageWithOCR(IntPtr ctx, IntPtr list, ref IntPtr out_page, ref int out_stext_block_count, float zoom, float x0, float y0, float x1, float y1, string prefix, string language, [MarshalAs(UnmanagedType.FunctionPtr)] ProgressCallback callback);
1458
1459 /// <summary>
1460 /// Free a native structured text page and its associated resources.
1461 /// </summary>
1462 /// <param name="ctx"></param>
1463 /// <param name="page"></param>
1464 /// <returns>An integer equivalent to <see cref="ExitCodes"/> detailing whether any errors occurred.</returns>
1465 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1466 internal static extern int DisposeStructuredTextPage(IntPtr ctx, IntPtr page);
1467
1468 /// <summary>
1469 /// Redirect the standard output and standard error to named pipes with the specified names. On Windows, these are actually named pipes; on Linux and macOS, these are Unix sockets (matching the behaviour of System.IO.Pipes). Note that this has side-effects.
1470 /// </summary>
1471 /// <param name="stdoutFD">When the method returns, this variable will contain the file descriptor corresponding to the "real" stdout.</param>
1472 /// <param name="stderrFD">When the method returns, this variable will contain the file descriptor corresponding to the "real" stderr.</param>
1473 /// <param name="stdoutPipeName">The name of the pipe where stdout will be redirected. On Windows, this should be of the form "\\.\pipe\xxx", while on Linux and macOS it should be an absolute file path (maximum length 107/108 characters).</param>
1474 /// <param name="stderrPipeName">The name of the pipe where stderr will be redirected. On Windows, this should be of the form "\\.\pipe\xxx", while on Linux and macOS it should be an absolute file path (maximum length 107/108 characters).</param>
1475 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1476 internal static extern void RedirectOutput(out int stdoutFD, out int stderrFD, string stdoutPipeName, string stderrPipeName);
1477
1478 /// <summary>
1479 /// Write the specified <paramref name="text"/> to a file descriptor. Use 1 for stdout and 2 for stderr (which may have been redirected).
1480 /// </summary>
1481 /// <param name="fileDescriptor">The file descriptor on which to write.</param>
1482 /// <param name="text">The text to write.</param>
1483 /// <param name="length">The length of the text to write (i.e., text.Length).</param>
1484 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1485 internal static extern void WriteToFileDescriptor(int fileDescriptor, string text, int length);
1486
1487 /// <summary>
1488 /// Reset the standard output and standard error (or redirect them to the specified file descriptors, theoretically). Use with the <paramref name="stdoutFD"/> and <paramref name="stderrFD"/> returned by <see cref="RedirectOutput"/> to undo what it did.
1489 /// </summary>
1490 /// <param name="stdoutFD">The file descriptor corresponding to the "real" stdout.</param>
1491 /// <param name="stderrFD">The file descriptor corresponding to the "real" stderr.</param>
1492 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1493 internal static extern void ResetOutput(int stdoutFD, int stderrFD);
1494
1495 /// <summary>
1496 /// Unlocks a document with a password.
1497 /// </summary>
1498 /// <param name="ctx">A context to hold the exception stack and the cached resources.</param>
1499 /// <param name="doc">The document that needs to be unlocked.</param>
1500 /// <param name="password">The password to unlock the document.</param>
1501 /// <returns>0 if the document could not be unlocked, 1 if the document did not require unlocking in the first place, 2 if the document was unlocked using the user password and 4 if the document was unlocked using the owner password.</returns>
1502 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1503 internal static extern int UnlockWithPassword(IntPtr ctx, IntPtr doc, string password);
1504
1505 /// <summary>
1506 /// Checks whether a password is required to open the document.
1507 /// </summary>
1508 /// <param name="ctx">A context to hold the exception stack and the cached resources.</param>
1509 /// <param name="doc">The document that needs to be checked.</param>
1510 /// <returns>0 if a password is not needed, 1 if a password is needed.</returns>
1511 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1512 internal static extern int CheckIfPasswordNeeded(IntPtr ctx, IntPtr doc);
1513
1514 /// <summary>
1515 /// Returns the current permissions for the document. Note that these are not actually enforced.
1516 /// </summary>
1517 /// <param name="ctx">A context to hold the exception stack and the cached resources.</param>
1518 /// <param name="doc">The document whose permissions need to be checked.</param>
1519 /// <returns>An integer with bit 0 set if the document can be printed, bit 1 set if it can be copied, bit 2 set if it can be edited, and bit 3 set if it can be annotated.</returns>
1520 [DllImport("MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1521 internal static extern int GetPermissions(IntPtr ctx, IntPtr doc);
1522 }
1523}
An IDisposable wrapper around an IntPtr that frees the allocated memory when it is disposed.
Definition: MuPDF.cs:422
DisposableIntPtr(IntPtr pointer, long bytesAllocated)
Create a new DisposableIntPtr, adding memory pressure to the GC to account for the allocation of unma...
Definition: MuPDF.cs:447
DisposableIntPtr(IntPtr pointer)
Create a new DisposableIntPtr.
Definition: MuPDF.cs:437
The exception that is thrown when an attempt is made to render an encrypted document without supplyin...
Definition: MuPDF.cs:510
EventArgs for the MuPDF.StandardOutputMessage and MuPDF.StandardErrorMessage events.
Definition: MuPDF.cs:566
string Message
The message that has been logged.
Definition: MuPDF.cs:570
MessageEventArgs(string message)
Create a new MessageEventArgs instance.
Definition: MuPDF.cs:576
The exception that is thrown when a MuPDF operation fails.
Definition: MuPDF.cs:494
readonly ExitCodes ErrorCode
The ExitCodes returned by the native function.
Definition: MuPDF.cs:498
Contains static methods to perform setup operations.
Definition: MuPDF.cs:586
static async Task RedirectOutput()
Redirects output messages from the native MuPDF library to the StandardOutputMessage and StandardErro...
Definition: MuPDF.cs:614
static EventHandler< MessageEventArgs > StandardOutputMessage
This event is invoked when RedirectOutput has been called and the native MuPDF library writes to the ...
Definition: MuPDF.cs:603
static EventHandler< MessageEventArgs > StandardErrorMessage
This event is invoked when RedirectOutput has been called and the native MuPDF library writes to the ...
Definition: MuPDF.cs:608
static void ResetOutput()
Reset the default standard output and error streams for the native MuPDF library.
Definition: MuPDF.cs:834
Holds a summary of the progress of the current rendering operation.
Definition: MuPDF.cs:384
ThreadRenderProgress[] ThreadRenderProgresses
Contains the progress of all the threads used in rendering the document.
Definition: MuPDF.cs:410
DocumentOutputFileTypes
Document file types supported in output by the library.
Definition: MuPDF.cs:230
InputFileTypes
File types supported in input by the library.
Definition: MuPDF.cs:123
EncryptionState
Possible document encryption states.
Definition: MuPDF.cs:277
RestrictionState
Possible document restriction states.
Definition: MuPDF.cs:298
ExitCodes
Exit codes returned by native methods describing various errors that can occur.
Definition: MuPDF.cs:32
DocumentRestrictions
Document restrictions.
Definition: MuPDF.cs:319
PixelFormats
Pixel formats supported by the library.
Definition: MuPDF.cs:251
PasswordTypes
Password types.
Definition: MuPDF.cs:350
RasterOutputFileTypes
Raster image file types supported in output by the library.
Definition: MuPDF.cs:199
Holds the progress of a single thread.
Definition: MuPDF.cs:389
int Progress
The current progress.
Definition: MuPDF.cs:393
long MaxProgress
The maximum progress. If this is 0, this value could not be determined (yet).
Definition: MuPDF.cs:398