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'; }
|
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) {
}
//...
}
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:
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)
Code View: 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; }
|
So, you can use the downloader class not only to download text
information, but also to provide dynamic resources such as
TrueType/OpenType fonts.