public Bitmap GetPage(Tile page, bool isPrinting)
        {
            var imgBuffer = new byte[page.Width * page.Height * 4];
            var imgHandle = GCHandle.Alloc(imgBuffer, GCHandleType.Pinned);

            try
            {
                var pagePtr = _nativeXps.Pages[page.PageNum];
                if (RenderLibrary.render_page(imgHandle.AddrOfPinnedObject(), pagePtr, (float)page.Scale, page.Width, page.Height) == 0)
                {
                    var bitmap = new Bitmap(page.Width, page.Height, 4 * page.Width,
                                            PixelFormat.Format32bppPArgb,
                                            Marshal.UnsafeAddrOfPinnedArrayElement(imgBuffer, 0));
                    return(bitmap);
                }
                else
                {
                    return(null);
                }
            }
            catch (Exception e)
            {
                return(null);
            }
            finally
            {
                imgHandle.Free();
            }
        }
        public void Dispose()
        {
            if (XpsPtr == IntPtr.Zero)
            {
                return;
            }

            foreach (var page in Pages)
            {
                try
                {
                    RenderLibrary.close_page(XpsPtr, page);
                }
                catch
                {
                }
            }
            Pages = null;

            try
            {
                RenderLibrary.close_xps(XpsPtr);
            }
            finally
            {
                XpsPtr = IntPtr.Zero;
            }
        }
        public TilesManager(Stream xpsStream)
        {
            if (xpsStream == null)
            {
                return;
            }
            var errorBuffer = new byte[256];
            var errorHandle = GCHandle.Alloc(errorBuffer, GCHandleType.Pinned);
            var dataBuffer  = StreamToByteArray(xpsStream);

            _dataHandle = GCHandle.Alloc(dataBuffer, GCHandleType.Pinned);
            try
            {
                lock (_locker)
                {
                    if (_nativeXps != null)
                    {
                        throw new RenderException("Already initialized");
                    }

                    var pageCount    = 0;
                    var xpsNativePtr = RenderLibrary.open_xps_with_stream(
                        _dataHandle.AddrOfPinnedObject(),
                        dataBuffer.Length,
                        ref pageCount,
                        errorHandle.AddrOfPinnedObject(),
                        errorBuffer.Length);

                    if (xpsNativePtr == IntPtr.Zero)
                    {
                        var nativeError = Encoding.UTF8.GetString(errorBuffer).TrimEnd((char)0);
                        throw new Exception(nativeError);
                    }

                    if (pageCount == 0)
                    {
                        throw new Exception("Initialization failed");
                    }

                    _nativeXps = new NativeXps(xpsNativePtr, pageCount, _dataHandle);
                }
            }
            catch (RenderException)
            {
                _dataHandle.Free();
                _nativeXps = null;
                throw;
            }
            catch (Exception e)
            {
                _dataHandle.Free();
                _nativeXps = null;
                throw new RenderException("Initialization failed");
            }
            finally
            {
                errorHandle.Free();
            }
        }
        public void LoadPage(int pageNumber, ref int pageWidth, ref int pageHeight, bool skipText)
        {
            lock (_locker)
            {
                try
                {
                    if (_nativeXps == null || _nativeXps.Pages == null || _nativeXps.Pages[pageNumber] != IntPtr.Zero)
                    {
                        return;
                    }
                }
                catch (Exception e)
                {
                    new RenderException(string.Format("Failed open page %i %s", pageNumber, e.Message));
                    return;
                }

                var errorBuffer = new byte[256];
                var errorHandle = GCHandle.Alloc(errorBuffer, GCHandleType.Pinned);
                try
                {
                    var pagePtr = RenderLibrary.open_xps_page(_nativeXps.XpsPtr, pageNumber, ref pageWidth,
                                                              ref pageHeight, errorHandle.AddrOfPinnedObject(), errorBuffer.Length, skipText ? 1 : 0);

                    if (pagePtr == IntPtr.Zero)
                    {
                        var nativeError = Encoding.UTF8.GetString(errorBuffer).TrimEnd((char)0);
                        new RenderException(string.Format("Failed open page %i %s", pageNumber, nativeError));
                    }
                    else
                    {
                        _nativeXps.Pages[pageNumber] = pagePtr;
                    }
                }
                finally
                {
                    errorHandle.Free();
                }
            }
        }
        public byte[] GetPageInBytes(Tile page, bool isPrinting)
        {
            var imgBuffer = new byte[page.Width * page.Height * 4];
            var imgHandle = GCHandle.Alloc(imgBuffer, GCHandleType.Pinned);

            try
            {
                var pagePtr = _nativeXps.Pages[page.PageNum];
                if (RenderLibrary.render_page(imgHandle.AddrOfPinnedObject(), pagePtr, (float)page.Scale, page.Width, page.Height) == 0)
                {
                    var bitmap = new Bitmap(page.Width, page.Height, 4 * page.Width,
                                            PixelFormat.Format32bppPArgb,
                                            Marshal.UnsafeAddrOfPinnedArrayElement(imgBuffer, 0));
                    using (bitmap)
                    {
                        using (var ms = new MemoryStream())
                        {
                            bitmap.Save(ms, ImageFormat.Png);
                            imgBuffer = ms.ToArray();
                        }
                        return(imgBuffer);
                    }
                }
                else
                {
                    return(null);
                }
            }
            catch (Exception e)
            {
                return(null);
            }
            finally
            {
                imgHandle.Free();
            }
        }