Draw a PDF in Landscape with Core Graphics

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:


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s