Glider
"In het verleden behaalde resultaten bieden geen garanties voor de toekomst"
About this blog

These are the ramblings of Matthijs Kooijman, concerning the software he hacks on, hobbies he has and occasionally his personal life.

Most content on this site is licensed under the WTFPL, version 2 (details).

Questions? Praise? Blame? Feel free to contact me.

My old blog (pre-2006) is also still available.

See also my Mastodon page.

March
Sun Mon Tue Wed Thu Fri Sat
         
28 29 30
31            
Powered by Blosxom &Perl onion
(With plugins: config, extensionless, hide, tagging, Markdown, macros, breadcrumbs, calendar, directorybrowse, feedback, flavourdir, include, interpolate_fancy, listplugins, menu, pagetype, preview, seemore, storynum, storytitle, writeback_recent, moreentries)
Valid XHTML 1.0 Strict & CSS
Copying references from one font to another in FontForge

For the live roleplaying game Symbols, I've been learning a bit about fonts and how to modify them. In the game, we use different fonts to represent different languages. These fonts are not "normal" fonts, but fonts with symbols instead of letters. This means that a text in such a font is not readable, unless you have the corresponding key that maps each symbols back to a letter.

For this, a number of fonts was found on the Internet. These fonts had a symbol for each letter, but had an important shortcoming: They had no accents. So when a text contained, for example, an é it would be displayed as an empty box, or not at all. This was previously solved by replacing all accented letters with their normal equivalents. This was a manual process, which makes it time consuming and error-prone.

I decided to explore FontForge, an open source font editing program to add accents to these fonts. The program turned out to be well-suited to the task.

I first, manually, made all accented characters references to their unaccented equivalents (instead of empty glyphs). Then I created a grave, acute, dieresis and circumflex (yay for my Wacom tablet). Then, I copied references to these into all the accented characters (all the other accented characters simply stayed unaccented). After some manual positioning, the new font was done.

Now, for the actual topic of this post. I now had one font that had the proper references to have all accented characters. I planned on copying a big part of the FontForge .sfd file from that font to all the others, so they would automatically define all accented characters as well.

But, it turned out that FontForge uses the glyph number (based on the order in which the glyphs are in the file) instead of the proper (Unicode) character name/number to save references. Since these glyph numbers were not consistent among the fonts I had to modify, this got completely messed up.

So, I tried the scripting approach. Fortunately, FontForge is easily scriptable, in python as well as in some built in language. I opted for the latter and experimented with scripting. By doing something like the following, I could create the â automatically (I had to apply the fix in this post before CopyReference() would work as expected).

Select('a')
CopyReference()
Select('acircumflex')
Paste();
Select('circumflex')
CopyReference()
Select('acircumflex')
PasteInto();

But, I didn't feel like writing hundreds of these lines manually, so I also wrote a Perl script to extract all references from an existing font file (the one I created manually before). In hindsight, it might have been faster to have done it manually, but now I have this pretty script:

#!/usr/bin/perl

# Usage: pipe in a sfd through stdin.
# ./parse.pl < Guardion/Guardion.sfd > fix.ff

while(<STDIN>) {
        if ( /^StartChar: (.*)$/ ) {
                $code = $1;
                push(@bases, $code);
        }
        if ( /^Refer: ([0-9]*)/ ) {
                push(@{$uses{$1}}, $code);
        }
}

while (($key, $value) = each(%uses)) {
        foreach $other (@{$value}) {
                        print("Select('$other')\n");
                        print("Clear()\n");
        }
}

while (($key, $value) = each(%uses)) {
        print("Select('$bases[$key]')\n");
        print("CopyReference()\n");
        print("SelectNone()\n");
        foreach $other (@{$value}) {
                        print("SelectMore('$other')\n");
        }
        print("PasteInto()\n");
}

You simply give it an sfd file to parse and it outputs a script that will reproduce all the references from a given font in another font (using File -> Execute Script...). It does not do any position of referenced glyphs, so I still needed to do the positioning of accents manually

 
0 comments -:- permalink -:- 18:00
Copyright by Matthijs Kooijman - most content WTFPL