I've been looking for a way to force "Same JRE as Workspace" as the default in my ANT build targets under FDT / Eclipse. I haven't figured it out yet, but I finally found where this setting is stored:

{workspace}/.metadata/.plugins/org.eclipse.debug.core/.launches/myProject myBuildfile.xml.launch

Remove the entries for org.eclipse.jdt.launching.JRE_CONTAINER & org.eclipse.jdt.launching.MAIN_TYPE, and Eclipse should use the workspace's JRE.

I'm sure someone could take this information and throw together a plugin / fix? The powerflasher team would honestly make the best candidates. (Hint! hint!)

Debugging The Dreaded “Null Object Reference”

Add -verbose-stacktraces=true to your mxmlc compiler arguments to get the line number of the dreaded "Cannot access a property or method of a null object reference."

How have I been programming ActionScript 3 for this long and not known this?

Creating EOT files with TTF2EOT

Continuing in the vein from yesterday, I wanted to post some findings about a great little utility called TTF2EOT. It's an open-source alternative to Microsoft's WEFT, which I'm not even able to compare it to because it crashes before I can export the first font! That's fine, I didn't want to use it anyway (I want to run on OS X for example).

The first issue is that you might want to convert an OTF (OpenType) font to EOT. TTF2EOT won't give you an error, but I wasn't able to get the outputted file to work. (Comments?) No problem, FontForge handles this nicely. You can even script this process so it's available from the command-line. Awesome.

So TTF2EOT should work now, right? Well, perhaps. It didn't for me with the font I'd chosen. I'm sure it varies greatly. I did some troubleshooting with FontForge and TTX and eventually determined that there was a problem in the resulting TTF's name table. If you don't get this part just right, you can expect problems with all sorts of downstream utilities, including the one we care about: TTF2EOT (which will fail silently. Very helpful.)

Paraphrasing O'Reilly's Fonts and Encodings here's the magic recipe to fix incorrect name tables with TTX.

Here's an example excerpt:
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
MyFont Std
</namerecord>
<namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>
<namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
UniqueID
</namerecord>
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
MyFont Std-Regular
</namerecord>

The "font family name" in nameID 1 added to the "style" in nameID 2 should match the value in the "complete name" in nameID 4 (separated by a hyphen). NameID 6 is the "postscript name." I use the value from nameID 4.

EOT files run on Windows, where usually the following Windows-specific entries would be required as well. If I'm just interested in generating EOT outlines, I've had luck omitting them.

<namerecord nameID="16" platformID="3" platEncID="1" langID="0x409">
MyFont Std
</namerecord>
<namerecord nameID="17" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>

I simply use the values from nameID 1 and nameID 2. You may have noticed a change of platformID, platEncID, and langID. Those refer to Windows, Unicode, and American English respectively.

To repeat, if you just want EOT outlines, I've had success with the minimum block including nameIDs 1, 2, 3, and 4. If you actually care to use the resulting TTF for anything else though, I highly recommend using the "full set", which I'll go out on a limb and specify as nameIDs 1, 2, 3, 4, 6 (PostScript Name), 16, 17, and 18 (Mac Family Name). In addition, you'll want to duplicate all namerecord entries using the following attributes:

Unicode, Version (use 0 or 3), and Language (supposedly unused, but TTX fails without it)
platformID="0" platEncID="0" langID="0x0"

Mac, Roman, and English
platformID="1" platEncID="0" langID="0x0"

Windows, Unicode, and American English
platformID="3" platEncID="1" langID="0x409"

I haven't (and can't) test every combination, so I'm not sure if including a malformed "optional" record would cause the output to fail. It's probably possible.

Again, I don't know whether the problem lies with FontForge (at the OTF to TTF conversion step) or the name table in the initial font. I have a feeling I'll find out.

Flex Font Transcoder with FontForge and/or TTX

I've been doing some deep font science as have a bunch of other folks, both with flash and without.

If you want to play along, I highly recommend, O'Reilly's Fonts and Encodings. It's the business. Be careful though -- it's a monster. Check with your local laws concerning weapon permits, etc. Also proven effective as a powerful sleep aid!

One of the many useful utilities thoroughly discussed is TTX, an extremely powerful font decompiling / recompiling tool. In short, it allows you to dump TrueType and OpenType to XML, make modifications (or inspections), and roundtrip back into a working font again.

