Dynamic LiveTile - render a custom font TextBlock on LiveTile with background task

862 views Asked by At

I'm having problems in rendering custom textblock with custom font resource on liveTile ?

My project updates a live tile in background. but it should be personalized.

Im using this code. but its does not woks, the text shows blank when i try to use an embedded font the bitmap background works just fine. But the fonts does not works.

When i use this same code in "foreground agent" the fonts shows perfectly.

Grid grid = new Grid();

// load your image 
StreamResourceInfo info = Application.GetResourceStream(new Uri("tile.jpg", UriKind.Relative));

// create source bitmap for Image control (image is assumed to be alread 173x173)
WriteableBitmap wbmp2 = new WriteableBitmap(1, 1);
wbmp2.SetSource(info.Stream);
Image img = new Image();
img.Source = wbmp2;

// add Image to Grid
grid.Children.Add(img);

TextBlock text = new TextBlock() 
{
    FontFamily = new FontFamily("/MyTaskAgent;component/Fonts/Fonts.zip#Buxton Sketch"),
    Foreground = new SolidColorBrush(Colors.Black) ,
    TextWrapping = TextWrapping.Wrap,
};

text.Text = "Test";

// this is our final image containing custom text and image
WriteableBitmap wbmp = new WriteableBitmap(173, 173);

// now render everything - this image can be used as background for tile
wbmp.Render(grid, null);
wbmp.Invalidate();
2

There are 2 answers

0
Martin Lottering On BEST ANSWER

I had a similar problem, and found a solution, please have a look here or here

I boils down to either 1. creating a hidden textblock that use the font before doing the conversion, or 2. creating a FontSource.

I used the first because it was simpler for now.

The textblock is hidden, but it ensures that the embedded font is loaded.

Inside my control, I added the following:

void Grid_Loaded(object sender, RoutedEventArgs e) {
#if SILVERLIGHT
    Grid Grid = (Grid)sender;
    AddFontLoaderTextBox(Grid, "Signs Road Features");
    AddFontLoaderTextBox(Grid, "Signs G Old");
    AddFontLoaderTextBox(Grid, "Signs G");
    AddFontLoaderTextBox(Grid, "Signs G1");
    AddFontLoaderTextBox(Grid, "Signs G2");
    AddFontLoaderTextBox(Grid, "Signs G3");
    AddFontLoaderTextBox(Grid, "Signs Info");
    AddFontLoaderTextBox(Grid, "Signs Regulatory");
    AddFontLoaderTextBox(Grid, "Signs Regulatory1");
    AddFontLoaderTextBox(Grid, "Road Manager");
    AddFontLoaderTextBox(Grid, "Signs Temporary");
    AddFontLoaderTextBox(Grid, "Road Manager");
    AddFontLoaderTextBox(Grid, "Signs Warning");
    AddFontLoaderTextBox(Grid, "Signs Warning1");
#endif
}

#if SILVERLIGHT
void AddFontLoaderTextBox(Grid Grid, string fontName) {

    TextBlock TextBlock = new TextBlock();
    TextBlock.FontFamily = new FontFamily(string.Format(
        "pack://application:,,,/ITIS.Controls.LinearViewer.Silverlight;component/Fonts/{0}.ttf#{0}", fontName));
    TextBlock.Opacity = 0; /* hide the text block, we only load it for the font to be cached */
    Grid.SetRowSpan(TextBlock, 3); /* just to ensure the text block doesn't affect the size of the first row */
    Grid.Children.Insert(0, TextBlock); /* keep underneath other children */
}
#endif
2
Claus Jørgensen On

I wouldn't be certain the issue is related to the posted code. I find it likely that loading a custom font, will take quite some time, and thus the Background Agent will finish before the font is loaded, and as such not rendering anything.

Are you certain the rendering completes, before you call NotifyComplete() ?