Using TypeKit with Cappuccino

On one of the projects we're working on we're using Cappuccino for the more involved bits of the website, as it takes out a lot of the grunt work for building desktop caliber GUIs in a browser. The flip side is you're then left pondering how to tweak some bits of the Cappuccino interface to make it match the rest of your website.

One example of this is fonts. The project in question makes good use of TypeKit to provide nice fonts for the website. Normally with TypeKit you select the fonts you want to use and then specify a bunch of CSS selectors you want them to apply to. This is fine for regular HTML, but goes against the Cappuccino flow, where you essentially write your front end like you would a Mac app. In Cappuccino you should be writing code like this:

   label = [[CPTextField alloc] initWithFrame: CGRectMake(10, 142, 80, 24)];
   [label setStringValue: @"My nice label"];
   [label setFont: [CPFont boldFontWithName: @"Helvetica" size: 14.0]];
   [container addSubview: label];

I was all ready to hack a subclass of CPFont and get dirty with making it work with TypeKit when it turned out the solution was in fact very simple, and no hacking was required. Phew!

When you use CPFont the name provided essentially ends up the in the style attribute of the div created for the label. So, the underlying HTML looks like this:

   <div style="position: absolute; z-index: 200; font: normal normal bold 14px/normal Helvetica, Arial, sans-serif; 
    overflow-x: hidden; overflow-y: hidden; text-overflow: clip; white-space: pre; word-wrap: normal; 
    top: 0px; left: 0px; width: 76px; height: 20px; ">My nice label</div>

The first entry in the font list on that div is taken from the CPFont that we specified in our Objective-J. So, you can just put in any font name you like there, and as long as the browser can find it, it'll work out okay. However, if you look in TypeKit you'll see that as part of their copy protection mechanism they split individual fonts up into several sub-fonts. So, I'm using Ratio, but the actual font names used are "ratio-1" and "ratio-2". Fortunately, as CPFont just passes font name straight through to the underlying HTML, you can specify your fontname with both fonts in, like so:

   # globally declared constant to save on typing
   var PWSystemFont = @"ratio-1,ratio-2";
   label = [[CPTextField alloc] initWithFrame: CGRectMake(10, 22, 80, 24)];
   [label setStringValue: @"My nice label"];
   [label setFont: [CPFont boldFontWithName: PWSystemFont size: 14.0]];
   [container addSubview: label];

And that just works. Similarly, for any TypeKit font you just need to check for the CSS names used, which you can find in your kit editor by clicking the "Using fonts in CSS" link, which will show you the names like so:

Typekit CSS.png

The only other thing you need to do is put the embed code that TypeKit give you at the top of your Cappuccino app's root HTML file, and your Cappuccino apps will be looking beautiful before you know it.