# Image-Based Printing

# Overview

Foxit PDF SDK for Web provides the <print:print-dialog> printing component in the UIExtension layer. Its implementation works by exporting a PDF based on the user's selected options and printing it via the browser. However, some browsers, particularly Safari on iOS, encounter compatibility issues when handling PDF printing. To address this problem, Foxit PDF SDK for Web offers an image-based printing feature as an alternative solution.

Technical Note: The <print:print-dialog> component utilizes a underlying API to export PDFs internally, however, this API is currently not publicly available. If you need to directly control the PDF export and printing process, it is recommended to use the PDFViewer.print API instead.

# PDFViewer.print API

Foxit PDF SDK for Web not only provides a UI-level printing component but also offers the underlying printing API PDFViewer.print. This API converts PDF pages into images before printing, effectively addressing compatibility issues encountered by some browsers during the PDF printing process.

# Technical Principle

Unlike the default <print:print-dialog> component, the PDFViewer.print API uses a different technical implementation approach:

  • <print:print-dialog> Component: Uses a underlying PDF export API to pass the PDF file to the browser for printing.

  • PDFViewer.print API: Directly parses the PDF content, converts pages into images, and then utilizes the browser's printing functionality for output.

Although the print quality of PDFViewer.print might differ slightly, this method ensures reliable operation across various browser environments, especially in browsers with compatibility issues.

# Key Advantages

  • Cross-browser compatibility: Ensures stable printing functionality across different environments, effectively addressing compatibility issues with browsers like iOS Safari.
  • Flexible configuration: Support customization of parameters such as page range, print quality, and content type to meet diverse requirements.
  • Progress monitoring: Provide print progress callback functionality, allowing developers to optimize user experience.
  • Area-specific printing: Support printing specific areas of a page, enhancing flexibility and precision in printing.

# Basic Usage

pdfviewer.print({
    pages: [0, 1],                      // Specify the pages to be printed  
    printType: ['page', 'annot'],       // Content types to print: pages and annotations
    quality: 100,                       // Print quality settings  
    showHeaderFooter: false             // Whether to display header and footer 
}, function(message) {
    switch(message.state) {
        case 'start':
            console.log('Start generating page images');
            break;
        case 'progress':
            console.log('Page images generated', message.pageIndex, message.total);
            break;
        case 'end':
            console.log('Finished generating page images');
            break;
    }
});

# Usage Scenarios

While the default printing component works well in most cases, there are specific scenarios where using the PDFViewer.print API might be a better choice:

  1. iOS Safari Browser Compatibility Issues

    • Safari on iOS has limited support for PDF printing
    • Printing functionality may not work properly or encounter unexpected issues
  2. Other Browser Compatibility Issues

    • Certain browser versions have limitations on PDF printing
    • Print preview may display incorrectly or fail to render properly
  3. Cross-platform Compatibility Requirements

    • Ensures consistent printing functionality across different browser environments
    • Applications with high requirements for browser compatibility
  4. Underlying Printing Control Needs

    • Provide the ability to implement custom printing logic using an image-based approach

# Solution

If you are using the default UI components of Foxit PDF SDK for Web, you can enable image-based printing through UI Fragments configuration:

new PDFUI({
    appearance: UIExtension.appearances.adaptive.extend({
        getDefaultFragments() {
            return [{
                target: '@print:print-dialog',
                config: {
                    attrs: {
                        'is-image-based': PDFViewCtrl.DeviceInfo.isIOS && PDFViewCtrl.BrowserInfo.isSafari
                    }
                }
            }]
        }
    })
})

# Custom Component Implementation

If you need to implement the printing functionality in custom components, you can directly call the PDFViewer.print API:

pdfviewer.print({
    pages: [0, 1],                      // Specify the pages to be printed  
    printType: ['page', 'annot'],       // Content types to print: pages and annotations
    quality: 100,                       // Print quality settings
    showHeaderFooter: false             // Whether to display header and footer 
})

# Parameter Configuration

# API Parameter Description

