October 1, 2009 11:56 am

Fraction Fever 2

A while back I described an idea for a different approach to implementing a fraction feature. Since then, I have gotten feedback from Karsten Luecke and others, the algorithm has been improved and a large number of fonts have been released that use this implementation. The revised code is below. It now handles things like 2009/10/01, 1/22/333/4444/55555/666666/7777777 and so on. I haven’t modified this in a few months so I consider it “stable.” As before, feel free to use this if you want to, but do so at your own risk, it is provided “AS IS”, my company, Type Supply, and I are not liable for anything, etc., etc. etc.

The revised code:

@figures = [
    zero
    one
    two
    three
    four
    five
    six
    seven
    eight
    nine
];
@numerators = [
    zero.numerator
    one.numerator
    two.numerator
    three.numerator
    four.numerator
    five.numerator
    six.numerator
    seven.numerator
    eight.numerator
    nine.numerator
];
@denominators = [
    zero.denominator
    one.denominator
    two.denominator
    three.denominator
    four.denominator
    five.denominator
    six.denominator
    seven.denominator
    eight.denominator
    nine.denominator
];

feature frac {

   lookup FractionBar {
        ignore sub slash
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            slash';
        ignore sub slash'
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            slash;
        ignore sub slash
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            slash';
        ignore sub slash'
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            slash;
        ignore sub slash
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            slash';
        ignore sub slash'
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            slash;
        ignore sub slash
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            slash';
        ignore sub slash'
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            slash;
        ignore sub slash
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            slash';
        ignore sub slash'
            @figures
            @figures
            @figures
            @figures
            @figures
            @figures
            slash;
        ignore sub slash
            @figures
            @figures
            @figures
            @figures
            @figures
            slash';
        ignore sub slash'
            @figures
            @figures
            @figures
            @figures
            @figures
            slash;
        ignore sub slash
            @figures
            @figures
            @figures
            @figures
            slash';
        ignore sub slash'
            @figures
            @figures
            @figures
            @figures
            slash;
        ignore sub slash
            @figures
            @figures
            @figures
            slash';
        ignore sub slash'
            @figures
            @figures
            @figures
            slash;
        ignore sub slash
            @figures
            @figures
            slash';
        ignore sub slash'
            @figures
            @figures
            slash;
        ignore sub slash
            @figures
            slash';
        ignore sub slash'
            @figures
            slash;
        sub @figures slash' @figures by fraction;
   } FractionBar;

   lookup Numerator1 {
        sub @figures'
        fraction by @numerators;
   } Numerator1;

   lookup Numerator2 {
        sub @figures'
        @numerators
        fraction by @numerators;
   } Numerator2;

   lookup Numerator3 {
        sub @figures'
        @numerators
        @numerators
        fraction by @numerators;
   } Numerator3;

   lookup Numerator4 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
   } Numerator4;

   lookup Numerator5 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
   } Numerator5;

   lookup Numerator6 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
   } Numerator6;

   lookup Numerator7 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
   } Numerator7;

   lookup Numerator8 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
   } Numerator8;

   lookup Numerator9 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
   } Numerator9;

   lookup Numerator10 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
   } Numerator10;

   lookup Denominator {
        sub [fraction @denominators]
        @figures' by @denominators;
   } Denominator;

   sub @figures space' @numerators by thinspace;

} frac;

PS: No, I don’t always break lines like this in my feature code. I did it to fit the column width here. Remove the unnecessary line breaks if you want to.

July 15, 2009 8:16 pm

.webfont Proposal

A quick note about web font progress: Erik van Blokland and I have been working on a new web font format. You can read all about it on the W3C WWW-Font mailing list.

Update: Lots of foundries are liking it.

Filed under: Programming,Type Design
April 21, 2009 4:15 pm

Web Fonts

There has been a lot of recent discussion about the possibility of web pages containing embedded fonts. The professional type design world has been relatively silent on this issue. That’s probably because there are significantly fewer of us than there are web designers. As a type designer who understands type technology, I thought I’d break the silence and offer my own thoughts on this issue.

Note: These are my views. They do not reflect the views of my clients, my colleagues, my friends, my family, my company or, if you want to argue, me. Also, these are my current opinions. I reserve the right to change my mind.

First a little background. In August of 2007, Håkon Wium Lie published a proposal for embedding fonts into web pages on A List Apart. (Full disclosure, I emailed Håkon shortly after he published his article. Our email exchange resulted in another proposal to improve typography on the web.) The WebKit team implemented Håkon’s proposal shortly after it was published. The web erupted in cheers and more than a few shouts along the lines of “Down with the monopolistic font industry!” Apple has announced that this will be a feature of Safari 4. From what I gather, other browsers are working on their own implementation. There was a W3C member meeting to discuss this. It has been a fast period of development that has opened up several cans of worms of the technical, legal and ethical variety. That’s where we stand now.

The W3C has a proposal for a working group that will address the various issues that have come up, but it has not yet been started. Unfortunately, at this time, there doesn’t seem to have been much input from people who actually make the fonts that these folks are discussing. I looked into joining the W3C so that I could contribute to the group, but it would cost $7900 per year for three years ($23,700 total plus the expenses of traveling to meetings). Based on my reading of the charter, it looks like the discussions will take place behind closed doors. This is quite depressing.

There are relatively few type designers in the world. (If you doubt me, think of all the type “foundries” you know of, go to their websites and look at how few type designers actually work there. Shocking, no?) There is no “type industry”. We have no lobbying group. Anyone who claims to represent the “industry” probably has a bridge in Brooklyn to sell you as well. We haven’t had much of a voice on technical matters in the past. We’ve had to roll along with whatever the OS vendors will support. Essentially, we’ve been told that we have to rely on the honor system as the basis of our livelihood. That’s where the small number of type designers there are stand and it is where we have stood for a long time. We’re constantly under threat of having the technical rug pulled out from under us, but we keep going on because this is what we have been called to do. So, here we are.

I’m excited by the possibilities of web fonts. I see this as the future of type design. This will be great for web designers and, above all, readers. It will be great for companies that commission custom typefaces who want to extend their branding to their websites. I think this could be done in a way that honors all of the work that we’ve done to create the fonts that people want to use. I think this can be done is an easy to implement, backwards compatible, shady-DRM free way that gives everyone what is being sought.

Enough with the moving soliloquy, time for the details.

The Current Proposals

  1. Raw TrueType/OpenType: Håkon Wium Lie has proposed using raw TrueType and OpenType files. His justification is that there are quite a few free fonts that can be used for web pages. These fonts already exist, so they should not have to be modified to work.

  2. EOT: This is a font format that was developed by Microsoft. It seems some of the browser manufacturers are very resistant to EOT.

  3. Root Table/New Web Font Format: Sampo Kaasila proposed an extension of the OpenType (and therefore TrueType) specification. This would create a new font format specifically for web embedding. However, it wouldn’t be completely new since it would simply be OpenType with a couple of new things. Specifically, these are the changes:

  • A new “root” table that would contain a string that ties a font to a specific domain. When a browser downloads a font, the domain that the web page belongs to will be compared to the root table. If they don’t match, the font isn’t used.
  • The first 100 bits in the font data would be obfuscated to make the font data unique from an OpenType font.

Additionally there has been discussion about referencing and honoring the fsType embedding bits in the OS/2 table.

My Thoughts

Overall, I see Håkon’s point on the free font issue. However, this will unfortunately put type designers into the role of license police. If someone can take one of our fonts, put it in a freely accessible directory on their server, that’s a violation of most of our license agreements. We’re going to have to spend a considerable amount of time trying to catch this when it happens. I don’t think any sane person is looking forward to this. I have a possible solution for fonts that are created in the future, which I’ll explain below when I discuss embedding bits below.

