Hershey Roman Simplex Font - release

Woof - I think it’s done.

https://gist.github.com/1331260

This is a Font class for your Codea programs. It includes a sample main program loop so you can mess with it.

I’ve re-encoded the font data to make it (1) smaller, and (2) less likely to mess with the Codea editor (which currently frowns on data with an umpteen gajillion numbers). I’ve also got rid of some the issues my prior version had, like polluting global variable space. Finally, I’ve reproduced some useful information and links that I should have included with the original.

While this is finally at what I think is a “release” level (ie. code I’m comfortable sharing that won’t make me look like a damn fool, I hope) - it’s by no means “done”. If you can think of useful font activities (I know I want to add “width (and height) of a string”), I am open to suggestions or patches, or you can fork it and go nuts. If I waited to release it until it’s “done” - it’d never get released.

If you enjoy this or find it useful, let me know - I have a ton of other fonts, and the software to convert them pretty easily now. If there’s enough demand, perhaps I’ll just convert them all and put em up on github. (Not gonna do it if nobody cares… this font fulfills my current needs…)

I am a leaf on the wind - watch how I soar!

Thanks to A. V. Hershey, Paul Bourke, Simeon and the other Codea devs, voiceoftreason, and Frank Zappa.

Wow that’s incredible, Bortels. I like your vector fonts more than bitmap fonts :slight_smile:

A quick note from looking at your code:

In setup() you shouldn’t have to call f:init() – it should be called when you do f = Font()

Edit: I would really like to include this code in a future version of Codea, with your permission. Similar to the way the class() function is defined now, as hidden Lua files integrated with every project.

See, I thought that was the case, but when I had it gone before it wasn’t working… but when I remove it now, yup, it’s fine. I must have had some other bug. I’ll update the gist, thanks! I like the vector fonts too, and they’re faster than I had hoped they would be, even on my original iPad version 1.

Here’s a minute mystery for you - sometimes, when I run this, then stop and run it again - no rendering. I get a blank background in the color I chose, but no line drawing. I’m still trying to figure out a reliable way to reproduce the issue, but maybe you’ve seen it…

Side question because I’m too lazy to make a different thread - how often is draw() called? I had thought it was 30 times a second - but it appears it’s “as soon as you finish, we call it again”. I’m thinking here about getting consistent speed between an iPad and an iPad2. It might be nice to do some sort of “maximum frame rate” setting. I guess I could monkey with ElapsedTime and spin, but yuck.

I think with noSmooth() enabled they might even be faster than bitmap fonts (no pixel blending). The no rendering thing is our bug, it seems to be a problem with the graphics state after certain drawing operations. It’s so odd that it never came up in testing yet happens to me as well now.

Draw is called at the default displayLink refresh rate, I believe this is 60 times per second. However it’s possible for drawing to take longer and thus slow the rate. You should be able to use the DeltaTime global to multiply against your movement / physics calculations to ensure consistent speed across devices.

Added this to the FAQ

Nice work, cheers for sharing this, it’s definitiely much nicer with the font data encoded.

Bortels,

Now you belong to the reign of awesomeness!!! ^:)^

Great (unbelievable) job!

Just found a small bug… The stringwidth() function is missing a ‘return x’

nice job!

Small suggestion: color and size should be properties of the font class.

I would expect color to be taken from the current stroke() color. (Which I expect it does, given it uses lines).

You’re right. An ellipse() doesn’t have color as a property, why would font(). I just haven’t got used to the global style properties.

@voiceoftreason - thanks! I had it on the ipad, but it hadn’t got into the gist. (I bounce back and forth a lot, and although it’s bad practice because this sort of bug creeps in, I often just fix things in both places rather than cut-and-paste).

I’ve modified the code since I last posted, optimizing draws by not drawing off-screen characters. I’m also making a kind of marquee scrollable you can use, like a ticker tape crawl, just because it was fun.

One thing that’s not working the way I had wanted was “thicker” - I had been hoping that simply having a bigger strokeWidth would work, but… well, try it, they get funky. I may have to move scaling into the font drawing code itself, and use a rectangle for each segment rather than a line with an endcap. Or something else entirely - I’m very open to suggestions. I’m not super-worried - I think what’s there covers the 95% case, from here on out we’re just tweaking things.

Any preferences on the next font types? I’m thinking something chunky. (It would be marginally more work to just convert em all… I should just bite the bullet and do it)

A couple of tweaks:

I added an optional “size” parameter - it turns out changing size with scaling doesn’t work well past a certain point.

I also optimized the string drawing routing to not draw characters that are clearly offscreen (for regular old horizontal text); the old draw routine is there in case you want it (there are some reasons you may). This speeds some types of things (scrolling text) up immensely.

