Categories Displayed in Flash

Archive for the 'Flash IDE' Category

Flash: Embedding Fonts via the Font Symbol

This is far tricker than I remember it being in Flash8. Again, since the introduction of AS3 it seems like bar for working in Flash for doing everyday things has gotten harder for people, instead of easier.

Embedding Fonts via a Font Symbol in the library, I believe used to allow textfields just to select that Font (denoted with an *) and that's all they had to do to embed a font. In AS3 it appears they have to add a few more steps. I was actually surprised at some of the results. The linkageID and Class name don't make a difference.

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

Here's the Fla

I certainly wouldn't expect ExampleA and ExampleB to work they way they did.

I model this behavior as internal to the Flash player is a Embedded Font Table, that either has the character(s) or doesn't, and the embed property has access to those goodies or not. The character request is just an IDE trick/compiler hint, to build that font table if one hasn't already been provided, but doesn't exist anywhere in actionscript... a TextField doens't have embedCharacters, nor would that particularly make sense.

Metaphorically the behavior is a bit like having a locked-refrigerator full of food vrs going out to the OS to eat, and each swf as a guest has keys to to that or not. There is only room in the refridgerator for one gallon of milk in the door so even if that's partly empty (e.g. you only embedded capitals), if you try to put a full one in, it won't fit, until the previous one is unloaded. I have run into cases where one swf wouldn't share the fonts with another 'guest' swf, which I still haven't figured out yet.

Note you can test whether a font is embedded or not by rotating the TextField, else you may think it's embedded but since it's on your OS, it still shows up.

If you haven't you may want to check out loading Font Libraries dynamically. Here and Here

Flash: SOS Max, the best Flash trace() output debugger on the planet

PowerFlasher has released a new verison of the best trace output debugger on the planet (IMO). Called SOS Max. Though the new version was released just a month ago, and it's not even Halloween, It's feels just like Christmas to me!

Here's why SOS rocks.

  • It's cross plaform, written in Java.
  • It's fast, small...kinda like Flash
  • It's can use RegExp to search through the logs.
  • It can talk birectionally to the content, and react.
  • It can read the trace logs of the debug player...even when compiling normally in Flash
  • It has colorizing and folding of messages.

Here's my favorite reason. Normally when using Flash you have to compile in order to see the trace output. But sometimes debugging it's trying different things, and you don't really need to recompile, just retest different things. Often in more complicated projects, compiling, with all the fonts and assets takes a long time.  With Flash's trace output, you can't see it unless you compile again. With SOS setup to view the trace log ...you can.

Since it's socket based, it can help with a swf running from anywhere. But for using the socket debugger you need help.

There are a few AS libaries to make SOS more friendly.   This FDT post covers one of them.

The troyworks framework has an TraceAdapter which I prefer and use. It's pretty easy to use, in fact it's injectable and can be turned back to the normal trace with a single commenting of a line.

A test case which shows all the features it supports is here

What it does is introspect the string passed to the trace to look for certain fields. One of my favorite is the ability for SOS to color highlight lines.

  1.  
  2.       public function traceOutputTests():void{
  3.                 trace("number " + 1);
  4.                 trace("string" +  new String("HelloWorld"));
  5.                 trace("error " +  "error message"); //won't work
  6.                 trace("ERROR " +  "error message2"); //will work
  7.                 trace("WARNING " +  "warning message");
  8.                 trace("INFO " +  "info message");
  9.                 trace("HIGHLIGHT " +  "highlight message");
  10.                 trace("\\\\\\\\\\\\\\\\ " +  "start section message");
  11.                                 var _ary : Array = ["A","B","C","D"];
  12.                 trace("array1 " + _ary);
  13.                 trace("array2 " + util.Trace.me(_ary, "Array2", true)); //shows code folding
  14.                 trace("////////////////// " +  "end section message");
  15.                
  16.         }
  17.  

Getting setup with SOS is pretty easy, just download and start it up (if you have java installed), but to get it to work with the normal trace() output you may have to follow these instructions primarily getting the flash debugger installed and coordinating where the debug log is created.

Using TraceAdapter with SOS
Past that you have to override the trace function. You can do it at a class level like

  1.  
  2. public var trace:Function = TraceAdapter.SOSTracer;
  3.  

Then to set it back do

  1.  
  2. public var trace:Function = TraceAdapter.NormalTracer;
  3.  

or

  1.  
  2. //public var trace:Function = TraceAdapter.SOSTracer;
  3.  

I prefer setting it once early on like

  1.  
  2. TraceAdapter.CurrentTracer = TraceAdapter.SOSTracer;
  3.  

And then have other classes use that reference, which centralizes configuration, during initiailzation. (Though will not update all references a 2nd time)

  1.  
  2. public var trace:Function = TraceAdapter.SOSTracer;
  3.  

The only thing I've found using it, is that it does seem (along with Eclipse) to need lots of RAM and CPU. Periodically I assume to memory leaks or fragmentation in garbage collection I find I have to cose down both SOS and Eclipse. Also if I'm not doing lots of debugging I find that SOS consumes significant CPU when it's idling, waiting for connections, so I shut it down.

Flash: fl.managers:FocusManager could not be found FIX

Got these compiler errors compiling a document level script only movie, that didn't use any components. That had an import statement like

  1.  
  2. import fl.managers.FocusManager;
  3.  var fm : FocusManager;
  4. fm = new FocusManager(view);
  5. fm.activate();
  6.  

You would think that would work, however when compiling it gives these errors:


1046:Type was not found or was not a compile-time constant: FocusManager

1180:Call to a possibly undefined method FocusManager

1172: Definition fl.managers:FocusManager could not be found

The last is the key to solving it, it means that despite the import request, the compiler can't find anything else to go with it. Meaning that it's not actually there!

