Archive for 2008

Iterating properties creates unwanted side-effects

Sunday, October 12th, 2008

Also known as:

  • iterating properties in actionscript 2 causes getter setter to execute
  • I was working on our AS2 logger today. In particular I was creating a setup where you could simply drop in a couple components in your fla and ‘tada’, you would have a reflecting logger at your disposal.

    I’ll go into the reflecting logger and component creation in another post, because what happened was that during a test run I ran into the dreaded 256 levels recursion problem.

    Some research indicated that the problem lay with getters and setters.

    Imagine you have a class:

    class TestClass {
        public function get id1 () {
            trace ("hello world");
        }
    
        public function id2() {
            trace ("goodbye world");
        }
    }
    

    Now do:

    _global.ASSetPropFlags(TestClass.prototype, null, 0, 7);
    for (var i:String in TestClass.prototype) {
        trace (
             "Property:"+i+" is function ? "+
             (TestClass.prototype[i] instanceof Function)
        );
    }
    

    Ok, truth be told, you will not do this every day. In fact building a reflection package is probably the only time this issue shows up. However I like to document stuff for posterity’s sake, so here we are.

    Executing the code above will show something like:
    hello world
    Property:id1 is function ? false
    Property:id2 is function ? true
    Property:__get__id1 is function ? true
    Property:__proto__ is function ? false
    Property:constructor is function ? true

    The _global.ASSetPropFlags is used to unprotect all the prototypes properties, in order to force them to show up. In a real situation, you should always make sure you keep track of the original settings of an object’s properties and revert the object back to those settings after you are done with it.

    Anyway what is really interesting is that testing the id1 property to see whether it is a function or not, causes the underlying method (the ‘get’ method) to execute.

    Luckily I never use getters and setters. But other people do. This is not to say that getters and setters are bad, just that I ran into a situation which I hadn’t anticipated :) .

    In most situation this will not cause a problem either, but you never know. The getter might go into a recursive loop if no parameters are passed. A class might update it’s properties unintentionally, who knows? I don’t. I do know that if those side effects do happen, you will lose hours of precious time bughunting.

    So how to circumvent these special properties of woe?
    If you look closely at the output again, you’ll see something like __get__id1 in there as well.
    These kind of methods will only be created by flash if you use getters and setters.

    So how can you detect if obj[i] refers to a getter/setter and should not be executed?

    Test for the existence of __set__i and __get__i.

    As the saying goes, you’ll find the solution in the last place you look.

    Finding character positions in ActionScript 2

    Sunday, October 12th, 2008

    Also known as:

    • finding the position of a character in a dynamic textfield with embedded fonts using actionscript 2

    One of current projects involves some texteffects and I am loath to do anything on the timeline that can be done quicker by code. So my basic idea was (keeping the designer in me happy):

    Doing the design stuff at design time on stage:

    • put a dynamic textfield on stage
    • apply a font, fontsize, color, anti-aliasing
    • apply effects such as dropshadow, glow etc to make it look good

    Doing the animate stuff at runtime through code:

    • break apart the stage textfield into little textfields that I could animate

    At this point I was already thinking about converting the stage textfields to bitmaps but found I was thinking about optimising things too early, so back to KISS, basic principles first.

    Silly me, I thought it would be easy in actionscript 2 to get the position of a character in a dynamic textfield. As in:

    textfield.getCoordsOfChar (pIndex:Number)

    but apparently no such thing exists. Ofcourse if you have a monospaced font, there are other ways to accomplish this, but this solution works for both monospaced and other fonts.

    Although in actionscript 3 there is something like getCharIndexAtPoint, that is not quite what I needed.

    Using a trick I managed to implement it in actionscript 2. Note that this is still under development, being researched etc, so it’s not a general I-will-work-everytime-approach. Anyway the basic principle is this:

    • create a bitmap as large as your textfield
    • create two textformats derivatives of your textfield’s textformat and set the textcolor of one to white, the other to black
    • now loop over the characters in your textfield (i = 0 to textfield.length), and:
    • apply first the white textformat to everything, then applying the black textformat to the range (i, i+1)
      (basically in every iteration of the loop you set everything to white except the character whose position you are looking for)
    • copy the textfield to the bitmap
    • perform a getColorBoundsRect on the bitmap and voila an approximation of the character position

    And I say approximation since it’s seems to be off by a couple of pixels, but close enough to be usuable. In addition large amounts of text will slow down the process considerably and small font sizes wreak havoc, but it’s good enough:

    Download the prototype here Texteffect 1 (78), it includes the Greensock Tween classes, but you can use anything you like.

    JSFL FLfile.listFolder archive bit bug

    Wednesday, May 7th, 2008

    Today I ran into a nasty ‘feature’ of FLfile.listFolder in Flash 8 on Windows XP.

    FLfile.listFolder doesn’t list files that don’t have the archive flag enabled.

    Workaround: none except enabling the archive flag for all files you are searching for.

    Flash 8 hitArea quirks

    Monday, May 5th, 2008

    Also known as:

    • dynamically drawn hitarea bug
    • filter applied hitarea bug
    • hitarea no longer works
    • hitarea stops working

    I recently noticed two weird bugs while handling hitArea’s in Flash (I say bug you might say feature).
    Situation 1:

    • you have a clip on the timeline, let’s call it dialog
    • you have a large hitarea below the dialog, let’s call it largeHitArea
    • you have connected the hitarea to the dialog: dialog.hitArea = largeHitArea
    • you have set the onPress of the dialog to anything but null

    Everything works fine up to this point, the large hitarea makes the dialog act as a modal dialog, since you cannot trigger any mouse events below it.

    Now the following happens:

    • during a graphical redesign you think you are smart, fast and furious YEAH BABY and you apply a DropShadow to the dialog clip on the timeline.

    Next thing you know, your hitArea has died and gone forever, dramatic ain’t it?

    Cause: no idea, but I think cacheAsBitmap has to do with it.
    Workaround: set the dropshadow on the dialog clip through code.
    Situation 2:

    • you have a clip on the timeline to which you want to attach a dynamically drawn hitarea

    Everything works fine up to this point.

    Now the following happens:

    • during a graphical redesign you think you are smart, fast and furious YEAH BABY and you apply a glow filter to the dynamically drawn hitArea.

    Next thing you know, your hitArea has died and gone forever, dramatic ain’t it?

    Cause: no idea, but I think cacheAsBitmap has to do with it (again)
    Workaround: create a bitmap from the dynamically drawn hitArea first, attach it to a clip, set THAT clip as hitArea and apply the glow filter to it.

    Consuming webservices in Flash 8

    Monday, May 5th, 2008

    During a partial refactoring process of the Behrloo client system, one of the items on my list was the backend webservice result processing. Without going into a lot of detail how these services are wrapped, it suffices to say that somewhere in the application a couple of webservices are being initialized and utilized through the macromedia webservice classes.

    You might be familiar with them, they come in several flavours, for example the WebServiceConnector and the Webservice class. Personally I don’t like to use the WebServiceConnector, mostly since the Webservice class is simple enough to use and tends to give you more control over what is happening.

    Basic example

    As a simple example of using this Webservice class, paste the following code onto the first frame of the timeline in a new fla document (on a sidenote, REAL applications are not written on a timeline, but for example purposes/quick proof of concepts, this will do just fine):

    //example 1
    import mx.services.*;
    
    var lLog:Log = new Log (Log.VERBOSE, "myLog");
    var lWebService:WebService =
         new WebService ("http://www.flash-mx.com/mm/tips/tips.cfc?wsdl", lLog);

    You’ll note some log information passing by in your output window, showing you the progress during the initialization process and such. Somewhere at the end you’ll see a line like:

    4/23 13:14:32 [INFO] myLog: Made SOAPCall for operation getTipByProduct

    This means the webservice supports an operation called getTipByProduct. Other than that you don’t really know much about it. This is the first step in handling webservices, getting a grip on what your dealing with. Although there are different methods for doing so, I’ll mention two:
    1. the webservice panel in flash, this allows you to enter a webservice url, and check the methods including the required parameters and expected return types in flash.
    2. WebServiceStudio, a neat little tool. You might need to disable your proxy if it is giving you the same headaches as ours, but other than that, this tool will let you open, inspect and interrogate webservices.

    Looking through Flash’s helpfiles you’ll find an example where the getTipByProduct is called with a string argument of “Flash”, so let’s try that one by extending our example.

    Webservices are asynchronous

    First thing to realize is that, just like most things in flash, a webservice is asynchronous, meaning that code following the instantiation of a webservice will execute before the webservice is actually instantiated. An example that demonstrates this fact extends the previous example:

    //example 1
    import mx.services.*;
    
    var lLog:Log = new Log (Log.VERBOSE, "myLog");
    var lWebService:WebService =
        new WebService ("http://www.flash-mx.com/mm/tips/tips.cfc?wsdl", lLog);
    
    //example 2 addition
    trace ("*** You'll see me before the log output has completed ***");

    This ofcourse means that if you try to call a method on the webservice before it has been instantiated the call will fail. In other words: we will have to wait till it has been successfully instantiated. Without too much further explanation, we’ll just show the complete process of calling a method on the webservice and showing the results and then continue to the result processing part, since the process itself is explained in enough detail in the Flash Manual:

    //example 1
    import mx.services.*;
    
    var lLog:Log = new Log (Log.VERBOSE, "myLog");
    var lWebService:WebService = new WebService ("http://www.flash-mx.com/mm/tips/tips.cfc?wsdl", lLog);
    
    //example 2 addition
    trace ("*** You'll see me before the log output has completed ***");
    
    //example 3 addition
    import mx.utils.Delegate;
    
    lWebService.onFault = function () { trace ("WHOOPS!"); }
    lWebService.onLoad = Delegate.create (this, _performExampleCall);
    
    function _performExampleCall() {
       trace("\n\nPerforming example call...");
       var lPendingCall:PendingCall = lWebService.getTipByProduct("Flash");
       lPendingCall.onResult = Delegate.create (this, _parseResult);
    }
    
    function _parseResult (pResults:Object) {
       trace ("\n\nResults:\n"+pResults);
    }

    Decoding webservices results

    The thing to note in this example is that the result is a simple string. However, and that is were we get to the interesting part of this post: that is not always the case. The result could be an array, a predefined class, or some other complex object. This is were a couple of other settings/flags come into play:

    - doDecoding
    - doLazyDecoding

    The Flash manual has this to say with respect to these two flags:

    SOAPCall.doDecoding-description:
    Turns decoding of the XML response on (true) or off (false). By default, the XML response is converted (decoded) into ActionScript objects. If you want just the XML, set SOAPCall.doDecoding to false.

    SOAPCall.doLazyDecoding-description:
    Turns “lazy decoding” of arrays on (true) or off (false). By default, a “lazy decoding” algorithm is used to delay turning SOAP arrays into ActionScript objects until the last moment; this makes functions execute much more quickly when returning large data sets. This means any arrays you receive from the remote location are ArrayProxy objects. Then when you access a particular index (foo[5]), that element is automatically decoded if necessary. You can turn this behavior off (which causes all arrays to be fully decoded) by setting SOAPCall.doLazyDecoding to false.

    Let’s look into doDecoding first:

    Although the description is pretty clear, the actual results I got when interpreting webservice results in Behrloo (which uses a .Net webservice backend), were kind of puzzling. When I turned decoding off, I still got an xml object as a result (while I was expecting a large string of some sort), and when I turned decoding on, I got an object which consisted of nodes of type String, Boolean, Array but also of XmlNode (so part of the result was still xml).

    In the first implementation of the Behrloo backend, I had decoding turned on, and I dealt with both ‘decoded’ nodes, and xml nodes, which I decoded myself using several xml parsing mechanisms. However triggered by the testresults above, I decided to dive a bit deeper into the WebService class source code, and I found that under the hood the Webservice class is already an XML object to execute any calls to a webservice. This means that WHATEVER you do, the result is always already an XML object. With or without decoding.
    With decoding turned on, it goes on to try and decode your object, EXCEPT for the nodes with an xsi:type=”…” attribute, which unfortunately most of my nodes had. I found no way to override this behavior, which means that the default decoding mechanism didn’t do a lot to help me.

    Disabling the default decoding

    By default, the result is decoded. This takes time, and is kind of useless if you are not using this feature anyway. However disabling the decoding cannot be done on a pendingcall since in order to get a reference to a pendingcall, you need to execute it first, so we disable the decoding through:

    _myWebService.getCall ("operation name here").doDecoding = false;

    If you want to do this automatically for all calls defined on a webservice use something like:

    for (var lOperationName:String in _myWebService.stub.activePort) {
    	myWebService.getCall (lOperationName).doDecoding = false;
    }

    So what about doLazyDecoding?

    LazyDecoding only kicks in if you have doDecoding enabled, after all if we do not decode anything, setting it to lazy has no effect.

    Parsing the webservice result with decoding turned off

    Well assuming you still want to use webservice and don’t want to switch to something like remoting, we use a simple XmlUtil class that converts XML objects to complete actionscript objects. In our project we need to interpret the complete result from the webservice, so this is feasible (in other words, we don’t spend time decoding object we don’t use anyway).

    /**
    * Converts an Xml document to an object corresponding with the xml structure.
    *
    * Eg
    *
    * <top>
    * <children>
    * <mychild>rocks</mychild>
    * </children>
    * </top>
    *
    * Becomes an object in which you can do: myObj.top.children.mychild (has value rocks)
    *
    * If a certain node has 2 children with the same name, it becomes an array:
    * <top>
    * <children>
    * <mychild>rocks</mychild>
    * <mychild>drums</mychild>
    * </children>
    * </top>
    *
    * trace (myObj.top.children.mychild[0]); //rocks
    * trace (myObj.children.mychild[1]); //drums
    *
    * If a single string valued node has a type attribute, the value is typed as well (possible types are number and boolean):
    * <top type="boolean">
    * <children type="boolean">
    * <mychild type="boolean">true</mychild>
    * <mychild type="boolean">false</mychild>
    * </children>
    * </top>
    *
    * The top and children nodes have one or more children, but neither of them of type string, so the type attribute simply
    * becomes a value of the object (eg top.type traces boolean). The mychild node has only one child and of type string as well,
    * so top.children.mychild[i] will be of type boolean since it will be converted.
    *
    * In general all other attributes becomes properties of the object but name clashes might cause an toArray conversion:
    *
    * <top children="nothanks">
    * <children type="boolean">
    * <mychild type="boolean">true</mychild>
    * <mychild type="boolean">false</mychild>
    * </children>
    * </top>
    *
    * top will now hold a children object of type array, with element 0 = nothanks, and element1 is another array
    */
    class XmlUtil
    {

    public static function convert (pXml:XMLNode):Object {
    return _doConversion (pXml);
    }

    private static function _doConversion (pXmlTree:XMLNode):Object {
    //no children only attributes possibly
    if (pXmlTree.childNodes.length == 0) {
    var lStore:Object = new Object();
    var lAttribsFound:Boolean = false;
    for (var lAttrib:String in pXmlTree.attributes) {
    lAttribsFound = true;
    lStore [lAttrib] = pXmlTree.attributes[lAttrib];
    }
    if (lAttribsFound) {
    return lStore;
    } else {
    return null;
    }

    //one child and it is a simple value
    } else if (pXmlTree.childNodes.length == 1 && pXmlTree.childNodes[0].nodeName == null) {

    var lStore:Object = pXmlTree.childNodes[0].nodeValue;

    switch (pXmlTree.attributes.type) {
    case "number":
    lStore = new Number (lStore);
    break;
    case "boolean":
    lStore = new Boolean (lStore == "true");
    break;
    default : break; //do nothing
    }

    //now test the object
    var lAttribsFound:Boolean = false;
    for (var lAttrib:String in pXmlTree.attributes) {
    if (lAttrib != "type") {
    trace("A simple node cannot have attributes, it’s one or the other:"+pXmlTree.nodeName);
    }
    }

    return lStore;

    //one or more children with nodeNames (nested objects)
    //you cant have two children of which one has a null nodeName, so all nodes are bound to have them
    } else {
    var lStore:Object = new Object();

    //first store attributes for the current node
    //attributes are always simple values
    for (var i:String in pXmlTree.attributes) {
    lStore[i] = pXmlTree.attributes[i];
    }

    //then do nested children themselves
    for (var i:Number = 0; i < pXmlTree.childNodes.length; i++) {

    var lChild:XMLNode = pXmlTree.childNodes[i];

    //first time we found a child with this name
    if (lStore [lChild.nodeName] == null) {
    lStore[lChild.nodeName] = _doConversion (lChild);
    } else {

    //if child was already converted to an array, just add it
    if (lStore[lChild.nodeName] instanceof Array) {
    lStore[lChild.nodeName].push (_doConversion(lChild));
    } else {
    //first convert what was already there
    var currentNode:Object = lStore[lChild.nodeName];
    lStore[lChild.nodeName] = new Array ();
    lStore[lChild.nodeName].push (currentNode);

    //now add new one:
    lStore[lChild.nodeName].push (_doConversion (lChild));
    }
    }
    }

    return lStore;
    }
    }

    /**
    * Converts the child with the parent to an array node IF it is not already an array.
    * If it is already an array nothing happens.
    *
    * @param pObject
    * @param pChild
    */
    public static function forceArrayNode (pParent:Object, pChild:String):Array {
    if (pParent[pChild] == null) {
    pParent[pChild] = new Array();
    } else if (pParent[pChild] instanceof Array) {
    //already done
    } else {
    //first convert what was already there
    var currentNode:Object = pParent[pChild];
    pParent[pChild] = new Array ();
    pParent[pChild].push (currentNode);
    }

    return pParent[pChild];
    }

    public static function getNodeAsArray (pPath:Object):Array {
    if (pPath == null) return null;

    if (pPath instanceof Array) return [pPath][0];

    return [pPath];
    }

    /**
    * Checks if the given node is an array, if not, the node is converted to an array through forceArrayNode,
    * then the objects in the array are added to the array as an associative array, based on the field you passed.
    *
    * For example imagine you have:
    * <children>
    * <child id="first" other values….">
    * </children>
    *
    * Now you do createObjectMapFromArrayNode (children, "child", "id");
    * children.child now contains an array with 1 element reachable through child[0] or child["first"]
    */
    public static function createObjectMapFromArrayNode (pParent:Object, pChild:String, pMappingField:String):Array {
    var lResult:Array = forceArrayNode (pParent, pChild);

    for (var i:Number = 0; i < lResult.length; i++) {
    //eg the child at i is queried for its value of its id field
    lResult[lResult[i][pMappingField]] = lResult[i];
    }
    return lResult;
    }

    /**
    * @param pXml the xml node to search
    * @param pNodeName the nodename to look for
    * @return first child encountered with given name
    */
    public static function findNode (pXml:XMLNode, pNodeName:String):XMLNode {
    if (pXml.nodeName == pNodeName) return pXml;

    var lResult:XMLNode = null;
    for (var i:Number = 0; i < pXml.childNodes.length; i++) {
    lResult = findNode (pXml.childNodes[i], pNodeName);
    if (lResult != null) break;
    }
    return lResult;
    }

    /**
    * Map the names of all children for a given xmlnode to a function within the given scope passing the childnode to that function,
    * storing the result in an array so it can be returned.
    *
    * @param pXml the xmlnode whose childnodes you want to traverse
    * @param pScope the scope for the functions to run in
    * @param pPrefix any prefix you want to add to the node name to come to a functionname eg parse_
    * @return an array with all the results for the executed functions, if no function was found for a node, it will be skipped
    */
    public static function mapChildNamesToFunctions (pXml:XMLNode, pScope:Object, pPrefix:String):Array {
    var lResult:Array = new Array();

    for (var i:Number = 0; i < pXml.childNodes.length; i++) {
    var lFunctionName:String = pPrefix + XMLNode(pXml.childNodes[i]).nodeName;
    if (pScope[lFunctionName] == null) continue;
    lResult [i] = pScope[lFunctionName] (pXml.childNodes[i]);
    }

    if (lResult.length > 0) {
    return lResult;
    } else {
    return null;
    }
    }

    }

    Skinning the v2 Alert component

    Saturday, April 19th, 2008

    I ran into some trouble today that after skinning a v2 Alert component, none of my changes showed up when I implemented it in my main fla. My main fla ofcourse had it’s class export frame set to something different than export in first frame, and I knew that was the problem, but not quite how to fix it.

    Normally you set the class export frame to something like 2 or 20 or whatever, disable the ‘export in first frame flag’ on all your content by running a jsfl like:

    //
    // DisableExport
    //
    // Sets the linkage identifiers for all items to false

    var items = fl.getDocumentDOM().library.items;
    var item;
    for (var i=0; i item = items[i];
    if (item.linkageExportForAS == true) {
    fl.trace (item.name);
    item.linkageExportInFirstFrame = false;
    }
    }

    and then you make sure that somewhere after your class export frame you have a movieclip on the timeline containing all the stuff for which you disabled the first frame export.

    Apparently there is an order to that content as well, and I had never encountered that before. In my case I had overridden the TitleBackground clip, the ActivatorSkin and ButtonSkin, and you have to make sure these are loaded before the components that use them.

    So imagine you have a ‘all_my_content’ clip, simply put 2 frames in it, put the overriding clips on the first frame and all the components on the second with a nice stop(); to go along.

    Problem solved.

    Outlook 2003 An object could not be found

    Wednesday, January 30th, 2008

    The funny thing with ‘professional’ software is the weird things you run into. Everytime. When you don’t need it. At 1 A.M. This time around Outlook started whining about objects not found. It didn’t say which object which is kind of an easy way out. I can just see ourselves running around “Couldn’t find an object, couldn’t find an object”. Go figure.

    Solutions on the microsoft site led to nowhere. They proposed creating a new profile, migrating all your mail, settings, rules etc to the new profile. I think not! The problem was easily created (really, I didn’t even had to do anything !) it should be easily fixable.

    Luckily after googling for an hour or so I found this one:
    Outlook 2003 The operation failed. An object could not be found error

    “Answer: Close outlook, simply delete all the *srs files from %userprofile%\application data\Microsoft\Outlook.

    EG C:\Documents and Settings\username\Application Data\Microsoft\Outlook\outlook.srs

    When outlook is re-opened it will create a new *.srs file (* = the name of your profile in outlook)”

    Yeah baby, simplicity rocks!

    Non selectable transparent textfield with embedded font

    Wednesday, January 30th, 2008

    Some of the V2 Flash Components are less than intuitive now and then. While working on the new trophy tour for Heineken we had to create an application with a transparent textarea with non selectable non editable text using a non standard (embedded) font with Spanish characters.

    Oh and the text had to be rendered smoothy using advanced anti-aliasing.

    This leaves you with different options. Although I was tempted to simply use a standard textfield, this should be easy to implement using a TextArea component as well, right? As a reference for our own and your convenience, here is a step by step approach.

    Creating the test movie

    1. create a new flash movie, size it 300 x 300, and choose a background other than white
    2. drag a TextArea on stage, name it ‘ta_test’ and enter some text for the text parameter in the parameter section
    3. compile the movie, you’ll see a textarea with a border, a white background, whose text is editable and selectable

    ActionScript 2, timeline scripting or parameter settings?

    You’ll have to decide if you want to approach this using the parameter settings, timeline code or actionscript 2 code. In some cases you can choose, and in some I found timeline code was the easy/only option. This can probably be fixed by waiting a few frames after instantiating the TextArea, but this sounds like a nice exercise for some other time. Let’s keep it simple for now and use whatever works for demonstration purposes.

    Making the label non selectable

    • wrong:  switch the editable parameter to false, test the movie again, the text is no longer editable, but still selectable
    • wrong: add some actionscript on the timeline:import mx.controls.TextArea;
      var ta_test:TextArea;
      ta_test.enabled = false;
      You’ll see this code disables the text selection, but it disables the scrollbar and grays out the text as well, so this is not an option
    • right: replace that last actionscript on the timeline with:import mx.controls.TextArea;
      var ta_test:TextArea;
      ta_test.label.selectable  = false;

      This code accesses the underlying label, and does exactly what we want.

    Hiding the background

    It gets even better now, there is no real good way to hide the background. However digging through the original sources, we see we can do:

    ta_test["depthChild0"]._visible = false;

    Add this code to what you already had.  Google comes up with alternative solutions, and not one of them worked for me.  If you put this code in an actionscript class, you probably have to wait a bit after initializing the component before executing it.

    Using a non standard font

    Now we choose a non standard font. This means you’ll have to acquire a non standard font first. A great test font can be found here. It’s called Amped For Evil, by Ryan Splint

    1. download the font
    2. install the font (eg goto c:\windows\fonts, click install new fonts, and install it)
    3. now based on the font you have actually chosen, multiple things can apply. It might be enough to do:ta_test.setStyle ("fontFamily", "YourFontName"); eg ta_test.setStyle (“fontFamily”, “Amped For Evil”);Note that this code assumes you are using the default of ta_text.html = false;

    For some fonts you will actually see text, but one way or another, assuming this font does not exist on another system, this will not be enough to display the font there. You’ll need to embed the font as well using:
    ta_test.setStyle ("embedFonts", true);
    If you test the movie now, nothing will appear, since although you have told the TextArea to use an embedded font, the font itself still has to be embedded as well.
    Embedding the font can be done it two ways:

    • selectively
    • completely

    Selective font embedding

    Create an empty movieclip, drop a textfield in it, select the font you want to embed, and click the embed button. Select the characters you need. I’m definitely not an expert on all the different charactersets, but here is a short overview taken from http://www.p22.com/support/Opentype.html
    It is by no means complete, but I found it to come in pretty handy at times.
    For this example just select Basic Latin. Make sure your other selections match the text you are using. For example don’t select bold if you are not using a bold text or you won’t see anything. If you see nothing, you either haven’t embedded the font correctly, or you are leaving out some other important steps such as making sure the characters are exported as well. For example if the movieclip containing your textfield with the embedded characters is not on stage, you will have to select “export for actionscript” and “export in first frame”. If you see squares, you did right, but your font doesn’t support them. Scroll through the example text to see how that looks.
    Of course you can mix fonts as well. If you replace:

    ta_test.setStyle ("fontFamily", "Amped For Evil");
    ta_test.setStyle (“fontSize”, 20);

    with:

    ta_test.html = true;ta_test.text = “<html><font size=’20′ face=’Amped For Evil’><b>Bold</b> Normal</font></html>”;

    …and make sure you have two textfields in your library, one with normal characters and the other with bold characters, the text will show up fine.

    Complete font embedding

    Another option is to embed a complete font. In this case the font shown will be the font you created in the library (choose New Font..). Enter a font name, and make sure that after creating it, you enable “Export for ActionScript” and “Export in first frame”. Note the linkage id you have entered for “Export for ActionScript”. When you are using ta_test.setStyle (“fontFamily”,… you can refer to your font using either the linkage id or the font’s full name. Don’t be fooled by the name you enter for the font upon creation. When you are referring to the font from html font tags however only the linkage id will work.
    Mixing fonts works entirely the same as with selective character embedding.

    Advanced Anti Aliasing
    Is easy as (w/h)ell :
    ta_test.label.antiAliasType = "advanced";

    So wrapping it up (no pun intended), in the end it’s all pretty simple. Below is an example of a text (Betrayed by Avenged Sevenfold) over an image (Dimebag Darrel).

    Flash Button Bug

    Wednesday, January 23rd, 2008

    Also known as:

    • cannot click more than once on flash button
    • have to move mouse before you can click a button again
    • v2 components cause weird strange button behavior

    If you work with V2 components in Flash, this tip will surely help you out some day: when using V2 Components such as a Combobox, you may find your buttons no longer work correctly. Overall, this manifests itself by not being able to click more than once on a button. Before you can once again click on the button, you must first move the mouse again. Especially with navigation buttons, on which you are usually click-click-click-click-click-ing, this is less than optimal.

    This is apparently caused by some components which are not playing nice with a component’s focus. The fix is relatively simple and disturbing at the same time:

    In the onPress handler of such a button, you must include the following:

    Selection.setFocus (this);

    A focus rectangle now appears on every button, and to remove that, you use the following:

    this._focusrect = false;

    It is also possible to apply this to all buttons at once:

    Button.prototype.onPress = function () (
    this._focusrect = false;
    Selection.setFocus (this);
    )

    This will not be an option in most cases however, unless you rigidly commit yourself to overriding only a button’s onRelease handler.

    Update:

    On the previous installment of this blog, Muzak posted an easier fix.