using System; using System.IO; using Android.Content; using Android.Graphics; using Android.Util; using Com.Shockwave.Pdfium; using Syncfusion.SfPdfViewer.XForms; using Syncfusion.SfPdfViewer.XForms.Droid; [assembly: Xamarin.Forms.Dependency(typeof(PRS.Mobile.Droid.PDFRenderer))] namespace PRS.Mobile.Droid { public class PDFRenderer : ICustomPdfRenderer, ICustomPdfRendererService { internal PdfiumCore m_pdfiumCore; internal PdfDocument m_pdfDocument; internal int m_pageCount; internal Bitmap.Config m_bitmapConfig; /// /// Gets or sets the total page count of the PDF document /// public int PageCount { get { return m_pageCount; } set { m_pageCount = value; } } /// /// Gets or sets Bitmap.Config to render the bitmap from PDF document /// public Bitmap.Config BitmapConfig { get { return m_bitmapConfig; } set { m_bitmapConfig = value; } } /// /// Gets the dependency object of ICustomPdfRenderer /// public object AlternatePdfRenderer { get { return this; } } /// /// Initializes the required object /// /// Context of the application /// PDF document stream public void Initialize(Context context, Stream inputStream) { if (inputStream == null) { throw new System.NullReferenceException("object reference is not set to an instance: inputStream"); } //Initializes the PdfiumCore instance m_pdfiumCore = new PdfiumCore(context); byte[] byteArray = ReadBytes(inputStream); if (m_pdfiumCore == null) { throw new System.NullReferenceException("object reference is not set to an instance: m_pdfiumCore"); } //Creates the PdfDocument instance from the PDF byte array m_pdfDocument = m_pdfiumCore.NewDocument(byteArray); if (m_pdfDocument == null) { throw new System.NullReferenceException("object reference is not set to an instance: m_pdfDocument"); } if (m_bitmapConfig == null) { m_bitmapConfig = Bitmap.Config.Rgb565; } //Gets the total number of pages from the PDF document m_pageCount = m_pdfiumCore.GetPageCount(m_pdfDocument); } /// /// Converts stream to byte array to render the PDF document using Pdfium renderer /// /// PDF document stream to convert into byte array /// byte array of PDF document private static byte[] ReadBytes(Stream input) { if (input.CanSeek) { input.Position = 0; } byte[] buffer = new byte[16 * 1024]; using (MemoryStream ms = new MemoryStream()) { int read; while ((read = input.Read(buffer, 0, buffer.Length)) > 0) { ms.Write(buffer, 0, read); } return ms.ToArray(); } } /// /// Renders the PDF page as bitmap with specified page index /// /// Bitmap to draw the content of the PDF page /// Render the bitmap of PDF page with the page index /// Width of the page to draw on to the bitmap /// Height of the page to draw on to the bitmap public void Render(Bitmap bitmap, int pageIndex, int pageWidth, int pageHeight) => Render(bitmap, pageIndex, 0, 0, pageWidth, pageHeight); private int _pageIndex = int.MinValue; private bool bFirst = true; public void Render(Bitmap bitmap, int pageIndex, int x, int y, int width, int height) { if (bitmap == null) { throw new System.NullReferenceException("object reference is not set to an instance: bitmap"); } if (m_pdfiumCore == null) { throw new System.NullReferenceException("object reference is not set to an instance: m_pdfiumCore"); } else if (m_pdfDocument == null) { throw new System.NullReferenceException("object reference is not set to an instance: m_pdfDocument"); } else if (pageIndex < 0 && pageIndex > m_pageCount - 1) { throw new System.ArgumentOutOfRangeException("pageIndex", "Index was out of range. Must be non-negative and less than the size of the PageCount."); } else { if (bFirst) { //Sets the config of Bitmap format we required to render the PDF pages bFirst = false; bitmap.SetConfig(m_bitmapConfig); } //Opens the PDF page with the specified page index to render the page as bitmap if (_pageIndex != pageIndex) { _pageIndex = pageIndex; m_pdfiumCore.OpenPage(m_pdfDocument, pageIndex); } m_pdfiumCore.RenderPageBitmap(m_pdfDocument, bitmap, pageIndex, x, y, width, height); } } /// /// Gets the Page size of the PDF document with given page index /// /// Page index to the get page size /// Size of the page of PDF document public Size GetPageSize(int pageIndex) { if (m_pdfiumCore == null) { throw new System.NullReferenceException("object reference is not set to an instance: m_pdfiumCore"); } else if (m_pdfDocument == null) { throw new System.NullReferenceException("object reference is not set to an instance: m_pdfDocument"); } else if (pageIndex < 0 && pageIndex > m_pageCount - 1) { throw new System.ArgumentOutOfRangeException("pageIndex", "Index was out of range. Must be non-negative and less than the size of the PageCount."); } else { //opens the PDF page with specified index to get the Size of a Page m_pdfiumCore.OpenPage(m_pdfDocument, pageIndex); int pageHeight = m_pdfiumCore.GetPageHeightPoint(m_pdfDocument, pageIndex); int pageWidth = m_pdfiumCore.GetPageWidthPoint(m_pdfDocument, pageIndex); return new Size(pageWidth, pageHeight); } } /// /// Closes the initialized object to release memory /// public void Close() { //Closes the created PdfDocument instance m_pdfiumCore.CloseDocument(m_pdfDocument); //Disposes PdfiumCore instance m_pdfiumCore.Dispose(); } } }