A while back, I mentioned how I was using TIFF files to embed a 3rd party report into XPS content. It was decided that the bitmap was rather jarring when compared to the surrounding beautiful vector elements, so I coded up a solution that leveraged the component's export to XPS feature and converted the XPS FixedPages to Canvases thereby creating XAML for a WPF visual which I deserialized and hosted in the app.
There was a problem though. The first page of the report looked great. Second+ pages were missing characters. It seemed to be consistent within each document.
Fonts in XPS are stored as shared resources. I was taking the first occurrence of any font, say "Arial", and putting it in an in-memory package. I'd update the Xaml of my FixedPages-turned-Canvases to point to the in-memory package for the FontUri rather than using the original resource. Because of the consistency with which this was happening, I could only figure that the font files were being corrupted somehow.
It turned out that this was in fact this case. Each report's "Arial" file was a different size. I skimmed the web for a while and found some vague allusions to XPS optimizing fonts.
Today my coworker pinpointed a likely cause:
XpsSerializationManager.SetFontSubsettingPolicy
This method lets you control exactly what I was describing. It determines if all glyphs from the fonts are preserved or if the unused glyphs are stripped out per page or per document.
Thanks Matt!!
Friday, September 19, 2008
Tuesday, September 9, 2008
XamlReader in .Net 3.5 SP1
If you've done any WPF development involving dynamic object creation from XAML, you're probably familiar with XamlReader.Load().
There are several overloads which take a stream or an XmlReader. This usually leads to an excessively verbose syntax in my code, where I generally have the XAML string in memory:
MyClass myObject = (MyClass) XamlReader.Load(XmlReader.Create(new StringReader(myObjectXamlString)));
With SP1, we now have the object of using XamlReader.Parse() which simply takes in a string. All of my verbose code that follows the style above now becomes:
MyClass myObject = (MyClass) XamlReader.Parse(myObjectXamlString);
Life keeps getting better and better!
There are several overloads which take a stream or an XmlReader. This usually leads to an excessively verbose syntax in my code, where I generally have the XAML string in memory:
MyClass myObject = (MyClass) XamlReader.Load(XmlReader.Create(new StringReader(myObjectXamlString)));
With SP1, we now have the object of using XamlReader.Parse() which simply takes in a string. All of my verbose code that follows the style above now becomes:
MyClass myObject = (MyClass) XamlReader.Parse(myObjectXamlString);
Life keeps getting better and better!
Tuesday, September 2, 2008
J# and .Net 3.5
I think most everyone has probably accepted that J# project types are no longer supported in VS 2008, but how much does that really affect a .Net 3.5 project? Couldn't you just compile your J# classes against the 2.0 framework and reference that from your 3.5 project?
Well, I ran into a fun situation today. In a VS 2005 solution, we used to serialize J# classes using the BinaryFormatter. No problems there. The classes implemented Serializable, the BinaryFormatter dutifully formatted them as binary.
I tried doing the same in .Net 3.5 and it began complaining that my J# types (declared in a compiled .Net 2.0 assembly) were not marked as Serializable. I did a quick check - BinaryFormatter is declared in mscorlib.dll, which was clearly upgraded between 2.0 and 3.5. I didn't dig into the disassembly, but I think it's safe to say that J# serialization via BinaryFormatter is lost. :-(
Well, I ran into a fun situation today. In a VS 2005 solution, we used to serialize J# classes using the BinaryFormatter. No problems there. The classes implemented Serializable, the BinaryFormatter dutifully formatted them as binary.
I tried doing the same in .Net 3.5 and it began complaining that my J# types (declared in a compiled .Net 2.0 assembly) were not marked as Serializable. I did a quick check - BinaryFormatter is declared in mscorlib.dll, which was clearly upgraded between 2.0 and 3.5. I didn't dig into the disassembly, but I think it's safe to say that J# serialization via BinaryFormatter is lost. :-(
Subscribe to:
Posts (Atom)