Solution
The solution is easy. Take any interactive component (Label, Button are smallest), from the components library, drag it to the stage, then delete it from the stage. At this point the library will have a bunch of stuff for that particularly component, hidden within (likely the CompiledClip, "ComponentShim") is the appropriate magic to get FocusManager. Then recompile..should be fine.

<Head> Conference is rocking! and thoughts about the past and future of webconferences

It's all about getting ... <head>

Dude, this is the way conference presentations should be. Hella fun.  No messy travel plans, No standing in lines at airports, No rental car misadventures with wrong MapQuest printouts. No need to dressup. No consuming bad closest-restaurant-to-hotel food+coffee. No worrying about hooking up the projectors, no worrying about having enough battery power, or being close to an outlet, or being able to read the slides clearly behind the head of the person in front of you, all the while juggling the cup of coffee and danish and laptop in the lap. No trying to rush get to the session conveniently located the opposite end of the convention center, only to find the room already at capacity. No staying up late nights adding last minute details to presentations... well okay that's tradition.

I'll be presenting in a few minutes in room 2 (schedule changed) on 'One SWF' to rule them all on what I think is a very cool approach to maintaining swf portability between web and AIR runtimes, which wasn't possible in Flash9, not sure about the Flash10.  I'll be showing an app that when running in AIR can create, update, read and delete images from a webcam to the desktop, and when running the same swf running from the server, can create, read, update, and delete those images on the appropriately configured server via a PHP  All with only a few paragraphs of code. Try that with C++!

It's day2 at if you're not "there", you should definitely check it out, I'm loving it. It's a distinctly different flavor than the traditional conferences I've been to so far like Max, Flex|360. Also if your in San Fran, London. you might be able to still attend one of the live hubs. Even Second Life.

Having helped run a few conferences and presented a few times, I know how challenging and rewarding putting on an event like this can be, I've been on all sides of the podium, IT, organizer and presenters. This conference (like all) has had some significant technical issues. But really the problems are expected, it's how the team recovers, and managing expectations.  So far Aral and his team are doing a great job rolling with the punches. In the end as disappointing as it is for all when a presentation doesn't work right, the chat always works so in some ways it's more collaborative than the normal conferences.

It's my first time attending a conference via Connect, counter intuitively I find it's pretty intimate, a buzz of chat, the low threshold in which anybody can join the fray. the live face of a person talking, and well miced, bandwidth permitting.

The Past of Online Presentations
Waxing philosophical. It's funny how life can take you round full circle. Back in 2000 right, right after the first wave of dot-com-fallout. I joined a small company called Presedia who had the same goals I mentioned in the first paragraph. At the time, somewhat at the start of the first internet bubble, the web was in it's first golden age.  Presedia's target was the corporate market, where as R&D turned into commercialization, routine "Road Shows" would be organized to put gobs of salespeople in the same room, up to date on what they would soon be selling. Getting 1000's of people across the country into the same room with enough donuts wasn't cheap.. gas wasn't $3-4/gallon either at the time.

So Presedia had the simple idea, make PowerPoint web friendly, add a plugin to the desktop to narrate, it, and upload it, share it, have it play in the webbrowser. As an aside, I think that Microsoft's failure to make the office suite web friendly has spurred countless competition like this.

The first client for Presedia, was...Sun Microsystems, which had just 3 years earlier created the Java programming language.  Java was the darling of the day, applets were going places that html and even Flash just couldn't touch. As at the time Flash 4, just turned to Flash 5, scripting was still mostly timeline hacks, like instead of a function, it used gotoAndPlay("doSomething") !!! for loops were gotoAndPlay, then gotoAndPlay! (and we had to walk uphills both ways, with dialup).

After getting a reliable presentation narration, and conversion. Ironically, Java as the front end on the network (in particular sun) was very finicky about streaming through corporate firewalls and after months of headbanging. I in a bold move told the CEO and President that we should explore using Flash for the presentations and player, at the time I was a server side engineer working in Java. I was the only person in the team with any design ability, or any particular care for what is now the IxD field, and could put up with Flash's extremely quirky nature. So I was asked to come up with a prototype which I built by hand, and the CTO started investigating rendering PowerPoint to Flash instead of Java. This was a rather significant and positive step for both Presedia and myself.

Turns out for me, that working with visual components made me far happier than working purely server side, and my intuitions that Flash > Java for the presentations were correct. We had far fewer problems, and the presentations streamed and started better. Fast Forward... Presedia became Macromedia Breeze, and Breeze became Adobe Connect which is the technology, that powers the conference. And I've been preparing yet another PowerPoint to get converted to Flash. Deja Vu!

Given that was 10 years ago, makes me wonder, did Dinosaurs have PowerPoint?

Another strange connection, is one of the conferences I helped organize was largely Singularity oriented, and in it's recent incarnation has turned into "SingularitySummit". The original name of the conference was Singularity, which confused me for the longest period of time.

The other amusing bits, at the time PowerPoint to Flash was a very proprietary and expensive thing to purchase. Now PowerPoint to Flash conversion is in the commodity camp. There are $50-$100 stand alone tools with unlimited, and Open Office will do it for free. I'm actually using Open Office (built in Java) to create the presentation for the talk, that will be converted to Flash.

The Future of Online Presentations + Conferences
I think that <head> is a good example of how conferences are going to go.  In many ways is a parallel to the way home theater is competing with traditional movie sales.  With the ubiquity in highspeed bandwidth, the sensory impact between online and physical conferences is less, and in some cases opposite, online can have higher fidelity than live.   Like I'm watching on a big screen perfectly setup, I have headphones, the speakers have headphones rather than drifting in and out of the mic.

In head's level, the convenience overshadows other.   As the technology get's more solid with tools like Connect, the barrier to entry drops, it takes less skill, costs less for all, takes less time.     Soon kids will be throwing conferences for kids.

