Unicode Complete

Woopsi is now 100% unicode. Except for anything in the “bonus” folder, which I’ll get around to at some point.

I’ve tidied up the WoopsiString, removing redundant methods and sorting out which should be public and which shouldn’t. To cater for iteration, rather than trying to redesign the string, I’ve added a new StringIterator class. The WoopsiString can produce instances of these (in the same way that Gadgets produce instances of the GraphicsPort class) that can iterate over the string. It has some cunning optimisations so that it will always choose the optimal way of moving to a new character index.

On top of that, I’ve moved the FileRequester and associated classes into the main codebase. Lakedaemon pointed out that, unless you use any libfat features, it isn’t included in the final ROM. A quick test revealed that this was indeed the case, so there’s really no reason not to enable libfat in the makefile by default and include the FileRequester in the main library.

I’ve fixed a few problems in the FileRequester. Its background was transparent in places, which was caused by one of the gadgets in its children not having a draw() method. The sorting was broken - I thought I’d fixed this - so although the items were sorted alphabetically, directories were intermingled with files. Lastly, it doesn’t try to draw before the rest of Woopsi has been drawn, a problem which caused some graphical corruption.

The Bmp2Font .NET utility for converting BMP files to Woopsi fonts now creates working Font subclasses. I’ve removed four fonts from Woopsi as they didn’t seem to be converted properly by Jeff’s original process - they either had glyphs with missing sections or the vertical positioning of some of the glyphs was off.


Lakedaemon on 2010-01-13 at 16:32 said:

Nice stuff !

I looked at the code in svn and it looks very good. Thanks ! There are very slight changes, in the string/iterator methods, where things could be sped up just a little bit, I’ll post them in the Forum.

Do you have any idea how long (clockwise) it takes an arm cpu to : 1) divide an integer by an integer ? 2) multiply an integer by an integer ? 3) do a bit rotation ? if 3 is substancially faster than 1 and/or 2, I have come up with a way to (really) speed up the copying of a freetype bitmap with anti-aliasing on. (there is a little penalty memory wise though)

Ant on 2010-01-13 at 18:41 said:

I don’t know, I’m afraid. One of my readers sent me this link:


It’s a book on ARM assembly. It includes a description of the timings, but because of the ARM architecture it appears more complicated than to say “instruction X takes n cycles”.

Jeff was the resident ARM guru.

Lakedaemon on 2010-01-14 at 11:44 said:

Thanks for the link.

The speed of the new optimisations will really depend of the speed of fetching 1 byte in Ram (it’s a balance between that and doing 3 multiplication and 3 divisons ) multiplication take around 4-8 clock cycles and division should take more than 15+…

If there was a way to load and keep 1k or 8k of data in the cpu L1 cache when starting copying freetype bitmaps, those new optimisation would blow the present algorithm out of the water (be like 20/40 times faster).

Lakedaemon on 2010-01-14 at 18:57 said:

I have updated the demo to work with the new iterator class. It looks like there are bugs either : 1) in the string class/iterator class (unlikely but who knows) 2) in the text class (likely) and the wrapping algorithm 3) in the graphicport class :

In my demo, there are weird newlines at odd places. In my app, the stings are either half-displayed or displayed twice, or wrapped strangely.

The recent library changes have fixed the problems I had with the scrolling pannel (yayyy ^^). Sadly, scrolling seems to have become quite a bit slower than it was before (the text are long, is that it ? maybee that’s a good time to see if I can speed up display a bit)

Lakedaemon on 2010-01-14 at 19:42 said:

(It was compiled with revision 1235)

Ant on 2010-01-14 at 23:31 said:

I think that the string problems are actually in the MultiLineTextBox class, but they might be in the Text class, or there might not be a bug at all and the two might not agree on what the data they each store represents. Either way, you’re right. I’ve been trying to track that one down.

Scrolling might be slower now. I went through the scrolling function in the GraphicsPort class and found a whole host of really nasty bugs. I’ll do a whole blogpost on the latest bugfixes at some point. Anyway, I’ve had to rely more on drawing than on copying, which will generally be slower.

Lakedaemon on 2010-01-15 at 13:52 said:

