Wednesday, November 22, 2006

Resolution independence for icons

Jakub Steiner wrote an interesting blog about woes of creating resolution independent icons. It's a problem I've been thinking about during the last few days, one that has been solved, at least to some extend, already.

It was solved for fonts. Grid-fitting (aka. "font hinting") is a crucial step on the way to produce legible output at small sizes for any font. Hinting can be manual (e.g TrueType has a stack-based language for it, each glyph in the font contains its own little hint program and as a result of running that program control points for the outlines can be adjusted in any way the creator of the hints desired) or automatic (as used by FreeType). An interesting medium is described in "Example-Based Hinting of TrueType Fonts" paper, in which a method of reusing hints from one font for another are described. All in all it's a very common problem for fonts.

The iSlayer blog that Jakub mentioned makes it very clear we need it fast. His example showing how much worse his logo looks in the vector form than the as bitmap looks almost precisely like the "example of hinting" image that can be found on Wikipedia:
(The upper sample in each case is unhinted)
When talking about fonts we're just dealing with a subset of our exact problem.

In Qt, Gunnar just implemented support for non-scaling stroke, which is great. Now we need to figure out a way of doing automatic hinting for vector shapes and we'll be set.

I've always been all for manual adjustment of icons on a pixel-by-pixel basis, simply because they looked a lot better, but during the last few days I've became convinced that we can, in fact, create resolution independent icons. Or let me rephrase, not "resolution independent icons" but "icons that preserve their good looks across resolutions". We have the former, we need the latter.

I'm taking a week off and that's exactly what I'll work now.

I think manual hinting is too cumbersome and we'd need a new container format for icons to make it really work. A way of specifying a whole icon theme along hints for each icon to make them look good across different resolutions wouldn't necessarily be a bad idea. In fact that would be great, it's the problem of developing the way of storing and producing those hints that would be quite challenging. XML format (with some namespace of course) that can be embedded right in the SVG's would probably work fairly well but I'm afraid wouldn't be enough. Then there's also a question of how would we get artists to create those hints.

No, I think auto-hinting makes a lot more sense here. The research FreeType people did in that area is outstanding.

All in all, I think I can make it work =)

Oh, and if you have a SVG icon that you hand-adjusted to produce a better looking bitmap, I'd appreciate a lot if you could send me both examples via email to <my first name>@kde.org address so that I have some testcases to work with :)

16 comments:

Anonymous said...

The funny thing is, I find freetype autohinted fonts completely unreadable, and I much prefer the unhinted version of the font you show -- despite being something of a font and typography maven.

Boudewijn
(Who designed his first fount when he as fifteen)

Zack said...

@Boudewijn: Do you really? The unhinted version is insanly blurry.

Velmont / Odin said...

Boudewijn: I think you should right-click the image and press «view image» to view it in it's full goodness. It's just the blog that really and truly fucks it up. It's using linear resizing - which makes the ugly picture. I didn't know what you talked about before I saw the pic on the site. Normally I only read these posts with an RSS-reader. (that doesn't ruin pictures) :-)

zack: Really, really great! I'm looking forward to this. But what do you mean by hand-tweaked? You mean «made a small raster - then fixed it up in Gimp»? I guess you could find a fair bit on the tango-site.

Anonymous said...

I also prefer the unhinted (top) version of the posted font. I even clicked the image for full size and everything. The bottom font is way too thin, and barely readable.

Anonymous said...

I agree with you Zack, the bottom font is much clearer.

Zack said...

@Velmont / Odin: yeah, that's exactly what I meant :)

@anonymous who says that he/she prefers the unhinted version: this is how that font should look. The fact that you seem to like blurry fonts, doesn't mean that the best way of achieving that is by distorting the original. You have the option of making the font bold, or even changing the font if you don't like it :) Creating artificial distortions is never the right way. So let me say one thing: hinting is never a taste matter, it's a way of making sure the rendering looks like it was supposed to. If you don't like it, then you most likely don't like the original so it doesn't matter.

Daniel "Suslik" D. said...

I bumped into similar line of thoughts while tweaking the BasKet icon before 0.6 release.

http://accentsolution.com/files/basket.png

2 things that I found lacking for good SVG scaling in that case were:
- non-scaling strokes (for outlines)
- and ability to tag and auto turn off layers at lower rez.

The last one is perhaps more usefull than hinting. It seems the original SVG of BasKet was designed to look good at around 32 - 48 pixels. Details (blink, extra shade, more transparency) were added for 64 and up. - All manual labor for people rendering it.

Hinting will not allow increasing, decreasing level of detail.

If I could tag layers like "rez>64px" and have renderer pick it up automatically => profit.

Daniel "Suslik" D. said...

I bumped into similar line of thoughts while tweaking the BasKet icon before 0.6 release.

http://accentsolution.com/files/basket.png

2 things that I found lacking for good SVG scaling in that case were:
- non-scaling strokes (for outlines)
- and ability to tag and auto turn off layers at lower rez.

The last one is perhaps more usefull than hinting. It seems the original SVG of BasKet was designed to look good at around 32 - 48 pixels. Details (blink, extra shade, more transparency) were added for 64 and up. - All manual labor for people rendering it.

Hinting will not allow increasing, decreasing level of detail.

If I could tag layers like "rez>64px" and have renderer pick it up automatically => profit.

Jason said...

I don't get it... Isn't this Smooth PixmapTransform? using a bilinear or bicubic interpolation? Would this be implemented as a IntelligentPixmapTransform render hint?

Still I am eager to see what you trolls can do!

Anonymous said...

Yes... I really mean I prefer the unhinted version. Perhaps it's just that my eyes need more contrast or something: turning the hinting off is the first thing I do.