Having participated in 'unconferences' and 'conferences'.   <head> took a nice middle ground.  It was scheduled so I knew what I was going in for, but the sessions were 30minutes, which like TED talks reminds me that brevity is a powerful ally.  As since we are on the web, further details are only a few clicks away.   It felt very different more like a group of friends piled into the living room vrs attending church.  It felt more community oriented than hierarchical.  With the chat window on the bottom, and back channel communication with other speakers, it felt very much like a dashboard...it was reassuring where as live presentations, sometimes no audio man, just a bunch of people sitting quietly it often feels a bit exposed.

There is a qualitative difference in the stress levels of the speakers. I'll call it the "home turf" advantage. Most of the presenters presented as they lived, either at home, or at work, a few like myself rolling out of bed, walking into the home office a few feet away.  relaxed. Some taking beer breaks in the presentation! (hey it's the weekend).  One was even presenting in a car, via a community wireless she just found, where she parked.

This is to me a success of the web, taking the best that people have to offer, of the people across the world, without taking them out of their normal elements. The presentations are a bit rougher, more improvised, briefer, but what they don't offer in 'performance' they more than make up in charm, and commradarie.  Especially in today's rapid moving times, the nature of a presentation being a dialog than a narrative feels appropriate.  With the audience at all levels, a dialog is also the best way to ensure that people at all skill levels are at the same page.  Rather than stilted, they feel more honest, more philosophical, more heartfelt, less of a corporate agenda, many of the goals weren't at a tech level, but rather increasingly purpose driven.   In each presentation the person's personality showed through.  All a very positive experience.

I missed most of Friday's sessions, (partly due to work) now I'm sorry I missed them, I suspect that this is one of the challenges for virtual conferences, it's harder to cleanly separate the time for a conference as when it's a trip. Though at least for me, I end up finding conferences filled with work anyway.

With the upcoming tide of virtual conferences, one thing I think this all means to presenters, are you should get used to having:

  • a decent webcamera, ideally a decent backdrop (unless you've got a green screen like Aral) $20-30
  • decent light, as webcams suck on low-light.  A window nearby will do, but at night time I was practically invisible until I pointed some lights on me. Aral in the excellent speaker orientation recommended a firewire plus conventional DV cam, which is a good though far less portable
  • a good headset mic - knowing how to set it up, adjust levels  $30 at Radio Shack
  • have a few subjects you could contribute to the community, in your backpocket you can present easily.  Note you don't have to be a super genius, the community exists at all levels.
  • that the number of conferences is increasing to a steady dialog.  So in some cases picking.This reminds me over burningman, in that you won't be able to experience everything, so you have to prudent in what makes it and not.  Even though many of these conferences will be recorded and later made public, there is something about being there able to see it unfold that makes it more special, perhaps it's just the allocation of time and attention.

Here are some other pics and reviews.
Jeremy Adactio (with pics!)
Mark Grossnickle attendee, )

Flash: Multiple Runtime Font Sharing Embedding with only Partial Character sets: How To.

Here's another example of runtime font loading, this time using html text, multiple flavors of the font library, in two separate swf libs, one with the regular font, the other with the bold, italic, bold italic flavors. Typically these would be loaded at different times, but this example should give you the basic idea.

The multiple font lib built by FlashDevelop + Flex 3.0 as "FontLibs.swf", being output as 'MyriadProExtendedFontLibs.swf', the one we created in the previous is now being loaded as 'MyriadProRegMinLib.swf'

