Edit this page

Customize PDF Rendering

RadPdfViewer provides customization options for the way PDF documents are rendered.

Creating a Decoder

When rendering the content, RadPdfViewer uses different decoders. It finds the decoder that it needs to use by its name. These are the decoders that can be plugged:

  • ASCIIHexDecode

  • ASCII85Decode

  • LZWDecode

  • FlateDecode

  • RunLengthDecode

  • CCITTFaxDecode

  • JBIG2Decode

  • DCTDecode

  • JPXDecode

Table 1 indicates the status of the respective decoders in RadPdfViewer.

Table 1: Decoders support in RadPdfViewer

Fully supported Partially supported Not supported
ASCII85Decode CCITTFaxDecode JPXDecode
LZWDecode
FlateDecode
DCTDecode
ASCIIHexDecode
RunLengthDecode
JBIG2Decode

Although JPXDecode is not supported out-of-the-box, you can implement a custom decoder and enable RadPdfViewer to read and render the content that uses this filter following the guides in this article. An implementation of this scenario is available in the Custom Decoder example from our SDK repository as well.

All decoders implement the IPdfFilter interface and if you decide, you can implement your own decoder and set the viewer to use it. RadPdfViewer uses the Name property in order to recognize the filter - it must return one of the values listed above.

For example, you can create a custom decoder for Tiff images by implementing the interface and setting the Name of the filter to CCITTFaxDecode. Then, just register the new class by calling FiltersManager.RegisterFilter() method and the viewer will use your implementation instead of the default one.

The cod from Example 1 shows the members that should be implemented when inheriting the IPdfFilter interface.

Example 1: Members of IPdfFilter

public class CustomFilter : IPdfFilter
{
    public byte[] Encode(PdfObject encodedObject, byte[] inputData)
    {
        throw new NotImplementedException();
    }

    public byte[] Decode(PdfObject decodedObject, byte[] inputData, DecodeParameters parms)
    {
        throw new NotImplementedException();
    }

    public string Name { get { return PdfFilterNames.CCITTFaxDecode; } }
}

You should also register the filter as demonstrated in Example 2:

Example 2: Register a custom filter

private PDFAndTiffFilter _filter;

public MainPage()
{
    _filter = new PDFAndTiffFilter();
    FiltersManager.RegisterFilter(_filter);
    InitializeComponent();
}

The result that a custom filter should return depends on the type of the filter. For the binary filters it is enough to decode the byte array into decoded byte array using the respective algorithm. As for the filters listed below, additional transformation is required.

  • CCITTFaxDecode

  • JBIG2Decode

  • JPXDecode

  • DCTDecode

    You can override the DctDecode class and its Decode() method. This will enable you to call the DecodeWithJpegDecode() method in order to achieve backward compatibility by using Telerik's JpegDecoder. In some cases, this approach decodes faster than the BitmapImage class, which is currently used to decode the images.

RadPdfViewer expects these filters to return data that depends on the decoded object's colors space and bits per component (there are such properties in the decodedObject). The resulting byte array should contain exactly BitsPerComponent bits for each color component in the color space. For example, if you have RGB color space and 8 bits per component, the resulting byte array should contains a single byte value for each Red, Green and Blue value (for each pixel) in the decoded image.

See Also