I also added some demos of different effects (size changing, spinning, smooth scrolling) to the Main as a demo. One of the nice emergent properties of having to recalc everything each frame is that you get certain types of effects (morphing) almost for free, because you have to recalc anyway.

Screenshot: http://t.co/86WiGBSo

It’s gratifying to see people using the font - I’ll add some of the others soon (as seperate files, so you can pick and choose). For the people who have messed with them - any feedback, good or bad? If there are suggestions, I’m open.

On thing I’m thinking of doing is “spritifying” the text - so instead of saying “draw this here”, you’d say “make a text object with these traits”, and you’d just call it’s draw() routine. That may enable the hiding of a lot of setup detail that you can see in the demons in the Main tab now. I’d leave the current interface available, of course.

@Bortels It works a treat, the only issue I had was when scaling the text - because the whole canvas is scaled it cuts off the text at WIDTH pixels. I just used the old draw function as I knew everything was on screen anyway. This may also be because I’m using scale() wrong.

On spritifying the text, I think I prefer the ‘draw this here’ approach and it’s nice that it works basically the same way as drawing lines, ellipses etc. It certainly wouldn’t hurt though if the old interface is still exposed.

scale() in general works poorly for the Hershey fonts; in the new versions of the class, I’ve added an optional “size” parameter that simply multiples the coordinates; that looks a lot better, and the size is taken into account in the width calculations.

I did the “spritifying” thing (called it “labels” to avoid the name collision), and it’s neat - there are big advantages. I’ll have samples up soon - and yes, I would never get rid of the old direct access methods, sometimes you just want to print some text. But if you’re doing a lot of text manipulation, the object framework makes it easier to deal with.

I’m also going to add more fonts; in prep for that, I’ve made a real github repo; it’s not quite 100% done, but you can get the latest code from:

https://github.com/bortels/HersheyCodea

feedback always welcome

Could you outline the steps needed to add a new font? I’m tempted to have a go if it’s easy enough.

Not much - I wrote a quick-and-dirty encoder in perl that takes the font coordinate data and packs it into the text in the library. The only caveat is that some of the other fonts may have coordinates outside my -9 thru 26 range, and so would need different encoding. (the “large” characters are rare - I’m thinking of just having Z be an escape, so 24, 25, 26, 27 might encode as X, Y, Z+26, Z+27 - does that make sense? It’s late here…)

I’ll put up the scripts on github tomorrow if you want to mess with them.

Long term, I’m thinking the font data should be online, and when you instance a font for the first time, it could grab the data (sockets!) and save it (persistent storage). Then we could have a ton of them and not worry about the lua code ballooning.

I’ll put up the scripts on github tomorrow if you want to mess with them.

Yes please.

Ok - turns out there was some hand-massaging. Here’s what I have - go to Paul Bourke’s site (http://paulbourke.net/dataformats/hershey/) and grab hershey.zip (or the japanese one) - that’s his encoding of all 2k+ characters in the roman fonts shown on that page. Also grab the .hmp files you’re interested in - this is the list of which of the characters in the big font file map to ascii 32 thru 127. He did the juicy work - all I did was re-encode, and write a bit of lua wrapper.

Now, laugh at my code:

#!/usr/bin/perl

$f = shift @ARGV || "romans.hmp";

open (I, "hershey");
while (<I> ) { # load font data
   chomp;
   s/^\\s+//g;
   ($k, $v) = split(/\\s+/, $_, 2);
#   $v =~ s/"/\\\"/g;
#   $v =~ s/\\\\/\\\\\\\\/g;
   $H{$k}=$v;
}
close I;

open (I, $f); $m='';
while (<I> ) { # load this font's character list
   chomp;
   $m .= $_ . " ";
}
close I;
$m =~ s/\\s+$//g;
@ma = split(/\\s+/, $m);

$i = 32; @aa=();

while (@ma) { # convert ranges to lists of values (ie. 1-4 becomes 1,2,3,4)
      $r = shift @ma;
   if ($r =~ /\\-/) {
      ($a, $b) = split(/\\-/, $r);
      for $d ($a..$b) { push @aa, $d; }
   }
   else { push @aa, $r; }
}

while (@aa) {
   $r = shift @aa;
   print "\\t$i, [[$H{$r}]],\

";
$i++;
}

That’s it - that takes the font and the .hmp, and squirts out lua. I believe my “big block” font code is just the data from that concatenated into a giant blob (I take it back - I prepended the # of points as a 0-padded decimal, ie. “07” for 7 points), and formatted nicely (which I did by hand).

Crude, but effective. It was a one-off. :slight_smile:

Gah. I take it back. This is an earlier version - it does NOT do the encoding I ended up using. I’ll try to find the real one - it may be on my work computer…