So I'd been playing with this and FontForge, and if you manage to screw up a font so it's unusable, you'll get used to Flex giving an error like:

/Users/projects/externalFontLibrary/src/classes/EmbedFontLibrary2.as(14): Error: exception during transcoding: The font file:/Users/projects/externalFontLibrary/mxml/fonts/MyFont.tff is not usable.

[Embed(source="/Users/projects/externalFontLibrary/mxml/fonts/MyFont.ttf", fontFamily="MyFont", mimeType="application/x-font")]

/Users/projects/externalFontLibrary/src/classes/EmbedFontLibrary2.as(14): col: 3: Error: unable to build font 'MyFont'

I'd gotten so used to it, in fact, that I managed to overlook a subtile difference in error message for a font that had actually exported correctly:

TTX will generate unique names for its output files so it doesn't accidentally overwrite an original. You'll end up with filenames like: MyModifiedFont#1.ttf

So, let's try plugging that into our ActionScript class to embed outlines:

[Embed(source="/Users/projects/MyModifiedFont#1.ttf", fontFamily="MyFont", mimeType="application/x-font")]
private var myFont:Class;

To which Flex replies:

/Users/projects/externalFontLibrary/src/classes/EmbedFontLibrary2.as(14): col: 3: Error: transcoding parameter 'symbol' is not supported by 'flex2.compiler.media.FontTranscoder'

[Embed(source="/Users/projects/externalFontLibrary/mxml/fonts/MyModifiedFont#1.ttf", fontFamily="myFont", mimeType="application/x-font")]

/Users/projects/externalFontLibrary/src/classes/EmbedFontLibrary2.as(14): col: 3: Error: Unable to transcode /Users/projects/externalFontLibrary/mxml/fonts/MyModifiedFont.

Maybe you've got a sharper eye than I do, or maybe you're just more clever. In any case, I saw my compile fail and didn't look closely enough at the details. And the days that became weeks! It never did dawn on me (until today!) that the mysterious "symbol" parameter was the result of the pound symbol ("#") in the filename! After a rename to remove it, everything works awesomely!

Looking forward to talking about this more. I'm still looking into similar problems that can occur when exporting fonts from FontForge and ttf2eot Online typography is really heating up right now and I'm hoping to assemble some useful developer tools, or at the very least cobble together a workflow I can count on.

Recently, Blogger began appending a tracking gif to the content of each entry in their Atom feeds. The URL used in the image src uses https, most likely to avoid warnings when it's rendered in a https context. For some reason, when rendering the feed content containing the tracking image, the Flash player can crash, taking the browser with it on certain platform/browser combinations. We found the problem in FireFox 3.0 on OSX, but only on PPC Macs. Go figure.

In our case, we are proxying the Atom feed through a PHP script so we can display the feed contents to user agents without the Flash player. This made it fairly easy to iterate through the entries, and with a simple bit of regex, strip out the offending markup from the contents.

Blogger is wrapping the image tag in a div with a very specific CSS class, which makes our job easy:

foreach($feed->entries as $currEntry)
{
    
$currEntry->content ereg_replace('<div class=\"blogger-post-footer\">.*</div>'''$currEntry->content);
}

Depending on what you're using to parse the feed, you may or may not need to be concerned about decoding and encoding html entities during this process.

, ,

I just ran across a really annoying problem with Thickbox after upgrading from jQuery 1.3.1 to 1.3.2. The gallery functionality in Thickbox broke after the upgrade - instead of opening with the first image, the loading animation displayed forever without loading any content at all.

Turns out, the @ selector syntax was deprecated in jQuery 1.3, and was removed in 1.3.2. Simply removing the single occurrence of the @ character in the Thickbox js solved the problem.

I knew you wouldn't believe me, so I made a movie to prove it. This is on a macbook pro 15" with a 24" cinema display. The dock and menu bar are running on the laptop display. If I mirror or move the dock and menu bar to the external display, the problem disappears! If I plug it into another external display, it does exactly the same thing.

ClipStation Clipboard Writer 2.0 Released

ClipStation is a free lightweight solution for writing to your user’s clipboard from an HTML page. Using a small SWF that is embedded dynamically via JavaScript, you can pass an unlimited number of content clips onto the clipboard.

