Cross-platform limitations of Mono.

1/28/2013 By Frank 0 comments

Some customers indicated that they were having issues running PDFRasterizer.Net on Mono. And although we do not officially support mono, we decided to do some experiments with it nonetheless.

Running a sample in MonoDevelop on Windows

So, we installed MonoDevelop, and we tried to run some of the PDFRasterizer.NET samples. This immediately led to the following error:

Error CS1566: Error reading resource file '…\TallComponents.PDF.Rasterizer_3.0.84.2\Code Samples\CS\ViewPDF\MainForm.resources' -- 'The system cannot find the file specified. ' (CS1566) (ViewPDF_vs2010)

In order to solve this issue we had to manually call resgen on all the .resx files. This allowed us to build the project, but when trying to debug it, we got the following:

error-report.png

Luckily, this appeared to be rather an issue with running the MonoDevelop debugger than anything else. Without debugging, things appeared to be fine, so we did not pursue debugging in Windows any further.

pdfrasterizer-pdf-mono.png

Running a sample in MonoDevelop on OSX

Then, we figured that we should also try things on Mac OSX. At first this gave some weird compile errors, like:

…/TallComponents.PDF.Rasterizer_3.0.84.2/Code Samples/CS/ViewPDF/MainForm.cs(35,35): Error CS0584: Internal compiler error: Method not found: 'TallComponents.PDF.Rasterizer.Document.ConvertToWpf'. (CS0584) (ViewPDF_vs2010)

This was strange because we used a sample that made no reference to any WPF functionality at all. It occurred to us however that this sample referenced a .Net 4.0 assembly, and we remembered some old blogs talking about MonoDevelop having issues with that. So we removed the .Net 4.0 PDFRasterizer.NET assembly and added the .Net 2.0 one instead. This looked quite hopeful at first, and interestingly we had no trouble running the debugger here:

pdfrasterizer-pdf-mono-2.png

But then we noticed that the evaluation banner was missing. The banner should have been there because we were running in evaluation mode. We started looking further. On OSX, PDFRasterizer.NET turned out to be plagued by basically 2 problems:

  • Some pages would render completely blank, or only partially.
  • Mono would just quit on some pages, leaving no further option to debug:

error-report-2.png

Compiling in MonoDevelop

In order to track this down, we decided to try and get our PDFRasterizer.NET sources compiled under MonoDevelop. We started doing so on Windows, soon to discover that the MonoDevelop compiler (3.0.5) has some limitations compared to standard Microsoft .Net. Amongst others:

  • it gives errors on vars.
  • it gives errors on extension methods
  • one needs to specify brackets for some #if evaluations

After “fixing” these, we went on to OSX with our sources. Here we discovered that some further issues were flagged. These were relatively minor, but it was certainly a surprise to find out that these differences exist between the PC and the Mac version of MonoDevelop. More so, because we also discovered that the Windows issues mentioned above were not flagged by the compiler on OSX at all. Both versions are the latest stable versions for both platforms, which at this point means 3.0.5 for windows and 3.1.1 for OSX.

Debugging

In any case, after having fixed these compilation issues, it became more or less possible to debug PDFRasterizer.Net on OSX. Apart from the occasional crash, we were able to identify the following 2 runtime issues:

  • there were runtime differences in casts from (negative) doubles to uints. Once we were aware of this, this was easy to fix.
  • The System.Drawing implementation on OSX turned out to behave differently with respect to clipping. In OSX the clipping area becomes empty at unpredictable times, leading to loss of graphics. If we turned off clipping altogether, we were able render additional graphics on some problematic pages , but part of the page would still be rendered incorrectly due to improper clipping handling.

The following pictures illustrate the latter. With clipping enabled, we would get the following on OSX:

pdfrasterizer-pdf-mono-3.png

Whereas with clipping entirely disabled, we would get:

pdfrasterizer-pdf-mono-4.png

Notice that the last result does show additional images (as it should), but also that the colors that are projected in the topmost images are wrong in both cases. This happens because clipping is used to draw the “intersections” of various colors. Clearly this goes wrong no matter whether clipping is turned on or not. For comparison, the same code – with clipping enabled - renders the following on MonoDevelop on Windows:

pdfrasterizer-pdf-mono-5.png

In itself this issue was already a showstopper for us. Unfortunately, having compiled the system on MonoDevelop itself also did not preclude the crashes that we encountered earlier. There were still PDF files that we were unable to debug at all, because Mono just quits on them.

Conclusion

All in all, it was very disappointing to discover that Mono is not as platform-independent as it claims to be, while also being very unstable on OSX. This means that it is currently impossible for us to have a workable solution for Mono on various platforms.

Apart for improvements in Mono itself, our hopes are now mainly on our own “TallBitmap” renderer, which will allow us to render PDF pages without relying on System.Drawing, and thus without depending on Mono’s implementation of this functionality on various platforms.