none
XamlReader.Load and fonts...need help ASAP!

    Question

  • Hi guys,

    I really really need a help on this issue as soon as possible.

    I have a font in my main project with build action set to Content. In my other project I have a resource dictionary where I have some templates that use that font.
    Also, I am using XamlReader.Load to create a control that also uses that font and then use WriteableBitmap to render that control to a an image. Everything is rendered fine if I first use that font somewhere on my page. If I don't no text that uses that font is shown. If I set font to a default system font it will always render correctly.

    Control created with XamlReader.Load obviously can't load that font by itself. It needs to be loaded already. Does anyone have any suggestions how to solve this?
    Thursday, March 22, 2012 3:13 PM

Answers

  • Thank you for your effort. But in my case that just can't work because code runs inside background agent. BUT, I found a solution. I am loading a font manually with FontSource. Then I planned to bind that to TextBlock.FontSource. But FontSource isn't a dependency property so I created an attached property to solve that problem. When attached property is changed it changes the FontSource of the TextBlock. FontFamiliy is set to name of the font only.

    Now everything works just as I wanted. Once again thank you for your time.
    Monday, March 26, 2012 8:50 PM

All replies

  • Set the build action of the font to Resource instead of Content. This will cause the font to be preloaded during app startup instead of on demand. Otherwise, the framework may start rendering before the font is loaded. The syntax for a resource path is: FontFamily="/AssemblyName;component/MyFontFolder/CustomFont.ttf#MyFont"



    Richard Woo

    Thursday, March 22, 2012 4:20 PM
  • Thank you for your response.

    I just tried that. But controls from my other project will show font only if I first use it in my main project. Just can't force it to load that font without actually using it on my page.
    Thursday, March 22, 2012 4:48 PM
  • I just tried it myself, and it works for me. From my understanding of how different assemblies should be able access each other's resources, it should work.

    In main assembly (project), I added a .ttf file with Build Action = Resource. The main project doesn't use it at all (but it will be loaded anyway because of the Resource build action). In the satellite assembly (project), it refers to the font with
    FontFamily="/<main_assembly_name>;component/Fonts/SegoeKeycaps.TTF#Segoe Keycaps"


    Richard Woo
    Thursday, March 22, 2012 7:18 PM
  • I created a new project just to test this. It works for me to, but not if control is created with XamlReader.Load and then rendered. It seems that XamlReader.Load does not trigger loading of the font.
    Thursday, March 22, 2012 9:45 PM
  • If you can make it work by using the font on the page, then do exactly that. Put a hidden TextBlock somewhere on the page. To hide it, use Opacity = 0 instead of Visibility.Collapsed to ensure that it will be created.


    Richard Woo
    Thursday, March 22, 2012 10:59 PM
  • I just tried it with XamlReader.Load, and had no problem with it.

    I have a project that contains no code and only resource files (text, xml, and image files). The files have Build Action set to Resource and they are accessed from other projects in the solution. I added some custom font files. From one of the projects, I ran the following code and it worked to use the font in my DataLibrary project:

                string xamlString = "<TextBlock "
                xamlString += "xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" "; 
                xamlString += "Text=\"hello\" "
                xamlString += "FontFamily=\"/DataLibrary;component/Fonts/SegoeKeycaps.TTF#Segoe Keycaps\" "
                xamlString += "/> "
                TitlePanel.Children.Add(XamlReader.Load(xamlString) as UIElement); 


    Richard Woo
    Friday, March 23, 2012 12:03 AM
  • You are missing one more step. Instead of adding that TextBlock directly to your visual tree, try to render that with WriteableBitmap and then show that image on your page (I am expecting that font will not render, but if it does please send me that test project if you can...it will save me to find out what am I doing wrong). I am trying to render controls off visual tree because I will have to do that from the background agent also.
    Friday, March 23, 2012 7:42 AM
  • Okay, I'm able to reproduce your problem now. It looks very similar to a known Silverlight bug with rendering Image controls into a WriteableBitmap, where it won't render if the Image isn't in the visual tree.
    The handling of the custom font is showing the same behavior. I think it is Silverlight's attempt at optimization, to avoid loading and rendering things that aren't actually displayed on the screen. However, it doesn't correctly handle cases when you want to build bitmaps completely offscreen.

    The workaround is what I mentioned earlier. Add to the page a hidden TextBlock that references the font. You can use something like this:
    <TextBlock FontFamily="/DataLibrary;component/Fonts/SegoeKeycaps.TTF#Segoe Keycaps" Height="0" Width="0"/> 
    I found that it isn't even necessary to give Text content to the TextBlock.


    Richard Woo
    Friday, March 23, 2012 7:01 PM
  • Thank you for your effort. But in my case that just can't work because code runs inside background agent. BUT, I found a solution. I am loading a font manually with FontSource. Then I planned to bind that to TextBlock.FontSource. But FontSource isn't a dependency property so I created an attached property to solve that problem. When attached property is changed it changes the FontSource of the TextBlock. FontFamiliy is set to name of the font only.

    Now everything works just as I wanted. Once again thank you for your time.
    Monday, March 26, 2012 8:50 PM