Happy New Year!

2007 is going to be a good year: There will be many new things to learn. There will be many opportunities to love somebody. A lot of things wait for you to do them. So long, a happy new year to you all!

Advertisements

Raw Power

I rewrote the java based rasterizer that is used in the X peers of GNU Classpath. Heres some interesting numbers. Rendering a relatively complex shape (actually, the outline of a glyph vector) 250 times takes:

  • ~60ms on JDK1.5
  • ~780 ms on Cacao with the Cairo peers
  • ~350 ms on Cacao with the X peers and the new Rasterizer

Learned lesson: native code is not necessarily faster than java code. The whole rendering pipeline of the X peers is implemented in plain java. X only draws horizontal lines here.

The comparison with the JDK is not necessarily fair but gives an interesting impression what should be possible.

Find the test program here. Yes it is a microbenchmark that highlights one particular case (rendering complex shapes). I will make more interesting and comprehensive benchmarks as soon as I am able to run the Java2D and AWT benchmarks that ship with GNU Classpath.

One Laptop Per Child?

I am reading more and more about that OLPC thingy. I’m asking myself, who needs this? Who has thought out this crap? In my opinion and experience as father, the last thing that a child needs is a laptop (with my definition of a child beeing <= 10 years old).Sorry folks, I don't get this. Here's my opinion on what our children really need:

  • Parents. This does not mean that they have to be the physical parents. ‘Nuff said.
  • Time to learn. Nowadays many parents seem to assume that children must learn early and everything. What is really happening is that they project the pressure that _they_ experience in life (and most likely don’t feel capable to deal with) on their children and think they do something good when the child learns to deal with it early. Sorry, there’s no good here. Overloading children only has the effect that it makes them passive. The first thing you must keep in mind is that children actually _want_ to learn. Let me give an example. I was told many times by my own parents that my son must learn walking (back when he was <1 year old) so I should teach it to him. I said, no, he first must learn how to crawl (is that the right english word?). And he learns walking himself. So, instead of taking him by the hand and pulling him (despite that he simply could not stand for himself) I let him do what he actually can do and learn own his own. And yes, he learned walking completely on his own. No need to push him. After all, this enabled him to experience himself how complicated it is to stand on two legs and to put one foot after the other. And you should have seen him how proud he was: 'Look! I am standing here. And now I am making one step after the other' Wow! What a great experience. Don't take this experience of learning themselves own away from your children!
  • Childhood. No kidding. AFAICS, god (yeah yeah) made the children so that they play. Now what good is it to hammer all kinds of knowledge and abilities into them for what they were not made? Sure, later in life they need alot of this. But you must understand that playing is how children learn living. Their play is very much like our work. In fact, it is real work for them to play. Let the children play and don’t push them in the adult world too early.

On the contrary, I think that children don’t need:

  • Floods of information and media. Personally I have banned TV and radio from our household. The only music that plays is some good records or (better yet) self-made music. We all like to sing. My son is enjoying to play his drumkit (and he’s good at that! wow) as well as singing (loudly. too loudly sometimes 😉 ) and all kinds of music. There’s no asking for TV or radio at all. I can’t stand people who say that children need TV. That’s pure bullshit. My tip if you have hyperactive kids: Throw out the TV and radio. Do it! There’s only shit coming out of it anyway, and you don’t want to load stockpiles of shit on your children, right?
  • Plastic toys. What sensual experience is plastic? None at all. It’s clean, its flat, its boring. The best thing is some real wooden sticks or some earth and water. Nothing expensive. Really. Ok, this means you have to clean the clothes a little more often. In the summer I try to let my son play naked to avoid this problem. I guess he’s coming into an age where that is not an option anymore. That’s life.
  • And certainly, kids don’t need a computer. What good is that? What should they do with that? Learn how to play with an automat? Or, learn calculating or writing with it? Sorry, the computer is by far the worst teacher or playmate that I could think of. There’s really no use for computers for children under 11 years or so. Don’t get me wrong. I DO think that our kids need to learn how to deal with computers. But they need to learn this when it’s time to learn this. When they are adolescent for example.

I can’t hear all that crap that is coming out of the ministries of education, that children have to go to school early (<=5 years) or that children need computers early (<= 5 years). It makes me sad that I get into a situation where I have to go through real efforts because I don't agree with the general opinion. I want to decide how my child grows up and I don't want some minister to decide what's good. I don't want to grow up zombie kids.

Man, I am really upset.

Edge Detection

Last time around we were able to detect edges and link them in order to detect stems and serifs. In the meantime I have made another nice picture of the glyph ‘C’ with its segments:

The last thing we need to do before we can actually hint our glyphs is to detect edges. Edges are sets of 1 or more segments that are positioned (approximately) at the same position. For the vertical direction and the glyph ‘M’ this would look like this (every edge marked with another color):

