Foxit PDF SDK for iOS

How to render with Foxit PDF SDK for iOS

PDF rendering is done with the Foxit renderer, a graphic engine that is used to render pages to a bitmap or a platform device. Foxit PDF SDK provides APIs to set rendering options/flags. For example, to set a flag to decide whether to render form fields and a signature, whether to draw anti-aliasing images and anti-aliasing paths. To render, you can use the following APIs:

  • To render a page and its annotations, first use the function FSRenderer::setRenderContentFlags to decide whether to render both the page and annotations, and then use the function FSRenderer::startRender to render. The function FSRenderer::startQuickRender can also be used to render page but only for thumbnail purposes.
  • To render a single annotation, use the function FSRenderer::renderAnnot
  • To render on a bitmap, use the function FSRenderer::startRenderBitmap
  • To render a reflowed page, use the function FSRenderer::startRenderReflowPage

Widget annotation is always associated with a form field and form control in Foxit PDF SDK. For how to render widget annotations, here is a recommended flow:

  • After loading a PDF page, first render the page and all annotations in the page (including widget annotations).
  • Then, if you are using the FSFiller object to fill the form, the function FSFiller::render should be used to render the focused form control instead of the function FSRenderer::renderAnnot.

Example:

How to render a specified page to a bitmap

#import "ViewController.h"
#import 
...
-(FSBitmap*)renderPageToBitmap: (FSPDFPage*) pdfPage drawWidth: (int)drawPageWidth drawHeight: (int)drawPageHeight
{
    // If the page hasn't been parsed yet, throw an exception.
    if(![pdfPage isParsed])
        @throw [NSException exceptionWithName:NSGenericException reason:@"PDF Page should be parsed first" userInfo:nil];
    // Pepare matrix to render on the bitmap.
    FSMatrix2D* matrix = [pdfPage getDisplayMatrix:0 top:0 width:drawPageWidth height:drawPageHeight rotate:FSRotation0];
    // Create a bitmap according to the required drawPageWidth and drawPageHeight.
    FSBitmap* bitmap = [[FSBitmap alloc] initWithWidth:drawPageWidth height:drawPageHeight format:FSBitmapDIBRgb];
    // Fill the bitmap with white color.
    [bitmap fillRect:0xFFFFFFFF rect:nil];
    FSRenderer* renderer = [[FSRenderer alloc] initWithBitmap:bitmap is_rgb_order:YES];
    // Set the render flag, both page content and annotation will be rendered.
    [renderer setRenderContentFlags:FSRendererRenderPage | FSRendererRenderAnnot];
    // Start to render the page progressively.
    FSProgressive* progress = [renderer startRender:pdfPage matrix:matrix pause:nil];
    if(progress) {
        FSProgressiveState state = [progress resume];
        while (state == FSProgressiveToBeContinued) {
            state = [progress resume];
        }
        if(state != FSProgressiveFinished)
            return nil;
    }
    return bitmap;
}

How to render a specified page to a platform device context

#import "ViewController.h"
#import 
...
-(void)renderPageToContext: (FSPDFPage*) pdfPage context: (CGContextRef)context
{
    // If the page hasn't been parsed yet, throw an exception.
    if(![pdfPage isParsed])
        @throw [NSException exceptionWithName:NSGenericException reason:@"PDF Page should be parsed first" userInfo:nil];
    // We set the width of drawing page to be equal to screen width, the drawing page height is calculated according to the ratio of page height and width.
    CGFloat scale = [UIScreen mainScreen].scale;
    int drawPageWidth = (int)[[UIScreen mainScreen] bounds].size.width * scale;
    float pageWidth = [pdfPage getWidth];
    float pageHeight = [pdfPage getHeight];
    int drawPageHeight = (int)drawPageWidth * (pageHeight/pageWidth) * scale;
    // Erase the background of context with white color.
    CGContextSaveGState(context);
    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
    CGContextFillRect(context, CGRectMake(0, 0, drawPageWidth, drawPageHeight));
    // Render to screen in the device coordinate, left:0, top:0, right:drawPageWidth, bottom:drawPageHeight.
    FSMatrix2D* matrix = [pdfPage getDisplayMatrix:0 top:0 width:drawPageWidth height:drawPageHeight rotate:FSRotation0];
    FSRenderer* renderer = [[FSRenderer alloc] initWithContext:context device_type:FSRendererDeviceDisplay];
    [renderer setRenderContentFlags:FSRendererRenderPage | FSRendererRenderAnnot];
    // Start to render the page progressively.
    FSProgressive* progress = [renderer startRender:pdfPage matrix:matrix pause:nil];
    if(progress) {
        FSProgressiveState state = [progress resume];
        while (state == FSProgressiveToBeContinued) {
            state = [progress resume];
        }
    }
    CGContextRestoreGState(context);   
}

Updated on July 21, 2021

Was this article helpful?
Thanks for your feedback. If you have a comment on how to improve the article, you can write it here: