I just got a question from a Core Graphics presentation I gave a while back (from the first Xamarin Seminar) about how to use Core Graphics to render a PDF with 2 pages side-by-side in landscape. Since this question has come up a couple times in the past I figured I’d write a blog post about it.
The solution I use for this is to create a rectangle to display each page and then apply a transform to render the page within the rectangle. CGPDFPage has a handy GetDrawingTransform function that returns the transform. To get back a transform that crops the page to the rectangle while preserving the aspect ratio simply call:
CGAffineTransform transform = pdfPage.GetDrawingTransform (CGPDFBox.Crop, pageRectangle, 0, true);
To do this for 2 pages, use the SaveState and RestoreState functions of the CGContext to get the transformation matrix back to its intial state, so that the transformation of the first page isn’t applied to the second page.
The following code shows how to implement this in a UIView subclass:
public override void Draw (RectangleF rect) { base.Draw (rect); var rect1 = new RectangleF (0, 0, Bounds.Width / 2, Bounds.Height); var rect2 = new RectangleF (Bounds.Width / 2, 0, Bounds.Width / 2, Bounds.Height); using (CGContext gctx = UIGraphics.GetCurrentContext ()) { gctx.TranslateCTM (0, Bounds.Height); gctx.ScaleCTM (1, -1); gctx.SaveState (); using (CGPDFPage page = pdf.GetPage (page1)) { CGAffineTransform transform = page.GetDrawingTransform (CGPDFBox.Crop, rect1, 0, true); gctx.ConcatCTM (transform); gctx.DrawPDFPage (page); } gctx.RestoreState (); using (CGPDFPage page = pdf.GetPage (page2)) { CGAffineTransform transform = page.GetDrawingTransform (CGPDFBox.Crop, rect2, 0, true); gctx.ConcatCTM (transform); gctx.DrawPDFPage (pdfPg); } } }
This renders the PDF to the screen as shown below: