söndag 17 april 2016

Boys keep swinging

When running the Swing applicaiton Jaguar, the AmigaGuide reader, I got exceptions due to some missing font stuff.

Light vs. heavy

When opening a Swing GUI, Swing draws all the interface components, buttons, lists, text input strings, etc, on its own. So on each platform, be it Windows, MacOS or AmigaOS, a Swing GUI would look the same. This can be compared to AWT where all the buttons are drawn by the operating system, meaning that an AWT application looks like a Windows application on Windows, and an AmigaOS application on AmigaOS. This should mean that implementing Swing requires less coding for each new platform -- if a platform can draw lines and boxes, it can also draw Swing applications, whereas to support AWT, someone would have to map each AWT button to, in our case, an intuition button. And repeat this for radio buttons, tabs, lists, text input string, etc. Usually Swing components are defined as a lightweight, and AWT componenets are heavyweight.

In GNU Classpath there exists implementations for the Swing stuff for various backends, such as GTK, X and QT. The font exception I got for Swing, is due to the Amiga implementation currently only returning "null" for some of these things. And, since Swing has to draw everything on its own, it also has to know what a font looks like. In the GTK/X/QT implementations this is handled by calling each frameworks native methods for that stuff (this is stuff like how many pixels wide the font is, where the baseline is, etc.). There is however a non-native font implementation in GNU Classpath called OpenTypeFont. This implementation actually reads the entire font file, and calculates the different font metrics in Java -- meaning I don't have to create native calls down to Amiga's font handling stuff (bullet.library, diskfont.library, etc), but instead rely on the Java implementation to read the TrueType fonts we usually have in Fonts:_ttf/.
Now, the OpenTypeFont implementation uses something called MappedByteBuffer's. A MappedByteBuffer is like a normal buffer of bytes, however backed by an actual file. The advantage of a MappedByteBuffer is that we can open a file, map it to memory, and pretend that we've read the entire file into memory, although we actually haven't. When the Java application reads a byte from the buffer, the underlying operating system will make sure that stuff is read from the file. Font files can be pretty large, so that's motivation behind using MappedByteBuffer's in this case -- we don't have to put the entire file in memory.

In order to implement MappedByteBuffer's, the Unix/Linux/Windows implementation uses mmap(), which does exactly what we want -- map a file to memory. There is an AmigaOS 4 equivalent in exec.library, the MMU interface called MapMemory. This is however:

       extremely dangerous to use if you don't know what
       you're doing. And since the virtual addressing architecture is
       not publically documented, you do *NOT* know what you're doing.
       If in doubt, don't use this function, and rely on ExecSG to do the job.


Anyhow, with some helpful pointers from fellow amigans at support.amigaos.net, I've actually gotten some sort of mapped byte buffer implementation in place. I'm currently simply reading the entire file into memory, and then I just reat like an ordinary byte buffer. So I've basically removed all the perks of the MappedByteBuffer. But now atleast the OpenTypeFont implementation happily reads the fonts!
But, of course, this isn't enough. When I run the Jaguar application, a windows do open, but it's oh so empty. I'm not very surprised, since the Swing implementation on Amiga isn't done. One could illustrate it like a painter standing with a brush, eagerly waving in the air, with no paint on the brush, and no canvas in sight.

Either way, I, like the boys, keep swinging.