December 31, 2006 Leave a comment
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!
My universe and all the rest
December 30, 2006 1 Comment
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:
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.
December 21, 2006 11 Comments
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:
On the contrary, I think that children don’t need:
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.
December 17, 2006 Leave a comment
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.
December 16, 2006 Leave a comment
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.
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:
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).
December 14, 2006 1 Comment
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.
December 14, 2006 Leave a comment
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.