Personally, I really like Sampo’s root table proposal. It is a very elegant solution that builds on solid technology and wouldn’t require a lot of extra work for the browser developers. It would create an opportunity for type designers to license fonts to specific websites. That’s a win-win. There are a few things I’d like to add to this:

  • There should be a way to specify “all domains” in the root table. This would, again, be useful for free, GPL, open source, etc. fonts.
  • There should be a way to specify “no domains” in the root table. This wouldn’t have any immediate value, but it seems logical that if there is a way to specify “all” there should be a way to specify “none”.
  • Web authoring tools should not create a web font from a raw TrueType or OpenType font. They should not modify existing root tables. I have a feeling that this will be addressed in EULAs, but it should be common sense that tools shouldn’t change the embedding settings in a font.
  • There should be a new file extension for this. I propose “.wtf” - “WebType Font”.

Embedding Bits

I’m happy to see that there is some interest in honoring what the designer has set. However, there is a problem with referencing these bits for info about web embedding restrictions. Most of the designers I know consider these to be PDF embedding bits. The OS/2 specification isn’t clear about what these bits should be used for, but that’s what we all seem to think. This is an important distinction because if we don’t allow PDF embedding we can cause major problems in print workflows. So, we have to set our fonts to at least “Print and Preview” embedding to enable graphic designers to do their jobs. This is not the same as allowing “Print and Preview” embedding for web pages. The embedding bit situation is a mess. There are proposals, such as EEULAA, that attempt to make this more clear, but I don’t think those will clear the major hurdles they face before the web font discussion draws to a close.

Given all of this, It would be great if a new bit could be added to the fsType bits that would let us flag a font as eligible for web embedding or not. This bit could be added to the OpenType 1.7 specification. For this to work, a browser would look at the bit in the table and determine if it is eligible for web embedding or not. The touchy side of this regards fonts in format 1.6 and earlier. As it stands now, Apple and others have browsers that handle raw TrueType and OpenType fonts without any regard for embedding bits. If browsers require fonts with format 1.7 or higher, old free fonts won’t work and users of Safari and others will see different rendering results for pages that already have embedded fonts. Users will be sad. If the browser doesn’t require 1.7, it means that existing fonts that aren’t intended for web embedding have no protection. Type designers will be heartbroken. I don’t know what the solution for old fonts is. I do think that a new bit will help with new fonts. This would be a simple, workable solution to the problem with the raw font file proposal I mentioned above.

“But People Will Hack Commercial Fonts”

Yes, they will. There is nothing that can be done about this. All we can do is present a person with a fork in the road. The person can license the font to give the designer the respect he/she deserves for creating something that the person likes and wants to use. Or, they can ignore the Golden Rule and hack the font. There is no way to prevent this other than relying on a shared hope that people will be nice to each other. The last ten years have proven that there is no encryption that can’t be cracked and that there is no complex format that can’t be parsed.

How will this work in practice?

I don’t like to predict the future, but here’s what I think could happen: Say you have a blog and you want to use a font from the XYZ foundry for headlines on your site. You go to the foundry’s website, you enter the domain that your font will be used for, you buy a web embedding license for a small fee, you download the web font file and you put it on your site.

In Conclusion

That’s all there is to it. Two formats: Sampo’s web font format and Håkon’s raw font format. One simple change to the OpenType spec: a new bit in OS/2 fsType for specifying if web embedding is allowed or not. Off we go into the future.

I think this is a good compromise. Each side wants certain polarizing things. I think what I’ve outlined above is a good middle ground. At the very least, I hope type designers get to be a part of the discussion.

Paul Bukhovko has translated this post into Belorussian.

Filed under: Type Design
October 9, 2008 9:37 am

Comparing Font Binaries

Yesterday I had to dive into a large number of fonts to fix a tiny bug. It sounds easy enough, but font mastering these days is a process of educated guessing, pure guessing, crashing software, MacGyver like problem solving and finger crossing. As a result of this chaos, I’ve gotten into the habit of testing font binaries. In this case, I wanted to compare the new files to the old files to make sure that the only differences were related to the bug fix. This is actually very easy to do. I usually dump the OpenType files to XML with Just van Rossum’s indispensable TTX and compare the files with TextWrangler/BBEdit/FileMerge/Whatever. However, in this case I had a large number of files to look at and it would have taken me days to sort through all of them. Python to the rescue.

I put together a script (below) that dumped all files to XML with FontTools, compared them and reported the results. You’ll need to have FontTools installed and you’ll need to run this in Terminal (or something that pipes a script to Terminal like TextMate) on the Mac. (Somewhere else on Windows.)

import os
import glob
from difflib import Differ
from fontTools.ttLib import TTFont

# Paths to the directories containing the fonts to compare.
oldDirectory = "/path/to/a/directory/of/old/fonts"
newDirectory = "/path/to/a/directory/of/new/fonts"

# Find all OTF file names.
pattern = os.path.join(oldDirectory, "*.otf")
fileNames = glob.glob(pattern)
fileNames = [os.path.basename(path) for path in fileNames]

# A function that filters out unwanted reports.
# It returns True if the line should be ignored
# and False if the line is relevant.
def ignoreLine(line):
    # OS/2 checksum
    if line.startswith("-     <checkSumAdjustment value="):
        return True
    if line.startswith("+     <checkSumAdjustment value="):
        return True
    # OS/2 created
    if line.startswith("-     <created value="):
        return True
    if line.startswith("+     <created value="):
        return True
    # OS/2 modified
    if line.startswith("-     <modified value="):
        return True
    if line.startswith("+     <modified value="):
        return True
    # fallback
    return False

# A place to store all reports.
report = []

# Run through all fonts.
for fileName in fileNames:
    # Construct the needed paths.
    oldFontPath = os.path.join(oldDirectory, fileName)
    newFontPath = os.path.join(newDirectory, fileName)
    oldTtxPath = os.path.splitext(oldFontPath)[0] + ".ttx"
    newTtxPath = os.path.splitext(newFontPath)[0] + ".ttx"
    # Create ttx for both of the fonts.
    ttxText = []
    paths = [
        (oldFontPath, oldTtxPath),
        (newFontPath, newTtxPath)
    ]
    for fontPath, ttxPath in paths:
        # Open the font.
        font = TTFont(fontPath)
        # Write ttx.
        font.saveXML(ttxPath)
        # Close the font.
        font.close()
        # Read the ttx.
        f = open(ttxPath)
        ttx = f.read()
        f.close()
        # Store the ttx.
        ttxText.append(ttx)
        # Remove the ttx path.
        os.remove(ttxPath)
    oldTtx, newTtx = ttxText
    # Find differences between the two ttx reports.
    diffs = []
    differ = Differ()
    oldTtx = oldTtx.splitlines()
    newTtx = newTtx.splitlines()
    result = differ.compare(oldTtx, newTtx)
    for line in result:
        # Only pay attention to the lines beginning
        # with - and +. (See the difflib documentation
        # for information output.)
        if not line[0] in ("-", "+"):
            continue
        # Pass the line to the line filter to see
        # if it is relevant.
        if not ignoreLine(line):
            diffs.append(line)
    # If diffs were found, add them to the report.
    if diffs:
        report.append("-" * len(fileName))
        report.append(fileName)
        report.append("-" * len(fileName))
        report += diffs

# Finally, print the report.
print "\n".join(report)

The output looks like this:

-------------
Some-Font.otf
-------------
-     <fontRevision value="2.0"/>
+     <fontRevision value="2.001"/>
-       Version 2.000;PS 002.000;hotconv 1.0.50;makeotf.lib2.0.16970
+       Version 2.001;PS 002.001;hotconv 1.0.50;makeotf.lib2.0.16970
-       Version 2.000;PS 002.000;hotconv 1.0.50;makeotf.lib2.0.16970
+       Version 2.001;PS 002.001;hotconv 1.0.50;makeotf.lib2.0.16970
-       <version value="002.000"/>
+       <version value="002.001"/>
Filed under: OpenType,Programming
July 8, 2008 3:01 pm

Studio Lettering

At long last, Ken Barber’s Studio Lettering is available to the public. I wrote the OpenType features for these fonts, so I thought that I’d give a quick behind the scenes tour. If you are interested, Ken and I will be explaining more of the overall logic in detail at the next ATypI conference.

This Took Forever