Another reason I may prefer the unhinted version is that I've got a high-res screen on my laptop-- 130 dpi. Hinting is more valuable on low-res screens, like the 19" 1280x1024 panel I've got on my desktop. But there, everything is too grainy to look good anyway.

Boudewijn

Anonymous said...

Velmont: I did read the blog in Akregator, but I already knew the difference between the four hinting styles KDE has.

Boudewijn

Zack said...

@Boudewijn: I'm not sure if you read my blog carefully but you're confusing two different technologies. Subpixel hinting, which you're referring to is very different from grid-fitting. What grind-fitting does is nicely shown here:
http://www.microsoft.com/typography/TrueTypeHintingWhat.mspx
and what subpixel hinting does is described here:
http://en.wikipedia.org/wiki/Subpixel_rendering
The fact that you tend to turn of the latter is most likely a testiment to the fact that we're not doing it in the best way (e.g. gamma adjustments are done on static gamma value that most likely doesn't match the one of your output device). Grid-fitting (aka. font-hinting) is really a property of the font in this case - if you don't like hinted font it means that you really don't like that font and should just switch to a different one - the font author envisioned it looking like this. Auto-hinting, to do what the author intented, is like i mentioned a hard problem, one that i think is very solvable.

Anonymous said...

That would be a real breakthrough! I don't think that any icon systems out there are rendering low resolution icons hinting for good their looks.
It's promising and will be the final solution for artists hand-breaking-their-balls adjusting pixel-by-pixel something that must be readjusted when the master svg changes.. thanks

Anonymous said...

"The fact that you seem to like blurry fonts, doesn't mean that the best way of achieving that is by distorting the original."
[snippidy snip]
"So let me say one thing: hinting is never a taste matter, it's a way of making sure the rendering looks like it was supposed to."
What? Are you saying that unhinted anti-aliased fonts are distorted versions of what the fonts actually should look like?
It is actually reversed. Hinting generally screws up kerning and the actual look of the font (especially with serif fonts). I guess the easiest way to proof this to print out a font and compare it to the hinted and unhinted version of the font on the display. I think it's pretty clear after comparing that the hinting visibly alters the look of the font.
Also every explanation, guide or introduction of "Hinting" pretty much makes it clear that hinting only exists to make fonts more readable (hence alter) on low res displays and/or low font-sizes. _That_ is the reason to hint a font.

- http://www.microsoft.com/typography/TrueTypeHintingWhy.mspx
"Scaling an unmodified outline's control point co-ordinates to the small sizes of a computer screen can result in severe quality control problems. At low resolutions, with few pixels available to describe the character shapes, features such as stem weights, crossbar widths and serif details can become irregular, inconsistent or even missed completely"

- http://en.wikipedia.org/wiki/Hinting
"At small sizes or without antialiasing, hinting is critical for producing a legible image."

- "Grid-fitting (aka. "font hinting") is a crucial step on the way to produce legible output at small sizes for any font."

OSX's "standard" font smoothing also looks like it's not using hinting at all (so it looks pretty much the same as unhinted antialiased fonts rendered by freetype). I put up this http://www.krof.chatvisual.com/kib/fonts/ (quite) a while ago to show what OSX does to make fonts more readable on colored/dark backgrounds when using the other settings beside standard.

So what now? I have no idea ;)
We would have to look into ways how to antialias differently maybe and check out how OSX does handle fonts rendering. But please don't use weird hinting to get a sharper looking font. People are more and more moving to (even I am and I'm piss poor.. and still on a 17" crt) or are already using high resolution displays and fonts should become less of a problem then. The MS Truetype site is 10 years old now and hinting might not as relevant now as it was when people used 640x and 800x resolutions.

People should just stop using small font sizes. Too small = hard to read. Doesn't matter if it's blurry or not.

...but hey. This is actually about icons, right?

Never mind then ;) ...but still: Hinting = bad :P

Gustavo Sverzut Barbieri said...

Hey Zack, any updates on this?

Anonymous said...

Consider the available mathematical tools.

Modern Font Hinting is about setting horizontal and vertical (rather than arbitrary vector direction) spans that distort differently to the spans next to them, so as to preserve transition points between spans as transition points between pixels.

Put in simpler english, The edges of the centre stem and serifs of the character "I" are quantized to the boundaries between pixels, at the expense of the true dimensions of fairly featureless areas, like whitespace, or the exact area enclosed by the "I".

In a nutshell, that's the only way to preserve the high-frequency components of the image. The Edges.

Look carefully at how an "e" deforms, especially vertically, as you change the font size from 10 to 3 pixels. "E" in most fonts has five major vertical segments, corresponding to the top, bottom, and middle stroke of the "E" and the two zone of whitespace that separate them. As it gets smaller, the serifs dissapear. At six pixels high it makes a choice about which area (top or bottom) to add the extra line of whitespace too. Five pixels high naturally works well. Four pixles high is, of course, the real test of how your font system works. All the same issues apply to "M"s in the horizontal.

This has led to a rather westernized approach for font hinting which often treats the X and Y co-ordinates as totally independant systems. This does make sense when the output is naturally a screen grid, but curved or mostly diagonal lines are often neglected. Many asian glyphs have slightly non-vertical angles and nearby dots that get rendered very badly. Semicolons and slashes suffer this effect too.

And the larger and more complicated the glpyh, the harder the problem to find two independants mappings (for X and Y) which works everywhere. This implies something like the 'morphing' algorithm would be useful, if you can break the image into triangles and then try to quantize the triangles to edges. Of course, this is practically a form of ray-tracing, but modern computers are pretty good at this, especially if you throw a nice and modern spatial partitioning scheme under the whole thing.

Jeremy Lee