package{ import flash.display.Sprite;import flash.text.Font;

public class MyriadExtendedLib extends Sprite

{

[Embed(source='C:/WINDOWS/Fonts/MyriadPro-Bold.otf', fontWeight='bold', fontName='Myriad Pro', unicodeRange='U+0020-U+0020,U+0021-U+0021,U+0022-U+0022,U+0023-U+0023,U+0024-U+0024,U+0025-U+0025,U+0026-U+0026,U+0027-U+0027,U+0028-U+0028,U+0029-U+0029,U+002A-U+002A,U+002B-U+002B,U+002C-U+002C,U+002D-U+002D,U+002E-U+002E,U+002F-U+002F,U+0030-U+0030,U+0031-U+0031,U+0032-U+0032,U+0033-U+0033,U+0034-U+0034,U+0035-U+0035,U+0036-U+0036,U+0037-U+0037,U+0038-U+0038,U+0039-U+0039,U+003A-U+003A,U+003B-U+003B,U+003C-U+003C,U+003D-U+003D,U+003E-U+003E,U+003F-U+003F,U+0040-U+0040,U+0041-U+0041,U+0042-U+0042,U+0043-U+0043,U+0044-U+0044,U+0045-U+0045,U+0046-U+0046,U+0047-U+0047,U+0048-U+0048,U+0049-U+0049,U+004A-U+004A,U+004B-U+004B,U+004C-U+004C,U+004D-U+004D,U+004E-U+004E,U+004F-U+004F,U+0050-U+0050,U+0051-U+0051,U+0052-U+0052,U+0053-U+0053,U+0054-U+0054,U+0055-U+0055,U+0056-U+0056,U+0057-U+0057,U+0058-U+0058,U+0059-U+0059,U+005A-U+005A,U+005B-U+005B,U+005C-U+005C,U+005D-U+005D,U+005E-U+005E,U+005F-U+005F,U+0060-U+0060,U+0061-U+0061,U+0062-U+0062,U+0063-U+0063,U+0064-U+0064,U+0065-U+0065,U+0066-U+0066,U+0067-U+0067,U+0068-U+0068,U+0069-U+0069,U+006A-U+006A,U+006B-U+006B,U+006C-U+006C,U+006D-U+006D,U+006E-U+006E,U+006F-U+006F,U+0070-U+0070,U+0071-U+0071,U+0072-U+0072,U+0073-U+0073,U+0074-U+0074,U+0075-U+0075,U+0076-U+0076,U+0077-U+0077,U+0078-U+0078,U+0079-U+0079,U+007A-U+007A,U+007B-U+007B,U+007C-U+007C,U+007D-U+007D,U+007E-U+007E,U+00A9-U+00A9,U+00AE-U+00AE,U+00B7-U+00B7,U+02C6-U+02C6,U+02DC-U+02DC,U+2013-U+2013,U+2014-U+2014,U+2018-U+2018,U+2019-U+2019,U+201A-U+201A,U+201C-U+201C,U+201D-U+201D,U+201E-U+201E,U+2020-U+2020,U+2021-U+2021,U+2022-U+2022,U+2026-U+2026,U+2030-U+2030,U+2039-U+2039,U+203A-U+203A,U+20AC-U+20AC,U+2122-U+2122')]

public static var _MyriadProBold:Class;

[Embed(source='C:/WINDOWS/Fonts/MyriadPro-BoldIt.otf', fontWeight='bold', fontStyle='italic', fontName='Myriad Pro', unicodeRange='U+0020-U+0020,U+0021-U+0021,U+0022-U+0022,U+0023-U+0023,U+0024-U+0024,U+0025-U+0025,U+0026-U+0026,U+0027-U+0027,U+0028-U+0028,U+0029-U+0029,U+002A-U+002A,U+002B-U+002B,U+002C-U+002C,U+002D-U+002D,U+002E-U+002E,U+002F-U+002F,U+0030-U+0030,U+0031-U+0031,U+0032-U+0032,U+0033-U+0033,U+0034-U+0034,U+0035-U+0035,U+0036-U+0036,U+0037-U+0037,U+0038-U+0038,U+0039-U+0039,U+003A-U+003A,U+003B-U+003B,U+003C-U+003C,U+003D-U+003D,U+003E-U+003E,U+003F-U+003F,U+0040-U+0040,U+0041-U+0041,U+0042-U+0042,U+0043-U+0043,U+0044-U+0044,U+0045-U+0045,U+0046-U+0046,U+0047-U+0047,U+0048-U+0048,U+0049-U+0049,U+004A-U+004A,U+004B-U+004B,U+004C-U+004C,U+004D-U+004D,U+004E-U+004E,U+004F-U+004F,U+0050-U+0050,U+0051-U+0051,U+0052-U+0052,U+0053-U+0053,U+0054-U+0054,U+0055-U+0055,U+0056-U+0056,U+0057-U+0057,U+0058-U+0058,U+0059-U+0059,U+005A-U+005A,U+005B-U+005B,U+005C-U+005C,U+005D-U+005D,U+005E-U+005E,U+005F-U+005F,U+0060-U+0060,U+0061-U+0061,U+0062-U+0062,U+0063-U+0063,U+0064-U+0064,U+0065-U+0065,U+0066-U+0066,U+0067-U+0067,U+0068-U+0068,U+0069-U+0069,U+006A-U+006A,U+006B-U+006B,U+006C-U+006C,U+006D-U+006D,U+006E-U+006E,U+006F-U+006F,U+0070-U+0070,U+0071-U+0071,U+0072-U+0072,U+0073-U+0073,U+0074-U+0074,U+0075-U+0075,U+0076-U+0076,U+0077-U+0077,U+0078-U+0078,U+0079-U+0079,U+007A-U+007A,U+007B-U+007B,U+007C-U+007C,U+007D-U+007D,U+007E-U+007E,U+00A9-U+00A9,U+00AE-U+00AE,U+00B7-U+00B7,U+02C6-U+02C6,U+02DC-U+02DC,U+2013-U+2013,U+2014-U+2014,U+2018-U+2018,U+2019-U+2019,U+201A-U+201A,U+201C-U+201C,U+201D-U+201D,U+201E-U+201E,U+2020-U+2020,U+2021-U+2021,U+2022-U+2022,U+2026-U+2026,U+2030-U+2030,U+2039-U+2039,U+203A-U+203A,U+20AC-U+20AC,U+2122-U+2122')]

public static var _MyriadProItalBold:Class;

[Embed(source='C:/WINDOWS/Fonts/MyriadPro-It.otf', fontName='Myriad Pro', fontStyle='italic', unicodeRange='U+0020-U+0020,U+0021-U+0021,U+0022-U+0022,U+0023-U+0023,U+0024-U+0024,U+0025-U+0025,U+0026-U+0026,U+0027-U+0027,U+0028-U+0028,U+0029-U+0029,U+002A-U+002A,U+002B-U+002B,U+002C-U+002C,U+002D-U+002D,U+002E-U+002E,U+002F-U+002F,U+0030-U+0030,U+0031-U+0031,U+0032-U+0032,U+0033-U+0033,U+0034-U+0034,U+0035-U+0035,U+0036-U+0036,U+0037-U+0037,U+0038-U+0038,U+0039-U+0039,U+003A-U+003A,U+003B-U+003B,U+003C-U+003C,U+003D-U+003D,U+003E-U+003E,U+003F-U+003F,U+0040-U+0040,U+0041-U+0041,U+0042-U+0042,U+0043-U+0043,U+0044-U+0044,U+0045-U+0045,U+0046-U+0046,U+0047-U+0047,U+0048-U+0048,U+0049-U+0049,U+004A-U+004A,U+004B-U+004B,U+004C-U+004C,U+004D-U+004D,U+004E-U+004E,U+004F-U+004F,U+0050-U+0050,U+0051-U+0051,U+0052-U+0052,U+0053-U+0053,U+0054-U+0054,U+0055-U+0055,U+0056-U+0056,U+0057-U+0057,U+0058-U+0058,U+0059-U+0059,U+005A-U+005A,U+005B-U+005B,U+005C-U+005C,U+005D-U+005D,U+005E-U+005E,U+005F-U+005F,U+0060-U+0060,U+0061-U+0061,U+0062-U+0062,U+0063-U+0063,U+0064-U+0064,U+0065-U+0065,U+0066-U+0066,U+0067-U+0067,U+0068-U+0068,U+0069-U+0069,U+006A-U+006A,U+006B-U+006B,U+006C-U+006C,U+006D-U+006D,U+006E-U+006E,U+006F-U+006F,U+0070-U+0070,U+0071-U+0071,U+0072-U+0072,U+0073-U+0073,U+0074-U+0074,U+0075-U+0075,U+0076-U+0076,U+0077-U+0077,U+0078-U+0078,U+0079-U+0079,U+007A-U+007A,U+007B-U+007B,U+007C-U+007C,U+007D-U+007D,U+007E-U+007E,U+00A9-U+00A9,U+00AE-U+00AE,U+00B7-U+00B7,U+02C6-U+02C6,U+02DC-U+02DC,U+2013-U+2013,U+2014-U+2014,U+2018-U+2018,U+2019-U+2019,U+201A-U+201A,U+201C-U+201C,U+201D-U+201D,U+201E-U+201E,U+2020-U+2020,U+2021-U+2021,U+2022-U+2022,U+2026-U+2026,U+2030-U+2030,U+2039-U+2039,U+203A-U+203A,U+20AC-U+20AC,U+2122-U+2122')]

public static var _MyriadProItal:Class;

public function MyriadExtendedLib()

{

super();

Font.registerFont(_MyriadProBold);

Font.registerFont(_MyriadProItalBold);

Font.registerFont(_MyriadProItal);

}

}

}

