Rasterizing PDF on WinRT

10/18/2012 By Frank 0 comments

Today we released a beta version of PDFRasterizer.NET 4.0 (4.0.0.3) that includes a WinRT edition. It took us a little bit longer than we hoped for. I want to explain why. In addition it also includes a Silverlight 4 edition. If you are interested, send a request to sales@tallcomponents.com and we will provide download instructions.

Known restriction of current beta (4.0.0.3)

This version does not support:

  • Soft masks.
  • Non-embedded fonts. This is related to not having access to system fonts from WinRT.
  • Shadings other than gradient, radial, function based (shadings are slow)
  • IccProfiles. We revert to the alternate colorspace.
  • Special colors (such as CMYK) are not entirely correct. E.g. too bright or too pale.
  • Blendings;

So why did it take us so long?

The main problem with rasterizing PDF documents are the restrictions of the graphics API of WinRT itself. Among others, it only supports rectangular clipping paths. This alone is a showstopper.

We struggled with similar problems when using GDI+ or WPF as the graphics API. But their shortcomings always came down to not being able to render edge cases (exotic shadings and blend modes). But even then we could revert to a bitmap-based workaround. If a graphics API is able to render to bitmaps, one can implement extensions in terms of operations on these bitmaps. This is not an ideal solution (espcially w.r.t. printing), but it often works well for on-screen solutions.

This bitmap-based solution is unavailable when developing for WinRT. There is no equivalent for GDI+ code like this:

1 // Create bitmap 2 Bitmap bitmap = new Bitmap(500, 500, PixelFormat.Format32bppRgb); 3 4 // Create graphics object from bitmap 5 Graphics graphics = Graphics.FromImage(bitmap); 6 7 // Create pen 8 Pen blackPen = new Pen(Color.Black, 3); 9 10 // Create points that define line 11 Point point1 = new Point(100, 100); 12 Point point2 = new Point(500, 100); 13 14 // Draw line to bitmap 15 graphics.DrawLine(blackPen, point1, point2);

When developing for WinRT, you can create a WriteableBitmap which can only be manipulated by setting pixel values. There is no way to e.g. stroke or fill a path.

Because of the shortcomings of GDI+ and WPF, we had considered developing our own graphics engine before. WinRT gave us that last push.

On May 15, I sent off an internal e-mail to the development team announcing a new internal project. Here is the first part of this e-mail:

"Until now we relied heavily on the graphics API as provided by Microsoft such as GDI+ and WPF for rendering PDF documents. Because of this we were not able to render all PDF features such as complex shadings and complex blend modes. With the introduction of new platforms such as WinRT and Silverlight, even less exotic graphical features have become unavailable. Because of this we have decided to develop an internal module (100% managed code) that frees us from the graphical capabilities that Microsoft decides to offer. Let's call this module TallBitmap."

"The graphical feature set of TallBitmap should cover all graphical features of PDF such as:

  • path construction and painting (PDF spec 4.4)
  • fill rules (non-zero winding number, even-odd)
  • clipping
  • patterns (PDF spec 4.6). Including shading patterns.
  • transpareny and blend modes (PDF spec Chapter 7)
  • clipping
  • dash patterns
  • jin style / cap style
  • images (PDF spec 4.8). Note that the library does not have to include decoding. The library assumes that the images have been decoded."

For five months, two of our engineers spent 50% of their time implementing TallBitmap. They worked in sprints of five days and alternated this with support.

Today, this work paid off when we released a WinRT edition of our PDF render engine that is based on our internal module TallBitmap.