I am mucking about with WPF glyphs and documents and have run into a null reference exception in the .Net 4 framework.
I extract and save true-type fonts to disk as .ttf files, then try to create Glyphs based on the fonts. The first time I save a font to disk and instantiate a GlyphTypeface based on the font after creating a GlyphTypeface from another font in the same folder I get a null reference exception.
Say I have fonts A and B. B has not been saved to disk (A may or may not have been saved to disk; that doesn't seem to matter):
1) save B to disk in the same folder as A,
2) create GlyphTypeface using font A,
3) create GlyphTypeface using font B = exception.
Null reference exception at:
at MS.Internal.FontCache.FontFaceLayoutInfo.IntMap.TryGetValue(Int32 key, UInt16& value)
at MS.Internal.FontCache.FontFaceLayoutInfo..ctor(Font font)
at System.Windows.Media.GlyphTypeface.Initialize(Uri typefaceSource, StyleSimulations styleSimulations)
at System.Windows.Media.GlyphTypeface..ctor(Uri typefaceSource)
If I restart my app and run it again (with font B already on disk), step 3 doesn't throw an exception.
The code to save a font to disk is simply writing a section from a binary stream and letting go of the file:
if (!File.Exists(filename))
{
using (FileStream fs = File.Create(filename, length))
{
fs.Write(m_data, m_index, length);
fs.Close();
}
}
Any ideas? I don't want to have to put every font in its own folder...
Thanks for your time.
This bug has been driving me nuts but I think I have a better understanding of what is going on now.
For testing I used the following XAML:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Glyphs
FontUri="C:\Users\Public\Desktop\A.ttf"
FontRenderingEmSize="100"
Fill="Black"
UnicodeString="Test"/>
</Page>
Using the XamlPadX application which runs on the .NET 2 runtime I could reliably render the XAML no matter where I placed the font.
Using the Kaxaml application which runs on the .NET 4 runtime the XAML would often fail to render depending on where I placed the font in the file system. By moving the font file around and renaming I tried to discover a pattern in what was allowed. However, it was very hard to see a pattern.
For instance storing the font in the path below would render the glyphs:
C:\Users\Public\Desktop\A.ttf - OK
Renaming it from A.ttf
to B.ttf
would throw the exception:
C:\Users\Public\Desktop\B.ttf - throws exception
Changing the extension would also throw the exception:
C:\Users\Public\Desktop\A.odttf - throws exception
Renaming parts of the path would sometimes wreak havoc but I was unable to see any pattern. Initially I used the temp path and getting exceptions lead me to this question and the answer about not using that path. However, later I have actually been able to use that path as long as the name of the file is A.ttf
and not B.ttf
so avoiding the temp path is not a sure fix.
At some point during my tests using my own WPF application the B.ttf
file name suddenly started working. However, I had to restart the Kaxaml application before it would accept the B.ttf
file name. Also, at that point the A.odttf
file name was still throwing exceptions.
My suggestion is to use an application like Kaxaml or to create a small WPF application to test which font file names are acceptable and then use them. However, I fear that the nature of this bug is such that a "good" font file name may turn "bad" at a later point in time. Only time will show.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With