From BlenderWiki

Jump to: navigation, search

The current system for rendering interface text in blender has some limitations, see Design documents/Text Rendering, the following is my proposal to deal with some of these. sheep 15:58, 1 August 2007 (CEST)

Current Patch

The current patch is here, there are plenty of problems with it at the moment though.

Proposal

  • Eliminate all direct use of the BMF_Font (Bitmap) API.
    • Reroute all font drawing through the BIF_ API, which handles translation, and choosing between different modes of font drawing.

This consists of a considerable amount of work for most spacetypes since spaces such as the Oops and Text Editor are drawn entirely with 2D openGL functions.

  • patch 6787 converts the Oops space to use the BIF_ API.
  • patch 6795 converts the Ipo space to use the BIF_ API.



  • Improve the BIF API so that instead of being called with a *BMF_Font as an argument, (which is primarily used to control the size of the text drawn in bitmap mode) a size argument is passed. This would have the additional benefit of propagating relative size changes across all fonts. At the moment the font size changes in some screens with bitmap fonts, but is fixed with pixmap and texture fonts.
  • Use the hinting functionality of the freetype library to make the anti-aliased fonts more readable.
    Hinting aligns the stems of letters like 'm' to pixel boundaries, reducing the blurriness of fonts.
    • this may require adjustments to the freetype lib shipped with blender


  • Implement sub-pixel hinting functionality using the freetype library.
    • Requires the font drawing API to know both the text colour and the background colour.
      • In order to get the background colour, the GLReadPixels functions are far too slow: so a single colour must be passed to the API.
      • Modification of BIF_Drawstring, and all places where it is called, including probable problems in deciding what background colour to use in places like the 3D view.
    • Requires either a solid background colour for a text string, or a solid outline, which would ideally be blurred.
    • This means that the textures used must be 24bit RGBA, and require a significant amount of preprocessing, alterations are required to bFTGL:
    1. The blurred outline must be applied to whole strings, not single characters, since the spaces between characters is often a single pixel (or less!) at small font sizes:
      This requires modifications to the way that bFTGL draws fonts: the low level drawing (with the freetype library) must be done at the level of FTGLFont rather than FTGLGlyph.
    2. Since these RGBA textures could be quite slow to render, a caching system might be needed, noting that:
      1. The textures are no longer colour-independent alpha, so the colour of the string matters when caching, (as does font size, and font).
      2. The textures can be very large for large font sizes, but may contain large areas of empty space, some form of compression may be desirable.
      3. The textures should be generated and stored in the format that is easiest to upload to the graphics hardware. This is system dependant, and may involve a different colour component order, or component size.
    3. If a caching system is implemented, a cacheString(...) interface should be provided, ideally the cache would be thread safe.


  • Implement per-call font override, in the BIF_ API, so that Font Previews can be provided.
    • Something along the lines of BIF_DrawSingleString(string, font_path, size, forecolour, backcolour, flags)
    • If the cache is designed to be thread-safe, then a thread could cache the strings that might be needed to draw a font preview menu or list in the background, vastly improving performance over the font menus in many other applications.
  • Ideally the last goal is to trim out the unnecessary font drawing API and userpreferences, and to provide a new language and font userpreference interface, with a font-preview panel that can be reused wherever a font choice is required.

Details

Freetype Library Issues

More recent version & LCD hinting disbled on default build

OpenGL Issues

are there issues with textured fonts on some platforms? If so, how can they be dealt with


I've found a nice script for testing the upload to the graphics card in various pixel formats ( pixel_transfer_test.c original), and modified and improved it a little, improved version. Its a useful utility for finding the best combinations of pixel formats and types for different setups.

Sub-Pixel Rendering

This is now largely completed, or at least in a working: Each glyph is rendered into a larger, 3 bytes per pixel bitmap, the larger bitmap is then processed, before being displayed by either a FTGLPixmapFont, or FTGLTextureFont. The processing consists of creating an alpha channel based on the red green and blue channels, and then blurring the alpha channel, applying gain to the alpha channel, and then recombining everything into a 24 bit RGBA bitmap (in the recombining step the bitmap is also colored based on the foreground and background colours).


The alpha channel is blurred because this creates a border of background color around the text, which allows the text to be rendered onto a transparent background, where the exact background color is not known - so normally subpixel rendering could not be used. (subpixel rendering requires both the foreground and background colours to be available).


Enough of the details, screenshots:

Dev-Text Rendering-preview screenshot 1

Dev-Text Rendering-preview screenshot 0

Cache System

threadsafe?

As of recent versions of freetype (2.?+) the freetype library is completely threadsafe. The version of freetype currently built into blender for windows is 2.17, Linux uses the system freetype installation? Check mac too.

The current state of my caching system. sheep 10:01, 4 July 2007 (CEST)

The cache is a static member of the base, FTGLCachingFont, class. Whenever the render function of each derived class is called to render a string, the derived font asks for a bitmap of the string from its base class. If the image for that string already exists in the cache (at the right font face, size and colours) then that image will be drawn, instead of calling FreeType to recreate it.

The cache is a std::map indexed using the FTGLCacheKey class, which is designed to be fast to compare, which should make cache look-ups nice and fast. Currently FTGLCacheKey uses a simple type of checksum on the string which it represents - this leads to quite a few cache collisions.