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 MainWindow()
{
_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.