The blog of dlaa.me

Posts from May 2007

Lighting up the XML Paper Specification [Proof-of-concept XPS reader for Silverlight!]

Since getting involved with Silverlight and finding out the XPS document type WPF enables has XAML at its core, I've been wondering how Silverlight would do as a lightweight XPS viewer.

First, a bit of background: WPF is the Windows Presentation Foundation and represents a new approach to UI for Windows. XPS refers to the XML Paper Specification, a device-independent file format for flexible document representation (think PDF) that's part of Office 2007 and .NET 3.0. WPF offers rich support for displaying XPS documents via its DocumentViewer and XpsDocument classes (among others). Because the 1.1 Alpha release doesn't currently include the relevant classes, Silverlight wouldn't appear to be well suited for XPS document display at first glance...

However, Silverlight does have the Downloader class which includes support for packages (for the purposes of this discussion, packages are basically just ZIP archives). Since an XPS document is really just a package, and the core document format XPS uses is XAML, and Silverlight speaks XAML (well, at least a subset of it!), maybe it's not such a stretch to do XPS with Silverlight after all.

I thought it would be a neat exercise to try to write an XPS viewer with the publically available Silverlight 1.1 Alpha bits so I gave it a try and ended up with an application I call SimpleSilverlightXpsViewer:

SimpleSilverlightXpsViewer Application

Go ahead and click here (or on the image above) to play around with the application in your browser. If you find yourself wondering how it works, just click here to download the complete source code/resources and play around with it yourself! (To build the SimpleSilverlightXpsViewer project, you'll want to use Orcas Beta 1 and the Silverlight Tools.)

Of course, this is just a proof-of-concept application built on an Alpha platform, so there are some rough edges. :) Some notes are in order:

  • I created my own XPS documents so I wouldn't have to worry about getting permission to use someone else's XPS documents. Office 2007 comes with a handy "Microsoft XPS Document Writer" printer driver that lets you create an XPS document from any application simply by printing to the XPS "printer" (which then saves the resulting output to a file you specify). I created the three sample documents this way: the "Intro" document came from a simple Word document, the "Blog" document came from my blog via IE7, and the "Site" document came from the Silverlight Forums via IE7 with a landscape page layout.
  • Because the only kind of XPS document I've worked with is the kind the XPS printer driver outputs, there's a very good chance SimpleSilverlightXpsViewer won't understand the internal format of other valid XPS files. Remember, though, that I didn't set out to write an XPS file parser - I just set out to write a simple XPS viewer for Silverlight. :)
  • The translation of "XPS XAML" to "Silverlight XAML" is done by the XpsToSilverlightXamlReader class, a minimal derivation from XmlReader that performs on-the-fly modification of the "XPS XAML" to translate it into "Silverlight XAML". Specifically, some elements are renamed, some attribute values are tweaked, and some attributes are removed entirely. The tweaking is done to address the Glyphs.FontUri/ImageBrush.ImageSource issue mentioned next and re-points the relevant content to an external location.
  • XPS documents are entirely self-contained, with any necessary fonts and images embedded in the file (package) itself. This is great for simplifying distribution and Silverlight's Downloader class makes it easy to get at individual files in a package. However, SimpleSilverlightXpsViewer works best when the images and the fonts are extracted from the XPS file:
    • Under the right conditions, embedded images can be fetched by Silverlight by using the ImageBrush.SetSource method. However, things tend to break if there are multiple references to the same image in a single page (an exception is thrown when the second call to SetSource is made), so SimpleSilverlightXpsViewer doesn't enable this by default. Interested parties can #define SETSOURCE (for both C# files) to experiment with this feature (things work fine for the first page of all of the sample documents, but break on the second pages of the Blog and Site documents).
    • The default behavior of Glyphs.FontUri does not seem to automatically pull the font out of the package - at least not as it's used by SimpleSilverlightXpsViewer (possibly because Silverlight doesn't seem to like the leading '/' on package-relative paths). TextBlock has a SetFontSource method that seems interesting, but XPS XAML uses the Glyphs class which doesn't seem to support SetFontSource.
  • For some reason, the XPS documents generated by the XPS printer driver aren't directly open-able by Silverlight's Downloader (a COM exception is thrown). However, I've found that a quick un-ZIP/re-ZIP with either of my favorite ZIP tools yields XPS documents that open right up. I suspect this is due to a simple issue with the Alpha Downloader implementation (endian-ness of the ZIP file, some special section embedded by the XPS printer driver, etc.) that could be fixed by the Silverlight team without much difficulty.
  • Silverlight doesn't support the TIFF file format (which is not surprising because full support can be quite complex and TIFF images are hardly ever used on the web). As it happens, XPS printer driver output may contain TIFF images (it seems they're used as a mask of some kind behind another PNG or JPG image) - SimpleSilverlightXpsViewer simply ignores the TIFF images and neatly side-steps the support issue. :)

