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.

Passing Custom-Classed Parameters to AMF (PHP)

I spent a day or two pulling my hair out and wondering if AMFPHP should be considered abandon-ware (no). I could get data to go back-and-forth. That part was pretty easy. But I wanted to pass a custom configuration object to the server as part of my request and couldn't get any further than it showing up in PHP as an anonymous array.

I gave up, installed the Zend framework (which now includes an AMF implementation), and had similar (although slightly different) issues. After resorting to Charles to figure out what might be going wrong, I found the problem in my remote service class. It turns out my PHP chops were coming up short.

There are a bunch of AMF examples and tutorials out there, and I feel like I looked at most of them ; ) Very few talk about sending custom-classed parameters to the server. Instead, they show you how to pass numbers and strings (if anything at all). The best of these test-your-gateway examples have you send your parameter object to the server as an array. In php, you'd access those (array) properties like this: $config['myParam'].

However, if you've got mapping between Actionscript and PHP classes properly configured, that syntax isn't going to work. Actionscript lets you access an object's child properties via either 'dot syntax' or 'array syntax', but PHP is more picky.

Once you get your custom class mapping working, you need to access (class) properties like this: $config->myParam. Simple to be sure.

So, I thought I'd tried this (and every other syntax combination), but apparently not while I had the class mapping setup correctly. PHP errors in your AMF service class can be notoriously hard to debug. Most of the time when something went wrong with mine, I simply never got a response. But, once I fixed my service class, I could use either Zend or AMFPHP. Rock on.

You may remember my article on scrollRect and getBounds().

Colin Moock just posted a bitmap-based solution. Slower, but very, very effective.