And the consumer of the fonts

  1. package {import flash.display.Loader;import flash.display.Sprite;
  2.  
  3. import flash.events.Event;
  4.  
  5. import flash.net.URLRequest;
  6.  
  7. import flash.text.*;
  8.  
  9. public class MultiFontLoader extends Sprite {
  10.  
  11. public function MultiFontLoader() {
  12.  
  13. loadFont("MyriadProRegMinLib.swf");
  14.  
  15.                loadFont("BaskervilleRegFontLib.swf");
  16.  
  17.                loadFont("MyriadProExtendedFontLibs.swf", true);
  18.  
  19. }
  20.  
  21. private function loadFont(url:String, complete:Boolean = false):void {
  22.  
  23. var loader:Loader = new Loader();
  24.  
  25. if (complete) {
  26.  
  27. loader.contentLoaderInfo.addEventListener(Event.COMPLETE, fontLoaded);
  28.  
  29. }
  30.  
  31. loader.load(new URLRequest(url));
  32.  
  33. }
  34.  
  35. private function fontLoaded(event:Event):void {
  36.  
  37. drawText();
  38.  
  39. }
  40.  
  41. public function drawText():void {
  42.  
  43. var tf:TextField = new TextField();
  44.  
  45. tf.defaultTextFormat = new TextFormat("Myriad Pro", 16, 0);
  46.  
  47. tf.embedFonts = true;
  48.  
  49. tf.antiAliasType = AntiAliasType.ADVANCED;
  50.  
  51. tf.multiline = true;
  52.  
  53. tf.autoSize = TextFieldAutoSize.LEFT;
  54.  
  55. tf.border = true;
  56.  
  57. tf.htmlText = "<p><b>Troy</b> was <b><i>here</i></b><br/> <font face='Baskerville'>Scott was</font> <i>here too</i><br/>...:;*&amp;^% </p>";
  58.  
  59. tf.rotation = 15;
  60.  
  61. addChild(tf);
  62.  
  63. }
  64.  
  65. }
  66.  
  67. }

Flash: Runtime Font Sharing Embedding with only Partial Character sets: How To.

While not planning on it, spent most the day figuring out how to implement runtime shared fonts, while only embedding a fraction off the characters. Holy moly was this a minefield. But happily got a simple solution.

Here's the goal, I'm working on the phase 2.x of a website, and we are using several flavors of Myriad Pro to make it look great, plus a few others. However with each flavor weighing in at ~35Kb each we are loading about 200K worth of fonts (bold, italic, bold italic etc), and at present many of the pages have their own copies of the fonts (the typical evil that comes up on projects with no time), so the sight loads far more sluggish than it should. After this and the following are done, the load is down to 54kb, as only the elements needed are loaded once.

In Flash IDE (CS3) and prior selecting partial characters was easy if you only had one swf, just select from the characters in the embed button, in the properties panel. If you have character sets you use often, short cut this by creating custom character sets, with this neat approach, perhaps even with this tool However this is only really good for elements scoped inside the swf with the embedded font, no way to share them between swfs without resorting to traditional runtime shared libraries that have several issues (like bypassing preloaders all together). In AS2.0 there was a nifty hack possible to help,where a embedded font was coerced into sharing by a proxy clip that referenced it as a runtime shared library, at the preloaders convenience, but this (for me) was brittle in having font collisions, e.g. a static textfield on stage could render the approach useless, and I'm pretty sure this doesn't work anymore in AS3. UPDATE. !%!$ AS3 has the exact same issue, flash player appears to load a font in a given swf scope on a first come-first serve only once. Meaning any static or textfield anywhere on teh stage (regardless or not if any characters are embedded) will collide with whatever you load in dynamically later, rendering the dynamically loaded useless,...and any references to it. Meaning your dynamic textfields will break...not show up at all!. A possible workaround is having either the placeholder textfields with a sacrificial font (e.g. sans), or renaming the font in the embed created in a few steps to something like (Myriad Pro ->MyriadPro) and adjusting the css/etc.

For reasons unknown to me, adding a Font symbol to the library (either for use with actioncript, or runtime sharing) embeds the whole font. Needless to say, when on the web, getting every character known to mankind is not going to help your site load fast. This can be the difference of 2kb for only what you need for the preloader, to 2MB for entire international character sets. Also it can grind compile times to a halt, as every publish requires every glyph to be embedded and this is time consuming. Both seem like major oversights on the Flash IDE's design.