Ken and I started talking seriously about the features when I was still working at House. I think the first time we sat down and started sketching out the desired behavior was right after the Ed Benguiat collection was released in late 2004. We kicked ideas around for the next couple of years while Ken worked on the drawing. In 2005 we presented some of our initial work at ATypI in Helsinki. From that point on, Ken would call me from time to time to talk about ideas he had while drawing and I made small experiments to check the viability of the ideas. The development of the final features didn’t begin until late last year when Ken and Ben Kiel came down to the Type Supply World Headquarters to officially get the ball rolling. I worked on the features steadily up until the middle of last week. Yes, we were making changes up until the last minute. Big changes in some cases.

Alternates for Alternates of Alternates

The features in in Swing are by far the most complex features I have ever written. That font uses most of the tricks that I’ve developed over the years: meta classes, triggers, fixer lookups, rotation schemes and so on. A couple of weeks ago, Ken called me and asked how a certain alternate glyph was being inserted. I replied that I honestly had no idea. I explained to him that these features are a lot like Plinko on the Price is Right. The text comes in, bangs around various algorithms and comes out at the end. Where it ends up is dependent on a long list of variables. I know how the individual algorithms work, but the overall thing? No idea.

The algorithm that inserts the size alternates was written from the ground up at least five times. The very first version implemented a rather complicated pseudo-random pattern insertion scheme that Ken and I cooked up. We had this wild idea that we could swap entire glyph runs with alternate patterns and create something that was nearly indistinguishable from lettering produced by an organic life form. The code for this was bonkers, but it worked really well in our initial tests. However, as we got deeper into developing these features the pattern complexity started to backfire. It was too complicated to predict what would come out of the various cycles of the algorithm. This caused problems when inserting positional forms and ligatures. Also, it made my head hurt really bad. I rewrote and rewrote until we got to a point that gave us a more controlled randomness. We really crashed into the edge of the OpenType universe and I have the scars to prove it.

The other fonts have lots of nifty features as well. All of them have lots of language specific alternates, initial and terminal forms, lots of ligatures and alternates for alternates of alternates.

Ben did a heroic job of corralling Ken’s late night glyph stampedes, wrestling the kerning into a usable form and dealing with my surly rants when I realized that I would have to rewrite features to accommodate the latest alternate Estonian alternates. We owe Ben a trophy.

Ken Barber, Living Legend

I can’t talk about these fonts without pointing out how great they are. Set aside the OpenType features (seriously, turn the features off) and these things still look perfect. I spent many hours on this project flipping through the various glyphs and marveling at how well drawn everything was. The third alternate German d that in all likelihood no one will ever see? Not a point out of place and not a curve unperfected. The fit and finish in these fonts is phenomenal. Ken is working on a level that few people ever attain and I can’t wait to see what he does next.

PS: Jokes for Lettering Nerds

For the last few months, people at House kept mentioning “the photos of Ken.” I had no idea what they were talking about and my inquiries were always met with, “We’ll email them to you.” I finally saw them yesterday and one in particular amuses me to no end. Ken is a student of lettering history and he loves to pay tribute to the masters here and there. Well, one of the photos is direct homage to the great Mortimer Leach. It replicates the portrait of Mr. Leach that is displayed in the forward of his outstanding Lettering for Advertising.

Ken Barber and Mortimer Leach

Bravo Mr. Barber, bravo.

April 16, 2008 9:57 am

Fraction Fever

I’ve never liked the way fraction feature is usually implemented in OpenType fonts. I thought I was the only person until Kent Lew wrote to me with the same frustration. We talked about it a bit and I worked up a possible solution. Here goes…

The Current Situation

The standard fraction feature algorithm works like this:

  1. Convert all numbers in the string to numerators.
  2. Starting at the beginning of the string, convert any numerator following a slash or a denominator to a denominator.
  3. Convert all instances of a slash to a fraction bar.

This works perfectly well from a programming standpoint, but from a user standpoint it is cumbersome. The user is required to select the precise text to which to apply fractions. This is a lot of work in practice. For example, it requires nine (9!) steps for the designer to set fractions in this simple list of ingredients.

1

Select “1/2”

2

Activate the fractions feature.

3

Select “1/4”

