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);
}
}
}
}