So oddly the best way to create fonts is to use the Flex 3.x SDK (download). For this the great and free FlashDevelop (download) will work great (if your on windows). Just follow the installation instructions, setup a new Actionscript 3, Flex 3 Project.

Create a class like the following in the 'src' directory, and in the righthand tree, right click over it and select 'always compile'

  1.  
  2.  package {  
  3.  
  4.       import flash.display.Sprite;
  5.           import flash.text.Font;
  6.       public class MyriadProFontLib extends Sprite {  
  7.  
  8.            [Embed(source='C:/WINDOWS/Fonts/MyriadPro-Regular.otf', fontName='Myriad Pro', unicodeRange='U+0020-U+0020,U+0021-U+0021,U+0022-U+0022,U+0023-U+0023,U+0024-U+0024,U+0025-U+0025,U+0026-U+0026,U+0027-U+0027,U+0028-U+0028,U+0029-U+0029,U+002A-U+002A,U+002B-U+002B,U+002C-U+002C,U+002D-U+002D,U+002E-U+002E,U+002F-U+002F,U+0030-U+0030,U+0031-U+0031,U+0032-U+0032,U+0033-U+0033,U+0034-U+0034,U+0035-U+0035,U+0036-U+0036,U+0037-U+0037,U+0038-U+0038,U+0039-U+0039,U+003A-U+003A,U+003B-U+003B,U+003C-U+003C,U+003D-U+003D,U+003E-U+003E,U+003F-U+003F,U+0040-U+0040,U+0041-U+0041,U+0042-U+0042,U+0043-U+0043,U+0044-U+0044,U+0045-U+0045,U+0046-U+0046,U+0047-U+0047,U+0048-U+0048,U+0049-U+0049,U+004A-U+004A,U+004B-U+004B,U+004C-U+004C,U+004D-U+004D,U+004E-U+004E,U+004F-U+004F,U+0050-U+0050,U+0051-U+0051,U+0052-U+0052,U+0053-U+0053,U+0054-U+0054,U+0055-U+0055,U+0056-U+0056,U+0057-U+0057,U+0058-U+0058,U+0059-U+0059,U+005A-U+005A,U+005B-U+005B,U+005C-U+005C,U+005D-U+005D,U+005E-U+005E,U+005F-U+005F,U+0060-U+0060,U+0061-U+0061,U+0062-U+0062,U+0063-U+0063,U+0064-U+0064,U+0065-U+0065,U+0066-U+0066,U+0067-U+0067,U+0068-U+0068,U+0069-U+0069,U+006A-U+006A,U+006B-U+006B,U+006C-U+006C,U+006D-U+006D,U+006E-U+006E,U+006F-U+006F,U+0070-U+0070,U+0071-U+0071,U+0072-U+0072,U+0073-U+0073,U+0074-U+0074,U+0075-U+0075,U+0076-U+0076,U+0077-U+0077,U+0078-U+0078,U+0079-U+0079,U+007A-U+007A,U+007B-U+007B,U+007C-U+007C,U+007D-U+007D,U+007E-U+007E,U+00A9-U+00A9,U+00AE-U+00AE,U+00B7-U+00B7,U+02C6-U+02C6,U+02DC-U+02DC,U+2013-U+2013,U+2014-U+2014,U+2018-U+2018,U+2019-U+2019,U+201A-U+201A,U+201C-U+201C,U+201D-U+201D,U+201E-U+201E,U+2020-U+2020,U+2021-U+2021,U+2022-U+2022,U+2026-U+2026,U+2030-U+2030,U+2039-U+2039,U+203A-U+203A,U+20AC-U+20AC,U+2122-U+2122')]  
  9.  
  10.             public static var _MyriadPro:Class;  
  11.  
  12.                         public function MyriadProFontLib()
  13.                         {
  14.                                 super();
  15.                                  Font.registerFont(_MyriadPro);
  16.                         }
  17.       }
  18.  }

Go to the Top Nav's "Project>Properties" and adjust the output file to something like "bin\FontLibs.swf"

Copy the characters you want as Ascii e.g. (missing white space)
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~©®·ˆ˜–—‘’‚“”„†‡•…‰‹›€™

goto this great unicode converter here

top left 'characters' box, then hit convert