4

Activate the fractions feature.

5

Select “7/8”

6

Activate the fractions feature.

7

Select “1/3”

8

Activate the fractions feature.

9

Remove the spaces.

10

That is a lot of work. Now think about doing that in a 150 page cookbook.

A Possible Solution

So, what can be done? I kicked around the idea and came up with this algorithm:

  1. Convert every instance of a slash preceded and followed by a figure to a fraction bar.
  2. For every found fraction bar or numerator, look back one glyph. If the found glyph is a figure, convert it to a numerator. Do this for the 10 glyphs preceding the fraction bar until a non-figure is encountered.
  3. For every glyph following a fraction bar or a denominator, if the glyph is a figure, convert it to a denominator. Do this until a non-figure is encountered.
  4. Convert every space preceded by a figure and followed by a numerator to a thin space.

In code it looks like this:

@figures = [
    zero
    one
    two
    three
    four
    five
    six
    seven
    eight
    nine
];
@numerators = [
    zero.numerator
    one.numerator
    two.numerator
    three.numerator
    four.numerator
    five.numerator
    six.numerator
    seven.numerator
    eight.numerator
    nine.numerator
];
@denominators = [
    zero.denominator
    one.denominator
    two.denominator
    three.denominator
    four.denominator
    five.denominator
    six.denominator
    seven.denominator
    eight.denominator
nine.denominator
];

feature frac {
    sub @figures slash' @figures by fraction;

    lookup Numerator_1 {
        sub @figures'
        fraction by @numerators;
    } Numerator_1;

    lookup Numerator_2 {
        sub @figures'
        @numerators
        fraction by @numerators;
    } Numerator_2;

    lookup Numerator_3 {
        sub @figures'
        @numerators
        @numerators
        fraction by @numerators;
    } Numerator_3;

    lookup Numerator_4 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
    } Numerator_4;

    lookup Numerator_5 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
    } Numerator_5;

    lookup Numerator_6 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
    } Numerator_6;

    lookup Numerator_7 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
    } Numerator_7;

    lookup Numerator_8 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
    } Numerator_8;

    lookup Numerator_9 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
    } Numerator_9;

    lookup Numerator_10 {
        sub @figures'
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        @numerators
        fraction by @numerators;
    } Numerator_10;

    lookup Denominator {
        sub [fraction @denominators]
        @figures' by @denominators;
    } Denominator;

    sub @figures space' @numerators by thinspace;
} frac;

How many steps does this require the user to perform? Two (2!). Actually, it could be less than two because they could activate fractions in their style sheet definition. In that case it would require them to perform zero (0!!!) steps to apply the fraction feature. In any case, here are the two steps:

Select all of the text.

1

Activate the fractions feature.

2

Done.

But

There are some drawbacks. This is what Kent and I have come up with so far:

  1. This only works with fractions that have 10 or fewer numerators. In reality, is this an issue? I’m not certain, but it doesn’t seem likely. In any case, this could probably be extended to 20 numerators. I stopped at 10 to avoid the dreaded table overflow issue.
  2. It requires a non-figure to act as an indication of the leading edge of the fraction. In this case I used the space. This won’t work for fractions formatted as “21/2” to represent 2 and one-half. Are fractions ever formatted this way? Maybe, maybe not.
  3. If the user uses a font that implements this type of fraction feature and then switches to a font that implements an older style fraction feature, things will be broken. Any instances of this problem should be very visible to the user and manual intervention will solve it.
  4. The common date format 04/16/08 will be considered a fraction and formatted as such. The user could simply turn off fractions in this text.
  5. It isn’t what users are used to. This could be a legitimate issue, but if a user uses it in the way that they have been using the old fraction feature it will work properly.

That said, there are some clear advantages:

  1. It makes much more sense from a user point of view. We are in the age of the “smart” OpenType font. We now make fonts that automatically insert ligatures and swashes, and users have come to expect this behavior. It seems that fractions should work the same way. I don’t think it would be a good idea for a user to activate fractions at all times, but this should make it much easier for users to apply the fraction feature to lots of text with a broad stroke.
  2. This new algorithm preserves the space separating the integer and the fraction. This makes it far more usable in situations when this text needs to be sent to a feature-less environment, for example searching a PDF. If the user searches for “1 1/4” the appropriate result will be found. Using the old algorithm, plus the space removal mentioned above, the user would have to search for “11/4”. That looks like “eleven fourths” not “one and one fourth.”

