Resource Bundles and Fonts
If you've been working with Flash for a while, especially FlashBuilder, you've probably heard of resource bundles. If you are like me you heard they had something to do with localization. Then you quickly forgot about them. The truth is they aren't only for localization. In fact, they are a really good way to centralize and manage resources in actionscript project. They also happen to work really well for localization. So if they do more than just localization, what are resource bundles.
If you've been working with Flash for a while, especially FlashBuilder, you've probably heard of resource bundles. If you are like me you heard they had something to do with localization. Then you quickly forgot about them. The truth is they aren't only for localization. In fact, they are a really good way to centralize and manage resources in actionscript project. They also happen to work really well for localization. So if they do more than just localization, what are resource bundles.
What are Resource Bundles
I hate to state the obvious, but resource bundles are bundles of...wait for it...resources! So with that the next question is, "What is a resource?"
- A resource could be a...
- ...String
- ...Image
- ...Config Value
- ...Font
Why would you want to use them?
Okay, now you know what resources are. You've managed these resources in other ways. Why would you want to use resource bundles over the way you already do?
- Here are a few good reasons
- 2 words, cleaner code
- easier localization
- change text, configs, etc. in one spot
How to setup
Before we get into using resource bundles with fonts, it is important to know how to set them up. Also you might want to know how to use them with the other, simpler types of resources. There are many great articles already available online if you want to search. I plan to write a "how to setup resource bundles" post next week so check back then.
I hate fonts (but I understand they make stuff look good)
I have always dreaded working with embedded fonts on a flash project. Even though I've done it many times, and should know how, each project has brought its own wrinkle that has caused grief for me. Embedding fonts via resource bundles gives you more control over the specifics of the font. Also, since it is built into development with the Flex SDK, you can more readily change them for your needs right in the project. Need to embed more characters? Change to/from CFF embedding? Just type in the appropriate text and you are done. Depending on your development environment you may need to clean your project.
One other point, I recently work on a localization project for game that was already live. Even though we had all the text strings externalized this project sucked and was slow going. If I had my strings, and other resources, setup in resource bundles I would have been halfway done with the project before I even started. So enough talk, how can we use resource bundles to help with font embedd?
Embedding fonts with resource bundles
A font gets embedded in a resource bundle much like an image get embedded, using the Embed metatag. In fact it is awfully similar to using the Embed metatag as you would in an actionscript file.
It might look something like this:
#a file called fonts.properties AFontDesignersLove="ComicSans" ComicSans=Embed( source="./assets/fonts/comic.ttf", fontName="ComicSans", embedAsCFF="false", mimeType="application/x-font", advancedAntiAliasing="true", unicodeRange="U+0020-007E")
The backslash() is useful in property files to make long entries more readable. I'm all about readable, editable code.
To use this font in its current form would work like this:
[ResourceBundle("fonts")] public class MyFontUsingClass { // put some other code here var resources:IResourceManager = ResourceManager.getInstance(); var fontName:String = resources.getString("fonts", "AFontDesignersLove"); var format:TextFormat = new TextFormat(fontName, FONT_SIZE); _questionField = new TextField(); _questionField.defaultTextFormat = format; _questionField.embedFonts = true; // put some more code here
You probably noticed a couple things here:
- I lied - designers hate Comic Sans
- I also put the font name (string resource) in the property file and just used it to bring in the font.
Once you use the resource bundle metatag in your code for a bundle that has fonts, those fonts are already embedded in your code. There is no need to do the old Font.registerFont()
silliness. At least not when you compile the resource bundle into your swf.
The above code is still a bit heavy and I'd hate to have to write it every time. My advice is to clean it up into something that looks a bit more like this:
_questionField.defaultTextFormat = Fonts.getFormat(); _questionField.embedFonts = true;
Depending on what type of format data is used, you might need to make this a little more robust than this but aiming towards this will make you enjoy the benefits gained from embedding fonts this way. For now, I leave this as an exercise for the reader. I plan to write an article on some resource bundle good practices* in the future.
Decreasing load times with RSLs
Recently, Adobe released version 3.5 of the Flex SDK. I updated a project I was currently working on from 3.3 to 3.5 and I had to reset up my runtime shared library (RSL) for the project. This got me thinking that many people don't know how to properly use RSLs. The world of flex development is better if we all use the the SDK RSLs so that is the topic of today's post
[ad#Adobe Banner]Every Flex application that you create uses the same class files. Some of these are your class files, some are other libraries you have included and then of course you have the files that make up the Flex framework itself. One of the constant complaints I hear about Flex apps ( and flash in general ) is that it takes too long to load. One reason for the long load times is that every Flex application needs to be sure it has all the classes it needs, so all the necessary classes get compiled into the SWF. So, even if the same classes are used in most of the applications you create you are reloading that data again with every new application that gets loaded. Not only is this reloading of data bad for your application but much of what gets reloaded is the Flex framework itself. The fact that it gets reloaded with every Flex application out there means it is adding to bandwidth use on the internet and thus bad for the image of Flex and Flash. Before you give up and start exclusively building AJAX applications, I'd like to introduce you to runtime shared libraries (RSLs).
RSLs were introduced in Flex to allow common libraries to be extracted from Flex application SWF files and put into their own files. That way the Flex apps that use classes from the library(ies) would be smaller and the classes would only need to be loaded once for all the SWF files that need them. Originally there were only two types of RSLs, signed and unsigned. Basically this is still the case but unsigned RSLs are now split into standard and cross-domain varieties while signed RSLs are now referred to as Framework RSLs.
The great thing about the signed, Framework RSLs ( and to a lesser extent cross-domain RSLs if the location used is the same ) is that once someone has loaded the RSL of that Flex SDK on their system, they shouldn't have to reload it for any other app that requires that RSL. In other words, if someone has used another app that required the same Flex SDK (3.2, 3.3, 3.5, etc ) RSL as your app requires then your application will benefit with faster load times ( and vice versa ).
For today's post we are going to focus only on using RSLs. I will save the lesson on creating them for another post if there is interest. Because of this fact I will explain how to use the framework RSLs specifically, but the same technique can be used with standard and cross-domain RSLs.
Using the framework RSLs is actually quite easy. It is even easy enough to take existing live apps and set them up to use RSLs in an effort to decrease load. I made one of my clients, extremely happy by doing this one little task.
In the Flex Build Path screen of project properties window select the Library Path tab ( you can also do this when initially setting up a project ). At the top of you should see a ComboBox labeled Framework Linkage: and you are given the choice of Merged into code (the default) or Runtime shared library (RSL). Select Runtime shared library (RSL). If you are going to have your RSL files in the same directory as your SWF, then that is all you need to do, as your RSL files will be in your bin-debug/bin-release folder along with your application SWF. For the Flex 3.5 SDK these are framework_3.5.0.12683.swz and framework_3.5.0.12683.swf. The SWF is just a backup for the SWZ.
[ad#Google Adsense] If, however, you want to put your RSL into a different location on your server, or on a different server altogether, you'll need to take a couple extra steps to let your application know where to look. The framework RSL files will still show up in your bin-debug and bin-release folders next to your application SWF but it will look for them in a different location. To make these changes you'll need to go to the tree view labeled Build path libraries: and open the node for your flex SDK ( in my picture it says Flex 3.5 ) and then open the node that says framework.swc. Select the node that says RSL URL: and click the Edit... button on the right that probably just became enabled. The only thing you want to edit here are the deployment paths.
When editing the deployment paths for BOTH the SWZ and SWF files, you have the ability to edit 3 things:
- An input field labeled - Deployment Path/URL:
- A checkbox labeled - Copy library to deployment path
- Another input field labeled - Policy file URL:
The deployment path input field is the path to your SWZ or SWF file. Relative paths are acceptable and I recommend using them. The copy library checkbox is used to tell Flex Builder whether or not to include the SWZ or SWC file in your bin-debug/bin-release folders. I like to uncheck this once I already have a copy of the SWZ and SWC available somewhere else because I'm not a big fan of having multiple copies of the exact same file on my computer. The policy file field is used for RSLs served from different domains. It is the path to the appropriate cross-domain policy file. As such it needs to be an absolute path. Cross-domain policy files are out of the scope of this document but more info can be found at: http://livedocs.adobe.com/flex/3/html/security2_04.html#139879.
Now that you have set up your project just upload the RSL file(s) to the appropriate location and everything should be ready to go. You probably noticed quite a difference in file size and on subsequent loads should see an improvement in loading time. However there is one problem that is common with RSLs.
Usually you will get an RSL error if the RSL files aren't where your application SWF is expecting them to be. An easy enough problem to fix. The problem arises in that you won't be able to recreate this error if you already have the files in your cache. Another hiccup is that, while standard and cross-domain RSLs are stored in your browser cache, signed framework RSLs are stored in the much lesser known flash cache. The flash cache is the location shared objects are stored in. It can be managed via the Adobe Flash Player™ Settings Manager's Global Storage Settings tab ( available at: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager03.html ). Just uncheck the store common Flash components to reduce download times checkbox while testing to make sure you load the framework RSL every time instead of pulling them from your cache.
I highly recommend using the runtime shared library for the Flex framework on all your Flex projects. This will speed up the load time of all Flex applications online that are set up to use them and that is good for all of us. The other reason is that there are some drawbacks to using RSLs and the framework RSLs don't really suffer from any of them. In fact from the looks of beta 1 and beta 2 of Flash Builder 4, the framework runtime shared libraries are going to be set by default and they'll be served up by Adobe's own servers. I hope this remains true upon release as it will greatly help Flex apps and their image in the developer community. [ad#Adobe Banner] If you liked this post please subscribe to my RSS feed and/or follow me on Twitter. If you only want to see my Flash Friday posts you can follow the subscribe to the Flash Friday feed. How's that for alliteration :) Until next time keep on coding.
Embedding Fonts in Flex Builder Using the Flash IDE
[ad#Adobe Banner] Flex is great for building rich internet applications quickly. Building an application quickly is nice, but to give your application that truly professional touch you need to customize the look and feel of your app. In order to fully customize the look and the feel you will need to use a font that's different than the default serif font that is used everywhere.
The flash player affords you the opportunity to embed many non standard fonts into your app, something that sets it apart from AJAX applications that need to rely on web safe fonts. In the flash IDE this is as easy as setting the font in the properties panel and selecting which character from that font which you want to embed. In a Flex app, things get a little trickier - especially if you want to use a non True Type font, which is the only type it can import natively. However, if you have the Flash IDE you can use its simplicity to get any font you can use in Flash into your Flex app.
The process is broken up into two steps.
- Create a SWF with the font(s) you need embedded in it
- Add Style (CSS) info to your Flex project that imports the font into your Flex project
Step one starts with the simplest of FLA files and can be created with earlier versions of the Flash IDE (so you can use Flash 8 or MX2004 if that's all you have). I recommend using a separate FLA for each font you want to embed, that way it is easier to catalog, store and reuse in other projects. Create 4 dynamic text fields. Each text field is for the different versions of the font so you should have:
- normal
- italic
- bold
- bold italic
You need to make sure you set up all 4 text fields to embed all the glyphs from the font you will need. For most western languages Numerals, Punctuation and Basic Latin should cover all the glyphs you will need. Once again, make sure to set up the character embedding for all 4 text fields. If you notice certain parts of your flex document using the default font you may not have set up character embedding. You can of course leave out any of the 4 ( ie italic and italic bold ) that you aren't going to use but if you are going to reuse the SWF I would do all 4.
Once you are done setting the character embedding for all 4 text fields, publish the file to a SWF. [ad#Google Adsense] The second step of this process is to add Style to your Flex project that imports the font into the project. That's as simple as adding an @font-face entry to your CSS file or <mx:Style> block. At first you simply give it the path to your font SWF and the name of the font ( ie Futura Book, Calibri ).
@font-face
{
src:url( "path/to/yourFont.swf" );
fontFamily:"Exact Name of Font"
}
You also need to add an @font-face entry for each version of the font you want to use. So if you also wanted to use the bold version you would add the following:
@font-face
{
src: url( "path/to/yourFont.swf");
fontWeight:"bold";
fontFamily:"Exact Name of Font";
}
After you are done adding the appropriate @font-face entries you can style any component you need to or you can style the entire application with your font.
Application
{
fontFamily:"Exact Name of Font";
}
There are a couple other ways to embed fonts, and if you don't have a version of the flash IDE those are the only way to go. If there is enough interest I can cover those in comments or another post. However this is by far the simplest, it allows you the ability to embed non True Type fonts and you can reuse a font more quickly in the future. [ad#Adobe Banner] If you liked this post please subscribe to my RSS feed and/or follow me on Twitter. If you only want to see my Flash Friday posts you can follow the subscribe to the Flash Friday feed. How's that for alliteration :) Until next time keep on coding.
The Open Source Media Framework
The Open Source Media Framework (OSMF ) is a new open source project managed by Adobe. It's aim is to make the creation of media players a simpler process and to give everyone who uses it access to best practices that they may have missed while rolling their own. I took it for a test drive and here are my first thoughts.
I first heard about the Open Source Media Framework (OSMF) while watching one of the Adobe Max 2009 keynote speeches online. As a person who has built a lot of video players, galleries and mp3 players for my work I was very excited that this was being built. I have wanted to work on something like this myself for a long time. Now here was an open source project I could contribute to while building off of best practices others have contributed. Building robust custom players was going to be much quicker and easier.[ad#Adobe Banner]While watching the keynote I looked OSMF up, but it was still in early development. So I just added it too my ever growing research and development document. Recently I found a free ezine called Flash & Flex Developers Magazine and the most recent issue was focused around OSMF. I decided to take the framework for a test drive and while I was at it I would give the API docs a skimming read. Here is what I found.
Testing out the sample code
The first thing I did was try out the examples straight from the magazine. This was straightforward. The samples didn't build anything too advanced but I noticed something. It didn't take very many lines of code to get the video playing. Most of the code was for adding buttons and making them call a single function in the OSMF API. As usual when doing samples from an article I decide to tweak it to see has intuitive it was to do things. Adding and customizing simple playback controls and capabilities was a breeze. I only needed to check the documentation to make sure my assumptions were true, which they were in most cases. For a basic custom player, this thing is extremely easy to use.
Looking under the hood
The second thing I did is something I like to do with a framework I'm looking at, skim over the documentation. This consists of going through each package and seeing what classes are where. For the most part I will click into each classes documentation to find out what the class is meant for. Sure, this has me look at a lot of helper classes that I may never use ( which is a good learning exercise ), but it also has me find obscure classes that might be quite useful in a pinch. [ad#Google Adsense] One class that interested me both for educational and practical reasons was the ListenerProxyElement class. It is actually quite beautiful in its simple use. It is a class that is meant to be extended. The class itself sets up all the listeners for a MediaElement and has them trigger hook functions that you override to handle these events with custom code. I foresee using this in many projects. There are quite a few other things taken care of in this framework, such as handling of a video player that is sized differently from the video content.
Overall, Adobe ( who is in charge of this open source project ) has put together a very useful, intuitive and extensible framework that is still in the early stages. I'm looking forward to see what types of media players I can build now that so much is already handled for me. Is there anything you want to know about OSMF? Have you already used it on a project? If you have can we see your work (and hopefully code)?[ad#Adobe Banner]
For more information check out:
FSI Navigator Alpha 2 released
I have released the alpha 2 version of my FSI Navigator AIR Application. The only new feature is that it uses the AIR Update Framework to check for an update once a day. At this point the updates are automatic only, with no way to manually update. Manual update checks will be available before the 1.0 release.
It is recommended that all current users update to this version so that they can keep up with the latest news in the pre-release process.
Also, don't forget to report bugs and request features at my issue tracking site:
http://www.ducharme.cc/mantis/
Language Lessons 2 - My first decent AIR app
A while ago I wrote a blog post titled "Language Lessons." It was a post designed to showcase some of the 'cheap as free'™ ways to study a language. One of those ways was fsi-language-courses.com, a website dedicated to making the public domain FSI language courses freely available in an electronic format. While it is a great resource, the site isn't extremely usable. Adobe Integrated Runtime(AIR) to the rescue. ...
For all my talk of being a Flash/Flex expert ( Flexpert? ), I have yet to make a decent AIR app. Sure I've made a couple of tools to help me out with some minor tasks( get map lat/lon coordinates, creating a tool to help me learn degrafa ) but nothing very usable for anybody else ( or exciting to make ).
With all that in mind it is with great excitement that I announce my first alpha release of th AIR FSI Navigator. This tool allows you to navigate their different language programs and view the pdfs while you listen to the accompanying audio ( if they are available of course ). As with most alpha software, this has a long way to go before it is considered released ( and I will most likely release it as open source long before that ), but you might find it useful.
FSI_Navigator.air
This application requires Adobe AIR 1.1 be installed on your computer. If it is not you can download it from the Adobe website.UPDATE: It is easier to just use the install badge at the bottom of this post.
Known Issues ( not an exhaustive list )
- Certain courses do not work. Especially if the course contents are located in a zip file.
- PDFs take a while to load and there is no download notification. Be patient, if you have Adobe Acrobat 8.1 and the screen is black,it just means the PDF is loading ( some of them are quite large ).
- Closing the MP3 Playback window shade and then reopening it decreases its height.
- Downloads are not saved to your hard drive for offline work. This feature is planned for the future, in fact it will be the default so that files don't have to be downloaded from the server every time.
- Volume thumb bar isn't visible when the program starts. Just click on the volume adjustment area and it will show up.
Update: I thought I'd do a quick attempt to add an install badge for this:
Flexbuilder for Flash post on Flexcoders
Okay, so the title sucks but this morning I posted a workflow for using Flex Builder for working with Flash (FLA) files.
Check it out at Flexcoders.
Other Posts
Many of my programming posts are Flex or Actionscript related and will now be posted in the FlexCoders group. So I haven't stopped posting about programming, just moved where much of it occurs.
Degrafa post at Flexcoders
I just posted a short article on Degrafa - the declarative graphics framework for Flex. Check out the article over at the Flex coders group.
Yahoo Flex Map Component Part 3 available
Part 3 in my multi part series on building a flex component out of the Yahoo! Maps API is available over at the Flexcoders group.
In part 1 of this series I talked about the reasons why you would want to make a flex component out of something you can do in actionscript. In part 2 I discussed the basics of the component architecture. From that second article you can create a component that works however you still haven't handled most of the reasons to make a component in the first place. In this article I will take care of those issues the issues of data binding, event handling and making it easier for non coders( sometimes called designers or managers :) ) to work with.