select the output from the Unicode U+hex notation box, and paste it into this app's left side.
(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

Copy the right side and replace the 'unicodeRange=''' in the above class.
Build the file by pressing the green play looking button. If all goes well you should see the console output

(fcsh)
Build succeeded
Done (0)

and a new FontLibs.swf in the bin folder.

You can use the excellent Action Script Viewer 6 to look at the glyphs embedded into the FontLibs.swf. This is very useful for seeing if the unicode is getting you the characters you think you are putting in. I tried several ascii to unicode convertors, and only the one linked above got it right.

Then using the tool of your choice create this class to load up the fontlib and use a dynamic textfield.

  1. package {  
  2.  
  3.       import flash.display.Loader;  
  4.  
  5.       import flash.display.Sprite;  
  6.  
  7.       import flash.events.Event;  
  8.  
  9.       import flash.net.URLRequest;  
  10.  
  11.       import flash.text.*;
  12.         import flash.utils.describeType;
  13.  
  14.       public class FontLoader extends Sprite {  
  15.  
  16.            public function FontLoader() {  
  17.  
  18.                 loadFont("FontLibs.swf");
  19.            }  
  20.  
  21.            private function loadFont(url:String):void {  
  22.  
  23.                 var loader:Loader = new Loader();  
  24.  
  25.                 loader.contentLoaderInfo.addEventListener(Event.COMPLETE, fontLoaded);  
  26.  
  27.                 loader.load(new URLRequest(url));  
  28.  
  29.            }  
  30.  
  31.            private function fontLoaded(event:Event):void {  
  32.  
  33.                 drawText();  
  34.  
  35.            }  
  36.  
  37.            public function drawText():void {  
  38.  
  39.                 var tf:TextField = new TextField();  
  40.  
  41.                 tf.defaultTextFormat = new TextFormat("Myriad Pro", 16, 0);  
  42.  
  43.                                 tf.embedFonts = true;  
  44.  
  45.               tf.antiAliasType = AntiAliasType.ADVANCED;  
  46.  
  47.                 tf.autoSize = TextFieldAutoSize.LEFT;  
  48.  
  49.                 tf.border = true;
  50.                 tf.text = "Troy was here\nScott was here too\nblah scott...:;*&amp;^% ";
  51.                 tf.rotation = 15;
  52.                 addChild(tf);  
  53.  
  54.            }  
  55.  
  56.       }  
  57.  
  58.  }

In decreasing order of relevance, these are some of the posts that I read to get to this point.

If characters that are embedded are funky, and your using Flex 2.0, upgrade to Flex SDK 3.x. I was originally using Flex 2.0...very dated at this point.

If your using OTF (Open Type Fonts) like Myriad Pro make sure your using Flex SDK 3.x else you might have issues...flex 2.0 is very dated at this point. Also consider using a tool like the excellent CrossFont if you're trying to use Mac Fonts.

[1] The one that helped me realize the ability to limit the unicode. The more readable one on the yahoo labs, and the authors blog with many comments. The solution he and others presented didn't work for me, and I think the solution here is cleaner.

[2] Flex 3.x Compiler comes with multiple The font transcoder doesn't always work, try another. in particular the (flash.fonts.AFEFontManager);

[3] Runtime Font Sharing For Flash CS3...[Robert's excellent article and followup] [far more verbose] , using the traditional whole-enchilda Font.

[4] Special considerations when using Japanese character sets (a) usin (b)

[5] A must read if you want a grand Q&A of embedded fonts and many quirks, (CSS specific)

[6] More details on mime-type for the font, I think this was only relevant in Flex 2.0 than Flex 3.x.

[7 ] Basics with AS3/Flex without using a library

[ 8 ] More rants on Flash CS3's lack of proper embedding, in particular with pixel fonts..Flash CS3 renames them for you.

Fix for Error #1063: Argument count mismatch on BitmapData Expected 2, got 0.

Normally creating blank BitmapData requires you pass in an the width and height in pixels.  But what about when you embed an image with a linkageid?  You'll get the above error trying to create a new myEmbeddedImage(); unless you pass it with two numbers, even if they don't mean anything e.g.

var bdata:BitmapData = new imageInLibraryLinkageID(0,0);

I would have thought that these would be optional for embedded assets.  Fix originally discovered here.

Flash: Some characters could not be converted to outlines…

Wierd, ran into this trying to track down another problem with Flash.  I reinstalled from the Web Premium DVD  just Flash CS3, which took like 45 minutes (WTF?!), booting up flash, opened a file tried publishing and got that error...and none of the fonts (just myriad pro) showed up anymore.

Restarting the machine fixed it.

Flash: Fast Prototyping and Sketching UI with FlowControl

While I enjoy the new power of Flash9/AS3.0, one of the things I really dislike about the AS3, is how much extra work to do basic things like setup buttons to do simple timeline control, this is especially hard on designers and animators who don't code. I agree with 5etdemi post 4 years ago, the basics have ironically gotten harder to do.

What wrong with ECMAScript/Actionscript? Well, it is not especially well suited for certain tasks, the worst of which is time-based/timeline-oriented animation and declarative drawing. I mean, it seems pretty ironic that ActionScript is derived from ECMAScript which was primarily oriented at scripting in a text-based environment, HTML and the DOM. Simply put, ActionScript has leaned more and more towards heavy lifting text operations (like RegEx and the new XML implementation) and less towards building programmatically what Flash was originally meant for, animation.

While there are useful utilities like Lee Brimelow's nice event generator utility, I wanted less, as even if being good with actionscript, when you have a few minutes to put together something for (or during!) a client/skype meeting, scripting isn't really an option. Thankfully AS3 has some tricks to help!

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.) ( press RIGHT arrow key to advance)

One tennant of Sketch is using the type and instance names to do most the event binding work, largely this is to allow Designers to stay on the timeline, but the same could apply to objects created in actionscript as well. So in the above example there are 2 scenes, and a bunch of empty frames, and a nav control. What's special is the buttons you see are actually just semi-transparent buttons (I call InvisiButtons) that have instance names like 'next', 'prev', (shown in the button names) there is no other script on the timeline for them. That via the FlowControl listening to ADDED event are autowired up to call 'nextFrame()' , 'prevFrame()' etc. These InvisiButtonscould be used as a hotspot over a comped image or basic text and wireframe graphics, allowing low to high fidelity comps to be created.

In this example a ENTER_FRAME event updates the TextField off to the right to show the current scene, frame et, to show where you are.
FlowControl has some other nifty features.

  • optional features is the fadein, fadeout effect, with configureable color, so while there is a normal timeline, the fade effect is free and ads a bit of polish IMHO.
  • tooltips telling you where the buttons go/do.
  • keypress for left/right arrow to go to the next previous frame, escape to goto first frame-useful for slide shows
  • XXX_autoBtn. If it sees this pattern that button will generate an XXX event (e.g. sayHi_autoBtn generates a new Event("sayHi"), which anybody is free to listen to.

All these are in the example (as well as all the code for FlowControl) on code.google.
Flow Control can be used 'embedded' as the document level class (or extending from it) or loaded as an external swf, and I'll be demoing that in the future. That latter feature is more targetted to creating highly skinnable games which I'll be covering in future blog posts.

Flash: 4 Tricks for using MovieClips as Buttons

So here are 4 tricks I've found useful:

  1. Use actionscript to create the Button behavior (enlarging etc), centralizing it in one place.
  2. Use clips styled in the IDE, and copy their style/filters for mouse over, down, disabled state.
  3. Use mouseEnabled (and alpha/brightness) to temporarily disable a button
  4. Use the instance name as the label, and in the event parsing.

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

Styling MOUSE_OVER, MOUSE_DOWN States

Similar to CSS centralizing style, centralizing behavioral style offers the same maintenance advantages.   Using clips on the stage for style allows the designer to visually see what's desired, rather than spending countless iterations tweaking actionscript to get it right, it's a good handoff in team based approach.   I also sometimes use describeType 'autowire' any buttons of particular classes.   For the disabled state I stacked two brightness filters ontop of each other.

Styling it to send all the events to a central controller (MVC UCM style), allows things to be debugged far easier than when events are going everywhere, and the controller has internal state, respond appropriately, say ignoring all clicks during loading, without having to rewire all the various components.

For 1 and 2 here's the underlying code. Notice I use mouseChildren = false to keep the label textfield from generating events.

  1.  
  2. function configureMC_Button(ary:Array, addL:Boolean = true):void {var a:MovieClip;
  3.  
  4. var i:int = 0;
  5.  
  6. var n:int =ary.length;
  7.  
  8. for (true; i < n; ++i) {
  9.  
  10. a = ary[i];
  11.  
  12. if (addL) {
  13.  
  14. a.addEventListener(MouseEvent.MOUSE_OVER, onMouseOverHandler);
  15.  
  16. a.addEventListener(MouseEvent.MOUSE_OUT, onMouseOutHandler);
  17.  
  18. a.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler);
  19.  
  20. a.addEventListener(MouseEvent.MOUSE_UP, onMouseOverHandler);a.addEventListener(MouseEvent.CLICK, onMouseClickHandler);
  21.  
  22. a.mouseChildren =false;
  23.  
  24. } else {
  25.  
  26. a.removeEventListener(MouseEvent.MOUSE_OVER, onMouseOverHandler);
  27.  
  28. a.removeEventListener(MouseEvent.MOUSE_OUT, onMouseOutHandler);
  29.  
  30. a.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler);
  31.  
  32. a.removeEventListener(MouseEvent.MOUSE_UP, onMouseOverHandler);
  33.  
  34. a.removeEventListener(MouseEvent.CLICK, onMouseClickHandler);
  35.  
  36. }
  37.  
  38. }
  39.  
  40. }
  41.  
  42. function onMouseClickHandler(evt:Event):void {
  43.  
  44. var mc:MovieClip = MovieClip(evt.target);
  45.  
  46. output_txt.text =(" \r"+ mc.label_txt.text + "**Clicked **");
  47.  
  48. }
  49.  
  50. function onMouseDownHandler(evt:Event):void {
  51.  
  52. var mc:MovieClip = MovieClip(evt.target);
  53.  
  54. mc.filters = downTreatment.filters;
  55.  
  56. }
  57.  
  58. function onMouseOverHandler(evt:Event):void {
  59.  
  60. var mc:MovieClip = MovieClip(evt.target);
  61.  
  62. mc.scaleX = mc.scaleY = 1.2;
  63.  
  64. mc.filters = overTreatment.filters;
  65.  
  66. }
  67.  
  68. function onMouseOutHandler(evt:Event):void {
  69.  
  70. var mc:MovieClip = MovieClip(evt.target);
  71.  
  72. mc.scaleX = mc.scaleY = 1;
  73.  
  74. mc.filters = [];
  75.  
  76. }
  77.  
  78. overTreatment.visible = downTreatment.visible = disabledTreatment.visible = false;
  79.  
  80. configureMC_Button([a_btn, b_btn, c_btn, d_btn, e_btn, f_btn, g_btn]);

