Dev:2.4/Source/UI/Text Rendering

提供: wiki
移動先: 案内検索

Some Terminology

APIs that are referred to by their prefixes:

BMF_...
FTF_...
FTGL_...
BIF_...

The uses of these, and the relationships between them are the subject of this document, but it probably makes this more readable if you know that these are all used for drawing fonts in one way or another, and all of them have one (or more!) DrawString(...) functions.

Current Specification

Overview

Interface text rendering in Blender is currently achieved through a series of APIs using the FreeType library at the lowest level, as shown by the callgraph.

The callgraph is for a cvs build circa 2.44 The untidy calls from ui_draw_but_tip() (red block, second line) are resolved by patch 6770, after this patch all of the translatable interface text rendering is all achieved through the dark blue functions on the third row.

There is some a lot of non-translatable text however - see below - that is still drawn directly using the bitmap functions.

cachgrind callgraph for BIF_Drawstring (draws translatable text)
Class diagram of fonts in the FTGL library
cachgrind callgraph for FT_Render_Glyph



Summary

The relationships can be summarised:

Structure of the current text rendering system
  • Bitmap text rendering using internal fonts.
    • This is the BMF_Font API, which can only use the bitmap fonts (of various sizes) built into blender at compile time, the actual font drawing is done using 2D OpenGL functions.
  • Pixmap text rendering using external fonts.
    • Provided by FTGL (a modified version of, compiled into Blender)
    • Pixmap fonts are drawn using OpenGL's 2D drawing functions, which makes them very slow on most systems.
  • Texture text rendering using external fonts.
    • Also provided by FTGL, the choice between Pixmap or texture font is made by the BFFont_TTFont layer.
    • Texture fonts are fully 3D OpenGL entities, they are also very fast.
  • Translation of strings as they are drawn.
    Using the GNUGetText library.




2D and 3D Coordinate systems

When calling BIF_DrawString(), the string may be drawn in either Bitmap, pixmap, or texture modes, depending on the current settings. This means that any function that draws text must first set up both the 2D openGL coordinates, and a correct openGL transformation matrix before drawing.

2D

The BMF_ and FTGL pixmap fonts both render strings starting from the current openGL raster position, (set with glRasterPos2f(float, float); and family).

The funtion BIF_RasterPos(float x, float y); does not set an offset for the raster fonts, but only for the 3D texture fonts, See below.

The Pixmap fonts are drawn at the resolution at which they are loaded by FTGL, which can be set with a call to BIF_SetScale(float aspect). This function calls FTF_SetScale(float s), which indirectly results in a series of calls to the FTGL functions that change the resolution of the font glyph images that are loaded. This has the same effect on the glyph images used by the 3D fonts.

The scale of the Bitmap fonts is determined by the particular font face (struct BMF_Font*) that is passed as the first argument to BIF_DrawString(...). At the moment three different built-in fonts are used for different sizes, and are available through the Global struct:

typedef struct Global {
...
	/* fonts, allocated global data */
	struct BMF_Font *font, *fonts, *fontss;
...
} Global;

Their values are set as:

	G.font= BMF_GetFont(BMF_kHelvetica12);
	G.fonts= BMF_GetFont(BMF_kHelvetica10);
	G.fontss= BMF_GetFont(BMF_kHelveticaBold8);

3D

FTGL draws text strings in texture mode starting at the origin, and then moves in the positive x direction at one texel per pixel.

The funtion BIF_RasterPos(float x, float y); sets an additional x and y offset for the texture fonts, it effectively results in a call to glTranslatef(x, y, 0) before the drawing of each string. This is useful, because since the raster position is transformed by openGL just like a 3D vertex coordinate, provided the matrices are left unchanged between calls, a call to BIF_RasterPos has the same effect for texture fonts that a call to glRasterPos has for bitmap and pixmap fonts.

The function BIF_SetScale(float aspect) that is used to select the resolution of the fonts also sets a scaling factor for texture fonts in order to assure that the text is drawn at one texel per pixel. The calls that result are essentially:

FTF_SetScale(float s) ->
FTF_TTFont::SetScale(float s) ->
... ->
glscalef(fsize, fsize , 1)

This compensates for the increased resolution of the glyph images being drawn into the textures see 2D section.

Setting up for drawing fonts

In order for fonts drawn by BIF_DrawString to work (ie appear in the same place and at the same scale), the following is a rough guide to the calls that should be made. TODO: add more detail here

  • Setting up a matrix for drawing 3D fonts

TODO: this section

    • The offset of the transformation matrix is not important - since any call to set the openGl raster position is subject to the same matrix as vertices. However, BIF_RasterPos() must be called with the same coordinates as glRasterPos().
    • The scale ?
uiPanelPush(block); // push matrix onto the stack
...
uiPanelPop(block); // restore previous matrix
glRasterPos
BIF_Rasterpos

the function void ui_rasterpos_safe(float x, float y, float aspect); essentially calls both of the above, setting up the 2D raster position for bitmap/pixmap fonts, and the BIF_Rasterpos offset for the 3D fonts

Current Limitations

  • Only a single font can be used at any time.
    • Font previews in menus are impossible
    • The same font must be used for the whole interface
  • There is poor support for anti-aliasing, making blenders fonts particularly ugly:
    • Hinting is currently turned off.
    • There is no support for sub pixel hinting.
  • There is a large amount of redundancy in interfaces and ways of doing things:
    • There are three different ways of rendering fonts.
    • The bitmap font is still used when in international mode for views other than the buttons or nodes.
    This includes the 3DView, file browsers, Text Editor and many others; the strings in these windows can not be translated, ugly aliased fonts are always used.
  • Restricted range of font sizes.
    As panels are scaled, the font size is picked from one of three distinct sizes, and three fonts are loaded at any time.