ClipStation is designed to be lightweight, flexible, and easy to implement. What makes ClipStation different from other clipboard SWF solutions is the ability to decode HTML character entities, allowing you to pass complex HTML markup to the clipboard from within form elements, divs, pre tags, etc. We developed ClipStation for use on a widget sharing page we've implemented for a client. After looking around for a good lightweight cross-browser solution and coming up empty handed, we decided to build our own. We're now happy to offer it to you at the low, low price of free.

Version 2.0 includes changes to allow access to the clipboard in Flash Player 10. Adobe changed the security requirements for clipboard access in version 10 of the player; now a user action is required before a SWF may access the clipboard. Instead of using a single hidden instance of the ClipStation SWF, we embed an instance for every clip that the user clicks to perform the clipboard copy. A source distribution is available, so you can change the design to fit your needs.

More information and the release package can be found at thirdpartylabs.com/clipstation/

»Download ClipStation 2.0

, , ,

Automatic AMF class mapping in Zend (Part 2)

see Part 1

Polishing off automatic mapping of objects to the correct class from PHP (Zend) back to ActionScript turned out to be easier than I thought.

In addition to the more commonly used $_explicitType class property, Zend also supports using a function called getASClassName. You can either paste this into each of your remote class stubs, or modify the getClassName method in Serializer to do it automatically.

public function getASClassName() 
{
 return ">" . str_replace("_", ".", get_class($this)); 
}

Clearly you'll need to avoid underscores appearing package and class names. That may be true regardless if you're planning to take advantage of Zend's automatic class loading.

On the Flash side, if you're not using the Flex compiler, you can use this to automatically register class aliases to the correct string.

function autoRegisterClassAlias (localClass:Class):void
{
registerClassAlias(">" + flash.utils.describeType(localClass).@name.split("::").join("."), localClass)
}

I've made it compatible with the Flex version. If the greater-than character is the cause of annoyance and confusion, feel free to remove it, but you'll need to do so on the PHP classes as well.

I'm sure this won't be our last post on this topic. If you've got lots of experience with AMF and Zend (I honestly don't) please post your thoughts in the comments.

Automatic AMF class mapping in Zend (Part 1)

First off, much thanks to Lee Coltrane for figuring this out. He's a bit busy at the moment, so I'm writing this up without the benefit of his input which I'm sure will be extremely valuable once our schedules mesh up.

A few caveats right off the bat. 1) We're still figuring out our best practices. 2) This is Flex only (see below)  3) We haven't (yet) written any code to automatically populate the $_explicitType variable going back to Flash from PHP.

If you're reading this, you've more than likely come across a Flex metatag like the one below:

[RemoteClass(alias="com.domain.FooBar")]

Personally, I found it annoying to have to populate the alias manually. The compiler knows the package name and the class name. Don't make me type it again! And, in fact, the compiler will accept the metatag without it:

[RemoteClass]

The only problem is getting Zend (in our case) to map it to the correct remote class. The Adobe engineers saw fit to prepend a greater-than character to the outgoing classname when using this syntax. So, if you omit the alias, ">com.domain.FooBar" will be sent instead.

To get ZendAmf to map this automatically, you'll need to make a slight modification to the Deserializer.php class. Mine is located in Zend/Amf/Parse/Amf3/Deserializer.php (Note: I haven't even looked at the Amf0 class yet, but my understanding is that custom class mapping isn't supported in AMF0) Insert the following code around line 315 in the readObject method after it has tried to determine the className but before it has assigned a return object.

// Allow and map automatic aliases via RemoteClass metatag & flex
if (strpos ($className, '>') === 0)
{
  $className = substr ($className, 1);
}
//translation: If the classname begins with '>' use the rest of the string instead.

This addition will deal with incoming class mapping. If you want to remove the alias parameter from all of your ActionScript RemoteClass metatags, you'll need to format your $_explicitType entries like this:

$_explicitType = ">com.domain.FooBar";

...which is what we'll look at in Part 2! 

NOTE: I said at the very beginning this is Flex only. Compiling with the Flash IDE does not support the RemoteClass metaTag, so you'll need to use registerRemoteClass as you've probably read about elsewhere. Perhaps in part 2 (or 3?) I'll write up an ActionScript class that can register classes against the correct package names automatically. Until then, I'll give you a hint: flash.utils.describeType.