These edges are then associated with our Blue Zones (where possible). Later we will move these edges around to fit on the grid (rather than moving single points).

Next time it will become interesting: Then we will start the actual grid-fitting process.

Hint!

Let me insert a small break in my series of font lectures to show the latest and greatest screenshots. Just today I got the first hinted text rendered (left without hinting, right with hinting):

Both are rendered using Sun’s Graphics2D impl with anti-aliasing turned on (via Graphics2D.fill(Shape) ). The outcome is quite similar with Cairo though. Unfortunately I haven’t found a rasterizer yet that can render this thing properly without AA. Classpath’s Cairo backend doesn’t support turning off AA right now and Sun’s rasterizer fails to render this nicely without AA, although I’m sure that the outlines are ok now. But Graphis2D.fill(Shape) is not exactly a font renderer though. I haven’t tried the X peers with the Java-only rasterizer yet. I will try this soon though.

Update:

Francis was so kind to quickly implement support for non-AA rendering. Here comes the comparison for rendering hinted text without AA. Left Sun, right Cairo (yes!):

This seems to confirm that the general hinting is mostly ok. The missing curve segments in the e and o are quite certainly to blame to Sun’s rasterizer. However, there are definitely small glitches in the hinting still, visible in the W, r and d glyphs.

Here are some more unsorted screenshots on my way to a hinting implementation:

A little accident:

A little accident

Some glyph outlines with the original (red) and hinted (green) shapes magnified to show the grid-fit:

Again, the ‘e’ glyph, where hinting was a work in progress. I made this screenshot for debugging purposes. Notice how the middle horizontal stem got accidentally collapsed:

While working with this I stumbled over a bug in Classpath’s Cairo peers when trying to render a shape magnified. Is this abstract art? (This should have been the ‘e’ glyph above).

Segments

We finished the global feature analysis last time and now get into the local (outline-specific) feature analysis. As a first step we detect so called segments. A segment is a set of consecutive points that form a approx horizontal or vertical line. The detection of segments is not too complicated. Simply iterate over the points of an outline and find points that have an in or out direction close to one of the major directions (up,down,right,left). The deviation of the angle must not be > arctan(1/12). Then group consecutive points with the same direction into segments.

Where it gets interesting is, when segments get linked to each other. Every segment can have zero or one ‘opposite’ segment. To find these linked segments, we compare each segment with every other segment to see if they are sufficiently close to each other and have a certain overlap in their major direction. The outcome of this is that we can now easily detect stems and serifs. We have a stem segment when s1->link == s2 and s2->link == s1. OTOH, we have a serif segment when s1->link == s2 and s2->link != s1. Look at the following diagram, which shows a typical serif. Segment A is linked to segment B (because that’s closest to A). But Segment B is NOT linked to segment A. So the segment A is forming a serif. The same is true for segment D. OTOH, segment B and C are linked to each other. They are forming a stem. This information is important for the hinting process; serifs and stems have to be rendered at a certain span, and all serifs and stems in a text should be the same width usually.

BTW. This is a good time to give some credits. This hinting implementation has been developed by David Turner and Werner Lemberg of the FreeType project. I am only studying their code, preparing a(nother) paper and doing a presentation about it and adapting it to Java. I have to say that I am really impressed by this work of genius! If this interests you, the original paper has a nice high-level overview.

Stems

Last time we looked at the blue zones. The other characteristic property of Latin fonts are the standard stem widths. Stems are the (basically) horizontal and (basically) vertical lines in a glyph. I.e. the glyph for ‘l’ normally has one vertical stem. In order to render glyphs smoothly, it must be assured that all stems are ‘snapped’ to approximately the same width (normally one pixel; unhinted glyphs tend to show 0 – 2 pixels instead).

So, in order to find out the standard width of the stems, we analyse the glyph for the character ‘o’ which proves to be very reliable for stem width detection. The diagram below shows how this glyph is represented as set of bezier points and control-points that ultimately span up the glyph.

Our algorithm first runs the local feature detection on this outline (explained later) which yields the segments of this glyph. Segments are sets of consecutive points that align approx. horizontally or vertically. The glyph ‘o’ below has 8 segments, each made up of 3 points. The local feature detection also ‘links’ pairs of segments to each other. Two linked segments form a stem. We have 4 stems in the ‘o’ glyph, which are highlighted in the diagram. Now it’s easy to get the standard stem widths, which is the distance between the segments that form the stems of our test glyph ‘o’.

BTW: If you don’t know what I’m talking about. I made two interesting screenshots that show how unhinted text is rendered. Left is without anti-aliasing (horrible) and right is with anti-aliasing (ok-ish but way to blurry). These screenshots are made with Classpath’s Java-only-TrueType implementation rendered with the Cairo backend.