using Android.Content; using Android.Graphics; using PdfViewerSample.Droid; using Syncfusion.SfPdfViewer.XForms; using Syncfusion.SfPdfViewer.XForms.Droid; using System.IO; using Com.Shockwave.Pdfium; using Xamarin.Forms; [assembly: Dependency(typeof(CustomPdfRenderer))] namespace PdfViewerSample.Droid { internal class CustomPdfRenderer : 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) { 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 { //Sets the config of Bitmap format we required to render the PDF pages bitmap.SetConfig(m_bitmapConfig); //Opens the PDF page with the specified page index to render the page as bitmap m_pdfiumCore.OpenPage(m_pdfDocument, pageIndex); m_pdfiumCore.RenderPageBitmap(m_pdfDocument, bitmap, pageIndex, 0, 0, pageWidth, pageHeight); } } /// /// 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 Android.Util.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 Android.Util.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(); } public void Render(Bitmap destination, int pageIndex, int x, int y, int width, int height) { if (destination == 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 { //Sets the config of Bitmap format we required to render the PDF pages destination.SetConfig(m_bitmapConfig); //Opens the PDF page with the specified page index to render the page as bitmap m_pdfiumCore.OpenPage(m_pdfDocument, pageIndex); m_pdfiumCore.RenderPageBitmap(m_pdfDocument, destination, pageIndex, x, y, width, height); } } } }