Enabling and Disabling via ActionScript

You can disable/enable a clip simply by using the mouseEnabled field which will turn on or off mouse events.   Contrast this with the approach of adding/removing listeners to enable or disable a button, which may have multiple listeners for different classes, you can't see, so you never know if you got them all.

  1.  
  2. function setEnabled(  ary:Array, enable:Boolean = true):void {var a:MovieClip;
  3.  
  4. var i:int = 0;
  5.  
  6. var n:int =ary.length;
  7.  
  8. for (true; i < n; ++i) {
  9.  
  10. a = ary[i];
  11.  
  12. if (enable) {
  13.  
  14. a.mouseEnabled = false;
  15.  
  16. a.filters =[];
  17.  
  18. } else {
  19.  
  20. a.mouseEnabled = false;
  21.  
  22. a.filters = disabledTreatment.filters;
  23.  
  24. }
  25.  
  26. }
  27.  
  28. }
  29.  
  30. setEnabled([d_btn, e_btn], false);

Using the instance name as id.

Using the instance as the basis for identification, saying parsing it for use the label, and in the event, can make things more uniform than having buttons dispatching events,.   In internationalized apps where the label changes based on whatever language is present, the instance name can serve as a key to finding the appropriate text in some multilanguage dictionary, or even show when a label is missing.

In Closing
Using a single movieClip has many advantages,  only one skin has to be created instead of 4-5 for a SimpleButton.   When handled in the way outlined above it has many of the advantages of being a component, without the work of being a full blown one.   It minimizes the number of classes/library items when each button is created with a unique label hard coded into it.

In conjunction with a tweening engine, it allows for what I call momentum styled buttons.   Buttons that don't have crisp state changes like SimpleButton attempts on the mouse up/over/down. Things that fade up, and down, like real world lightbulbs, cars.   When used with ColorTransform this can allow for adaptively styled UI, like that of CSS.

There are also safety benefits. In AS3.0 the timeline is purely script driven, there are still bugs when using multiple frames to manage state on particular versions of the flash player.   I've had odd issues with sound not firing or not stopping firing, components blowing up when in tweens or in timelines.

« Previous Entries