I’ll have a look at the TexT and multilineTextBox Classes (I”l bet on the Text class). Even if I don’t find the bug, it’ll be usefull for later, to be more familiar with it, like.

I forgot to paste the link to the .zip last time, it is at http://www.lakedaemon.org/WeirdBugs.zip Mainly usefull for the update freetypefont.cpp and .h files

Ant on 2010-01-15 at 15:42 said:

Try it with the latest revision and let me know how you get on!

Lakedaemon on 2010-01-16 at 09:54 said:

1) I found a few bugs (notably an important one in the woopsistring class) and reported on them in the forum

2) The last version fixes the scrolling speed issue (thanks !).

It brings back the old “scrolling only redraws part of a freetype rendered line” bug. But I think that this bug comes partly from my code and more specifically from the getLineHeight method in my freetypefont class :

to draw character, woopsy draws rectangles on the a line when Freetype draws rectangles with an y-offset compared to a baseline.

To solve this, the only way is to calculate line height after the wrapping algorithm has done it’s job horizontaly and not compute text height with (constant lineheight)*(number of lines) as the height of the lines will vary depending on the chars it contains.

And the computation of a char height should take into account the y-offset of this char or the getlineheight method should use this y-offset.

It should be done but it isn’t urgent at all… and it should only bring slight changes. (I’ll help with fixing that as it is a necessary step to be able to draw chars with varying fonts in a multilinetext box)

Ant on 2010-01-16 at 11:46 said:

The height that the font should return in getHeight() should be a constant. If I request a font 10px tall, it doesn’t matter that the maximum height of a character in the line is only 5px (because all characters are all vowels, for example) - it should still return 10. This ensures that all of the lines are drawn at regular spacings so you don’t end up with one line taking up twice as much vertical space as another line.

The font’s getCharHeight() method can be overloaded in the subclass, so you are free to implement whatever logic your font needs in there.

The scrolling problem was tricky. The original clipScroll() method in the GraphicsPort class was full of nasty bugs. I tried to fix all of the edge cases that it didn’t cater for, and ended up with a solution that basically just redrew the entire display multiple times, which caused the slowdown you experienced. It would also have fixed the “missing sections” bug. After deciding to start afresh on the function, I realised that all of the edge cases could be fixed without individually coding for them by inverting the order of some of the steps in the function.

As far as I can tell, the scrolling function works properly and might even be slightly faster than it was before I started mucking about.

Lakedaemon on 2010-01-16 at 12:27 said:

I see.

Another solution to my problem would be to parse the font and compute the max and min offset and add it to the bitmap height…and the maximum value I get, should be returned by getHeight()… This was what had been done in the previous app, I was working on.

I’ll start working on that soon, but first I’ve got to find/fix the nasty displaying/offset bug.

If I find more bugs and fixes for them, I’ll keep posting them in the forum (along with the revision number whose Code I’m revieving)

And let me thank you for all your hard work since implementing unicode support is quite demanding on you too. ^^;

Lakedaemon on 2010-01-17 at 09:41 said:

Update : here is the last demo : http://www.lakedaemon.org/Freetype.zip

Look for the Freetype.cpp and freetype.h files, they implement the 256 level of grays antialiased fretype font for woopsi and look like they are ready to go into production (got a stroke of luck and fixed the scrolling bug..it’s working great now).

You can see how to use it in the anki.cpp file.

If you are interrested, it is possible to implement a 1 bit freetype monofont too (just have to set one flag differently and to change the bitmap copy function to work with bits instead of bytes…). If you want it, I”ll code it (it’s interesting because it should be order of magnitude faster than the aniti aliased font).

in freetype.cpp…I implemented 4 different ways to copy the bitmap. it would be interresting to benchmark them and to choose the fastest (maybee) but… I’m not sure if the time it takes to copy is significant compared to the time freetype takes to load a glyph…in which case, we should either choose the “slow” or the “fast” methods (no memory penalty)

I solved the mysterious bug case (see in the forum), but there is still (at least )one weird bug lurking in the woopsi code base. My last demo reproduces this bug in the upper screen (and show that the scrolling pannel works with fretype in the bottom screen).