I don’t think the potential problems outweigh the benefits for the user, but they should be taken into consideration. I tend to think in terms of “most case scenario” rather than “worst case scenario.” This algorithm isn’t perfect and it will fail 1% of the time. However, I think that 99% of the time it will work infinitely better than what users are used to.

Now What?

I haven’t actually deployed this in a font yet, but I’m going to give it some thought next time I write a fraction feature. Feel free to use this if you want to. If you do, please let me know how it works out.

April 15, 2008 10:21 am

Ten Flags Inn

Ten Flags Inn

As a child, I was fascinated by this sign. It was located along the route my family would take into Baton Rouge and I remember sitting in the backseat of our car with my face pressed against the window eagerly waiting to see it. I think this was the first time I ever paid attention to the way letters looked. This sign isn’t perfect, but it is still my favorite.

(Wow. It sure has been a long time since I posted anything. I have been more than busy…)

Filed under: Lettering,Photos,Signs
September 29, 2007 12:50 pm

Signs In My Neighborhood

My friend Dave Hotstream has been posting photos of his neighborhood. That inspired me to dust off iPhoto and compile a set of photos of my own neighborhood. I’m a lettering nerd, so I usually take photos of signs. Luckily, my neighborhood is full of old, beautiful and/or weird specimens.

Electronic tubes. The swash makes no sense. Why is "Bar" highlighted?

Most of the sign aficionados I know consider the advent of vacuformed and cut plastic signs to be the beginning of the end. They are probably right, but I’m still kind of obsessed with these things.

Check out that ampersand. Crabs!?

I adore “boring” signs like these two. They don’t need fancy swashes or anything like that to get the job done.

Go fish.

I suppose it’s not surprising that this place is near the taxidermist.

1913-1917 4 FTW!

Some of the building owners seem to have gone out of their way to preserve old signs. They should get a trophy or something.

It's another dimension.

The ligature and the super thin parentheses on this one are stellar.

This is weird.

This place is covered in lettering like this. It’s crazy.

If you have to ask, you don't need to know.

“Klein Bros.” That’s all it says. No “Hardware Store” or “Attorney at Law” or “Pet Hotel”. Thus, I have no idea what the Klein brothers do.

Nice afii10029.

Nice afii10029.

Filed under: Lettering,Photos,Signs
September 21, 2007 7:20 am

FeatureProof Beta 1

Among the avalanche of code I just open sourced is a humble little application called FeatureProof. This application is an environment for testing features in OpenType fonts.

I’ve been thinking about this tool since TypoTechnica 2005. During a round table discussion at that conference, Erik van Blokland and I made the case for a robust tool for testing OpenType features. Specifically, we stated that we felt that there was a huge need for a tool capable of programmatically testing OpenType features. We had been doing this with our other programming work, so it seemed natural that we should be able to do it with our OpenType feature work.

I waited for someone to build such a tool. Nothing happened, so I decided to build it myself. FeatureProof is the result. It allows you to interactively test features and analyze the results, browse the compiled feature data and execute programmatic test cases. It has become indispensable in my work.

You can download the application over at code.typesupply.com. There is a good bit of documentation there as well.

This is a beta release, so I would appreciate any bug reports.

Filed under: OpenType,Programming
7:13 am

code.typesupply.com

I’m happy to announce that I’ve decided to open source a large portion of of my font development code repository. This batch of code includes core libraries for building font development applications, FontLab scripts and one full fledged application. At last count it was around 25,643 lines of Python code.

Why am I doing this? I really care about type design. It is what I love. I don’t just love doing it myself, I love seeing other people produce excellent typefaces. So, hopefully this will help people do good work.

The code is housed at code.typesupply.com.

Enjoy.

Filed under: Announcements,Programming
Next Page