Esempio n. 1
0
        /// <summary>
        /// Create a new <see cref="MuPDFPage"/> object from the specified document.
        /// </summary>
        /// <param name="context">The context that owns the document.</param>
        /// <param name="document">The document from which the page should be extracted.</param>
        /// <param name="number">The number of the page that should be extracted (starting at 0).</param>
        internal MuPDFPage(MuPDFContext context, MuPDFDocument document, int number)
        {
            this.OwnerContext  = context;
            this.OwnerDocument = document;
            this.PageNumber    = number;

            float x = 0;
            float y = 0;
            float w = 0;
            float h = 0;

            ExitCodes result = (ExitCodes)NativeMethods.LoadPage(context.NativeContext, document.NativeDocument, number, ref NativePage, ref x, ref y, ref w, ref h);

            this.Bounds         = new Rectangle(Math.Round(x * document.ImageXRes / 72.0 * 1000) / 1000, Math.Round(y * document.ImageYRes / 72.0 * 1000) / 1000, Math.Round(w * document.ImageXRes / 72.0 * 1000) / 1000, Math.Round(h * document.ImageYRes / 72.0 * 1000) / 1000);
            this.OriginalBounds = new Rectangle(x, y, w, h);

            switch (result)
            {
            case ExitCodes.EXIT_SUCCESS:
                break;

            case ExitCodes.ERR_CANNOT_LOAD_PAGE:
                throw new MuPDFException("Cannot load page", result);

            case ExitCodes.ERR_CANNOT_COMPUTE_BOUNDS:
                throw new MuPDFException("Cannot compute bounds", result);

            default:
                throw new MuPDFException("Unknown error", result);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Create a new <see cref="MuPDFDisplayList"/> instance from the specified page.
        /// </summary>
        /// <param name="context">The context that owns the document from which the page was taken.</param>
        /// <param name="page">The page from which the display list should be generated.</param>
        /// <param name="includeAnnotations">If this is <see langword="true" />, annotations (e.g. signatures) are included in the display list that is generated. Otherwise, only the page contents are included.</param>
        public MuPDFDisplayList(MuPDFContext context, MuPDFPage page, bool includeAnnotations = true)
        {
            this.OwnerContext = context;

            float x0 = 0;
            float y0 = 0;
            float x1 = 0;
            float y1 = 0;

            ExitCodes result = (ExitCodes)NativeMethods.GetDisplayList(context.NativeContext, page.NativePage, includeAnnotations ? 1 : 0, ref NativeDisplayList, ref x0, ref y0, ref x1, ref y1);

            switch (result)
            {
            case ExitCodes.EXIT_SUCCESS:
                break;

            case ExitCodes.ERR_CANNOT_RENDER:
                throw new MuPDFException("Cannot render page", result);

            default:
                throw new MuPDFException("Unknown error", result);
            }

            this.Bounds = new Rectangle(Math.Round(x0 * page.OwnerDocument.ImageXRes / 72.0 * 1000) / 1000, Math.Round(y0 * page.OwnerDocument.ImageYRes / 72.0 * 1000) / 1000, Math.Round(x1 * page.OwnerDocument.ImageXRes / 72.0 * 1000) / 1000, Math.Round(y1 * page.OwnerDocument.ImageYRes / 72.0 * 1000) / 1000);
        }
Esempio n. 3
0
        /// <summary>
        /// Create a new <see cref="MuPDFDocument"/> from an array of bytes.
        /// </summary>
        /// <param name="context">The context that will own this document.</param>
        /// <param name="data">An array containing the data bytes that make up the document. This must not be altered until after the <see cref="MuPDFDocument"/> has been disposed!
        /// The address of the array will be pinned, which may cause degradation in the Garbage Collector's performance, and is thus only advised for short-lived documents. To avoid this issue, marshal the bytes to unmanaged memory and use one of the <see cref="IntPtr"/> constructors.</param>
        /// <param name="fileType">The type of the document to read.</param>
        public MuPDFDocument(MuPDFContext context, byte[] data, InputFileTypes fileType)
        {
            bool isImage = fileType == InputFileTypes.BMP || fileType == InputFileTypes.GIF || fileType == InputFileTypes.JPEG || fileType == InputFileTypes.PAM || fileType == InputFileTypes.PNG || fileType == InputFileTypes.PNM || fileType == InputFileTypes.TIFF;

            this.OwnerContext = context;

            DataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
            IntPtr dataAddress = DataHandle.Value.AddrOfPinnedObject();
            ulong  dataLength  = (ulong)data.Length;

            float xRes = 0;
            float yRes = 0;

            ExitCodes result = (ExitCodes)NativeMethods.CreateDocumentFromStream(context.NativeContext, dataAddress, dataLength, FileTypeMagics[(int)fileType], isImage ? 1 : 0, ref NativeDocument, ref NativeStream, ref PageCount, ref xRes, ref yRes);

            if (xRes > 72)
            {
                this.ImageXRes = xRes;
            }
            else
            {
                this.ImageXRes = 72;
            }

            if (yRes > 72)
            {
                this.ImageYRes = yRes;
            }
            else
            {
                this.ImageYRes = 72;
            }

            switch (result)
            {
            case ExitCodes.EXIT_SUCCESS:
                break;

            case ExitCodes.ERR_CANNOT_OPEN_STREAM:
                throw new MuPDFException("Cannot open data stream", result);

            case ExitCodes.ERR_CANNOT_OPEN_FILE:
                throw new MuPDFException("Cannot open document", result);

            case ExitCodes.ERR_CANNOT_COUNT_PAGES:
                throw new MuPDFException("Cannot count pages", result);

            default:
                throw new MuPDFException("Unknown error", result);
            }

            Pages        = new MuPDFPageCollection(context, this, PageCount);
            DisplayLists = new MuPDFDisplayList[PageCount];
        }
Esempio n. 4
0
        /// <summary>
        /// Create a new <see cref="MuPDFMultiThreadedPageRenderer"/> from a specified display list using the specified number of threads.
        /// </summary>
        /// <param name="context">The context that owns the document from which the display list was extracted.</param>
        /// <param name="displayList">The display list to render.</param>
        /// <param name="threadCount">The number of threads to use in the rendering. This must be factorisable using only powers of 2, 3, 5 or 7. Otherwise, the biggest number smaller than <paramref name="threadCount"/> that satisfies this condition is used.</param>
        /// <param name="pageBounds">The bounds of the page being rendererd.</param>
        /// <param name="clipToPageBounds">A boolean value indicating whether the rendered image should be clipped to the original page's bounds. This can be relevant if the page has been "cropped" by altering its mediabox, but otherwise leaving the contents untouched.</param>
        /// <param name="imageXRes">If the document is an image, the horizontal resolution of the image. Otherwise, 72.</param>
        /// <param name="imageYRes">If the document is an image, the vertical resolution of the image. Otherwise, 72.</param>
        internal MuPDFMultiThreadedPageRenderer(MuPDFContext context, MuPDFDisplayList displayList, int threadCount, Rectangle pageBounds, bool clipToPageBounds, double imageXRes, double imageYRes)
        {
            threadCount = Utils.GetAcceptableNumber(threadCount);

            this.ThreadCount      = threadCount;
            this.DisplayList      = displayList;
            this.PageBounds       = pageBounds;
            this.ClipToPageBounds = clipToPageBounds;

            this.ImageXRes = imageXRes;
            this.ImageYRes = imageYRes;

            IntPtr[] contexts       = new IntPtr[threadCount];
            GCHandle contextsHandle = GCHandle.Alloc(contexts, GCHandleType.Pinned);

            try
            {
                ExitCodes result = (ExitCodes)NativeMethods.CloneContext(context.NativeContext, threadCount, contextsHandle.AddrOfPinnedObject());

                switch (result)
                {
                case ExitCodes.EXIT_SUCCESS:
                    break;

                case ExitCodes.ERR_CANNOT_INIT_MUTEX:
                    throw new MuPDFException("Cannot initalize mutex objects", result);

                case ExitCodes.ERR_CANNOT_CREATE_CONTEXT:
                    throw new MuPDFException("Cannot create master context", result);

                case ExitCodes.ERR_CANNOT_CLONE_CONTEXT:
                    throw new MuPDFException("Cannot create context clones", result);

                default:
                    throw new MuPDFException("Unknown error", result);
                }

                Contexts         = new MuPDFContext[threadCount];
                RenderingThreads = new RenderingThread[threadCount];
                for (int i = 0; i < threadCount; i++)
                {
                    Contexts[i]         = new MuPDFContext(contexts[i]);
                    RenderingThreads[i] = new RenderingThread();
                }
            }
            finally
            {
                contextsHandle.Free();
            }
        }
Esempio n. 5
0
 /// <summary>
 /// Create a new <see cref="MuPDFPageCollection"/> from the specified document, containing the specified number of pages.
 /// </summary>
 /// <param name="context">The context that owns the document.</param>
 /// <param name="document">The document from which the pages should be extracted.</param>
 /// <param name="length">The number of pages in the document.</param>
 internal MuPDFPageCollection(MuPDFContext context, MuPDFDocument document, int length)
 {
     Pages         = new MuPDFPage[length];
     OwnerContext  = context;
     OwnerDocument = document;
 }
Esempio n. 6
0
 /// <summary>
 /// Create a new document containing the specified (parts of) pages from other documents.
 /// </summary>
 /// <param name="context">The context that was used to open the documents.</param>
 /// <param name="fileName">The output file name.</param>
 /// <param name="fileType">The output file format.</param>
 /// <param name="includeAnnotations">If this is <see langword="true" />, annotations (e.g. signatures) are included in the display list that is generated. Otherwise, only the page contents are included.</param>
 /// <param name="pages">The pages to include in the document. The "page" element specifies the page, the "region" element the area of the page that should be included in the document, and the "zoom" element how much the region should be scaled.</param>
 public static void CreateDocument(MuPDFContext context, string fileName, DocumentOutputFileTypes fileType, bool includeAnnotations = true, params (MuPDFPage page, Rectangle region, float zoom)[] pages)
Esempio n. 7
0
        /// <summary>
        /// Create a new <see cref="MuPDFDocument"/> from a file.
        /// </summary>
        /// <param name="context">The context that will own this document.</param>
        /// <param name="fileName">The path to the file to open.</param>
        public MuPDFDocument(MuPDFContext context, string fileName)
        {
            bool isImage;

            string extension = Path.GetExtension(fileName).ToLowerInvariant();

            switch (extension)
            {
            case ".bmp":
            case ".dib":

            case ".gif":

            case ".jpg":
            case ".jpeg":
            case ".jpe":
            case ".jif":
            case ".jfif":
            case ".jfi":

            case ".pam":
            case ".pbm":
            case ".pgm":
            case ".ppm":
            case ".pnm":

            case ".png":

            case ".tif":
            case ".tiff":
                isImage = true;
                break;

            default:
                isImage = false;
                break;
            }


            this.OwnerContext = context;

            float xRes = 0;
            float yRes = 0;

            ExitCodes result = (ExitCodes)NativeMethods.CreateDocumentFromFile(context.NativeContext, fileName, isImage ? 1 : 0, ref NativeDocument, ref PageCount, ref xRes, ref yRes);


            if (xRes > 72)
            {
                this.ImageXRes = xRes;
            }
            else
            {
                this.ImageXRes = 72;
            }

            if (yRes > 72)
            {
                this.ImageYRes = yRes;
            }
            else
            {
                this.ImageYRes = 72;
            }

            switch (result)
            {
            case ExitCodes.EXIT_SUCCESS:
                break;

            case ExitCodes.ERR_CANNOT_OPEN_FILE:
                throw new MuPDFException("Cannot open document", result);

            case ExitCodes.ERR_CANNOT_COUNT_PAGES:
                throw new MuPDFException("Cannot count pages", result);

            default:
                throw new MuPDFException("Unknown error", result);
            }

            Pages        = new MuPDFPageCollection(context, this, PageCount);
            DisplayLists = new MuPDFDisplayList[PageCount];
        }
Esempio n. 8
0
 /// <summary>
 /// Create a new <see cref="MuPDFDocument"/> from data bytes accessible through the specified pointer.
 /// </summary>
 /// <param name="context">The context that will own this document.</param>
 /// <param name="dataAddress">A pointer to the data bytes that make up the document.</param>
 /// <param name="dataLength">The number of bytes to read from the specified address.</param>
 /// <param name="fileType">The type of the document to read.</param>
 public MuPDFDocument(MuPDFContext context, IntPtr dataAddress, long dataLength, InputFileTypes fileType) : this(context, dataAddress, dataLength, fileType, ref NullDataHolder)
 {
 }