Vixiom Axioms

June 30, 2009

Automate font compiling for Flex with Ruby

Filed under: ActionScript, Flex, Ruby Alastair @ 10:31 am

I came up with this solution when I had to compile over 100 fonts into SWF files for a recent project. Doing this by hand would have been madness so I wrote a ruby script and a shell script to automate the process.

Step 1: Setup

The directory structure I used was as follows.

convert.rb (the ruby script)
compile.sh (the shell script)
fonts/ (a directory for font files - .ttf and .otf)
as/ (a directory for the generated ActionScript)
swfs/ (a directory for the compiled swf files)

Step 2: Prep fonts

Ok told a tiny white lie when I said it was all automated. Since (to my knowledge) you can’t inspect a font file to determine if it’s normal, regular, bold, italic, or bold italic (the weights and styles Flex understands) you’ll have to set up a naming convention that the Ruby script can parse. You’ll be using the font name to create an ActionScript class so it should also be a legal name.

Here’s an example using the Arial family.

Arial.ttf (regular fontWeight and normal fontStyle)
Arial_Italic.ttf (regular fontWeight and italic fontStyle)
Arial_Bold.ttf (bold fontWeight and normal fontStyle)
Arial_BoldItalic.ttf (bold fontWeight and italic fontStyle)

Step 3: The Ruby Script

require 'find'

# delete any previous as
Find.find( 'as' ) do | as |
  if File.extname( as ) == ".as"
    File.unlink as
  end
end