Parameter Type Description Default Value
pages Array<number | object> Array of page indices or objects to specify the pages to print; if it is an object and contains a rect property, it prints the specified area, otherwise the whole page is printed All pages
printType Array<string> Print types, optional values: 'page', 'annot', 'stamps', 'form' ['page']
progress ProgressComponent | boolean Control the display of the printing progress bar: true displays the default progress bar, false hides it, or you can pass a custom progress component for replacement true
quality number Print quality setting, with a range from 100 to 1000 (expressed as a percentage) 100
showHeaderFooter boolean Whether to display headers and footers (supported only in Chrome, Firefox, and Chromium Edge) true
isPortfolio boolean Indicate whether the document is a portfolio false
rangeType string Specify the type of range for printing -
printer string Specify the printer to use for printing undefined

# Advanced Usage

In certain scenarios, it may be necessary to print only a specific area of a page, such as a table or chart, to meet specific business requirements.

// Print a specified area on page 0 of the document
pdfviewer.print({
    pages: [{
        pageIndex: 0,
        rect: { x: 100, y: 100, width: 400, height: 300 }
    }],
    printType: ['page'],
    quality: 200
});

# Custom Progress Indicator

To optimize the user experience, you can customize the progress indicator during the printing process.

//  Create a custom progress component 
const customProgress = {
    show: () => console.log('Show progress bar'),
    hide: () => console.log('Hide progress bar'),
    updateProgress: (progress) => console.log(`Progress: ${progress.current / progress.total * 100}%`)
};

pdfviewer.print({
    pages: [0, 1, 2],
    progress: customProgress,
    quality: 150
});

# Browser Detection Configuration

// Detect if the device is iOS
const isIOS = PDFViewCtrl.DeviceInfo.isIOS;

// Detect if the browser is Safari
const isSafari = PDFViewCtrl.BrowserInfo.isSafari;

// Combine conditional judgments
const shouldUseImageBased = isIOS && isSafari;

# Notes

# Differences in Print Quality

Although the PDFViewer.print API offers better compatibility, it may result in differences in print quality compared to the default printing method. When image-based printing is enabled, the clarity of text and graphics may decrease, and certain details might appear blurry or be lost. This compromise is necessary to achieve better compatibility.

# Performance Impact

Image-based printing requires converting PDF pages into images, which can affect performance. It may result in slower printing speeds and higher memory consumption, particularly for large documents, where delays could become more noticeable. It is recommended to adjust print quality parameters based on actual needs to achieve a balance between print quality and performance.

# Memory Consumption

High-quality printing can significantly increase browser memory consumption, especially when the print quality settings exceed 300%. When handling large documents or high-resolution prints, it is important to monitor memory usage. It is recommended to adjust the print quality settings reasonably based on actual needs.

# Best Practices

# Intelligent Selection of Printing Methods

Dynamically select the most suitable printing method based on the browser environment:

// Dynamically select the printing method based on the browser environment  
function getPrintConfig() {
    const isIOS = PDFViewCtrl.DeviceInfo.isIOS;
    const isSafari = PDFViewCtrl.BrowserInfo.isSafari;
    
    if (isIOS && isSafari) {
        return {
            useImageBased: true,
            quality: 100,
            showHeaderFooter: false
        };
    }
    
    return {
        useImageBased: false
    };
}

# User Experience Optimization

To enhance user experience, provide users with information about potential differences in print quality before printing:

// Display a notification before printing  
function printWithNotification() {
    const config = getPrintConfig();
    
    if (config.useImageBased) {
        // Show compatibility notification  
        showNotification('The current browser environment will use compatibility mode for printing. The print output may slightly differ from the expected quality');
    }
    
    // Execute the print operation
    pdfviewer.print(config);
}

# Error Handling

Add a robust error-handling mechanism for the printing functionality:

// Add error-handling mechanism
pdfviewer.print({
    pages: [0, 1],
    printType: ['page', 'annot'],
    quality: 100,
    showHeaderFooter: false
}).catch(error => {
    console.error('Printing failed:', error);
    // Display an error message or perform fallback handling  
    showErrorMessage('Printing failed. Please check your printer settings or try again');
});

# Summary

The image-based printing functionality enhances browser compatibility support for Foxit PDF SDK for Web, particularly in browser environments like iOS Safari where compatibility issues may occur.Although the print output might slightly differ, proper configuration and robust error-handling mechanisms can provide users with a stable and reliable printing experience.

In practical development, it is recommended to select an appropriate printing solution based on specific application scenarios and user needs. When necessary, inform users about potential differences in print quality. Additionally, implementing comprehensive error-handling mechanisms and conducting thorough cross-browser testing are critical to ensuring the stability of the printing functionality.