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  
 
Top 10
Installing the Exchange Server 2010 prerequisites
Algorithms for Compiler Design:
Business Intelligence in SharePoint 2010 with Business Connectivity Services : Consuming External Content Types (part 3) - Business Connectivity Services Web Parts
Windows Azure : Static reference data (part 2) - Performance disadvantages of a chatty interface & Caching static data
The Membership Data Store
Optimizing an Exchange Server 2010 Environment - Analyzing and Monitoring Core Elements
Algorithms for Compiler Design: IMPLEMENTATION in Bottom-up Parsing
Collaborating Within an Exchange Server Environment Using Microsoft Office SharePoint Server 2007 : Customizing and Developing MOSS Sites
Microsoft Malicious Software Removal Tool
Modifying Display Appearance and Video Settings
Most View
BizTalk 2006 : Building a Resequencing Aggregator
Windows Server 2008 : Transport-Level Security - Using IPSec Encryption with Windows Server 2008 R2
Windows 7 : Understanding User Account Control and Its Impact on Performance
Algorithms for Compiler Design: THE LR PARSER
Port-Binding Shellcode
Building Android Apps: Web SQL Database (part 4) - Deleting Rows
Silverlight : Play a Video
Windows Phone 7 Development : Understanding Trial and Full Modes (part 1) - Using the IsTrial Method
iPhone Application Development : Understanding Interface Builder
Server 2008 : Hardening Server Security
Managing Local User Accounts and Groups in Vista
Using Windows Phone 7 Technologies : Retrieving Accelerometer Data (part 1)
iPhone Application Development : Creating User Interfaces
Programming with DirectX : Textures in Direct3D 10 (part 1) - Textures Coordinates
Installing SQL Server 2008
Defensive Database Programming with SQL Server: The Ticket-Tracking System (part 2) - Removing the performance hit of ON UPDATE CASCADE
Android’s Securable IPC Mechanisms
Windows 7 :Navigating Your Computer with the Address Bar (part 1) - Accessing Locations on Your Computer
Advanced ASP.NET : Component-Based Programming - The ObjectDataSource
Windows 7 : Using Advanced Security Options (part 2) - Configuring Windows Defender