# generate new as
Find.find( 'fonts' ) do | font |
  if File.file?( font )
    # extension name
    ext = File.extname( font )
    # is font
    if ext == ".ttf" || ext == ".otf"
      # file name
      full_name = File.basename( font )
      name = File.basename( font, ext )
      # font weight and style
      font_weight = ""
      font_style = ""
      if full_name.include? "_Bold" + ext
        font_weight = "fontWeight='bold',"
      end
      if full_name.include? "_Italic" + ext
        font_style = "fontStyle='italic',"
      end
      if full_name.include? "_BoldItalic" + ext
        font_weight = "fontWeight='bold',"
        font_style = "fontStyle='italic',"
      end
      # generate as
      f = File.new("as/#{name}.as",  "w+")
      f.write "package
      {
        import flash.display.Sprite;

        public class #{name} extends Sprite
        {
          [Embed(source='../fonts/#{full_name}', fontName='#{name}', #{font_weight} #{font_style} unicodeRange='U+0000-U+00FF,U+2100-U+214F')]
          public var Font:Class;
        }
      }"
      # some helpful output
      print ',"', "#{name}", '"'
    end
  end
end

In TextMate you can open this script and hit Command-R to run it, or run it via the command line ‘ruby convert.rb’. Once the script runs you’ll have generated ActionScript files in the ‘as’ directory ready to be compiled.

Step 4: The Shell Script

echo "<h2>Fonts Custom Compile</h2>";
echo "<code> Started @ `date "+%H:%M:%S"`</code><br />";

for i in `cd as/; ls *.as`; do
  swf=`echo $i |  awk -F. '{print $1}'`
  swf="$swf.swf"
  "/Applications/Adobe Flex Builder 3/sdks/3.3.0.4589/bin/mxmlc" -file-specs="as/$i" -o="swfs/$swf" -managers="flash.fonts.AFEFontManager" 2>&1;
done

You’ll need to customize the script for your Flex SDK location, mine is at "/Applications/Adobe Flex Builder 3/sdks/3.3.0.4589/bin/mxmlc". The hidden gem in there is -managers="flash.fonts.AFEFontManager", about 90% of fonts will compile without it but the rest were blowing up until I added that argument.

Again with TextMate you can run the script with Command-R. Each font will take about five seconds to compile, my set of over 100 fonts took over ten minutes :)

That’s it! The SWFs are compiled and ready to be runtime loaded into a Flex app. Creating the ActionScript for 100+ fonts would have been a multi-day process but with a little scripting it took less than an hour.

Digg! submit Automate font compiling for Flex with Ruby to stumbleupon.com submit Automate font compiling for Flex with Ruby to del.icio.us submit Automate font compiling for Flex with Ruby to reddit.com Like this post? subscribe to the feed.

November 25, 2008

PureMVC for JavaScript Released

Filed under: JavaScript Alastair @ 11:41 pm

I won’t be dropping my beloved Flex anytime soon but it’s nice to know if you must do JavaScript (and let’s be honest Flex isn’t always the best tool) you can at least use a familiar framework.

Check out PureMVC for JavaScript.

Digg! submit PureMVC for JavaScript Released to stumbleupon.com submit PureMVC for JavaScript Released to del.icio.us submit PureMVC for JavaScript Released to reddit.com Like this post? subscribe to the feed.

Paperclip for easy Rails file uploads

Filed under: Ruby on Rails Alastair @ 11:17 pm

It’s my first post in months*, so it must be worth it right?

Rails Inside has the details on Paperclip as an alternative file upload/association plugin, I’ve tried them all and paperclip covers all your file upload bases.

*I’ve been busy with Fatherhood 101 and my new job as a Flex Dev at Captial Group (the largest company you’ve never heard of).

Digg! submit Paperclip for easy Rails file uploads to stumbleupon.com submit Paperclip for easy Rails file uploads to del.icio.us submit Paperclip for easy Rails file uploads to reddit.com Like this post? subscribe to the feed.

August 5, 2008

Skinning a Flex button with one MXML file (and Degrafa)

Filed under: ActionScript, Flex Alastair @ 9:13 pm

Skinning a flex button can often take multiple graphics and/or MXML files for each state. Here’s how to skin a button using MXML and Degrafa to handle three button states with just one file (plus a bonus ‘glow’ filter as an alternate way to get a drop shadow).

The secret is to override the updateDisplayList method and use the skin’s current name in a switch statement to apply different Degrafa strokes and fills to the button. Click to view an example with source.

Flex button skinning

<?xml version="1.0" encoding="utf-8"?>
<GraphicBorderSkin xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns="http://www.degrafa.com/2007">

    <mx:Script>
        <![CDATA[

            //////////////////////////////////////////////////////////////////////
            //
            // PRIVATE VARIABLES
            //
            //////////////////////////////////////////////////////////////////////

            [Bindable]
            private var awidth:Number=0;

            [Bindable]
            private var aheight:Number=0;

            //////////////////////////////////////////////////////////////////////
            //
            // PROTECTED METHODS
            //
            //////////////////////////////////////////////////////////////////////

            override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
            {
                super.updateDisplayList( unscaledWidth, unscaledHeight );

                awidth = unscaledWidth;
                aheight = unscaledHeight;

                // drop shadow is actually a black 'glow'
                var glow:GlowFilter = new GlowFilter();
                glow.color = 0x000000;
                glow.alpha = 1;
                glow.strength = .75;
                glow.quality = BitmapFilterQuality.MEDIUM;

                // which skin state?
                switch ( name )
                {
                    case "upSkin":
                        buttonRect.fill = upFill;
                        buttonRect.stroke = upStroke;
                        glow.blurX = 4;
                        glow.blurY = 4;
                        break;

                    case "overSkin":
                        buttonRect.fill = overFill;
                        buttonRect.stroke = overStroke;
                        glow.blurX = 5;
                        glow.blurY = 5;
                        break;

                    case "downSkin":
                        buttonRect.fill = downFill;
                        buttonRect.stroke = downStroke;
                        glow.blurX = 3;
                        glow.blurY = 3;
                        break;
                }

                // apply filter
                this.filters = [glow];
            }

        ]]>
    </mx:Script>

    <!-- FILLS -->
    <fills>

        <!-- UP -->
        <LinearGradientFill id="upFill" angle="90" >
            <GradientStop ratio="0" alpha="1" color="#666666" />
            <GradientStop ratio=".5" alpha="1" color="#333333" />
            <GradientStop ratio=".5" alpha="1" color="#000000" />
            <GradientStop ratio="1" alpha="1" color="#666666" />
        </LinearGradientFill>

        <!-- OVER -->
        <LinearGradientFill id="overFill" angle="90" >
            <GradientStop ratio="0" alpha="1" color="#666666" />
            <GradientStop ratio=".5" alpha="1" color="#333333" />
            <GradientStop ratio=".5" alpha="1" color="#000000" />
            <GradientStop ratio="1" alpha="1" color="#666666" />
        </LinearGradientFill>

        <!-- DOWN -->
        <LinearGradientFill id="downFill" angle="90" >
            <GradientStop ratio="0" alpha="1" color="#000000" />
            <GradientStop ratio=".5" alpha="1" color="#333333" />
            <GradientStop ratio=".5" alpha="1" color="#444444" />
            <GradientStop ratio="1" alpha="1" color="#777777" />
        </LinearGradientFill>

    </fills>

    <!-- STROKES -->
    <strokes>

        <!-- UP -->
        <SolidStroke id="upStroke" color="#ffffff" alpha="1" weight="1.5" />

        <!-- OVER -->
        <LinearGradientStroke id="overStroke" angle="90" weight="1.5">
            <GradientStop alpha="1" ratio="0" color="#ccffff"/>
            <GradientStop alpha="1" ratio="1" color="#66ccff"/>
        </LinearGradientStroke>

        <!-- DOWN -->
        <SolidStroke id="downStroke" color="#f4f4f4" alpha="1" weight="1.5" />

    </strokes>

    <!-- GEOMETRY -->
    <geometry>
        <RoundedRectangleComplex id="buttonRect" height="{aheight}" width="{awidth}"
            bottomLeftRadius="4" bottomRightRadius="4" topLeftRadius="4" topRightRadius="4" />
    </geometry>

</GraphicBorderSkin>
Digg! submit Skinning a Flex button with one MXML file (and Degrafa) to stumbleupon.com submit Skinning a Flex button with one MXML file (and Degrafa) to del.icio.us submit Skinning a Flex button with one MXML file (and Degrafa) to reddit.com Like this post? subscribe to the feed.

June 29, 2008

Display Rails associations in a Flex DataGridColumn

Filed under: ActionScript, Flex, Ruby, Ruby on Rails Alastair @ 10:17 am

Frameworks like Ruby on Rails and CakePHP make it easy to set up model associations with belongs_to, has_many, and the ever popular has_and_belongs_to_many. However, getting those associations to show up in a Flex DataGridColumn’s dataField isn’t immediately obvious, you’d assume you could just do parent.child or child.parent but that just gives a blank column. After some digging I found the answer is to use a labelFunction.

In the example below there are two models in Rails, ‘Group’ and ‘Category’, Group has_many Categories and Category belongs_to Group. Here’s the Flex code for the Categories DataGrid, groupName is the labelFunction that spits out a Category’s Group name (equivalent to @category.group.name in ruby):

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%">

    <mx:Script>
        <![CDATA[
            import mx.controls.dataGridClasses.DataGridColumn;

            private function groupName( item:Object, column:DataGridColumn ):String
            {
                return item.group.name;
            }

        ]]>
    </mx:Script>

    <mx:DataGrid id="dataGrid" width="100%" height="100%">
        <mx:columns>
            <mx:DataGridColumn headerText="Name" dataField="name" />
            <mx:DataGridColumn headerText="Group" labelFunction="groupName" />
        </mx:columns>
    </mx:DataGrid>

</mx:VBox>
Digg! submit Display Rails associations in a Flex DataGridColumn to stumbleupon.com submit Display Rails associations in a Flex DataGridColumn to del.icio.us submit Display Rails associations in a Flex DataGridColumn to reddit.com Like this post? subscribe to the feed.

April 16, 2008

New job! I’m now an ActionScript Developer at OpenSoft

After three years of consulting I’m heading back to a ‘real’ job as a Flash/Flex (mostly the latter) developer at OpenSoft (aka Farheap Solutions). It was a tough call but doing full time Flex work a mere 15 minute commute away was too good to pass up.

The blog, which was about 50/50 Ruby/Flex, will probably now swing wildly to ActionScript/Flex topics as I’m all business in the front from here on out. I now have smarter people than me to take care of the back-end (which at OpenSoft is Java and PHP, with a dash of Ruby thrown in for kicks).

Consulting was fun but a bit scattered, I always had like four projects in various stages of completion (not recommended). Not only was I switching between Ruby and Flex but also between design, business development, tech support, accounting, collections, db admin, server admin and on and on. However I learnt a ton, and really only because I was working for myself could I decide to take a day or two off to learn Rails or Flex. If you’re on the younger side (or have limited attachments, i.e., single, no mortgage) I highly recommend consulting for a couple of years to learn new skills and build a reputation.

So my conversion to the dark side is now complete, five jobs ago I was designing Teletubby books for the BBC and now I’m an evil flex developer.

PS OpenSoft is looking for a couple more ActionScripters, Flex jobs in OC are still pretty rare so send me a resume if you’re interested (alastairdotdawson at farheapdotcom).

Digg! submit New job! I’m now an ActionScript Developer at OpenSoft to stumbleupon.com submit New job! I’m now an ActionScript Developer at OpenSoft to del.icio.us submit New job! I’m now an ActionScript Developer at OpenSoft to reddit.com Like this post? subscribe to the feed.

April 15, 2008

Some App Engine links

Filed under: ActionSnip, Flash, Python Alastair @ 9:19 pm

Aral Balkan on Building Flash applications with Google App Engine.

PureMVC Python / Google App Engine Demo

Digg! submit Some App Engine links to stumbleupon.com submit Some App Engine links to del.icio.us submit Some App Engine links to reddit.com Like this post? subscribe to the feed.

April 7, 2008

Run your web applications on Google’s infrastructure

Filed under: Django, Ruby Alastair @ 11:01 pm

Google releases App Engine. It’s Python only for now, but there are rumors more languages (Ruby!) will soon be available.

Here’s a video intro. And Django runs out of the box (in the box?) - well some parts are missing like no relational db - still you can’t beat the one line deployment!

Docs! Running Django on Google App Engine

Digg! submit Run your web applications on Google’s infrastructure to stumbleupon.com submit Run your web applications on Google’s infrastructure to del.icio.us submit Run your web applications on Google’s infrastructure to reddit.com Like this post? subscribe to the feed.

April 2, 2008

List of Flex resources and tutorials

Filed under: ActionScript, Flash, Flex Alastair @ 6:45 pm

Paranoid Ferret Productions, who themselves are a great Flex resource, have a list of the ‘Best Adobe Flex Resources and Tutorial Sites‘.

Digg! submit List of Flex resources and tutorials to stumbleupon.com submit List of Flex resources and tutorials to del.icio.us submit List of Flex resources and tutorials to reddit.com Like this post? subscribe to the feed.

April 1, 2008

ActionScript MVC minimalist example for PureMVC 2.0.3

Filed under: ActionScript, Flash, Flex Alastair @ 9:50 pm

I’ve updated Chandima Cumaranatunge’s excellent PureMVC walk-through to work with the latest version of PureMVC (2.0.3). Although PureMVC has extensive documentation nothing beats a simple demo for wrapping your brain around the framework. The most helpful part of Chandima’s tutorial is when he steps through the sequence of actions which includes initialization and then following a user’s gesture on a round trip through the framework.

1. The Concrete Facade class called ApplicationFacade broadcasts a STARTUP Notification.

2. The STARTUP Notification triggers the StartupCommand command object which registers the KeyDataProxy proxy, and StageMediator mediator.

3. StageMediator mediator registers a KEY_DOWN Event handler to the stage to intercept key presses. It also registers to receive KEYUPDATE Notifications.

4. User presses a key generating a KEY_DOWN Event that is intercepted by the key down event handler in the StageMediator.

5. StageMediator broadcasts a KEYDOWN Notification with the character code of the key in the notification body.

6. The KEYDOWN Notification triggers the StoreKeyCommand command object, which accesses the KeyDataProxy proxy and updates the model (data object).

7. The KeyDataProxy proxy stores the data in a data object (just a property in the proxy in this case).

8. The KeyDataProxy proxy broadcasts a KEYUPDATE Notification with the character code of the key in the notification body.

9. The KEYUPDATE Notification handler in StageMediator intercepts the KEYUPDATE Notification and traces the key value.

In my updated example I trace out each action to clarify when (and in which file) they occur. Make sure you have PureMVC in your class path before running the demo.

Digg! submit ActionScript MVC minimalist example for PureMVC 2.0.3 to stumbleupon.com submit ActionScript MVC minimalist example for PureMVC 2.0.3 to del.icio.us submit ActionScript MVC minimalist example for PureMVC 2.0.3 to reddit.com Like this post? subscribe to the feed.
Older Posts »

Powered by WordPress