While SimpleSilverlightXpsViewer is a cute proof-of-concept application I enjoyed writing, it is hardly the final word on Silverlight XPS support. (Hey, I'm not even on the Silverlight team!) I don't know what the official plans are for more formal XPS support in the Silverlight platform, but my experience with SimpleSilverlightXpsViewer suggests that most of the pieces are already in place for a pretty reasonable XPS experience with the Silverlight 1.1 Alpha. Throw in a couple of tweaks to Silverlight (and/or SimpleSilverlightXpsViewer!), and it should be possible to provide a pretty compelling XPS-like user experience for Silverlight!

The web just got even better... [Silverlight announced at MIX07!]

During his keynote at the MIX07 conference in Las Vegas, Scott Guthrie showed off some of the power of Microsoft's recently announced Silverlight platform. In particular, the ability to easily run managed code in the web browser - coupled with a powerful rendering engine - seems like it will to radically change the landscape of the web. My team had the privilege of writing the Silverlight Airlines demonstration he used to show off just how easy it is to develop with Silverlight. Demoed on stage, it looked something like the following image:

Silverlight Airlines Demonstration

Now that your appetite is whetted, go ahead and click here (or on the image above) to view the demo in your browser with the Silverlight 1.1 Alpha thanks to the seamless cross-browser, cross-platform support that Silverlight provides.

When our manager Shawn Burke asked us to put this demo together, my coworker Ted Glaza and I had practically no experience with Silverlight or WPF. So we spent about a week playing around with the technology to learn how it worked. By that time, the general concept of the demo was fairly well established and we spent time the next week developing the foundations of the application. Before long, we had a working demo that we showed off to Scott. The third week was spent incorporating visual feedback from a designer and adding some finishing touches. For those of you keeping track at home, that's one cool app written by two developers in just three weeks - beginning with nothing and building on top of a platform that was still being developed - pretty compelling, I think!

In the spirit of openness and learning, you can click here to download the complete source code for this demo application and play around with it yourself!

A few notes on the application:

  • It's implemented as three self-contained controls (the map, calendar, and itinerary picker) that are hooked together via a couple of simple event handlers and property accessors.
  • The goal of code/design separation was achieved here to an extent I haven't experienced before. In particular, the fact that we were able to incorporate an external party's XAML design into our existing code with such ease was a rare treat.
  • I experimented with a vaguely CSS-y approach to XAML design with the calendar and itinerary picker controls I wrote, overlapping a number of different styles and using opacity to display the right style at the right time. I liked the way it worked out here because it enabled me to (for example) completely define the look of the calendar's day cells in a single XAML file - even though that style is actually somewhat complex (there are different styles for alternating months, weekends, hovering, selection, etc.).
  • The "plane flying" animation was Ted's doing and adds a really nice effect. All it took to implement was a plane graphic, a few transforms, a couple of animations, and a bit of high school math. :)
  • The XAML content is automatically resized to fit the browser window (while maintaining its original aspect ratio) with some JavaScript code that hooks the Silverlight control's onLoad and onResize events and manipulates two simple transforms it creates for that purpose. Silverlight lets you program against it with C# and JavaScript - at the same time!
  • In order to compile and build the source code, you need Visual Studio "Orcas" Beta 1 and the Silverlight Tools installed on you machine. Complete details and download links for these tools (and others) can be found on the Silverlight web site.
  • The inspiration for the demo application came from Bret Victor's Magic Ink essay which is a great read and recommended for anyone who's interested in user interface design.

The Silverlight Airlines demo was a fun project to work on - I look forward to be seeing (and doing!) a lot more with Silverlight in the coming days!

PS - Since the keynote presentation, there has been some interest in reusing the calendar control. Beyond making the source code available here, I may write a follow-up blog post going into more detail about the calendar itself. As a quick teaser: it's capable of more sophisticated display than what's in the demo application. :)

PPS - If you watched the Scott Guthrie keynote, you probably saw that there was a time Scott tried to switch the display screen over to the Mac to demonstrate something and it took a while for the conference's A/V folks to actually make the switch. A couple of people have asked if this delay was due to a problem with the Mac or Silverlight. I happen to have been sitting backstage mere inches away from the Mac in question (conferences use KVM switches to keep all the demo machines backstage) and I can assure you that there was no technical issue with the Mac or Silverlight. Aside from the conference tech taking a little while to switch the display over, there were no technical glitches during the demo. :)