# # 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

### # Configure via UI Fragments (Recommended)

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

#### # Print Specific Area

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.