WEBSITE

Using Additional Fonts with Silverlight

7/25/2010 5:07:17 PM
I_section2_d1e8009.html

As usual, we start with a simple XAML file that will be enriched with JavaScript code. Example 1 contains a rectangle (for visual reasons) and a . The text block uses the Lucida font by default . We want to change this using JavaScript, therefore we set up an event handler for the Loaded event so that we can load a font once the XAML has been loaded.

Example 11-6. Loading a font, the XAML file (TrueTypeFont.xaml)

<Canvas xmlns="http://schemas.microsoft.com/client/2007" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="loadFont">
<Rectangle Width="300" Height="150" Stroke="Orange" StrokeThickness="15" />
<TextBlock x:Name="FancyText" FontSize="64" Canvas.Left="20" Canvas.Top="35"
Foreground="Black" Text="Silverlight" />
</Canvas>

Loading the font starts the same as loading any file using the downloader object—it makes an HTTP request and sets up a Completed event handler. Make sure you have the calibri.ttf (the Calibri font installed as part of Office 2007 and Windows Vista) file available or use another font file and change the code accordingly:

function loadFont(sender, eventArgs) {
var plugin = sender.getHost();
var d = plugin.createObject('downloader');
d.addEventListener('Completed', displayFont); d.open('GET', 'CALIBRI.TTF');
d.send();
}

In the event handler function, we cannot use the HTTP response as a string. However, the object supports a method called setFontSource(). If you provide the downloader object as an argument, you can use the font you just downloaded!

function displayFont(sender, eventArgs) {
var textBlock = sender.findName('FancyText');
textBlock.setFontSource(sender);

Remember that the downloader object is automatically the event sender and, therefore, the first argument for any event handler function attached to the object.

The rest is easy: you can now set the fontSize property of the element to the name of the downloaded font:

  textBlock.fontFamily = 'Calibri';
}

Example 2 contains the complete code, and you can see the result in Figure 1.

Example 2. Loading a font, the JavaScript file (TrueTypeFont.js)

function loadFont(sender, eventArgs) {
var plugin = sender.getHost();
var d = plugin.createObject('downloader');
d.addEventListener('Completed', displayFont);
d.open('GET', 'CALIBRI.TTF');
d.send();
}

function displayFont(sender, eventArgs) {
var textBlock = sender.findName('FancyText');
textBlock.setFontSource(sender);
textBlock.fontFamily = 'Calibri';
}

Figure 1. The text now uses the Calibri font, which is on all supported systems


But that's not all! You can even download a ZIP file containing several font files, and use every font in there. The XAML file does not change from that shown in Example 1, except for one thing: clicking on the canvas executes an event handler. The application will change the currently displayed font whenever the user clicks on it. See Example 3 for the code.

Example 3. Loading multiple fonts, the XAML file (TrueTypeFonts.xaml)

<Canvas xmlns="http://schemas.microsoft.com/client/2007" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="loadFont" MouseLeftButtonDown="displayFont">
<Rectangle Width="300" Height="150" Stroke="Orange" StrokeThickness="15" />
<TextBlock x:Name="FancyText" FontSize="64" Canvas.Left="20" Canvas.Top="35"
Foreground="Black" Text="Silverlight" />
</Canvas>

Now create a ZIP file containing several TTF files; we are using Consolas and Calibri here. Then load the ZIP file as usual, in the loadFont() function. The displayFont() function will now be called on two occasions: when the font ZIP file has been loaded and when the user clicks on the rectangle. In the former case, the font source of the text box needs to be set to the downloader object. This works only if the event sender (first argument of the event handler function) is the downloader object, and not the <Canvas> element (when the user clicks it). A try...catch block avoids any JavaScript errors:

function displayFont(sender, eventArgs) {
var textBlock = sender.findName('FancyText');
try {
textBlock.setFontSource(sender);
} catch (ex) {
}
//...
}

Loading Images

You can also use the downloader class to load images that are then loaded into an <Image> or <ImageBrush> element. The object method is called setSource() again, but this time it expects two arguments:

  • The downloader object.

  • The filename of the image to use, if you downloaded a ZIP with multiplied images inside. If you directly downloaded just one image, use an empty string as the second method argument.

When downloading big images, you can also track the download progress of those images.


The rest is easy. Once the font source is set, you can set the TextBlock element's fontFamily property to the name of any font within the ZIP file. Example 4 shows the complete code, which also sets the correct font size depending on the font being used. You can see in Figure 2 that the application now also uses the Consolas font.

Example 4. Loading multiple fonts, the XAML JavaScript file (TrueTypeFonts.xaml.js)

var font = 'Calibri';

function loadFont(sender, eventArgs) {
var plugin = sender.getHost();
var d = plugin.createObject('downloader');
d.addEventListener('Completed', displayFont);
d.open('GET', 'fonts.zip');
d.send();
}

function displayFont(sender, eventArgs) {
var textBlock = sender.findName('FancyText');
try {
textBlock.setFontSource(sender);
} catch (ex) {
}
if (font == 'Calibri') {
font = 'Consolas';
var fontSize = '40';
} else {
font = 'Calibri';
var fontSize = '64';
}
textBlock.fontFamily = font;
textBlock.fontSize = fontSize;
}


Figure 2. Clicking on the canvas changes the font


So, you can use the downloader class not only to download text information, but also to provide dynamic resources such as TrueType/OpenType fonts.

Other  
 
Most View
SilverStone Argon AR01 - A Brilliant Budget Cooler
Summarize Small Liquid Cooling System (Part 2)
‘Space Junk’ Could Be Catastrophic
Which MacBook Is Right For You (Part 2)
Sony Cyber-shot DSC-HX20V - A Compact Super-Zoom That’s Worth Checking Out
LINQ to Objects : How to Join with Data in Another Sequence (part 2) - One-to-One Joins - The join Operator
Samsung Galaxy Beam - Stay For The Projector (Part 3)
Most Favorite Social - News Apps For Your Smartphone – November 2012
SQL Server 2012 : SQL Server Audit (part 3) - Viewing Audited Events,Querying Audit Catalog Views
Windows 7 : Programming KMDF Hardware Driver - Handling Interrupts (part 2) - Deferred Processing for Interrupts
Top 10
Sharepoint 2013 : Farm Management - Disable a Timer Job,Start a Timer Job, Set the Schedule for a Timer Job
Sharepoint 2013 : Farm Management - Display Available Timer Jobs on the Farm, Get a Specific Timer Job, Enable a Timer Job
Sharepoint 2013 : Farm Management - Review Workflow Configuration Settings,Modify Workflow Configuration Settings
Sharepoint 2013 : Farm Management - Review SharePoint Designer Settings, Configure SharePoint Designer Settings
Sharepoint 2013 : Farm Management - Remove a Managed Path, Merge Log Files, End the Current Log File
SQL Server 2012 : Policy Based Management - Evaluating Policies
SQL Server 2012 : Defining Policies (part 3) - Creating Policies
SQL Server 2012 : Defining Policies (part 2) - Conditions
SQL Server 2012 : Defining Policies (part 1) - Management Facets
Microsoft Exchange Server 2010 : Configuring Anti-Spam and Message Filtering Options (part 4) - Preventing Internal Servers from Being Filtered