I notice FreeType has a new version out, which has some reasonable changes since a key patent has expired.
|Version 2.3.9, Default
|Version 2.3.9, AutoHinting
|Version 2.4.4, Default
|Version 2.4.4, AutoHinting
|GDI Threshold (Current)
|GDI AA + Gamma
So a few observations: The “Default Hinting” has changed quite a bit for TrueType fonts in the latest version. I think this code is what the expired patent related to, allowing the font-specific hinting data to be used. The “AutoHinting” mode is based on font-independent logic built into FreeType. The Flash renderer uses component based sub-pixel rendering, using RGB components to get finer details. The font also looks a bit “fatter”.
Currently NME uses a single set of bitmaps for the fonts, which must be used for all colours. This means that component based sub-pixel rendering is not really an option. However, it may be possible to sort something out (at the expense of more memory) if the need really arises. But also note, this is counter-productive in landscape mode on mobile devices.
On windows, NME currently uses GDI fonts with a threshold. I like the look of this (I spend most of my time on windows) for the small fonts, but it looks pretty bad on the larger fonts. Particularly note the exactly 1-pixel wide vertical lines in the “H” and the “l”, which I like. The larger fonts look much better with anti-aliasing on. However, windows applies some kind of gamma-correction when rendering fonts, and you get quite a different look for black-on-white and white-on-black. To work around this, I have applied a lookup-table to get a bitmap that will work for both light and dark.
Finally notice the windows flash renderer does not use AA with this swf (although the Mac version did).
In the next version, I will change windows over to use GDI + AA + Gamma. It is possible to use FreeType, but I think the font is slightly less readable at the smaller sizes. What do you think?
Into this mix, I will add another interesting option: The V8 JS engine, running using the NME library in opengl mode. This cross-over mode is actually quite easy to implement because of 3 stars aligning: 1. The NME library has a external interface that uses opaque handles that map very naturally to the v8::Value *. 2. The haxe compiler makes it possible to program JS without losing your mind, and all the existing library code is valid for this target. and 3: The Google V8 JS engine has a clean API that makes it easy to embed (you would almost think they designed it that way – dispite the frugal documentation).
The benchmark I have chosen is the “Pentagonal Rain”, which is nice and stressful for the CPU. You can try for yourself – use the ‘5’ key to switch to this demo.
|Chrome 4.1, JS
|Opera 10.5.3, JS
So as you can see, the V8VM option is actually quite viable as a scripting vm. Since there is a lot in common between neko, v8vm and cpp haxe targets and plugin architectures, it should be relatively straight forward to switch between them.
The JS demo can run on the iPhone. But just because you can do something, it doesn’t not mean you should \- at about 2 FPS on the title screen, I can’t imagine how slow it would run in the Pentagonal Rain demo. And probably not great for your battery either 🙂
There has been some talk about creating flash preloaders for haxe. However, these methods step outside the haxe toolchain and add some additional complication.
I have come up with a reasonably simple method for creating a haxe preloader in haxe, and then linking to a (very almost) unmodified swf generated in haxe using a small neko program to produce a single file. The neko program uses code from the hxformat project, some of which is provided so you can easily recompile the tool.
Since each original haxe swf contains one frame, the resulting code
contains 2 frames. The first frame contains the preloader
which waits for the whole file to load and then locates the
PreloaderBoot class by name. This class runs the appropriate
initialisation code, creating and running the correct “main” class.
For classes that appear in both preloader and the main swf,
flash takes the first one – the one form the preloader. This means
that both classes will have the same “flash.Lib.current” and
(almost) everything will just work.
One complication comes from the fact that the flash.Boot class
is given a unique name for each of the swfs. This means flash.Boot
class in the main swf is not automatically “new”ed and placed
on the stage, and the standard haxe initialisation code is not
run. To compensate, we manually set the trace function and
call the Boot initialisation code explicitly.
This sounds a little dodgy to me, but it seems to work – I will
have to do some more testing.
The “Main” class in the example zip contains a resource to pad it out. The preloaded swf can be seen on it’s own screen. You can refresh to see it loading.
The example code is in
All code & data there is public domain, except for the hxformat code,
which has its own license. Use at your own risk.