With this article, I want to introduce you to some interesting facts about the new Icon format that Haiku is using. At first sight, they are just scalable vector icons, and Haiku is not the only operating system to have them. But the interesting bits are in the implementation details which should make Haiku stand out from the rest.
The first unique feature is that Haiku uses a special vector storage format, that has been specifically designed to store icons; we call it the Haiku Vector Icon Format, or HVIF for short. Haiku is not using the SVG format. Support for that is available through SVG import and export features in the Haiku icon editor "Icon-O-Matic". HVIF saves so much space, that icons are typically even smaller than the BeOS bitmap icons, which use 1280 bytes. The average Haiku vector icon uses about 500-700 bytes, with some icons slightly over 1000 bytes and some even below 250 bytes. This means that an icon stored as an attribute of a file will fit in the so-called small data region, which resides within the inode of the file. When Tracker reads information about a file to display it, its name, size, date and also the icon are all read within a single disk operation, when the files inode is fetched. Obviously, this is very beneficial for speed, since the hard disk remains one of the slowest components of a computer. The only performance hit is rendering the icons, which is fast compared to the disk operation. If Haiku were to use SVG icons, we would need at least one extra seek after fetching the inode (as the icon is too big to fit in there), and this would have a severe impact in performance. To put the size of the Haiku icons into perspective, Windows Vista icons can use around 80Kb, as they use PNG images to store an icon at different sizes. SVG icons in ZETA can be stored compressed, and use 2-10 KB.
Another unique feature of the new icon format is that rendering is done in a single pass, touching each pixel only once. Typically, vector shapes are rendered in multiple passes, on top of each other if they overlap. With the Haiku icons, the geometrical information of every shape is collected all at once, solving the problem of visible seams between shapes that can often be observed with traditional multi-pass rendering. This comes through new features in the Anti-Grain Geometry rendering library that Haiku uses already for its on-screen drawing. The way it is done in AGG is also more efficient than multi-pass rendering.
Most of the vector icon code sits in a static library called libicon that is linked into libbe. As of yet, the classes it contains are not intended for widespread usage, as the implementation might still change and improve. But there is a new class available called
BIconUtils, similar to
BTranslationUtils. The purpose of this class is to give unified access to icons, and for loading them into
BBitmaps. It handles old BeOS icons and the new vector icons transparently.
BMimeType have all been adjusted to load and save icons through the
BIconUtils class. There was a lot of code duplication before that too. The vector icons are loaded through the same API that was available before. For example
BNodeInfo::GetIcon(BBitmap* bitmap, icon_size size). The
size argument is unfortunately a bit redundant, since the bitmap, which the caller must preallocate, provides a size anyways. In BeOS, the bitmap size must match the
icon_size given. In Haiku, which icon an application gets, is determined by the colorspace of the provided bitmap. If it is
B_RGBA32 (in which case the bitmap may be of any size with the
icon_size argument being ignored), the vector icon is preferred. If the bitmap is
B_CMAP8, the old BeOS icon is preferred. If only one type of icon is available from a file, it will be put i