It is a software library that can be used by all kinds of
+ applications to access the contents of font files. Most notably, it
+ supports the following ‘features’:
+
+
+
+
It provides a uniform interface to access font files. It
+ supports both bitmap and scalable formats, including TrueType,
+ OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF, and
+ others.
+
+
+
+
It supports high-speed anti-aliased glyph bitmap generation
+ with 256 gray levels.
+
+
+
+
It is extremely modular, each font format being supported by a
+ specific module. A build of the library can be tailored to
+ support only the formats you need, thus reducing code size (a
+ minimal anti-aliasing build of FreeType can be less than 30KB)
+
+
+
+
+
+
+
+ What can I do with FreeType 2?
+
+
+
FreeType 2 is already used in many products. For example, it
+ serves as a font rendering engine
+
+
+
+ in graphics subsystem and libraries to display text
+
+
+ in text layout and pagination services to measure and eventually
+ render text
+
+
+ in font inspection and conversion tools
+
+
+
+
Generally speaking, the library allows you to access and manage
+ the contents of font files in a very easy way.
+
+
+
+
+
+ What can I not do with FreeType 2?
+
+
+
FreeType 2 doesn't try to perform a number of sophisticated
+ things, because it focuses on being an excellent font
+ service.
+
+
This means that the following features are not supported directly
+ by the library, even though they can be more or less implemented on
+ top of it, or by using it:
+
+
+
+
rendering glyphs to arbitrary surfaces
+ FreeType 2 doesn't try to be a graphics library and thus only
+ supports two pixel formats when rendering glyphs: monochrome 1-bit
+ bitmaps, or 8-bit gray-level pixmaps.
+
+
If you need to draw glyphs to other kinds of surfaces (for
+ example, a 24-bit RGB pixmap), you need to use your favorite
+ graphics library to do just that.
+
+
Note however that in the case of rendering scalable glyph
+ outlines to anti-aliased pixmaps, an application can also provide
+ its own rendering callback in order to draw or compose directly
+ the anti-aliased glyph on any target surface.
+
+
+
+
glyph caching
+ Each time you request a glyph image from a font, FreeType 2
+ does it by parsing the relevant portion of the font file or font
+ stream and interpreting it according to its font format. This can
+ be very slow for certain formats, including scalable ones like
+ TrueType or Type 1.
+
+
Any decent text-rendering sub-system must thus be capable of
+ caching glyph data in order to reach appropriate rendering
+ speed.
+
+
Note that we provide a caching sub-system with
+ FreeType 2 since version 2.0.1 which has become quite stable
+ at the time of this writing (version 2.2.1). However, it might
+ not suit your needs.
+
+
+
+
text layout
+ The library doesn't support text layout operations. Sophisticated
+ features like glyph substitution, positioning (kerning),
+ justification, bi-directional ordering, etc.m are not part of a
+ font service in itself. They must be handled one level
+ higher.
+
+
+
+
+
+
+
+ How portable is FreeType 2?
+
+
+
The FreeType 2 source code is extremely portable for the
+ following reasons:
+
+
+
+
Everything is written in standard ANSI C.
+
+
+
We are very pedantic to avoid any kinds of compiler warnings.
+ The current source code has been compiled with many compilers
+ without producing a single warning.
+
+
+
The library doesn't use any static writable data at all, making
+ it an ideal choice on various embedded systems (e.g., it can be
+ run from ROM directly). It is completely thread-safe too.
+
+
+
+
We have made great efforts to ensure that the library is efficient,
+ compact, and customizable.
+
+
+
+
+
+ What are the differences between FreeType 1.x and
+ FreeType 2?
+
+
+
The biggest differences are as follows.
+
+
+
+
FreeType 1 only supports the TrueType format, while
+ FreeType 2 supports a lot more.
+
+
+
+
The FreeType 2 API is simpler as well as more powerful
+ than the FreeType 1 API.
+
+
+
+
FreeType 1 includes an extension to support OpenType text
+ layout processing. This support hasn't become part of
+ FreeType 2; a much improved version is now part of the Pango library.
+
+
+
+
+
+
+
+ Is FreeType 2 backwards compatible with FreeType 1.x?
+
+
+
Short answer: No. However, transition from 1.x to 2 should be
+ rather straightforward.
+
+
The FreeType 2 API is a lot simpler than the one in 1.x
+ while being much more powerful. We thus encourage you to adapt your
+ source code to it as this should not involve much work.
+
+
+
+
+
+ Can I use FreeType 2 to edit fonts or create new ones?
+
+
+
No. The library has been specifically designed to read
+ font files with small code size and very low memory usage.
+
+
A good, freely available font editor is FontForge.
The library can be compiled in various ways, and detailed
+ documentation is available in documentation directory of the
+ FreeType 2 source tree.
+
+
For compilation on the command line, GNU make is necessary; other
+ build tools won't work. The source bundle also comes with project
+ files for some graphical IDEs like Visual C; note, however, that those
+ files are sometimes not up to date since it is contributed code not
+ used by the core developers.
+
+
+
+
+
+ How do I configure my build of the library?
+
+
+
This is fully described in the file CUSTOMIZATION in
+ FreeType's documentation directory. Basically, you have to edit the
+ header file ftoption.h for compile-time options and to select
+ the modules with the file modules.cfg. Finally, it is
+ possible to replace the standard system interface (dealing with memory
+ allocation and stream I/O) with a custom one.
+
+
+
+
+
+ Why does FreeType render differently on different platforms?
+
+
+
Different distributions compile FreeType with different options.
+ The developer version of a distribution's FreeType package, which is
+ needed to compile your program against FreeType, includes the file
+ ftoption.h. Compare each platform's copy of
+ ftoption.h to find the differences.
Please note that the name of auto-hinter module is
+ autofit, which is a reimplementation of the old autohint
+ module.
+
+
A rather complete description of the hinting algorithm (which is
+ slightly out of date regarding the internal structures) can be found
+ in the TUG-boat article Real-Time
+ Grid Fitting of Typographic Outlines.
+
+
The auto-hinter performs grid-fitting on scalable font formats that
+ use Bézier outlines as their primary glyph image format (this
+ means nearly all scalable font formats today). If a given font driver
+ doesn't provide its own hinter, the auto-hinter is used by default.
+ If a format-specific hinter is provided, it is still possible to use
+ the auto-hinter using the FT_LOAD_FORCE_AUTOHINT bit flag
+ when calling FT_Load_Glyph().
+
+
Currently, the auto-hinter doesn't use external hints to do its
+ job, as it automatically computes global metrics (when it
+ ‘opens’ a font for the first time) and glyph
+ ‘hints’ from their outline.
+
+
+
+
+
+ Why doesn't the auto-hinter work well with my script?
+
+
+
The auto-hinter was first designed to manage and hint Latin-based
+ fonts, as they consist of most of the fonts available today. It now
+ supports Asian fonts, but not other complex scripts like Arabic.
+
+
Hinting various scripts isn't really more difficult than Latin,
+ just different, with a set of different constraints, which must be
+ hard-coded into the autofit module. Volunteers welcome!
+ Can I use FreeType to draw text on a pixmap with arbitrary depth?
+
+
+
Not directly, as FreeType is a font library, not a general-purpose
+ graphics library or text rendering service. However, note that the
+ anti-aliased renderer allows you to convert a vectorial glyph outline
+ into a list of ‘spans’ (i.e., horizontal pixel segments
+ with the same coverage) that can be rendered through user-provided
+ callbacks.
+
+
By providing the appropriate span callback, you can render
+ anti-aliased text to any kind of surface. You can also use any
+ colour, fill pattern or fill image if you want to. This process is
+ called direct rendering.
Note that direct rendering is not available with
+ monochrome output, as the current renderer uses a two-pass algorithm
+ to generate glyphs with correct drop-out control.
+
+
+
+
+
+ How can I set the colour of text rendered by FreeType?
+
+
+
Basically, you can't do that, because FreeType is simply a font
+ library. In general, you need to use your favorite graphics library
+ to draw the FreeType glyphs with the appropriate colour.
+
+
Note that for anti-aliased glyphs, you can ‘set the
+ colour’ by using direct rendering as described in this answer.
+
+
+
+
+
+ I set the pixel size to 8×8, but the resulting glyphs are
+ larger (or smaller) than that. Why?
+
+
+
A lot of people have difficulties to understand this topic, because
+ they think of glyphs as fixed-width or fixed-height
+ ‘cells’, like those of fonts used in terminals/consoles.
+ This assumption is not valid with most ‘modern’ font
+ formats, even for bitmapped-based ones like PCF or
+ BDF.
+
+
Be aware that the character size that is set either
+ through FT_Set_Char_Size() or FT_Set_Pixel_Sizes()
+ isn't directly related to the dimension of the generated glyph
+ bitmaps!
+
+
Rather, the character size is indeed the size of an abstract
+ square, called the EM, used by typographers to design
+ fonts. Scaling two distinct fonts to the same character size, be it
+ expressed in points or pixels, generally results in bitmaps with
+ distinct dimensions!
+
+
Note that historically, the EM corresponded to the width of a
+ capital ‘M’ in Latin typefaces. However, later
+ improvements in typography led to designs that greatly deviate from
+ this rule. Today, it is not possible to connect the EM size to a
+ specific font ‘feature’ in a reliable way.
+
+
+
+
+
+ How can I compute the bounding box of a text string without loading
+ its glyphs before?
+
+
+
This is not possible in general. Reason is that hinting distorts
+ the glyph shape for optimal rasterization, and this process sometimes
+ creates outlines which have considerably different metrics. The
+ TrueType format provides the (optional) ‘hdmx’ table which
+ contains device horizontal metrics for selected pixel sizes, but even
+ here the vertical metrics are missing.
+
+
It is probably best to use both a glyph and a metrics cache to
+ avoid recomputation.
+
+
+
+
+
+ Which anti-aliasing algorithm is used by FreeType 2?
+
+
+
The algorithm has been specifically designed for FreeType. It is
+ based on ideas that were originally found in the implementation of the
+ libArt graphics library to
+ compute the exact pixel coverage of a vector image with no
+ sub-sampling and filtering.
+
+
However, these two implementations are radically distinct and use
+ vastly different models. The FreeType 2 renderer is optimized
+ specifically for rendering small complex shapes, like glyphs, at very
+ high speed while using very few memory. On the other hand, libArt has
+ been designed for general shape and polygon processing, especially
+ large ones.
+
+
The FreeType 2 anti-aliasing renderer is indeed
+ faster than the monochrome renderer for small character sizes
+ (typically <20 pixels). The reason is that the monochrome
+ renderer must perform two passes on the outline in order to perform
+ drop-out control according to the TrueType specification.
+
+
+
+
+
+ When will FreeType 2 support OpenType?
+
+
+
Well, the engine already reads OpenType/CFF files perfectly. What
+ it doesn't do is handling ‘OpenType Layout’ tables.
+
+
FreeType 1 comes with a set of extensions that are used to
+ load and manage OpenType Layout tables. It even has a demonstration
+ program named ftstrtto to show its capabilities. However,
+ this code is no longer maintained, and we strongly advise to not use
+ it.
+
+
For FreeType 2, we have decided that the layout operations
+ provided through these tables are better placed in a specific
+ text-layout library like Pango.
The character images are called glyphs. A
+ single character can have several distinct images,
+ i.e. several glyphs, depending on script, usage or
+ context. Several characters can also take a single glyph
+ (good examples are Roman ligatures like ‘fi’
+ and ‘fl’ which can be represented by a single
+ glyph). The relationship between characters and glyphs
+ can be very complex but won't be discussed in this
+ document. Moreover, some formats use more or less
+ complicated schemes to store and access glyphs. For the
+ sake of clarity, we only retain the following notions when
+ working with FreeType:
-
-
-
+
+
+
A font file contains a set of glyphs; each one can be
+ stored as a bitmap, a vector representation, or any
+ other scheme (most scalable formats use a combination
+ of mathematical representation and control
+ data/programs). These glyphs can be stored in any
+ order in the font file, and are typically accessed
+ through a simple glyph index.
+
+
+
The font file contains one or more tables, called
+ character maps (also called
+ ‘charmaps’ or ‘cmaps’ for
+ short), which are used to convert character codes for
+ a given encoding (e.g. ASCII, Unicode, DBCS, Big5,
+ etc.) into glyph indices relative to the font file. A
+ single font face may contain several charmaps. For
+ example, many TrueType fonts contain an Apple-specific
+ charmap as well as a Unicode charmap, which makes them
+ usable on both Mac and Windows platforms.
+
+
+
+
+
3. Character and font metrics
+
+
Each glyph image is associated with various metrics which
+ describe how to place and manage it when rendering text;
+ see section III for more.
+ Metrics relate to glyph placement, cursor advances as well
+ as text layout. They are extremely important to compute
+ the flow of text when rendering a string of text.
+
+
Each scalable format also contains some global metrics,
+ expressed in notional (i.e. font) units, to describe some
+ properties of all glyphs in the same face. Examples for
+ global metrics are the maximum glyph bounding box, the
+ ascender, descender, and text height of the font.
+
+
Non-scalable formats contain metrics also. However, they
+ only apply to a set of given character dimensions and
+ resolutions, and are usually expressed in pixels then.
The outline as stored in a font file is called the
+ ‘master’ outline, as its points coordinates
+ are expressed in font units. Before it can be converted
+ into a bitmap, it must be scaled to a given size and
+ resolution. This is done with a very simple
+ transformation, but always creates undesirable artifacts,
+ in particular stems of different widths or heights in
+ letters like ‘E’ or ‘H’.
-
-
-
+
As a consequence, proper glyph rendering needs the scaled
+ points to be aligned along the target device pixel grid,
+ through an operation called grid-fitting (often
+ called hinting). One of its main purposes is to
+ ensure that important widths and heights are respected
+ throughout the whole font (for example, it is very often
+ desirable that the ‘I’ and the ‘T’
+ have their central vertical line of the same pixel width),
+ as well as to manage features like stems and overshoots,
+ which can cause problems at small pixel sizes.
+
+
There are several ways to perform grid-fitting properly;
+ most scalable formats associate some control data or
+ programs with each glyph outline. Here is an
+ overview:
+
+
+
+
explicit grid-fitting
+
+
The TrueType format defines a stack-based virtual
+ machine, for which programs can be written with the
+ help of more than 200 opcodes (most of them
+ relating to geometrical operations). Each glyph is
+ thus made of both an outline and a control program to
+ perform the actual grid-fitting in the way defined by
+ the font designer.
+
+
+
implicit grid-fitting (also called hinting)
+
+
The Type 1 and CFF formats take a much simpler
+ approach: Each glyph is made of an outline as well as
+ several pieces called hints which are used to
+ describe some important features of the glyph, like
+ the presence of stems, some width regularities, and
+ the like. There aren't a lot of hint types, and it is
+ up to the final renderer to interpret the hints in
+ order to produce a fitted outline.
+
+
+
automatic grid-fitting
+
+
Some formats include no control information with each
+ glyph outline, apart from font metrics like the
+ advance width and height. It is then up to the
+ renderer to ‘guess’ the more interesting
+ features of the outline in order to perform some
+ decent grid-fitting.
+
+
+
+
The following table summarizes the pros and cons of each
+ scheme.
+
+
+
+
+
+ grid-fitting scheme
+
+
+ advantages
+
+
+ disadvantages
+
+
+
+
+
+
+
+
explicit
+
+
+
+
Quality. Excellent results at small sizes
+ are possible. This is very important for screen
+ display.
+
+
Consistency. All renderers produce the
+ same glyph bitmaps (at least in theory).
+
+
+
+
Speed. Interpreting bytecode can be slow
+ if the glyph programs are complex.
+
+
Size. Glyph programs can be long.
+
+
Technical difficulty. It is extremely
+ difficult to write good hinting programs. Very
+ few tools available.
+
+
+
+
+
implicit
+
+
+
+
Size. Hints are usually much smaller than
+ explicit glyph programs.
+
+
Speed. Grid-fitting is usually a fast
+ process.
+
+
+
+
Quality. Often questionable at small
+ sizes. Better with anti-aliasing though.
+
+
Inconsistency. Results can vary between
+ different renderers, or even distinct versions of
+ the same engine.
+
+
+
+
+
+
automatic
+
+
+
+
Size. No need for control information,
+ resulting in smaller font files.
+
+
Speed. Depends on the grid-fitting
+ algorithm. Usually faster than explicit
+ grid-fitting.
+
+
+
+
Quality. Often questionable at small
+ sizes. Better with anti-aliasing though.
+
+
Speed. Depends on the grid-fitting
+ algorithm.
+
+
Inconsistency. Results can vary between
+ different renderers, or even distinct versions
+ of the same engine.
The baseline is an imaginary line that is used to
+ ‘guide’ glyphs when rendering text. It can be
+ horizontal (e.g. Latin, Cyrillic, Arabic, etc.) or
+ vertical (e.g. Chinese, Japanese, Mongolian, etc.).
+ Moreover, to render text, a virtual point, located on the
+ baseline, called the pen position
+ or origin, is used to locate glyphs.
+
+
Each layout uses a different convention for glyph
+ placement:
+
+
+
+
With horizontal layout, glyphs simply
+ ‘rest’ on the baseline. Text is rendered
+ by incrementing the pen position, either to the right
+ or to the left.
+
+
The distance between two successive pen positions is
+ glyph-specific and is called the advance
+ width. Note that its value is always
+ positive, even for right-to-left oriented scripts like
+ Arabic. This introduces some differences in the way
+ text is rendered.
+
+
The pen position is always placed on the
+ baseline.
+
+
+
+
+
+
+
With a vertical layout, glyphs are centered around
+ the baseline:
+
+
+
+
+
+
+
+
+
2. Typographic metrics and bounding
+ boxes
+
+
A various number of face metrics are defined for all
+ glyphs in a given font.
+
+
+
+
Ascent
+
+
The distance from the baseline to the highest or
+ upper grid coordinate used to place an outline point.
+ It is a positive value, due to the grid's orientation
+ with the Y axis upwards.
+
+
+
Descent
+
+
The distance from the baseline to the lowest grid
+ coordinate used to place an outline point. In
+ FreeType, this is a negative value, due to the grid's
+ orientation. Note that in some font formats this is a
+ positive value.
+
+
+
Linegap
+
+
The distance that must be placed between two lines of
+ text. The baseline-to-baseline distance should be
+ computed as
+
+
+ linespace = ascent - descent + linegap
+
+
+
if you use the typographic values.
+
+
+
+
Other, simpler metrics are:
+
+
+
+
Bounding box
+
+
This is an imaginary box that encloses all glyphs
+ from the font, usually as tightly as possible. It is
+ represented by four parameters,
+ namely xMin, yMin, xMax,
+ and yMax, that can be computed for any
+ outline. Their values can be in font units if
+ measured in the original outline, or in integer (or
+ fractional) pixel units when measured on scaled
+ outlines.
+
+
A common shorthand for the bounding box is
+ ‘bbox’.
+
+
+
Internal leading
+
+
This concept comes directly from the world of traditional
+ typography. It represents the amount of space within the
+ leading which is reserved for glyph features
+ that lay outside of the EM square (like accentuation).
+ It usually can be computed as
+
+
+ internal leading = ascent - descent - EM_size
+
+
+
+
External leading
+
+
This is another name for the line gap.
+
+
+
+
+
3. Bearings and Advances
+
+
Each glyph has also distances called bearings and
+ advances. The actual values depend on the
+ layout, as the same glyph can be used to render text
+ either horizontally or vertically:
+
+
+
+
Left side bearing
+
+
The horizontal distance from the current pen position
+ to the glyph's left bbox edge. It is positive for
+ horizontal layouts, and in most cases negative for
+ vertical ones.
+
+
In the FreeType API, this is also called
+ bearingX. Another shorthand is
+ ‘lsb’.
+
+
+
Top side bearing
+
+
The vertical distance from the baseline to the top of
+ the glyph's bbox. It is usually positive for
+ horizontal layouts, and negative for vertical
+ ones.
+
+
In the FreeType API, this is also called
+ bearingY.
+
+
+
Advance width
+
+
The horizontal distance to increment (for
+ left-to-right writing) or decrement (for right-to-left
+ writing) the pen position after a glyph has been
+ rendered when processing text. It is always positive
+ for horizontal layouts, and zero for vertical
+ ones.
+
+
In the FreeType API, this is also called
+ advanceX.
+
+
+
Advance height
+
+
The vertical distance to decrement the pen position
+ after a glyph has been rendered. It is always zero
+ for horizontal layouts, and positive for vertical
+ layouts.
+
+
In the FreeType API, this is also called
+ advanceY.
+
+
+
Glyph width
+
+
The glyph's horizontal extent. For unscaled font
+ coordinates, it is
+
+
+ glyph width = bbox.xMax - bbox.xMin
+
+
+
For scaled glyphs, its computation requests specific
+ care, described in the grid-fitting chapter below.
+
+
+
Glyph height
+
+
The glyph's vertical extent. For unscaled font
+ coordinates, it is
+
+
+ glyph height = bbox.yMax - bbox.yMin
+
+
+
For scaled glyphs, its computation requests specific
+ care, described in the grid-fitting chapter below.
+
+
+
Right side bearing
+
+
Only used for horizontal layouts to describe the
+ distance from the bbox's right edge to the advance
+ width. In most cases it is a non-negative number:
+
+
+ right side bearing = advance_width -
+ left_side_bearing - (xMax-xMin)
+
+
+
A common shorthand for this value is
+ ‘rsb’.
+
+
+
+
Here is a picture giving all the details for horizontal metrics:
+
+
+
+
+
+
And here is another one for the vertical metrics:
+
+
+
+
+
+
+
4. The effects of grid-fitting
+
+
Because hinting aligns the glyph's control points to the
+ pixel grid, this process slightly modifies the dimensions
+ of character images in ways that differ from simple
+ scaling.
+
+
For example, the image of the lowercase ‘m’
+ letter sometimes fits a square in the master grid.
+ However, to make it readable at small pixel sizes, hinting
+ tends to enlarge its scaled outline horizontally in order
+ to keep its three legs distinctly visible, resulting in a
+ wider character bitmap.
+
+
The glyph metrics are also influenced by the grid-fitting
+ process:
+
+
+
+
The image's width and height are altered. Even if
+ this is only by one pixel, it can make a big
+ difference at small pixel sizes.
+
+
+
The image's bounding box is modified, thus modifying
+ the bearings.
+
+
+
The advances must be updated. For example, the
+ advance width must be incremented if the hinted bitmap
+ is larger than the scaled one, to reflect the
+ augmented glyph width.
+
+
+
+
This has some implications:
+
+
+
+
Because of hinting, simply scaling the font ascent or
+ descent might not give correct results. A possible
+ solution is to keep the ceiling of the scaled ascent,
+ and floor of the scaled descent.
+
+
+
There is no easy way to get the hinted glyph and
+ advance widths of a range of glyphs, as hinting works
+ differently on each outline. The only solution is to
+ hint each glyph separately and record the returned
+ values (for example in a cache). Some formats, like
+ TrueType, even include a table of pre-computed values
+ for a small set of common character pixel sizes.
+
+
+
Hinting depends on the final character width and
+ height in pixels, which means that it is highly
+ resolution-dependent. This property makes correct
+ WYSIWYG layouts difficult to implement.
+
+
+
+
Performing 2D transformations on glyph outlines is very
+ easy with FreeType. However, when using translation on
+ hinted outlines, one should always take care
+ of exclusively using integer pixel distances (which
+ means that the parameters to the
+ FT_Outline_Translate API function should all be
+ multiples of 64, as the point coordinates are in
+ 26.6 fixed-point format). Otherwise, the translation
+ will simply ruin the hinter's work, resulting in
+ very low quality bitmaps!
+
+
+
5. Text widths and bounding box
+
+
As seen before, the ‘origin’ of a given glyph
+ corresponds to the position of the pen on the baseline.
+ It is not necessarily located on one of the glyph's
+ bounding box corners, unlike many typical bitmapped font
+ formats. In some cases, the origin can be out of the
+ bounding box, in others, it can be within it, depending on
+ the shape of the given glyph.
+
+
Likewise, the glyph's ‘advance width’ is the
+ increment to apply to the pen position during layout, and
+ is not related to the glyph's ‘width’, which
+ really is the glyph's bounding width.
+
+
The same conventions apply to strings of text. This
+ means that:
+
+
+
+
The bounding box of a given string of text doesn't
+ necessarily contain the text cursor, nor is the latter
+ located on one of its corners.
+
+
+
The string's advance width isn't related to its
+ bounding box dimensions. Especially if it contains
+ beginning and terminal spaces or tabs.
+
+
+
Finally, additional processing like kerning creates
+ strings of text whose dimensions are not directly
+ related to the simple juxtaposition of individual
+ glyph metrics. For example, the advance width of
+ ‘VA’ isn't the sum of the advances of
+ ‘V’ and ‘A’ taken
+ separately.
The term kerning refers to specific information used to
- adjust the relative positions of coincident glyphs in a string of text.
- This section describes several types of kerning information, as well as
- the way to process them when performing text layout.
Kerning consists of modifying the spacing between two
+ successive glyphs according to their outlines. For
+ example, a ‘T’ and a ‘y’ can be
+ easily moved closer, as the top of the ‘y’
+ fits nicely under the upper right bar of the
+ ‘T’.
-
-
-
+
When laying out text with only their standard widths,
+ some consecutive glyphs seem a bit too close or too
+ distant. For example, the space between the
+ ‘A’ and the ‘V’ in the following
+ word seems a little wider than needed.
+
+
+
+
+
+
Compare this to the same word, where the distance between
+ these two letters has been slightly reduced:
+
+
+
+
+
+
As you can see, this adjustment can make a great
+ difference. Some font faces thus include a table
+ containing kerning distances for a set of given glyph
+ pairs for text layout.
+
+
+
+
The pairs are ordered, i.e., the space for pair
+ ‘(A,V)’ isn't necessarily the space for
+ pair ‘(V,A)’. They also use glyph
+ indices, not character codes.
+
+
+
Kerning distances can be expressed in horizontal or
+ vertical directions, depending on the layout and/or
+ the script. For example, some horizontal layouts like
+ Arabic can make use of vertical kerning adjustments
+ between successive glyphs. A vertical script can have
+ vertical kerning distances.
+
+
+
Kerning distances are expressed in grid units. They
+ are usually oriented in the X axis, which
+ means that a negative value indicates that two glyphs
+ must be set closer in a horizontal layout.
+
+
+
+
Note that OpenType fonts (OTF) provide two distinct
+ mechanisms for kerning, using the ‘kern’ and
+ ‘GPOS’ tables, respectively, which are part of
+ the OTF files. Older fonts only contain the former, while
+ recent fonts contain both tables or even
+ ‘GPOS’ data only. FreeType only supports
+ kerning via the (rather simple) ‘kern’ table.
+ For the interpretation of kerning data in the (highly
+ sophisticated) ‘GPOS’ table you need a
+ higher-level library
+ like ICU or
+ HarfBuzz since it can be
+ context dependent (this is, the kerning may vary depending
+ on the position within a text string, for example).
+
+
+
2. Applying kerning
+
+
Applying kerning when rendering text is a rather easy
+ process. It merely consists in adding the scaled kern
+ distance to the pen position before rendering the next
+ glyph. However, the typographically correct renderer must
+ take a few more details in consideration.
+
+
The ‘sliding dot’ problem is a good example:
+ Many font faces include a kerning distance between capital
+ letters like ‘T’ or ‘F’ and a
+ following dot (‘.’), in order to slide the
+ latter glyph just right to their main leg.
+
+
+
+
+
+
This sometimes requires additional adjustments between
+ the dot and the letter following it, depending on the
+ shapes of the enclosing letters. When applying
+ ‘standard’ kerning adjustments, the previous
+ sentence would become
+
+
+
+
+
+
This is clearly too contracted. The solution here, as
+ exhibited in the first example, is to only slide the dots
+ if the conditions fit. Of course, this requires a certain
+ knowledge of the text's meaning, and this is exactly what
+ ‘GPOS’ kerning is good for: Depending on the
+ context, different kerning values can be applied to get a
+ typographically correct result.
Laying out vertical text uses exactly the same processes,
+ with the following significant differences:
-
-
-
+
+
+
The baseline is vertical, and the vertical metrics
+ must be used instead of the horizontal one.
+
+
+
The left bearing is usually negative, but this
+ doesn't change the fact that the glyph origin must be
+ located on the baseline.
+
+
+
The advance height is always positive, so the pen
+ position must be decremented if one wants to write top
+ to bottom (assuming the Y axis is oriented
+ upwards).
+
+
+
+
Here the algorithm:
+
+
+
+ Convert the character string into a series of glyph
+ indices.
+
+
+ Place the pen to the cursor position.
+
+
+ Get or load the glyph image.
+
+
+ Translate the glyph so that its ‘origin’
+ matches the pen position.
+
+
+ Render the glyph to the target device.
+
+
+ Decrement the vertical pen position by the glyph's
+ advance height in pixels.
+
+
+ Start over at step 3 for each of the remaining
+ glyphs.
+
+
+ When all glyphs are done, set the text cursor to the new
+ pen position.
+
The purpose of this section is to present the way FreeType manages
- vectorial outlines, as well as the most common operations that can be
- applied on them.
A FreeType outline is described through a simple structure:
-
-
-
-
- FT_Outline
-
-
-
-
- n_points
-
-
- the number of points in the outline
-
-
-
-
- n_contours
-
-
- the number of contours in the outline
-
-
-
-
- points
-
-
- array of point coordinates
-
-
-
-
- contours
-
-
- array of contour end indices
-
-
-
-
- tags
-
-
- array of point flags
-
-
-
-
-
-
Here, points is a pointer to an array of
- FT_Vector records, used to store the vectorial coordinates of
- each outline point. These are expressed in 1/64th of a pixel, which
- is also known as the 26.6 fixed-point format.
-
-
contours is an array of point indices used to delimit
- contours in the outline. For example, the first contour always starts
- at point 0, and ends at point contours[0]. The second
- contour starts at point contours[0]+1 and ends at
- contours[1], etc. To traverse these points in a callback
- based manner, use FT_Outline_Decompose().
-
-
Note that each contour is closed, and that n_points should
- be equal to contours[n_contours-1]+1 for a valid outline.
-
-
Finally, tags is an array of bytes, used to store each
- outline point's tag.
An outline point's vectorial coordinates are expressed in the
- 26.6 format, i.e. in 1/64th of a pixel, hence the coordinates
- (1.0,-2.5) is stored as the integer pair (x:64,y:-192).
+
+
+ FT_Outline
+
+
+
+
+ n_points
+
+
+ the number of points in the outline
+
+
+
+
+ n_contours
+
+
+ the number of contours in the outline
+
+
+
+
+ points
+
+
+ array of point coordinates
+
+
+
+
+ contours
+
+
+ array of contour end indices
+
+
+
+
+ tags
+
+
+ array of point flags
+
+
+
+
+
+
Here, points is a pointer to an array of
+ FT_Vector
+ records, used to store the vectorial coordinates of each
+ outline point. These are expressed in 1/64th of a pixel,
+ which is also known as the 26.6 fixed-point
+ format.
-
After a master glyph outline is scaled from the EM grid to the
- current character dimensions, the hinter or grid-fitter is in charge of
- aligning important outline points (mainly edge delimiters) to the pixel
- grid. Even though this process is much too complex to be described in a
- few lines, its purpose is mainly to round point positions, while trying
- to preserve important properties like widths, stems, etc.
+
contours is an array of point indices to delimit
+ contours in the outline. For example, the first contour
+ always starts at point 0, and ends at
+ point contours[0]. The second contour starts at
+ point contours[0]+1 and ends at
+ contours[1], etc. To traverse these points in a
+ callback based manner,
+ use FT_Outline_Decompose.
-
The following operations can be used to round vectorial distances in
- the 26.6 format to the grid:
+
Note that each contour is closed, and that value
+ of n_points should be equal
+ to contours[n_contours-1]+1 for a valid
+ outline.
-
- round( x ) == ( x + 32 ) & -64
- floor( x ) == x & -64
- ceiling( x ) == ( x + 63 ) & -64
-
-
Once a glyph outline is grid-fitted or transformed, it often is
- interesting to compute the glyph image's pixel dimensions before
- rendering it. To do so, one has to consider the following:
-
-
The scan-line converter draws all the pixels whose centers
- fall inside the glyph shape. It can also detect drop-outs,
- i.e. discontinuities coming from extremely thin shape fragments, in
- order to draw the "missing" pixels. These new pixels are always located
- at a distance less than half of a pixel but it is not easy to predict
- where they will appear before rendering.
By grid-fitting the bounding box, it is guaranteed that all the pixel
- centers that are to be drawn, including those coming from drop-out
- control, will be within the adjusted box. Then the box's
- dimensions in pixels can be computed.
-
-
Note also that, when translating a grid-fitted outline, one should
- always use integer distances to move an outline in the 2D
- plane. Otherwise, glyph edges won't be aligned on the pixel grid
- anymore, and the hinter's work will be lost, producing very low
- quality bitmaps and pixmaps.
+
Finally, tags is an array of bytes, used to
+ store each outline point's tag.
As described earlier, a bounding box (also
+ called bbox) is simply a rectangle that
+ completely encloses the shape of a given outline. The
+ interesting case is the smallest bounding box possible,
+ and in the following we subsume this under the term
+ ‘bounding box’. Because of the way arcs are
+ defined, Bézier control points are not necessarily
+ contained within an outline's (smallest) bounding box.
-
-
-
+
Such a situation happens if one Bézier arc is, for
+ example, the upper edge of an outline and an
+ ‘off’ point happens to be above the bbox.
+ However, it is very rare in the case of character outlines
+ because most font designers and creation tools always
+ place ‘on’ points at the extrema of each
+ curved edges (as both the TrueType and PostScript
+ specifications recommend), as it makes hinting much
+ easier.
-Last update: 06-Mar-2011
+
We thus define the control box (also
+ called cbox) as the smallest possible rectangle
+ that encloses all points of a given outline (including its
+ ‘off’ points). Clearly, it always includes
+ the bbox, and the two boxes are identical in most
+ cases.
+
+
Unlike the bbox, the cbox is much faster to compute.
+
+
+
+
+
+
+
+
+
+
+
+
+
Control and bounding boxes can be computed automatically
+ using the
+ functions FT_Outline_Get_CBox
+ and
+ FT_Outline_Get_BBox.
+ The former function is always very fast, while the
+ latter may be slow in the case of
+ ‘outside’ control points (as it needs to find
+ the extreme of conic and cubic arcs for
+ ‘perfect’ computations). If this isn't the
+ case, it is as fast as computing the control box.
+
+
Note also that even though most glyph outlines have equal
+ cbox and bbox values to ease hinting, this is not
+ necessarily the case if a transformation like rotation is
+ applied to them.
+
+
+
3. Coordinates, scaling and
+ grid-fitting
+
+
An outline point's vectorial coordinates are expressed in
+ the 26.6 format, i.e. in 1/64th of a pixel, hence the
+ coordinates ‘(1.0,-2.5)’ is stored as the
+ integer pair ‘(64,-192)’, to name an
+ example.
+
+
After a glyph outline is scaled from the EM grid (in font
+ units) to the current character dimensions, the hinter or
+ grid-fitter is in charge of aligning important outline
+ points (mainly edge delimiters) to the pixel grid. Even
+ though this process is much too complex to be described in
+ a few lines, its purpose is mainly to round point
+ positions, while trying to preserve important properties
+ like widths, stems, etc.
+
+
The following operations can be used to round vectorial
+ distances in the 26.6 format to the grid:
+
+
+round( x ) == ( x + 32 ) & -64
+floor( x ) == x & -64
+ceiling( x ) == ( x + 63 ) & -64
+
+
Once a glyph outline is grid-fitted or transformed, it
+ often is interesting to compute the glyph image's pixel
+ dimensions before rendering it. To do so, one has to
+ consider the following:
+
+
The scan-line converter draws all the pixels
+ whose centers fall inside the glyph shape. In
+ B/W rendering mode, it can also detect drop-outs,
+ i.e., discontinuities coming from extremely thin shape
+ fragments, in order to draw the ‘missing’
+ pixels. These new pixels are always located at a distance
+ less than half of a pixel but it is not easy to predict
+ where they will appear before rendering.
By grid-fitting the bounding box, it is guaranteed that
+ all the pixel centers that are to be drawn, including
+ those coming from drop-out control, will
+ be within the adjusted box. Then the box's
+ dimensions in pixels can be computed.
+
+
Note also that, when translating a grid-fitted outline, one should
+ always use integer distances to move an outline
+ in the 2D plane. Otherwise, glyph edges won't be aligned
+ on the pixel grid anymore, and the hinter's work will be
+ lost, producing very low quality bitmaps and
+ pixmaps.
The purpose of this section is to present the way FreeType manages
- bitmaps and pixmaps, and how they relate to the concepts previously
- defined. The relationships between vectorial and pixel coordinates is
- explained.
The glyph loader and hinter always places the outline in the 2D
- plane so that (0,0) matches its character origin. This means that
- the glyph's outline, and corresponding bounding box, can be placed
- anywhere in the 2D plane (see the graphics in section III).
-
-
-
The target bitmap's area is mapped to the 2D plane, with its
- lower left corner at (0,0). This means that a bitmap or pixmap of
- dimensions [w,h] will be mapped to a 2D rectangle window
- delimited by (0,0)-(w,h).
-
-
-
When scan-converting the outline, everything that falls within
- the bitmap window is rendered, the rest is ignored.
-
+
+
+ FT_Bitmap
+
-
A common mistake made by many developers when they begin using
- FreeType is believing that a loaded outline can be directly rendered
- in a bitmap of adequate dimensions. The following images illustrate
- why this is a problem.
+
+
+ rows
+
+
+ the number of rows, i.e. lines, in the bitmap
+
+
+
+
+ width
+
+
+ the number of horizontal pixels in the bitmap
+
+
+
+
+ pitch
+
+
+ its absolute value is the number of bytes per bitmap
+ line; it can be either positive or negative depending
+ on the bitmap's vertical orientation
+
+
+
+
+ buffer
+
+
+ a typeless pointer to the bitmap pixel buffer
+
+
+
+
+ pixel_mode
+
+
+ an enumeration used to describe the pixel format of
+ the bitmap; examples are ft_pixel_mode_mono
+ for 1-bit monochrome bitmaps
+ and ft_pixel_mode_grays for 8-bit
+ anti-aliased ‘gray’ values
+
+
+
+
+ num_grays
+
+
+ this is only used for ‘gray’ pixel modes,
+ it gives the number of gray levels used to describe
+ the anti-aliased gray levels (256 by default with
+ FreeType 2)
+
+
+
-
-
- The first image shows a loaded outline in the 2D plane.
-
-
- The second one shows the target window for a bitmap of arbitrary
- dimensions [w,h].
-
-
- The third one shows the juxtaposition of the outline and window in
- the 2D plane.
-
-
- The last image shows what will really be rendered in the bitmap.
-
-
+
Note that the sign of the pitch field determines
+ whether the rows in the pixel buffer are stored in
+ ascending or descending order.
-
-
-
-
+
Remember that FreeType uses the Y upwards
+ convention in the 2D plane, which means that a coordinate
+ of (0, 0) always refer to the lower-left
+ corner of a bitmap.
-
Indeed, in nearly all cases, the loaded or transformed outline must
- be translated before it is rendered into a target bitmap, in order to
- adjust its position relative to the target window.
+
If the pitch is positive, the rows are stored in
+ decreasing vertical position; the first bytes of the pixel
+ buffer are part of the upper bitmap row.
-
For example, the correct way of creating a standalone glyph
- bitmap is as follows
+
On the opposite, if the pitch is negative, the first
+ bytes of the pixel buffer are part of the lower
+ bitmap row.
-
-
-
Compute the size of the glyph bitmap. It can be computed
- directly from the glyph metrics, or by computing its bounding box
- (this is useful when a transformation has been applied to the
- outline after the load, as the glyph metrics are not valid
- anymore).
-
-
-
Create the bitmap with the computed dimensions. Don't forget to
- fill the pixel buffer with the background color.
-
-
-
Translate the outline so that its lower left corner matches
- (0,0). Don't forget that in order to preserve hinting, one should
- use integer, i.e. rounded distances (of course, this isn't required
- if preserving hinting information doesn't matter, like with rotated
- text). Usually, this means translating with a vector
- (-ROUND(xMin), -ROUND(yMin)).
-
-
-
Call the rendering function (it can be
- FT_Outline_Render() for example).
-
-
+
In all cases, one can see the pitch as the byte increment
+ needed to skip to the next lower scanline in a
+ given bitmap buffer.
-
In the case where one wants to write glyph images directly into a
- large bitmap, the outlines must be translated so that their vectorial
- position correspond to the current text cursor/character origin.
+
+
+
+
+
+
+
+
+
+
-
+
The ‘positive pitch’ convention is very often
+ used, though some systems might need the other.
Generating a bitmap or pixmap image from a vectorial
+ image is easy with FreeType. However, one must understand
+ a few points regarding the positioning of the outline in
+ the 2D plane before converting it to a bitmap:
+
+
+
+
The glyph loader and hinter always places the outline
+ in the 2D plane so that (0, 0) matches its
+ character origin. This means that the glyph's outline
+ (and corresponding bounding box), can be placed
+ anywhere in the 2D plane (see the graphics in
+ section III).
+
+
+
The target bitmap's area is mapped to the 2D plane,
+ with its lower left corner at (0, 0). This means
+ that a bitmap or pixmap of dimensions
+ [w, h] will be mapped to a 2D
+ rectangle window delimited by
+ (0, 0)-(w, h).
+
+
+
When scan-converting the outline, everything that
+ falls within the bitmap window is rendered, the rest
+ is ignored.
+
+
+
A common mistake made by many developers when they
+ begin using FreeType is believing that a loaded outline
+ can be directly rendered in a bitmap of adequate
+ dimensions. The following images illustrate why this is
+ a problem.
+
+
+
+ The first image shows a loaded outline in the 2D
+ plane.
+
+
+ The second one shows the target window for a bitmap of
+ arbitrary dimensions [w, h].
+
+
+ The third one shows the juxtaposition of the outline
+ and window in the 2D plane.
+
+
+ The last image shows what will really be rendered in
+ the bitmap.
+
+
+
+
+
+
+
+
+
Indeed, in nearly all cases, the loaded or transformed
+ outline must be translated before it is rendered into a
+ target bitmap, in order to adjust its position relative to
+ the target window.
+
+
For example, the correct way of creating
+ a standalone glyph bitmap is as follows:
+
+
+
+
Compute the size of the glyph bitmap. It can be
+ computed directly from the glyph metrics, or by
+ computing its bounding box (this is useful when a
+ transformation has been applied to the outline after
+ loading it, as the glyph metrics are not valid
+ anymore).
+
+
+
Create the bitmap with the computed dimensions.
+ Don't forget to fill the pixel buffer with the
+ background color.
+
+
+
Translate the outline so that its lower left corner
+ matches (0, 0). Don't forget that in order to
+ preserve hinting, one should use integer, i.e.,
+ rounded distances (of course, this isn't required if
+ preserving hinting information doesn't matter, like
+ with rotated text). Usually, this means translating
+ with a vector
+ (-ROUND(xMin), -ROUND(yMin)).
+
+
+
Call the rendering function (it can be
+ FT_Outline_Render,
+ for example).
+
+
+
+
In the case where one wants to write glyph images
+ directly into a large bitmap, the outlines must be
+ translated so that their vectorial position corresponds to
+ the current text cursor or character origin.
This document presents the core conventions used within the FreeType
- library to manage font and glyph data. It is a must-read for all
- developers who need to understand digital typography, especially if you
- want to use the FreeType 2 library in your projects.
This document presents the core conventions used within
+ the FreeType library to manage font and glyph data. It is
+ a must-read for all developers who need to
+ understand digital typography, especially if you want to
+ use the FreeType 2 library in your projects.
FreeType is a software font engine that is designed to
+ be small, efficient, highly customizable, and portable
+ while capable of producing high-quality output (glyph
+ images). It can be used in graphics libraries, display
+ servers, font conversion tools, text image generation
+ tools, and many other products as well.
+
+
Note that FreeType is a font service and doesn't
+ provide APIs to perform higher-level features like text
+ layout or graphics processing (e.g., colored text
+ rendering, ‘hollowing’, etc.). However, it
+ greatly simplifies these tasks by providing a simple, easy
+ to use, and uniform interface to access the content of
+ font files.
+
+
FreeType is released under two open-source licenses: our
+ own
+ BSD-like FreeType
+ License and
+ the GNU
+ Public License, Version 2. It can thus be used
+ by any kind of projects, be they proprietary or not.
+
+
Please note that ‘FreeType’ is also called
+ ‘FreeType 2’, to distinguish it from the
+ old, deprecated ‘FreeType 1’ library, a
+ predecessor no longer maintained and supported.
+
+
+
+
+
+
+
Features
+
+
The following is a non-exhaustive list of features
+ provided by FreeType.
+
+
+
+
FreeType provides a simple and easy-to-use API to
+ access font content in a uniform way, independently of
+ the file format. Additionally, some format-specific
+ APIs can be used to access special data in the font
+ file.
+
+
+
The design of FreeType is based on modules that can
+ be either linked statically to the library at compile
+ time, or loaded on demand at runtime. Modules are
+ used to support specific font formats, or even new
+ glyph image formats!
+
+
+
FreeType was written with embedded systems in mind.
+ This means that it doesn't use static writable data
+ (i.e., it can be run from ROM directly), and that
+ client applications can provide their own memory
+ manager and I/O stream implementation. The latter
+ allows you to easily read from ROM-based, compressed
+ or remote font files with the same API. Several
+ stream implementations can be used concurrently with a
+ single FreeType instance.
+
+
You can also reduce the size of the FreeType code by
+ only compiling the modules you need for your embedded
+ project or environment.
+
+
+
By default, FreeType supports the following font
+ formats.
+
+
+
TrueType fonts (TTF) and TrueType collections
+ (TTC)
+
CFF fonts
+
WOFF fonts
+
OpenType fonts (OTF, both TrueType and CFF
+ variants) and OpenType collections (OTC)
+
Type 1 fonts (PFA and PFB)
+
CID-keyed Type 1 fonts
+
SFNT-based bitmap fonts, including color Emoji
+
X11 PCF fonts
+
Windows FNT fonts
+
BDF fonts (including anti-aliased ones)
+
PFR fonts
+
Type 42 fonts (limited support)
+
+
+
+
From a given glyph outline, FreeType is capable of
+ producing a high-quality monochrome bitmap, or
+ anti-aliased pixmap, using 256 levels of
+ ‘gray’.
+
+
+
FreeType supports all the character mappings defined
+ by the TrueType and OpenType specifications. It is
+ also capable of automatically synthetizing a Unicode
+ charmap from Type 1 fonts, avoiding painful
+ ‘encoding translation’ problems common
+ with this format (of course, original encodings are
+ also available if necessary).
+
+
+
The FreeType core API provides simple functions to
+ access advanced information like glyph names or basic
+ kerning data.
+
+
+
A full-featured and efficient TrueType bytecode
+ interpreter, trying to match the results of the
+ Windows bytecode engine. There is also the
+ possibility to activate subpixel hinting
+ (a.k.a. ClearType, still under
+ development).
+
+
+
For those who don't need or want to use the bytecode
+ interpreter for TrueType fonts, we developed our
+ own automatic hinter module. It is also used
+ by other scalable formats.
+
+
+
Due to its modular design, it is easy to enhance the
+ library, providing additional format-specific
+ information through optional APIs (as an example, an
+ optional API is provided to retrieve SFNT tables from
+ TrueType and OpenType fonts).
+
+
+
FreeType provides its own caching subsystem. It can
+ be used to cache either face instances or glyph images
+ efficiently.
+
+
+
A bundle of demo programs demonstrate the usage of
+ FreeType; look for the
+ ‘ft2demos-x.x.x’ archive (or
+ ‘ftdmoxxx’ in case you are on a
+ Windows platform) at the locations
+ given here.
+ ‘x.x.x’ (or
+ ‘xxx’) gives the version number,
+ for example ‘2.4.10’ or
+ ‘2410’.
+
+
+
+
+
+
+
+
+
Requirements
+
+
FreeType is written in industry-standard ANSI C and
+ should compile easily with any compliant C or C++
+ compiler. We have even taken great care to
+ eliminate all warnings when compiling with
+ popular compilers like gcc, Visual C++, and Borland
+ C++.
+
+
Apart from a standard ANSI C library, FreeType
+ doesn't have any external dependencies and can be compiled
+ and installed on its own on any kind of system. Some
+ modules need external libraries (e.g., for
+ handling fonts compressed with gzip or bz2), however, they
+ are optional and can be disabled.
+
+
+
+
+
+
+
Patent Issues
+
+
All patents related to the TrueType bytecode interpreter
+ have expired since May 2010. Support for the still
+ patented ClearType color filtering model is disabled by
+ default.
+
+
More information regarding this topic is available at
+ our patents page.
This is the first section of the FreeType 2 tutorial. It will teach
- you how to:
-
-
initialize the library
-
open a font file by creating a new face object
-
select a character size in points or in pixels
-
load a single glyph image and convert it to a bitmap
-
render a very simple string of text
-
render a rotated string of text easily
-
+
-
+
+
I. Simple Glyph Loading
-
- 1. Header files
-
+
1. Header Files
-
The following are instructions required to compile an application that
- uses the FreeType 2 library.
+
The following are instructions required to compile an
+ application that uses the FreeType 2 library.
-
-
-
Locate the FreeType 2 include
- directory.
+
+
+
Locate the FreeType 2 include
+ directory.
-
You have to add it to your compilation include path.
+
You have to add it to your compilation include
+ path.
-
Note that on Unix systems, you can now run the
- freetype-config script with the --cflags option to
- retrieve the appropriate compilation flags. This script can also be
- used to check the version of the library that is installed on your
- system, as well as the required librarian and linker flags.
-
+
In Unix-like environments you can run the
+ freetype-config script with
+ the --cflags option to retrieve the
+ appropriate compilation flags. This script can also
+ be used to check the version of the library that is
+ installed on your system, as well as the required
+ librarian and linker flags.
+
-
-
Include the file named
- ft2build.h.
+
+
Include the file named ft2build.h.
-
It contains various macro declarations that are later used to
- #include the appropriate public FreeType 2 header
- files.
-
+
It contains various macro declarations that are later
+ used to #include the appropriate public
+ FreeType 2 header files.
+
-
-
Include the main FreeType 2 API header
- file.
+
+
Include the main FreeType 2 API header file.
-
You should do that using the macro FT_FREETYPE_H,
- like in the following example:
+
You should do that using the
+ macro FT_FREETYPE_H, like in the following
+ example.
FT_FREETYPE_H is a special macro defined in
+ file ftheader.h. It contains some
+ installation-specific macros to name other public
+ header files of the FreeType 2 API.
The use of macros in #include statements is
+ ANSI-compliant. It is used for several reasons.
+
+
+
It avoids conflicts with (deprecated) FreeType 1.x
+ public header files.
+
+
The macro names are not limited to the DOS 8.3 file
+ naming limit; names like FT_MULTIPLE_MASTERS_H
+ or FT_SFNT_NAMES_H are a lot more readable and
+ explanatory than the real file names
+ ftmm.h and ftsnames.h.
+
+
It allows special installation tricks that will not be
+ discussed here.
+
+
+
+
2. Library Initialization
+
+
To initialize the FreeType library, create a variable of
+ type FT_Library
+ named, for example, library, and call the
+ function FT_Init_FreeType.
creating a new instance of the FreeType 2 library
+ and setting the handle library to it, and
+
+
loading each module that FreeType knows about in the
+ library. Among others, your new library object
+ is able to handle TrueType, Type 1, CID-keyed &
+ OpenType/CFF fonts gracefully.
+
+
+
As you can see, the function returns an error code, like
+ most other functions of the FreeType API. An error code
+ of 0 (also known
+ as FT_Err_Ok) always means that the
+ operation was successful; otherwise, the value describes
+ the error, and library is set to NULL.
+
+
+
3. Loading a Font Face
+
+
a. From a Font File
+
+
Create a new face object by
+ calling FT_New_Face.
+ A face describes a given typeface and style. For
+ example, ‘Times New Roman Regular’ and
+ ‘Times New Roman Italic’ correspond to two
+ different faces.
+
+
+FT_Library library; /* handle to library */
+FT_Face face; /* handle to face object */
+
+
+error = FT_Init_FreeType( &library );
+if ( error ) { ... }
+
+error = FT_New_Face( library,
+ "/usr/share/fonts/truetype/arial.ttf",
+ 0,
+ &face );
+if ( error == FT_Err_Unknown_File_Format )
+{
+ ... the font file could be opened and read, but it appears
+ ... that its font format is unsupported
+}
+else if ( error )
+{
+ ... another error code means that the font file could not
+ ... be opened or read, or that it is broken...
+}
+
+
As you can certainly imagine, FT_New_Face opens
+ a font file, then tries to extract one face from it. Its
+ parameters are as follows.
+
+
+
library
+
A handle to the FreeType library instance where the
+ face object is created.
+
+
filepathname
+
The font file pathname (a standard C string).
+
+
face_index
+
+
Certain font formats allow several font faces to be
+ embedded in a single file.
+
+
This index tells which face you want to load. An
+ error is returned if its value is too large.
+
+
Index 0 always works, though.
+
+
+
face
+
+
A pointer to the handle that is set to
+ describe the new face object.
+
+
It is set to NULL in case of error.
+
+
+
+
To know how many faces a given font file contains, load
+ its first face (this is, face_index should be set
+ to zero), then check the value
+ of face->num_faces, which indicates how many
+ faces are embedded in the font file.
+
+
b. From Memory
+
+
In the case where you have already loaded the font file
+ into memory, you can similarly create a new face object
+ for it by
+ calling FT_New_Memory_Face.
As you can see, FT_New_Memory_Face takes a
+ pointer to the font file buffer and its size in bytes
+ instead of a file pathname. Other than that, it has
+ exactly the same semantics as
+ FT_New_Face.
+
+
Note that you must not deallocate the memory before calling
+ FT_Done_Face.
+
+
c. From Other Sources (Compressed Files, Network,
+ etc.)
+
+
There are cases where using a file pathname or preloading
+ the file into memory is not sufficient. With
+ FreeType 2, it is possible to provide your own
+ implementation of I/O routines.
+
+
This is done through
+ the FT_Open_Face
+ function, which can be used to open a new font face with a
+ custom input stream, select a specific driver for opening,
+ or even pass extra parameters to the font driver when
+ creating the object. We advise you to look up
+ the FreeType 2
+ reference manual in order to learn how to use it.
+
+
+
4. Accessing the Face Data
+
+
A face object models all information that
+ globally describes the face. Usually, this data can be
+ accessed directly by dereferencing a handle, like
+ in face−>num_glyphs.
+
+
The complete list of available fields is in
+ the FT_FaceRec
+ structure description. However, we describe here a few of
+ them in more detail.
+
+
+
num_glyphs
+
This variable gives the number of glyphs
+ available in the font face. A glyph is a character
+ image, nothing more – it thus doesn't necessarily
+ correspond to a character code.
+
+
face_flags
+
A 32-bit integer containing bit flags that describe
+ some face properties. For example, the flag
+ FT_FACE_FLAG_SCALABLE indicates that the face's
+ font format is scalable and that glyph images can be
+ rendered for all character pixel sizes. For more
+ information on face flags, please read
+ the FreeType 2
+ API Reference.
+
+
units_per_EM
+
This field is only valid for scalable formats (it is
+ set to 0 otherwise). It indicates the number of
+ font units covered by the EM.
+
+
num_fixed_sizes
+
This field gives the number of embedded bitmap strikes
+ in the current face. A strike is a series of
+ glyph images for a given character pixel size. For
+ example, a font face could include strikes for pixel
+ sizes 10, 12, and 14. Note that even scalable font
+ formats can have embedded bitmap strikes!
+
+
available_sizes
+
+
A pointer to an array
+ of FT_Bitmap_Size
+ elements. Each FT_Bitmap_Size indicates the
+ horizontal and vertical character pixel sizes
+ for each of the strikes that are present in the
+ face.
+
+
Note that, generally speaking, these
+ are not the cell size of the bitmap
+ strikes.
+
+
+
+
+
5. Setting the Current Pixel Size
+
+
FreeType 2 uses size objects to model all
+ information related to a given character size for a given
+ face. For example, a size object holds the value of
+ certain metrics like the ascender or text height,
+ expressed in 1/64th of a pixel, for a character size of
+ 12 points.
+
+
When the FT_New_Face function is called (or one
+ of its siblings), it automatically creates a new
+ size object for the returned face. This size object is
+ directly accessible as
+ face−>size.
+
+
NOTE: A single face object can deal with one
+ or more size objects at a time; however, this is something
+ that few programmers really need to do. We have thus
+ decided to simplify the API for the most common use (i.e.,
+ one size per face) while keeping this feature available
+ through additional functions.
+
+
When a new face object is created, all elements are set
+ to 0 during initialization. To populate the
+ structure with sensible values, you should
+ call FT_Set_Char_Size.
+ Here is an example, setting the character size to 16pt for
+ a 300×300dpi device:
+
+
+error = FT_Set_Char_Size(
+ face, /* handle to face object */
+ 0, /* char_width in 1/64th of points */
+ 16*64, /* char_height in 1/64th of points */
+ 300, /* horizontal device resolution */
+ 300 ); /* vertical device resolution */
+
+
Some notes.
+
+
+
The character widths and heights are specified in
+ 1/64th of points. A point is a physical
+ distance, equaling 1/72th of an inch. Normally, it is
+ not equivalent to a pixel.
+
+
Value of 0 for the character width means
+ ‘same as character height’, value of 0
+ for the character height means ‘same as character
+ width’. Otherwise, it is possible to specify
+ different character widths and heights.
+
+
The horizontal and vertical device resolutions are
+ expressed in dots-per-inch, or dpi.
+ Standard values are 72 or 96 dpi for display
+ devices like the screen. The resolution is used to
+ compute the character pixel size from the character
+ point size.
+
+
Value of 0 for the horizontal resolution means
+ ‘same as vertical resolution’, value
+ of 0 for the vertical resolution means ‘same
+ as horizontal resolution’. If both values are
+ zero, 72 dpi is used for both dimensions.
+
+
The first argument is a handle to a face object, not a
+ size object.
+
+
+
This function computes the character pixel size that
+ corresponds to the character width and height and device
+ resolutions. However, if you want to specify the pixel
+ sizes yourself, you can call
+ FT_Set_Pixel_Sizes.
This example sets the character pixel sizes to
+ 16×16 pixels. As previously, a value of 0
+ for one of the dimensions means ‘same as the
+ other’.
+
+
Note that both functions return an error code. Usually,
+ an error occurs with a fixed-size font format (like FNT or
+ PCF) when trying to set the pixel size to a value that is
+ not listed in the face->fixed_sizes array.
+
+
+
6. Loading a Glyph Image
+
+
a. Converting a Character Code Into a Glyph Index
+
+
Normally, an application wants to load a glyph image
+ based on its character code, which is a unique
+ value that defines the character for a
+ given encoding. For example, code 65 (0x41)
+ represents character ‘A’ in ASCII
+ encoding.
+
+
A face object contains one or more tables, called
+ charmaps, to convert character codes to glyph
+ indices. For example, most older TrueType fonts contain
+ two charmaps: One is used to convert Unicode character
+ codes to glyph indices, the other one is used to convert
+ Apple Roman encoding to glyph indices. Such fonts can
+ then be used either on Windows (which uses Unicode) and
+ old MacOS versions (which use Apple Roman). Note also
+ that a given charmap might not map to all the glyphs
+ present in the font.
+
+
By default, when a new face object is created, it selects
+ a Unicode charmap. FreeType tries to emulate a Unicode
+ charmap if the font doesn't contain such a charmap, based
+ on glyph names. Note that it is possible that the
+ emulation misses glyphs if glyph names are non-standard.
+ For some fonts like symbol fonts, no Unicode emulation is
+ possible at all.
+
+
Later on we will describe how to look for specific
+ charmaps in a face. For now, we assume that the face
+ contains at least a Unicode charmap that was selected
+ during a call to FT_New_Face. To convert a
+ Unicode character code to a font glyph index, we use
+ FT_Get_Char_Index.
This code line looks up the glyph index corresponding to
+ the given charcode in the charmap that is
+ currently selected for the face. You should use the
+ UTF-32 representation form of Unicode; for example, if you
+ want to load character U+1F028, use value 0x1F028 as the
+ value for charcode.
+
+
If no charmap was selected, the function returns
+ the charcode.
+
+
Note that this is one of the rare FreeType functions that
+ do not return an error code. However, when a given
+ character code has no glyph image in the face,
+ value 0 is returned. By convention, it always
+ corresponds to a special glyph image called
+ the missing glyph, which is commonly displayed as
+ a box or a space.
+
+
b. Loading a Glyph From the Face
+
+
Once you have a glyph index, you can load the
+ corresponding glyph image. The latter can be stored in
+ various formats within the font file. For fixed-size
+ formats like FNT or PCF, each image is a bitmap. Scalable
+ formats like TrueType or CFF use vectorial shapes
+ (outlines) to describe each glyph. Some formats
+ may have even more exotic ways of representing glyphs
+ (e.g., MetaFont – but this format is not supported).
+ Fortunately, FreeType 2 is flexible enough to support
+ any kind of glyph format through a simple API.
+
+
The glyph image is always stored in a special object called a
+ glyph slot. As its name suggests, a glyph slot
+ is a container that is able to hold one glyph image at a
+ time, be it a bitmap, an outline, or something else. Each
+ face object has a single glyph slot object that can be
+ accessed as face->glyph. Its fields are
+ explained by
+ the FT_GlyphSlotRec
+ structure documentation.
+
+
Loading a glyph image into the slot is performed by
+ calling FT_Load_Glyph.
+
+
+error = FT_Load_Glyph(
+ face, /* handle to face object */
+ glyph_index, /* glyph index */
+ load_flags ); /* load flags, see below */
+
+
The load_flags value is a set of bit flags to
+ indicate some special operations. The default value
+ FT_LOAD_DEFAULT is 0.
+
+
This function tries to load the corresponding glyph image
+ from the face.
+
+
+
If a bitmap is found for the corresponding glyph and
+ pixel size, it is loaded into the slot. Embedded
+ bitmaps are always favoured over native image formats,
+ because we assume that they are higher-quality versions
+ of the same glyph. This can be changed by using
+ the FT_LOAD_NO_BITMAP flag.
+
+
Otherwise, a native image for the glyph is loaded. It
+ is also scaled to the current pixel size, as well as
+ hinted for certain formats like TrueType and
+ Type 1.
+
+
+
The field face−>glyph−>format
+ describes the format used for storing the glyph image in
+ the slot. If it is not FT_GLYPH_FORMAT_BITMAP,
+ one can immediately convert it to a bitmap
+ through FT_Render_Glyph.
The parameter render_mode is a set of bit flags
+ to specify how to render the glyph image.
+ FT_RENDER_MODE_NORMAL, the default, renders an
+ anti-aliased bitmap with 256 gray levels (also called
+ a pixmap), as this is the default. You can
+ alternatively use FT_RENDER_MODE_MONO if you want
+ to generate a 1-bit monochrome bitmap. More values are
+ available for
+ the FT_Render_Mode
+ enumeration value.
+
+
Once you have a bitmapped glyph image, you can access it
+ directly through glyph->bitmap (a simple
+ descriptor for bitmaps or pixmaps), and position it
+ through glyph->bitmap_left and
+ glyph->bitmap_top.
+
+
Note that bitmap_left is the horizontal distance
+ from the current pen position to the leftmost border of
+ the glyph bitmap, while bitmap_top is the
+ vertical distance from the pen position (on the baseline)
+ to the topmost border of the glyph bitmap. It is
+ positive to indicate an upwards distance.
+
+
c. Using Other Charmaps
+
+
As said before, when a new face object is created, it
+ looks for a Unicode charmap and select it. The currently
+ selected charmap can be accessed
+ via face->charmap. This field is NULL if no
+ charmap is selected, which typically happens when you
+ create a new FT_Face object from a font file that
+ doesn't contain a Unicode charmap (which is rather
+ infrequent today).
+
+
There are two ways to select a different charmap with
+ FreeType. It's easiest if the encoding you need already
+ has a corresponding enumeration defined
+ in FT_FREETYPE_H, for
+ example FT_ENCODING_BIG5. In this case, you can
+ call
+ FT_Select_Charmap.
Another way is to manually parse the list of charmaps for
+ the face; this is accessible through the
+ fields num_charmaps and
+ charmaps (notice the ‘s’) of the face
+ object. As you could expect, the first is the number of
+ charmaps in the face, while the second is a table of
+ pointers to the charmaps embedded in the face.
+
+
Each charmap has a few visible fields to describe it more
+ precisely. The most important ones are
+ charmap->platform_id
+ and charmap->encoding_id, defining a pair of
+ values that describe the charmap in a rather generic way:
+ Each value pair corresponds to a given encoding. For
+ example, the pair (3,1) corresponds to Unicode. The list
+ is defined in the TrueType specification; you can also use
+ the file FT_TRUETYPE_IDS_H, which defines several
+ helpful constants to deal with them.
+
+
To select a specific encoding, you need to find a
+ corresponding value pair in the specification, then look
+ for it in the charmaps list. Don't forget that there are
+ encodings that correspond to several value pairs due to
+ historical reasons.
+
+
+FT_CharMap found = 0;
+FT_CharMap charmap;
+int n;
+
+
+for ( n = 0; n < face->num_charmaps; n++ )
+{
+ charmap = face->charmaps[n];
+ if ( charmap->platform_id == my_platform_id &&
+ charmap->encoding_id == my_encoding_id )
+ {
+ found = charmap;
+ break;
+ }
+}
+
+if ( !found ) { ... }
+
+/* now, select the charmap for the face object */
+error = FT_Set_Charmap( face, found );
+if ( error ) { ... }
+
+
Once a charmap has been selected, either through
+ FT_Select_Charmap
+ or FT_Set_Charmap,
+ it is used by all subsequent calls
+ to FT_Get_Char_Index.
+
+
d. Glyph Transformations
+
+
It is possible to specify an affine transformation with
+ FT_Set_Transform,
+ to be applied to glyph images when they are loaded. Of
+ course, this only works for scalable (vectorial) font
+ formats.
+
+
+error = FT_Set_Transform(
+ face, /* target face object */
+ &matrix, /* pointer to 2x2 matrix */
+ &delta ); /* pointer to 2d vector */
+
+
This function sets the current transformation for a given
+ face object. Its second parameter is a pointer to an
+ FT_Matrix
+ structure that describes a 2×2 affine matrix. The
+ third parameter is a pointer to
+ an FT_Vector
+ structure, describing a two-dimensional vector that
+ translates the glyph image after the 2×2
+ transformation.
+
+
Note that the matrix pointer can be set to NULL, in which
+ case the identity transformation is used. Coefficients of
+ the matrix are otherwise in 16.16 fixed-point units.
+
+
The vector pointer can also be set to NULL (in which case
+ a delta of (0,0) is used). The vector coordinates are
+ expressed in 1/64th of a pixel (also known as 26.6
+ fixed-point numbers).
+
+
The transformation is applied to every
+ glyph that is loaded through FT_Load_Glyph and
+ is completely independent of any hinting process.
+ This means that you won't get the same results if you load
+ a glyph at the size of 24 pixels, or a glyph at the
+ size of 12 pixels scaled by 2 through a
+ transformation, because the hints are computed differently
+ (except if you have disabled hints).
+
+
If you ever need to use a non-orthogonal transformation
+ with optimal hints, you first have to decompose your
+ transformation into a scaling part and a rotation/shearing
+ part. Use the scaling part to compute a new character
+ pixel size, then the other one to call
+ FT_Set_Transform. This is explained in more
+ detail in part II of this tutorial.
+
+
Rotation usually disables hinting.
+
+
Loading a glyph bitmap with a non-identity transformation
+ works; the transformation is ignored in this case.
+
+
+
7. Simple Text Rendering
+
+
We now present a simple example to render a string of
+ 8-bit Latin-1 text, assuming a face that contains a
+ Unicode charmap.
+
+
The idea is to create a loop that loads one glyph image
+ on each iteration, converts it to a pixmap, draws it on
+ the target surface, then increments the current pen
+ position.
+
+
a. Basic Code
+
+
The following code performs our simple text rendering
+ with the functions previously described.
+
+
+FT_GlyphSlot slot = face->glyph; /* a small shortcut */
+int pen_x, pen_y, n;
+
+
+... initialize library ...
+... create face object ...
+... set character size ...
+
+pen_x = 300;
+pen_y = 200;
+
+for ( n = 0; n < num_chars; n++ )
+{
+ FT_UInt glyph_index;
+
+
+ /* retrieve glyph index from character code */
+ glyph_index = FT_Get_Char_Index( face, text[n] );
+
+ /* load glyph image into the slot (erase previous one) */
+ error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
+ if ( error )
+ continue; /* ignore errors */
+
+ /* convert to an anti-aliased bitmap */
+ error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL );
+ if ( error )
+ continue;
+
+ /* now, draw to our target surface */
+ my_draw_bitmap( &slot->bitmap,
+ pen_x + slot->bitmap_left,
+ pen_y - slot->bitmap_top );
+
+ /* increment pen position */
+ pen_x += slot->advance.x >> 6;
+ pen_y += slot->advance.y >> 6; /* not useful for now */
+}
+
+
This code needs a few explanations.
+
+
+
We define a handle named slot that points to
+ the face object's glyph slot. (The
+ type FT_GlyphSlot
+ is a pointer). That is a convenience to avoid using
+ face->glyph->XXX every time.
+
+
We increment the pen position with the vector
+ slot->advance, which correspond to the
+ glyph's advance width (also known as
+ its escapement). The advance vector is
+ expressed in 1/64th of pixels, and is truncated to
+ integer pixels on each iteration.
+
+
The function my_draw_bitmap is not part of
+ FreeType but must be provided by the application to draw
+ the bitmap to the target surface. In this example, it
+ takes a pointer to
+ an FT_Bitmap
+ descriptor and the position of its top-left corner as
+ arguments.
+
+
The value of slot->bitmap_top is positive
+ for an upwards vertical distance. Assuming
+ that the coordinates taken by my_draw_bitmap
+ use the opposite convention (increasing Y
+ corresponds to downwards scanlines), we subtract it
+ from pen_y, instead of adding to it.
+
+
+
b.Refined code
+
+
The following code is a refined version of the example
+ above. It uses features and functions of FreeType that
+ have not yet been introduced, and which are explained
+ below.
+
+
+FT_GlyphSlot slot = face->glyph; /* a small shortcut */
+FT_UInt glyph_index;
+int pen_x, pen_y, n;
+
+
+... initialize library ...
+... create face object ...
+... set character size ...
+
+pen_x = 300;
+pen_y = 200;
+
+for ( n = 0; n < num_chars; n++ )
+{
+ /* load glyph image into the slot (erase previous one) */
+ error = FT_Load_Char( face, text[n], FT_LOAD_RENDER );
+ if ( error )
+ continue; /* ignore errors */
+
+ /* now, draw to our target surface */
+ my_draw_bitmap( &slot->bitmap,
+ pen_x + slot->bitmap_left,
+ pen_y - slot->bitmap_top );
+
+ /* increment pen position */
+ pen_x += slot->advance.x >> 6;
+}
+
+
We have reduced the size of our code, but it does exactly
+ the same thing.
+
+
+
We use the
+ function FT_Load_Char
+ instead of FT_Load_Glyph. As you probably
+ imagine, it is equivalent to
+ calling FT_Get_Char_Index, then
+ FT_Load_Glyph.
+
+
+
We do not use FT_LOAD_DEFAULT for the
+ loading mode, but the bit
+ flag FT_LOAD_RENDER. It indicates that the
+ glyph image must be immediately converted to an
+ anti-aliased bitmap. This is of course a shortcut
+ that avoids calling FT_Render_Glyph
+ explicitly but is strictly equivalent.
+
+
Note that you can also specify that you want a
+ monochrome bitmap instead by using the
+ additional FT_LOAD_MONOCHROME load flag.
+
+
+
+
c. More Advanced Rendering
+
+
Let us try to render transformed text now (for example
+ through a rotation). We can do this
+ using FT_Set_Transform.
We now use a vector of type FT_Vector to
+ store the pen position, with coordinates expressed as
+ 1/64th of pixels, hence a multiplication. The position
+ is expressed in cartesian space.
+
+
Glyph images are always loaded, transformed, and
+ described in the cartesian coordinate system within
+ FreeType (which means that increasing Y corresponds
+ to upper scanlines), unlike the system typically used
+ for bitmaps (where the topmost scanline has
+ coordinate 0). We must thus convert between the
+ two systems when we define the pen position, and when we
+ compute the topleft position of the bitmap.
+
+
We set the transformation on each glyph to indicate
+ the rotation matrix as well as a delta that moves the
+ transformed image to the current pen position (in
+ cartesian space, not bitmap space). As a consequence,
+ the values of bitmap_left
+ and bitmap_top correspond to the bitmap origin
+ in target space pixels. We thus don't
+ add pen.x or pen.y to their values
+ when calling my_draw_bitmap.
+
+
The advance width is always returned transformed,
+ which is why it can be directly added to the current pen
+ position. Note that it is not rounded this
+ time.
+
+
+
A complete source code example can be found
+ here.
+
+
It is important to note that, while this example is a bit
+ more complex than the previous one, it is strictly
+ equivalent for the case where the transformation is the
+ identity. Hence it can be used as a replacement (but a
+ more powerful one).
+
+
The still present few shortcomings will be explained, and
+ solved, in the next part of this tutorial.
-
FT_FREETYPE_H is a special macro defined in the file
- ftheader.h. It contains some installation-specific macros
- to name other public header files of the FreeType 2 API.
The use of macros in #include statements is ANSI-compliant.
- It is used for several reasons:
-
-
-
-
It avoids some painful conflicts with the FreeType 1.x public
- header files.
-
-
-
-
The macro names are not limited to the DOS 8.3 file naming limit;
- names like FT_MULTIPLE_MASTERS_H or FT_SFNT_NAMES_H
- are a lot more readable and explanatory than the real file names
- ftmm.h and ftsnames.h.
-
-
-
-
It allows special installation tricks that will not be discussed
- here.
-
-
-
-
NOTE: Starting with FreeType 2.1.6, the old
- header file inclusion scheme is no longer supported. This means that
- you now get an error if you do something like the following:
It creates a new instance of the FreeType 2 library, and
- sets the handle library to it.
-
-
-
-
It loads each module that FreeType knows about in the library.
- Among others, your new library object is able
- to handle TrueType, Type 1, CID-keyed & OpenType/CFF fonts
- gracefully.
-
-
-
-
As you can see, the function returns an error code, like most others
- in the FreeType API. An error code of 0 always means that
- the operation was successful; otherwise, the value describes the error,
- and library is set to NULL.
-
-
-
-
-
- 3. Load a font face
-
-
-
- a. From a font file
-
-
-
Create a new face object by calling
- FT_New_Face. A face describes a given typeface
- and style. For example, ‘Times New Roman Regular’ and
- ‘Times New Roman Italic’ correspond to two different
- faces.
-
-
- FT_Library library; /* handle to library */
- FT_Face face; /* handle to face object */
-
-
- error = FT_Init_FreeType( &library );
- if ( error ) { ... }
-
- error = FT_New_Face( library,
- "/usr/share/fonts/truetype/arial.ttf",
- 0,
- &face );
- if ( error == FT_Err_Unknown_File_Format )
- {
- ... the font file could be opened and read, but it appears
- ... that its font format is unsupported
- }
- else if ( error )
- {
- ... another error code means that the font file could not
- ... be opened or read, or simply that it is broken...
- }
-
-
-
As you can certainly imagine, FT_New_Face opens a font
- file, then tries to extract one face from it. Its parameters are
-
-
-
-
- library
-
-
-
A handle to the FreeType library instance where the face object
- is created.
-
-
-
-
- filepathname
-
-
-
The font file pathname (a standard C string).
-
-
-
-
- face_index
-
-
-
Certain font formats allow several font faces to be embedded
- in a single file.
-
-
This index tells which face you want to load. An error will
- be returned if its value is too large.
-
-
Index 0 always work though.
-
-
-
-
- face
-
-
-
A pointer to the handle that will be set to describe
- the new face object.
-
-
It is set to NULL in case of error.
-
-
-
-
-
To know how many faces a given font file contains, simply load its
- first face (this is, face_index should be set to zero), then
- check the value of face->num_faces which indicates how
- many faces are embedded in the font file.
-
-
- b. From memory
-
-
-
In the case where you have already loaded the font file into memory,
- you can similarly create a new face object for it by calling
- FT_New_Memory_Face as in
-
-
- FT_Library library; /* handle to library */
- FT_Face face; /* handle to face object */
-
-
- error = FT_Init_FreeType( &library );
- if ( error ) { ... }
-
- error = FT_New_Memory_Face( library,
- buffer, /* first byte in memory */
- size, /* size in bytes */
- 0, /* face_index */
- &face );
- if ( error ) { ... }
-
-
-
As you can see, FT_New_Memory_Face simply takes a pointer
- to the font file buffer and its size in bytes instead of a file
- pathname. Other than that, it has exactly the same semantics as
- FT_New_Face.
-
-
Note that you must not deallocate the memory before calling
- FT_Done_Face.
-
-
- c. From other sources (compressed files, network, etc.)
-
-
-
There are cases where using a file pathname or preloading the file
- into memory is simply not sufficient. With FreeType 2, it is
- possible to provide your own implementation of i/o routines.
-
-
This is done through the
- FT_Open_Face function, which can be used to open a new
- font face with a custom input stream, select a specific driver for
- opening, or even pass extra parameters to the font driver when creating
- the object. We advise you to refer to the FreeType 2 reference
- manual in order to learn how to use it.
-
-
-
-
- 4. Accessing face content
-
-
-
A face object models all information that globally describes
- the face. Usually, this data can be accessed directly by dereferencing
- a handle, like in face−>num_glyphs.
-
-
The complete list of available fields in in the
- FT_FaceRec structure description. However, we describe
- here a few of them in more details:
-
-
-
-
-
- num_glyphs
-
-
-
This variable gives the number of glyphs available in
- the font face. A glyph is simply a character image. It doesn't
- necessarily correspond to a character code though.
-
-
-
-
- face_flags
-
-
-
A 32-bit integer containing bit flags used to describe some
- face properties. For example, the flag
- FT_FACE_FLAG_SCALABLE is used to indicate that the face's
- font format is scalable and that glyph images can be rendered for
- all character pixel sizes. For more information on face flags,
- please read the FreeType 2 API
- Reference.
-
-
-
-
- units_per_EM
-
-
-
This field is only valid for scalable formats (it is set
- to 0 otherwise). It indicates the number of font units
- covered by the EM.
-
-
-
-
- num_fixed_sizes
-
-
-
This field gives the number of embedded bitmap strikes
- in the current face. A strike is simply a series of
- glyph images for a given character pixel size. For example, a
- font face could include strikes for pixel sizes 10, 12
- and 14. Note that even scalable font formats can have
- embedded bitmap strikes!
-
-
-
-
- available_sizes
-
-
-
A pointer to an array of FT_Bitmap_Size
- elements. Each FT_Bitmap_Size indicates the horizontal
- and vertical character pixel sizes for each of the strikes
- that are present in the face.
-
-
Note that, generally speaking, these are
- not the cell size of the bitmap strikes.
-
-
-
-
-
-
-
-
- 5. Setting the current pixel size
-
-
-
FreeType 2 uses size objects to model all information
- related to a given character size for a given face. For example, a size
- object will hold the value of certain metrics like the ascender or text
- height, expressed in 1/64th of a pixel, for a character size of
- 12 points.
-
-
When the FT_New_Face function is called (or one of its
- cousins), it automatically creates a new size object for the
- returned face. This size object is directly accessible as
- face−>size.
-
-
NOTE: A single face object can deal with one or more size
- objects at a time; however, this is something that few programmers
- really need to do. We have thus decided to simplify the API for the
- most common use (i.e., one size per face) while keeping this feature
- available through additional functions.
-
-
When a new face object is created, all elements are set to 0
- during initialization. To populate the structure with sensible values,
- simply call
- FT_Set_Char_Size. Here is an example where the character
- size is set to 16pt for a 300×300dpi device:
-
-
- error = FT_Set_Char_Size(
- face, /* handle to face object */
- 0, /* char_width in 1/64th of points */
- 16*64, /* char_height in 1/64th of points */
- 300, /* horizontal device resolution */
- 300 ); /* vertical device resolution */
-
-
-
Some notes:
-
-
-
-
The character widths and heights are specified in 1/64th of
- points. A point is a physical distance, equaling 1/72th
- of an inch. Normally, it is not equivalent to a pixel.
-
-
-
-
A value of 0 for the character width means ‘same as
- character height’, a value of 0 for the character height
- means ‘same as character width’. Otherwise, it is
- possible to specify different character widths and heights.
-
-
-
-
The horizontal and vertical device resolutions are expressed in
- dots-per-inch, or dpi. Normal values are 72 or
- 96 dpi for display devices like the screen. The resolution
- is used to compute the character pixel size from the character
- point size.
-
-
-
-
A value of 0 for the horizontal resolution means
- ‘same as vertical resolution’, a value of 0 for the
- vertical resolution means ‘same as horizontal
- resolution’. If both values are zero, 72 dpi is used for
- both dimensions.
-
-
-
-
The first argument is a handle to a face object, not a size
- object.
-
-
-
-
This function computes the character pixel size that corresponds to
- the character width and height and device resolutions. However, if you
- want to specify the pixel sizes yourself, you can simply call
-
- FT_Set_Pixel_Sizes, as in
This example will set the character pixel sizes to
- 16×16 pixels. As previously, a value of 0 for one of
- the dimensions means ‘same as the other’.
-
-
Note that both functions return an error code. Usually, an error
- occurs with a fixed-size font format (like FNT or PCF) when trying to
- set the pixel size to a value that is not listed in the
- face->fixed_sizes array.
-
-
-
-
- 6. Loading a glyph image
-
-
-
- a. Converting a character code into a glyph index
-
-
-
Usually, an application wants to load a glyph image based on its
- character code, which is a unique value that defines the
- character for a given encoding. For example, the character
- code 65 represents the ‘A’ in ASCII encoding.
-
-
A face object contains one or more tables, called
- charmaps, that are used to convert character codes to glyph
- indices. For example, most TrueType fonts contain two charmaps. One
- is used to convert Unicode character codes to glyph indices, the other
- is used to convert Apple Roman encoding into glyph indices. Such
- fonts can then be used either on Windows (which uses Unicode) and
- Macintosh (which uses Apple Roman). Note also that a given
- charmap might not map to all the glyphs present in the font.
-
-
By default, when a new face object is created, it selects a
- Unicode charmap. FreeType tries to emulate a Unicode charmap if the
- font doesn't contain such a charmap, based on glyph names. Note that
- it is possible that the emulation misses glyphs if glyph names are
- non-standard. For some fonts, including symbol fonts and (older)
- fonts for Asian scripts, no Unicode emulation is possible at all.
-
-
We will describe later how to look for specific charmaps in a face.
- For now, we will assume that the face contains at least a Unicode
- charmap that was selected during a call to FT_New_Face. To
- convert a Unicode character code to a font glyph index, we use
- FT_Get_Char_Index, as in
This will look up the glyph index corresponding to the given
- charcode in the charmap that is currently selected for the
- face. You should use the UTF-32 representation form of Unicode; for
- example, if you want to load character U+1F028, use value 0x1F028 as
- the value for charcode.
-
-
If no charmap was selected, the function simply returns the
- charcode.
-
-
Note that this is one of the rare FreeType functions that do not
- return an error code. However, when a given character code has no
- glyph image in the face, the value 0 is returned. By convention,
- it always corresponds to a special glyph image called the missing
- glyph, which is commonly displayed as a box or a space.
-
-
- b. Loading a glyph from the face
-
-
-
Once you have a glyph index, you can load the corresponding glyph
- image. The latter can be stored in various formats within the font
- file. For fixed-size formats like FNT or PCF, each image is a bitmap.
- Scalable formats like TrueType or Type 1 use vectorial shapes,
- named outlines to describe each glyph. Some formats may have
- even more exotic ways of representing glyphs (e.g., MetaFont —
- but this format is not supported). Fortunately, FreeType 2 is
- flexible enough to support any kind of glyph format through a simple
- API.
-
-
The glyph image is always stored in a special object called a
- glyph slot. As its name suggests, a glyph slot is simply a
- container that is able to hold one glyph image at a time, be it a
- bitmap, an outline, or something else. Each face object has a single
- glyph slot object that can be accessed as face->glyph.
- Its fields are explained by the
- FT_GlyphSlotRec structure documentation.
-
-
Loading a glyph image into the slot is performed by calling
- FT_Load_Glyph as in
-
-
- error = FT_Load_Glyph(
- face, /* handle to face object */
- glyph_index, /* glyph index */
- load_flags ); /* load flags, see below */
-
-
-
The load_flags value is a set of bit flags used to
- indicate some special operations. The default value
- FT_LOAD_DEFAULT is 0.
-
-
This function will try to load the corresponding glyph image
- from the face:
-
-
-
-
If a bitmap is found for the corresponding glyph and pixel
- size, it will be loaded into the slot. Embedded bitmaps are
- always favored over native image formats, because we assume that
- they are higher-quality versions of the same glyph. This can be
- changed by using the FT_LOAD_NO_BITMAP flag.
-
-
-
-
Otherwise, a native image for the glyph will be loaded. It
- will also be scaled to the current pixel size, as well as hinted
- for certain formats like TrueType and Type 1.
-
-
-
-
The field face−>glyph−>format describes
- the format used to store the glyph image in the slot. If it is not
- FT_GLYPH_FORMAT_BITMAP, one can immediately convert it to a
- bitmap through
- FT_Render_Glyph as in:
The parameter render_mode is a set of bit flags used to
- specify how to render the glyph image. Set it to
- FT_RENDER_MODE_NORMAL to render a high-quality anti-aliased
- (256 gray levels) bitmap, as this is the default. You can
- alternatively use FT_RENDER_MODE_MONO if you want to generate
- a 1-bit monochrome bitmap.
-
-
Once you have a bitmapped glyph image, you can access it directly
- through glyph->bitmap (a simple bitmap descriptor), and
- position it through glyph->bitmap_left and
- glyph->bitmap_top.
-
-
Note that bitmap_left is the horizontal distance from the
- current pen position to the leftmost border of the glyph bitmap, while
- bitmap_top is the vertical distance from the pen position (on
- the baseline) to the topmost border of the glyph bitmap. It is
- positive to indicate an upwards distance.
-
-
The next section will give more details on the contents of a glyph
- slot and how to access specific glyph information (including
- metrics).
-
-
- c. Using other charmaps
-
-
-
As said before, when a new face object is created, it will look for
- a Unicode charmap and select it. The currently selected charmap is
- accessed via face->charmap. This field is NULL when no
- charmap is selected, which typically happens when you create a new
- FT_Face object from a font file that doesn't contain a
- Unicode charmap (which is rather infrequent today).
-
-
There are two ways to select a different charmap with
- FreeType 2. The easiest is when the encoding you need already
- has a corresponding enumeration defined in FT_FREETYPE_H, for
- example FT_ENCODING_BIG5. In this case, you can simply call
-
- FT_Select_CharMap as in:
Another way is to manually parse the list of charmaps for the face;
- this is accessible through the fields num_charmaps and
- charmaps (notice the ‘s&rsquo) of the face object. As
- you could expect, the first is the number of charmaps in the face,
- while the second is a table of pointers to the charmaps
- embedded in the face.
-
-
Each charmap has a few visible fields used to describe it more
- precisely. Mainly, one will look at charmap->platform_id
- and charmap->encoding_id that define a pair of values
- that can be used to describe the charmap in a rather generic way.
-
-
Each value pair corresponds to a given encoding. For example, the
- pair (3,1) corresponds to Unicode. The list is defined in the
- TrueType specification but you can also use the file
- FT_TRUETYPE_IDS_H which defines several helpful constants to
- deal with them.
-
-
To select a specific encoding, you need to find a corresponding
- value pair in the specification, then look for it in the charmaps
- list. Don't forget that there are encodings which correspond to
- several value pairs due to historical reasons. Here some code to do
- it:
-
-
- FT_CharMap found = 0;
- FT_CharMap charmap;
- int n;
-
-
- for ( n = 0; n < face->num_charmaps; n++ )
- {
- charmap = face->charmaps[n];
- if ( charmap->platform_id == my_platform_id &&
- charmap->encoding_id == my_encoding_id )
- {
- found = charmap;
- break;
- }
- }
-
- if ( !found ) { ... }
-
- /* now, select the charmap for the face object */
- error = FT_Set_CharMap( face, found );
- if ( error ) { ... }
-
-
-
Once a charmap has been selected, either through
- FT_Select_CharMap or FT_Set_CharMap, it is used by
- all subsequent calls to FT_Get_Char_Index.
-
-
- d. Glyph transformations
-
-
-
It is possible to specify an affine transformation to be applied to
- glyph images when they are loaded. Of course, this will only work for
- scalable (vectorial) font formats.
- error = FT_Set_Transform(
- face, /* target face object */
- &matrix, /* pointer to 2x2 matrix */
- &delta ); /* pointer to 2d vector */
-
-
-
This function will set the current transform for a given face
- object. Its second parameter is a pointer to a simple
- FT_Matrix structure that describes a 2×2 affine
- matrix. The third parameter is a pointer to a
- FT_Vector structure that describes a simple
- two-dimensional vector that is used to translate the glyph image
- after the 2×2 transformation.
-
-
Note that the matrix pointer can be set to NULL, in which case the
- identity transform will be used. Coefficients of the matrix are
- otherwise in 16.16 fixed-point units.
-
-
The vector pointer can also be set to NULL (in which case a delta
- of (0,0) will be used). The vector coordinates are expressed in
- 1/64th of a pixel (also known as 26.6 fixed-point numbers).
-
-
NOTE: The transformation is applied to every
- glyph that is loaded through FT_Load_Glyph and is
- completely independent of any hinting process. This means
- that you won't get the same results if you load a glyph at the size of
- 24 pixels, or a glyph at the size of 12 pixels scaled
- by 2 through a transform, because the hints will have been
- computed differently (except you have disabled hints).
-
-
If you ever need to use a non-orthogonal transformation with
- optimal hints, you first have to decompose your transformation into a
- scaling part and a rotation/shearing part. Use the scaling part to
- compute a new character pixel size, then the other one to call
- FT_Set_Transform. This is explained in details in a later
- section of this tutorial.
-
-
NOTE2: Rotation usually disables hinting.
-
-
Loading a glyph bitmap with a non-identity transformation works;
- the transformation is ignored in this case.
-
-
-
-
- 7. Simple text rendering
-
-
-
We will now present a very simple example used to render a string of
- 8-bit Latin-1 text, assuming a face that contains a Unicode charmap.
-
-
The idea is to create a loop that will, on each iteration, load one
- glyph image, convert it to an anti-aliased bitmap, draw it on the target
- surface, then increment the current pen position.
-
-
- a. Basic code
-
-
-
The following code performs our simple text rendering with the
- functions previously described.
-
-
- FT_GlyphSlot slot = face->glyph; /* a small shortcut */
- int pen_x, pen_y, n;
-
-
- ... initialize library ...
- ... create face object ...
- ... set character size ...
-
- pen_x = 300;
- pen_y = 200;
-
- for ( n = 0; n < num_chars; n++ )
- {
- FT_UInt glyph_index;
-
-
- /* retrieve glyph index from character code */
- glyph_index = FT_Get_Char_Index( face, text[n] );
-
- /* load glyph image into the slot (erase previous one) */
- error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
- if ( error )
- continue; /* ignore errors */
-
- /* convert to an anti-aliased bitmap */
- error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL );
- if ( error )
- continue;
-
- /* now, draw to our target surface */
- my_draw_bitmap( &slot->bitmap,
- pen_x + slot->bitmap_left,
- pen_y - slot->bitmap_top );
-
- /* increment pen position */
- pen_x += slot->advance.x >> 6;
- pen_y += slot->advance.y >> 6; /* not useful for now */
- }
-
-
-
This code needs a few explanations:
-
-
-
-
We define a handle named slot that points to the
- face object's glyph slot. (The type FT_GlyphSlot is
- a pointer). That is a convenience to avoid using
- face->glyph->XXX every time.
-
-
-
-
We increment the pen position with the vector
- slot->advance, which correspond to the glyph's
- advance width (also known as its escapement).
- The advance vector is expressed in 1/64th of pixels, and is
- truncated to integer pixels on each iteration.
-
-
-
-
The function my_draw_bitmap is not part of FreeType
- but must be provided by the application to draw the bitmap to the
- target surface. In this example, it takes a pointer to a
- FT_Bitmap descriptor and the position of its top-left corner as
- arguments.
-
-
-
-
The value of slot->bitmap_top is positive for an
- upwards vertical distance. Assuming that the coordinates
- taken by my_draw_bitmap use the opposite convention
- (increasing Y corresponds to downwards scanlines), we
- subtract it from pen_y, instead of adding to it.
-
-
-
-
- b. Refined code
-
-
-
The following code is a refined version of the example above. It
- uses features and functions of FreeType 2 that have not yet been
- introduced, and which are explained below:
-
-
- FT_GlyphSlot slot = face->glyph; /* a small shortcut */
- FT_UInt glyph_index;
- int pen_x, pen_y, n;
-
-
- ... initialize library ...
- ... create face object ...
- ... set character size ...
-
- pen_x = 300;
- pen_y = 200;
-
- for ( n = 0; n < num_chars; n++ )
- {
- /* load glyph image into the slot (erase previous one) */
- error = FT_Load_Char( face, text[n], FT_LOAD_RENDER );
- if ( error )
- continue; /* ignore errors */
-
- /* now, draw to our target surface */
- my_draw_bitmap( &slot->bitmap,
- pen_x + slot->bitmap_left,
- pen_y - slot->bitmap_top );
-
- /* increment pen position */
- pen_x += slot->advance.x >> 6;
- }
-
-
-
We have reduced the size of our code, but it does exactly the
- same thing:
-
-
-
-
We use the function FT_Load_Char instead of
- FT_Load_Glyph. As you probably imagine, it is equivalent
- to calling FT_Get_Char_Index then
- FT_Load_Glyph.
-
-
-
-
We do not use FT_LOAD_DEFAULT for the loading mode,
- but the bit flag FT_LOAD_RENDER. It indicates that the
- glyph image must be immediately converted to an anti-aliased
- bitmap. This is of course a shortcut that avoids calling
- FT_Render_Glyph explicitly but is strictly
- equivalent.
-
-
Note that you can also specify that you want a monochrome
- bitmap instead by using the addition FT_LOAD_MONOCHROME
- load flag.
-
-
-
-
- c. More advanced rendering
-
-
-
Let us try to render transformed text now (for example through a
- rotation). We can do this using FT_Set_Transform. Here is how
- to do it:
We now use a vector of type FT_Vector to store the pen
- position, with coordinates expressed as 1/64th of pixels, hence a
- multiplication. The position is expressed in cartesian space.
-
-
-
-
Glyph images are always loaded, transformed, and described in the
- cartesian coordinate system in FreeType (which means that
- increasing Y corresponds to upper scanlines), unlike the system
- typically used for bitmaps (where the topmost scanline has
- coordinate 0). We must thus convert between the two systems
- when we define the pen position, and when we compute the topleft
- position of the bitmap.
-
-
-
-
We set the transformation on each glyph to indicate the rotation
- matrix as well as a delta that will move the transformed image to
- the current pen position (in cartesian space, not bitmap space).
-
-
As a consequence, the values of bitmap_left and
- bitmap_top correspond to the bitmap origin in target space
- pixels. We thus don't add pen.x or pen.y to their
- values when calling my_draw_bitmap.
-
-
-
-
The advance width is always returned transformed, which is why it
- can be directly added to the current pen position. Note that it is
- not rounded this time.
-
-
-
-
A complete source code example can be found
- here.
-
-
It is important to note that, while this example is a bit more
- complex than the previous one, it is strictly equivalent for the case
- where the transform is the identity. Hence it can be used as a
- replacement (but a more powerful one).
-
-
It has however a few shortcomings that we will explain, and solve, in
- the next part of this tutorial.
-
-
-
-
- Conclusion
-
-
-
In this first section, you have learned the basics of
- FreeType 2, as well as sufficient knowledge how to render rotated
- text.
-
-
The next section will dive into more details of the API in order
- to let you access glyph metrics and images directly, as well as
- how to deal with scaling, hinting, kerning, etc.
-
-
The third section will discuss issues like modules, caching and a few
- other advanced topics like how to use multiple size objects with a
- single face. [This part hasn't been written yet.]
This is the second section of the FreeType 2 tutorial. It
- describes how to
-
-
-
retrieve glyph metrics
-
easily manage glyph images
-
retrieve global metrics (including kerning)
-
render a simple string of text, with kerning
-
render a centered string of text (with kerning)
-
render a transformed string of text (with centering)
-
access metrics in design font units when needed,
- and how to scale them to device space
-
-
-
-
-
- 1. Glyph metrics
-
-
-
Glyph metrics are, as their name suggests, certain distances
- associated with each glyph in order to describe how to use it to layout
- text.
-
-
There are usually two sets of metrics for a single glyph: Those used
- to layout the glyph in horizontal text layouts (Latin, Cyrillic, Arabic,
- Hebrew, etc.), and those used to layout the glyph in vertical text
- layouts (Chinese, Japanese, Korean, etc.).
-
-
Note that only a few font formats provide vertical metrics. You can
- test whether a given face object contains them by using the macro
- FT_HAS_VERTICAL, which is true when appropriate.
-
-
Individual glyph metrics can be accessed by first loading the glyph
- in a face's glyph slot, then accessing them through the
- face->glyph->metrics structure, whose type is
- FT_Glyph_Metrics. We will discuss this in more detail
- below; for now, we only note that it contains the following fields:
-
-
-
-
- width
-
-
-
This is the width of the glyph image's bounding box. It is
- independent of the layout direction.
-
-
-
-
- height
-
-
-
This is the height of the glyph image's bounding box. It is
- independent of the layout direction. Be careful not to confuse it
- with the ‘height’ field in the
- FT_Size_Metrics structure.
-
-
-
-
- horiBearingX
-
-
-
For horizontal text layouts, this is the horizontal
- distance from the current cursor position to the leftmost border of
- the glyph image's bounding box.
-
-
-
-
- horiBearingY
-
-
-
For horizontal text layouts, this is the vertical
- distance from the current cursor position (on the baseline) to the
- topmost border of the glyph image's bounding box.
-
-
-
-
- horiAdvance
-
-
-
For horizontal text layouts, this is the horizontal
- distance used to increment the pen position when the glyph is drawn
- as part of a string of text.
-
-
-
-
- vertBearingX
-
-
-
For vertical text layouts, this is the horizontal
- distance from the current cursor position to the leftmost border of
- the glyph image's bounding box.
-
-
-
-
- vertBearingY
-
-
-
For vertical text layouts, this is the vertical distance
- from the current cursor position (on the baseline) to the topmost
- border of the glyph image's bounding box.
-
-
-
-
- vertAdvance
-
-
-
For vertical text layouts, this is the vertical distance
- used to increment the pen position when the glyph is drawn as part
- of a string of text.
-
-
-
-
-
-
NOTE: As not all fonts do contain vertical
- metrics, the values of vertBearingX, vertBearingY and
- vertAdvance should not be considered reliable when
- FT_HAS_VERTICAL is false.
-
-
The following graphics illustrate the metrics more clearly. First,
- for horizontal metrics, where the baseline is the horizontal axis:
-
-
-
-
-
-
For vertical text layouts, the baseline is vertical, identical to the
- vertical axis:
-
-
-
-
-
-
The metrics found in face->glyph->metrics are normally
- expressed in 26.6 pixel format (i.e., 1/64th of pixels), unless you use
- the FT_LOAD_NO_SCALE flag when calling FT_Load_Glyph
- or FT_Load_Char. In this case, the metrics will be expressed
- in original font units.
-
-
The glyph slot object has also a few other interesting fields that
- will ease a developer's work. You can access them through
- face->glyph->xxx, where xxx is one of the
- following fields:
-
-
-
-
- advance
-
-
-
This field is a FT_Vector which holds the transformed
- advance for the glyph. That is useful when you are using a transform
- through FT_Set_Transform, as shown in the rotated text
- example of section I. Other than that, its value is
- by default (metrics.horiAdvance,0), unless you specify
- FT_LOAD_VERTICAL when loading the glyph image;
- it will then be (0,metrics.vertAdvance)
-
-
-
-
- linearHoriAdvance
-
-
-
This field contains the linearly scaled value of the glyph's
- horizontal advance width. Indeed, the value of
- metrics.horiAdvance that is returned in the glyph slot is
- normally rounded to integer pixel coordinates (i.e., it will be a
- multiple of 64) by the font driver used to load the glyph
- image. linearHoriAdvance is a 16.16 fixed-point number
- that gives the value of the original glyph advance width in
- 1/65536th of pixels. It can be use to perform pseudo
- device-independent text layouts.
-
-
-
-
- linearVertAdvance
-
-
-
This is the similar to linearHoriAdvance but for the
- glyph's vertical advance height. Its value is only reliable if the
- font face contains vertical metrics.
The glyph image that is loaded in a glyph slot can be converted into
- a bitmap, either by using FT_LOAD_RENDER when loading it, or by
- calling FT_Render_Glyph. Each time you load a new glyph image,
- the previous one is erased from the glyph slot.
-
-
There are situations, however, where you may need to extract this
- image from the glyph slot in order to cache it within your application,
- and even perform additional transformations and measures on it before
- converting it to a bitmap.
-
-
The FreeType 2 API has a specific extension which is capable of
- dealing with glyph images in a flexible and generic way. To use it, you
- first need to include the
- FT_GLYPH_H header file, as in:
-
-
- #include FT_GLYPH_H
-
-
-
We will now explain how to use the functions defined in this
- file:
-
-
- a. Extracting the glyph image:
-
-
-
You can extract a single glyph image very easily. Here some code
- that shows how to do it:
-
-
- FT_Glyph glyph; /* a handle to the glyph image */
+
Created a variable, named glyph, of type
- FT_Glyph. This is a handle (pointer) to an
- individual glyph image.
-
-
-
-
Loaded the glyph image normally in the face's glyph slot. We
- did not use FT_LOAD_RENDER because we want to grab a
- scalable glyph image, in order to later transform it.
-
-
-
-
Copy the glyph image from the slot into a new FT_Glyph
- object, by calling
- FT_Get_Glyph. This function returns an error code
- and sets glyph.
-
-
-
-
It is important to note that the extracted glyph is in the same
- format as the original one that is still in the slot. For example,
- if we are loading a glyph from a TrueType font file, the glyph image
- will really be a scalable vector outline.
-
-
You can access the field glyph->format if you want to
- know exactly how the glyph is modeled and stored. A new glyph object
- can be destroyed with a call to
- FT_Done_Glyph.
-
-
The glyph object contains exactly one glyph image and a 2D vector
- representing the glyph's advance in 16.16 fixed-point coordinates.
- The latter can be accessed directly as glyph->advance
-
-
Note that unlike other FreeType objects, the
- library doesn't keep a list of all allocated glyph objects. This
- means you have to destroy them yourself instead of relying on
- FT_Done_FreeType doing all the clean-up.
-
-
- b. Transforming & copying the glyph image
-
-
-
If the glyph image is scalable (i.e., if glyph->format
- is not equal to FT_GLYPH_FORMAT_BITMAP), it is possible to
- transform the image anytime by a call to
- FT_Glyph_Transform.
-
-
You can also copy a single glyph image with
- FT_Glyph_Copy. Here is some example code:
Glyph metrics are, as the name suggests, certain
+ distances associated with each glyph that describe how to
+ position this glyph while creating a text layout.
- error = FT_Glyph_Copy( glyph, &glyph2 );
- if ( error ) { ... could not copy (out of memory) ... }
+
There are usually two sets of metrics for a single glyph:
+ Those used to represent glyphs in horizontal text layouts
+ (Latin, Cyrillic, Arabic, Hebrew, etc.), and those used to
+ represent glyphs in vertical text layouts (Chinese,
+ Japanese, Korean, Mongolian, etc.).
- /* translate `glyph' */
+
Note that only a few font formats provide vertical
+ metrics. You can test whether a given face object
+ contains them by using the
+ macro FT_HAS_VERTICAL,
+ which returns true if appropriate.
- delta.x = -100 * 64; /* coordinates are in 26.6 pixel format */
- delta.y = 50 * 64;
+
Individual glyph metrics can be accessed by first loading
+ the glyph in a face's glyph slot, then accessing them
+ through the face->glyph->metrics structure,
+ whose type
+ is FT_Glyph_Metrics.
+ We will discuss this in more detail below; for now, we
+ only note that it contains the following fields.
- FT_Glyph_Transform( glyph, 0, &delta );
+
+
width
+
This is the width of the glyph image's bounding box.
+ It is independent of the layout direction.
- /* transform glyph2 (horizontal shear) */
+
height
+
This is the height of the glyph image's bounding box.
+ It is independent of the layout direction. Be careful
+ not to confuse it with the ‘height’ field in
+ the
+ FT_Size_Metrics structure.
For horizontal text layouts, this is the
+ horizontal distance from the current cursor position to
+ the leftmost border of the glyph image's bounding
+ box.
- FT_Glyph_Transform( glyph2, &matrix, 0 );
-
+
horiBearingY
+
For horizontal text layouts, this is the
+ vertical distance from the current cursor position (on
+ the baseline) to the topmost border of the glyph image's
+ bounding box.
-
Note that the 2×2 transform matrix is always applied to the
- 16.16 advance vector in the glyph; you thus don't need to recompute
- it.
+
horiAdvance
+
For horizontal text layouts, this is the
+ horizontal distance to increment the pen position when
+ the glyph is drawn as part of a string of text.
-
- c. Measuring the glyph image
-
+
vertBearingX
+
For vertical text layouts, this is the
+ horizontal distance from the current cursor position to
+ the leftmost border of the glyph image's bounding
+ box.
-
You can also retrieve the control (bounding) box of any glyph image
- (scalable or not) through the
- FT_Glyph_Get_CBox function, as in:
+
vertBearingY
+
For vertical text layouts, this is the
+ vertical distance from the current cursor position (on
+ the baseline) to the topmost border of the glyph image's
+ bounding box.
-
+
vertAdvance
+
For vertical text layouts, this is the
+ vertical distance used to increment the pen position
+ when the glyph is drawn as part of a string of
+ text.
+
+
+
As not all fonts do contain vertical
+ metrics, the values of vertBearingX,
+ vertBearingY and vertAdvance should not
+ be considered reliable if FT_HAS_VERTICAL returns
+ false.
+
+
The following graphics illustrate the metrics more
+ clearly. In case a distance is directed, it is marked
+ with a single arrow, indicating a positive value. The
+ first image displays horizontal metrics, where the
+ baseline is the horizontal axis.
+
+
+
+
+
+
For vertical text layouts, the baseline is vertical,
+ identical to the vertical axis. Contrary to all other
+ arrows, bearingX shows a negative value in this
+ image.
+
+
+
+
+
+
The metrics found in face->glyph->metrics
+ are normally expressed in 26.6 pixel format (i.e., 1/64th
+ of pixels), unless you use the FT_LOAD_NO_SCALE
+ flag when calling FT_Load_Glyph
+ or FT_Load_Char. In this case, the metrics are
+ expressed in original font units.
+
+
The glyph slot object has also a few other interesting
+ fields that eases a developer's work. You can access them
+ through face->glyph->xxx,
+ where xxx is one of the following fields.
+
+
+
advance
+
This field is a FT_Vector that holds the
+ transformed advance for the glyph. That is useful when
+ you are using a transformation
+ through FT_Set_Transform, as shown in the
+ rotated text
+ example of part I. Other than that, its value
+ is by default (metrics.horiAdvance,0), unless you
+ specify FT_LOAD_VERTICAL when loading the glyph
+ image; it is then (0,metrics.vertAdvance).
+
+
linearHoriAdvance
+
This field contains the linearly scaled value of the
+ glyph's horizontal advance width. Indeed, the value of
+ metrics.horiAdvance that is returned in the
+ glyph slot is normally rounded to integer pixel
+ coordinates (i.e., being a multiple of 64) by the
+ font driver that actually loads the glyph
+ image. linearHoriAdvance is a 16.16
+ fixed-point number that gives the value of the original
+ glyph advance width in 1/65536th of pixels. It can be
+ use to perform pseudo device-independent text
+ layouts.
+
+
linearVertAdvance
+
This is the similar to linearHoriAdvance but
+ for the glyph's vertical advance height. Its value is
+ only reliable if the font face contains vertical
+ metrics.
+
+
+
+
2. Managing Glyph Images
+
+
The glyph image that is loaded in a glyph slot can be
+ converted into a bitmap, either by
+ using FT_LOAD_RENDER when loading it, or by
+ calling FT_Render_Glyph.
+ Each time you load a new glyph image, the previous one is
+ erased from the glyph slot.
+
+
There are situations, however, where you may need to
+ extract this image from the glyph slot in order to cache
+ it within your application, and even perform additional
+ transformations and measures on it before converting it to
+ a bitmap.
+
+
The FreeType 2 API has a specific extension that is
+ capable of dealing with glyph images in a flexible and
+ generic way. To use it, you first need to include
+ the FT_GLYPH_H
+ header file.
+
+
+#include FT_GLYPH_H
+
+
a.Extracting the Glyph Image
+
+
You can extract a single glyph image very easily. Here
+ some code that shows how to do it.
Create a variable named glyph, of
+ type FT_Glyph.
+ This is a handle (pointer) to an individual glyph
+ image.
+
+
Load the glyph image in the normal way into the face's
+ glyph slot. We don't use FT_LOAD_RENDER
+ because we want to grab a scalable glyph image that we
+ can transform later on.
+
+
Copy the glyph image from the slot into a
+ new FT_Glyph object by
+ calling FT_Get_Glyph.
+ This function returns an error code and
+ sets glyph.
+
+
+
It is important to note that the extracted glyph is in
+ the same format as the original one that is still in the
+ slot. For example, if we are loading a glyph from a
+ TrueType font file, the glyph image is really a scalable
+ vector outline. You can access the
+ field glyph->format if you want to know
+ exactly how the glyph is modeled and stored.
+
+
A new glyph object can be destroyed with a call
+ to FT_Done_Glyph.
+
+
The glyph object contains exactly one glyph image and a
+ 2D vector representing the glyph's advance in 16.16
+ fixed-point coordinates. The latter can be accessed
+ directly as glyph->advance
+
+
Note that unlike other FreeType objects,
+ the library doesn't keep a list of all allocated glyph
+ objects. This means you have to destroy them yourself
+ instead of relying on FT_Done_FreeType doing all
+ the clean-up.
+
+
b. Transforming & Copying the Glyph Image
+
+
If the glyph image is scalable (i.e.,
+ if glyph->format is not equal
+ to FT_GLYPH_FORMAT_BITMAP), it is possible to
+ transform the image anytime by a call
+ to FT_Glyph_Transform.
+
+
You can also copy a single glyph image
+ with FT_Glyph_Copy.
Coordinates are relative to the glyph origin (0,0), using
+ the y upwards convention. This function takes a
+ special argument, the bbox mode, to indicate how
+ box coordinates are expressed.
+
+
If the glyph has been loaded
+ with FT_LOAD_NO_SCALE, bbox_mode must be
+ set to FT_GLYPH_BBOX_UNSCALED to get unscaled
+ font units in 26.6 pixel format. The
+ value FT_GLYPH_BBOX_SUBPIXELS is another name for
+ this constant.
+
+
Note that the box's maximum coordinates are exclusive,
+ which means that you can always compute the width and
+ height of the glyph image (regardless of using integer or
+ 26.6 coordinates) with a simple subtraction.
Note also that for 26.6 coordinates, if
+ FT_GLYPH_BBOX_GRIDFIT is used as the bbox mode,
+ the coordinates are also grid-fitted, which corresponds to
+ the following four lines.
To get the bbox in integer pixel coordinates,
+ set bbox_mode
+ to FT_GLYPH_BBOX_TRUNCATE.
+
+
Finally, to get the bounding box in grid-fitted pixel
+ coordinates, set bbox_mode
+ to FT_GLYPH_BBOX_PIXELS.
+
+
[Computing exact bounding boxes can be done with
+ function FT_Outline_Get_BBox,
+ at the cost of slower execution. You probably don't need
+ with the possible exception of rotated glyphs.]
+
+
d. Converting the Glyph Image to a Bitmap
+
+
You may need to convert the glyph object to a bitmap once
+ you have conveniently cached or transformed it. This can
+ be done easily with
+ the FT_Glyph_To_Bitmap
+ function, which handles any glyph object.
The first parameter is the address of the source
+ glyph's handle. When the function is called, it reads
+ it to access the source glyph object. After the call,
+ the handle points to a new glyph object that
+ contains the rendered bitmap.
+
+
The second parameter is a standard render mode to
+ specify what kind of bitmap we want. For example, it
+ can be FT_RENDER_MODE_DEFAULT for an 8-bit
+ anti-aliased pixmap, or FT_RENDER_MODE_MONO for
+ a 1-bit monochrome bitmap.
+
+
The third parameter is a pointer to a two-dimensional
+ vector to translate the source glyph image before the
+ conversion. After the call, the source image is
+ translated back to its original position (and is thus
+ left unchanged). If you do not need to translate the
+ source glyph before rendering, set this pointer
+ to NULL.
+
+
The last parameter is a boolean that indicates whether
+ the source glyph object should be destroyed by the
+ function. If false, the original glyph object is never
+ destroyed, even if its handle is lost (it is up to
+ client applications to keep it).
+
+
+
The new glyph object always contains a bitmap (if no
+ error is returned), and you must typecast its
+ handle to the FT_BitmapGlyph type in order to
+ access its content. This type is a sort of
+ ‘subclass’ of FT_Glyph that contains
+ additional fields
+ (see FT_BitmapGlyphRec).
+
+
+
left
+
Just like the bitmap_left field of a glyph
+ slot, this is the horizontal distance from the glyph
+ origin (0,0) to the leftmost pixel of the glyph bitmap.
+ It is expressed in integer pixels.
+
+
top
+
Just like the bitmap_top field of a glyph
+ slot, this is the vertical distance from the glyph
+ origin (0,0) to the topmost pixel of the glyph bitmap
+ (more precise, to the pixel just above the bitmap).
+ This distance is expressed in integer pixels, and is
+ positive for upwards y.
+
+
bitmap
+
This is a bitmap descriptor for the glyph object, just
+ like the bitmap field in a glyph slot.
+
+
+
+
3. Global Glyph Metrics
+
+
Unlike glyph metrics, global metrics are used to describe
+ distances and features of a whole font face. They can be
+ expressed either in 26.6 pixel format or in (unscaled)
+ font units for scalable formats.
+
+
a. Design global metrics
+
+
For scalable formats, all global metrics are expressed in
+ font units in order to be later scaled to the device
+ space, according to the rules described in the last
+ section of this tutorial part. You can access them
+ directly as fields of a FT_Face handle.
+
+
However, you need to check that the font face's format is
+ scalable before using them. One can do it with
+ macro FT_IS_SCALABLE, which returns true when
+ appropriate.
+
+
Here a table of the global design metrics for scalable
+ faces.
+
+
+
units_per_EM
+
This is the size of the EM square for the font face.
+ It is used by scalable formats to scale design
+ coordinates to device pixels, as described in the last
+ section of this tutorial part. Its value usually is
+ 2048 (for TrueType) or 1000 (for Type 1 or CFF),
+ but other values are possible, too. It is set to 1
+ for fixed-size formats like FNT, FON, PCF, or BDF.
+
+
bbox
+
The global bounding box is defined as the smallest
+ rectangle that can enclose all the glyphs in a font
+ face.
+
+
ascender
+
The ascender is the vertical distance from the
+ horizontal baseline to the highest
+ ‘character’ coordinate in a font face.
+ Unfortunately, font formats don't define the ascender in
+ a uniform way. For some formats, it represents the
+ ascent of all capital latin characters (without
+ accents), for others it is the ascent of the highest
+ accented character, and finally, other formats define it
+ as being equal to bbox.yMax.
+
+
descender
+
The descender is the vertical distance from the
+ horizontal baseline to the lowest
+ ‘character’ coordinate in a font face.
+ Unfortunately, font formats don't define the descender
+ in a uniform way. For some formats, it represents the
+ descent of all capital latin characters (without
+ accents), for others it is the ascent of the lowest
+ accented character, and finally, other formats define it
+ as being equal to bbox.yMin. This field is
+ negative for values below the baseline.
+
+
height
+
This field represents a default line spacing
+ (i.e., the baseline-to-baseline distance) when writing
+ text with this font. Note that it usually is larger
+ than the sum of the ascender and descender taken as
+ absolute values. There is also no guarantee that no
+ glyphs extend above or below subsequent baselines when
+ using this distance – think of it as a value the
+ designer of the font finds appropriate.
+
+
max_advance_width
+
This field gives the maximum horizontal cursor advance
+ for all glyphs in the font. It can be used to quickly
+ compute the maximum advance width of a string of
+ text. It doesn't correspond to the maximum glyph
+ image width!
+
+
max_advance_height
+
Same as max_advance_width but for vertical
+ text layout.
+
+
underline_position
+
When displaying or rendering underlined text, this
+ value corresponds to the vertical position, relative to
+ the baseline, of the underline bar's center. It is
+ negative if it is below the baseline.
+
+
underline_thickness
+
When displaying or rendering underlined text, this
+ value corresponds to the vertical thickness of the
+ underline.
+
+
+
Notice that the values of the ascender and the descender
+ are not reliable (due to various discrepancies in font
+ formats), unfortunately.
+
+
b. Scaled Global Metrics
+
+
Each size object also contains a scaled version of some
+ of the global metrics described above, to be directly
+ accessed through the face->size->metrics
+ structure (of type
+ FT_Size_Metrics). No rounding or
+ grid-fitting is performed for those values. They are
+ also completely independent of any hinting process. In
+ other words, don't rely on them to get exact metrics at
+ the pixel level. They are expressed in 26.6 pixel
+ format.
+
+
+
ascender
+
The scaled version of the original design
+ ascender.
+
+
descender
+
The scaled version of the original design
+ descender.
+
+
height
+
+
The scaled version of the original design text height
+ (the vertical distance from one baseline to the next).
+ This is probably the only field you should really use
+ in this structure.
+
+
Be careful not to confuse it with the
+ ‘height’ field in
+ the FT_Glyph_Metrics
+ structure.
+
+
+
max_advance
+
The scaled version of the original design maximum
+ advance.
+
+
+
Note that the face->size->metrics
+ structure contains other fields that are used to scale
+ design coordinates to device space. They are described in
+ the last section.
+
+
c. Kerning
+
+
Kerning is the process of adjusting the position of two
+ subsequent glyph images in a string of text in order to
+ improve the general appearance of text. For example, if a
+ glyph for an uppercase ‘A’ is followed by a
+ glyph for an uppercase ‘V’, the space between
+ the two glyphs can be slightly reduced to avoid extra
+ ‘diagonal whitespace’.
+
+
Note that in theory kerning can happen both in the
+ horizontal and vertical direction between two glyphs;
+ however, it only happens in a single direction in nearly
+ all cases.
+
+
Not all font formats contain kerning information, and not
+ all kerning formats are supported by FreeType; in
+ particular, for TrueType fonts, the API can only access
+ kerning via the ‘kern’
+ table. OpenType kerning via the
+ ‘GPOS’ table is not supported! You
+ need a higher-level library
+ like HarfBuzz,
+ Pango,
+ or ICU, since
+ GPOS kerning requires contextual string handling.
+
+
Sometimes, the font file is associated with an additional
+ file that contains various glyph metrics, including
+ kerning, but no glyph images. A good example is the
+ Type 1 format where glyph images are stored in files
+ with extension .pfa or .pfb, while
+ kerning metrics can be found in files with extension
+ .afm or .pfm.
+
+
FreeType 2 allows you to deal with this, by
+ providing
+ the FT_Attach_File
+ and FT_Attach_Stream
+ APIs. Both functions are used to load additional metrics
+ into a face object by reading them from an additional
+ format-specific file. Here an example, opening a
+ Type 1 font.
Note that FT_Attach_Stream is similar to
+ FT_Attach_File except that it doesn't take a
+ C string to name the extra file but
+ an FT_Stream
+ handle. Also, reading a metrics file is in no way
+ mandatory.
+
+
Finally, the file attachment APIs are very generic and
+ can be used to load any kind of extra information for a
+ given face. The nature of the additional content is
+ entirely font format specific.
+
+
FreeType 2 allows you to retrieve the kerning
+ information between two glyphs through
+ the FT_Get_Kerning
+ function.
+
+
+FT_Vector kerning;
+
+
+...
+error = FT_Get_Kerning( face, /* handle to face object */
+ left, /* left glyph index */
+ right, /* right glyph index */
+ kerning_mode, /* kerning mode */
+ &kerning ); /* target vector */
+
+
This function takes a handle to a face object, the
+ indices of the left and right glyph for which the kerning
+ value is desired, an integer, called the kerning
+ mode, and a pointer to a destination vector that
+ receives the corresponding distances.
+
+
The kerning mode is very similar to the bbox
+ mode described in a previous section. It is a
+ enumeration that indicates how the kerning distances are
+ expressed in the target vector.
+
+
The default value is FT_KERNING_DEFAULT, which
+ has value 0. It corresponds to kerning distances
+ expressed in 26.6 grid-fitted pixels (which means that the
+ values are multiples of 64). For scalable formats, this
+ means that the design kerning distance is scaled, then
+ rounded.
+
+
The value FT_KERNING_UNFITTED corresponds to
+ kerning distances expressed in 26.6 unfitted pixels (i.e.,
+ that do not correspond to integer coordinates). It is the
+ design kerning distance that is scaled without
+ rounding.
+
+
Finally, the value FT_KERNING_UNSCALED indicates
+ to return the design kerning distance, expressed in font
+ units. You can later scale it to the device space using
+ the computations explained in the last section of this
+ part.
+
+
Note that the ‘left’ and ‘right’
+ positions correspond to the visual order of the
+ glyphs in the string of text. This is important for
+ bidirectional or right-to-left text.
+
+
+
4. Simple Text Rendering: Kerning and Centering
+
+
In order to show off what we have just learned, we now
+ demonstrate how to modify
+ the example code that
+ was provided in part I to render a string of text,
+ and enhance it to support kerning and delayed
+ rendering.
+
+
a. Kerning Support
+
+
Adding support for kerning to our code is trivial, as
+ long as we consider that we are still dealing with a
+ left-to-right script like Latin. We simply need to
+ retrieve the kerning distance between two glyphs in order
+ to alter the pen position appropriately.
+
+
+FT_GlyphSlot slot = face->glyph; /* a small shortcut */
+FT_UInt glyph_index;
+FT_Bool use_kerning;
+FT_UInt previous;
+int pen_x, pen_y, n;
+
+
+... initialize library ...
+... create face object ...
+... set character size ...
+
+pen_x = 300;
+pen_y = 200;
+
+use_kerning = FT_HAS_KERNING( face );
+previous = 0;
+
+for ( n = 0; n < num_chars; n++ )
+{
+ /* convert character code to glyph index */
+ glyph_index = FT_Get_Char_Index( face, text[n] );
+
+ /* retrieve kerning distance and move pen position */
+ if ( use_kerning && previous && glyph_index )
+ {
+ FT_Vector delta;
+
+
+ FT_Get_Kerning( face, previous, glyph_index,
+ FT_KERNING_DEFAULT, &delta );
+
+ pen_x += delta.x >> 6;
+ }
+
+ /* load glyph image into the slot (erase previous one) */
+ error = FT_Load_Glyph( face, glyph_index, FT_LOAD_RENDER );
+ if ( error )
+ continue; /* ignore errors */
+
+ /* now draw to our target surface */
+ my_draw_bitmap( &slot->bitmap,
+ pen_x + slot->bitmap_left,
+ pen_y - slot->bitmap_top );
+
+ /* increment pen position */
+ pen_x += slot->advance.x >> 6;
+
+ /* record current glyph index */
+ previous = glyph_index;
+}
+
+
We are done. Some notes.
+
+
+
As kerning is determined by glyph indices, we need
+ to explicitly convert our character codes into glyph
+ indices, then later call FT_Load_Glyph instead
+ of FT_Load_Char.
+
+
We use a boolean named use_kerning, which is
+ set to the result of the macro FT_HAS_KERNING.
+ It is certainly faster not to
+ call FT_Get_Kerning when we know that the font
+ face does not contain kerning information.
+
+
We move the position of the pen before a new
+ glyph is drawn.
+
+
We initialize the variable previous with the
+ value 0, which always corresponds to the
+ ‘missing glyph’ (also
+ called .notdef in the PostScript world). There
+ is never any kerning distance associated with this
+ glyph.
+
+
We do not check the error code returned by
+ FT_Get_Kerning. This is because the function
+ always sets the content of delta to (0,0) if
+ an error occurs.
+
+
+
b. Centering
+
+
Our code begins to become interesting but it is still a
+ bit too simple for normal use. For example, the position
+ of the pen is determined before we do the rendering;
+ normally, you would rather determine the layout of the
+ text and measure it before computing its final position
+ (centering, etc.), or perform things like
+ word-wrapping.
+
+
Let us now decompose our text rendering function into two
+ distinct but successive parts: The first one positions
+ individual glyph images on the baseline, while the second
+ one renders the glyphs. As we will see, this has many
+ advantages.
+
+
We thus start by storing individual glyph images, as well
+ as their position on the baseline.
+
+
+FT_GlyphSlot slot = face->glyph; /* a small shortcut */
+FT_UInt glyph_index;
+FT_Bool use_kerning;
+FT_UInt previous;
+int pen_x, pen_y, n;
+
+FT_Glyph glyphs[MAX_GLYPHS]; /* glyph image */
+FT_Vector pos [MAX_GLYPHS]; /* glyph position */
+FT_UInt num_glyphs;
+
+
+... initialize library ...
+... create face object ...
+... set character size ...
+
+pen_x = 0; /* start at (0,0) */
+pen_y = 0;
+
+num_glyphs = 0;
+use_kerning = FT_HAS_KERNING( face );
+previous = 0;
+
+for ( n = 0; n < num_chars; n++ )
+{
+ /* convert character code to glyph index */
+ glyph_index = FT_Get_Char_Index( face, text[n] );
+
+ /* retrieve kerning distance and move pen position */
+ if ( use_kerning && previous && glyph_index )
+ {
+ FT_Vector delta;
+
+
+ FT_Get_Kerning( face, previous, glyph_index,
+ FT_KERNING_DEFAULT, &delta );
+
+ pen_x += delta.x >> 6;
+ }
+
+ /* store current pen position */
+ pos[num_glyphs].x = pen_x;
+ pos[num_glyphs].y = pen_y;
+
+ /* load glyph image into the slot without rendering */
+ error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
+ if ( error )
+ continue; /* ignore errors, jump to next glyph */
+
+ /* extract glyph image and store it in our table */
+ error = FT_Get_Glyph( face->glyph, &glyphs[num_glyphs] );
+ if ( error )
+ continue; /* ignore errors, jump to next glyph */
+
+ /* increment pen position */
+ pen_x += slot->advance.x >> 6;
+
+ /* record current glyph index */
+ previous = glyph_index;
+
+ /* increment number of glyphs */
+ num_glyphs++;
+}
+
+
This is a very slight variation of our previous code; we
+ extract each glyph image from the slot, then store it,
+ along with the corresponding position, in our tables.
+
+
Note also that pen_x contains the total advance
+ for the string of text. We can now compute the bounding
+ box of the text string with a simple function.
The resulting bounding box dimensions are expressed in
+ integer pixels and can then be used to compute the final
+ pen position before rendering the string.
+
+
In general, the above function
+ does not compute an exact bounding box of a
+ string! As soon as hinting is involved, glyph
+ dimensions must be derived from the resulting
+ outlines. For anti-aliased pixmaps,
+ FT_Outline_Get_BBox then yields proper results.
+ In case you need 1-bit monochrome bitmaps, it is even
+ necessary to actually render the glyphs because the rules
+ for the conversion from outline to bitmap can also be
+ controlled by hinting instructions.
The pen position is expressed in the Cartesian space
+ (i.e., y upwards).
+
+
We call FT_Glyph_To_Bitmap with
+ the destroy parameter set to 0 (false), in
+ order to avoid destroying the original glyph image. The
+ new glyph bitmap is accessed through
+ image after the call and is typecast to
+ FT_BitmapGlyph.
+
+
We use translation when
+ calling FT_Glyph_To_Bitmap. This ensures that
+ the left and top fields of the bitmap
+ glyph object are already set to the correct pixel
+ coordinates in the Cartesian space.
+
+
Of course, we still need to convert pixel coordinates
+ from Cartesian to device space before rendering, hence
+ the my_target_height - bitmap->top in the call
+ to my_draw_bitmap.
+
+
+
The same loop can be used to render the string anywhere
+ on our display surface, without the need to reload our
+ glyph images each time.
+
+
+
5. Advanced Text Rendering:
+ Transformation and Centering and Kerning
+
+
We are now going to modify our code in order to be able
+ to easily transform the rendered string, for example, to
+ rotate it. First, some minor improvements.
+
+
a. Packing and Translating Glyphs
+
+
We start by packing the information related to a single
+ glyph image into a single structure instead of parallel
+ arrays.
We also translate each glyph image directly after it is
+ loaded to its position on the baseline at load time. As
+ we will see, this has several advantages. Here is our new
+ glyph sequence loader.
+
+
+FT_GlyphSlot slot = face->glyph; /* a small shortcut */
+FT_UInt glyph_index;
+FT_Bool use_kerning;
+FT_UInt previous;
+int pen_x, pen_y, n;
+
+TGlyph glyphs[MAX_GLYPHS]; /* glyphs table */
+PGlyph glyph; /* current glyph in table */
+FT_UInt num_glyphs;
+
+
+... initialize library ...
+... create face object ...
+... set character size ...
+
+pen_x = 0; /* start at (0,0) */
+pen_y = 0;
+
+num_glyphs = 0;
+use_kerning = FT_HAS_KERNING( face );
+previous = 0;
+
+glyph = glyphs;
+for ( n = 0; n < num_chars; n++ )
+{
+ glyph->index = FT_Get_Char_Index( face, text[n] );
+
+ if ( use_kerning && previous && glyph->index )
+ {
+ FT_Vector delta;
+
+
+ FT_Get_Kerning( face, previous, glyph->index,
+ FT_KERNING_MODE_DEFAULT, &delta );
+
+ pen_x += delta.x >> 6;
+ }
+
+ /* store current pen position */
+ glyph->pos.x = pen_x;
+ glyph->pos.y = pen_y;
+
+ error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
+ if ( error ) continue;
+
+ error = FT_Get_Glyph( face->glyph, &glyph->image );
+ if ( error ) continue;
+
+ /* translate the glyph image now */
+ FT_Glyph_Transform( glyph->image, 0, &glyph->pos );
+
+ pen_x += slot->advance.x >> 6;
+ previous = glyph->index;
+
+ /* increment number of glyphs */
+ glyph++;
+}
+
+/* count number of glyphs loaded */
+num_glyphs = glyph - glyphs;
+
+
Note that translating glyphs now has several advantages.
+ The first one is that we don't need to translate the glyph
+ bbox when we compute the string's bounding box.
Coordinates are relative to the glyph origin (0,0), using the
- y upwards convention. This function takes a special argument,
- the bbox mode, to indicate how box coordinates are
- expressed.
-
-
If the glyph has been loaded with FT_LOAD_NO_SCALE,
- bbox_mode must be set to FT_GLYPH_BBOX_UNSCALED to
- get unscaled font units in 26.6 pixel format. The value
- FT_GLYPH_BBOX_SUBPIXELS is another name for this
- constant.
-
-
Note that the box's maximum coordinates are exclusive, which means
- that you can always compute the width and height of the glyph image,
- be in in integer or 26.6 pixels, with:
Note also that for 26.6 coordinates, if
- FT_GLYPH_BBOX_GRIDFIT is used as the bbox mode, the
- coordinates will also be grid-fitted, which corresponds to
To get the bbox in integer pixel coordinates, set
- bbox_mode to FT_GLYPH_BBOX_TRUNCATE.
-
-
Finally, to get the bounding box in grid-fitted pixel coordinates,
- set bbox_mode to FT_GLYPH_BBOX_PIXELS.
-
-
- d. Converting the glyph image to a bitmap
-
-
-
You may need to convert the glyph object to a bitmap once you have
- conveniently cached or transformed it. This can be done easily with
- the
- FT_Glyph_To_Bitmap function. It is in charge of
- converting any glyph object into a bitmap, as in:
The first parameter is the address of the source glyph's
- handle. When the function is called, it reads its to access the
- source glyph object. After the call, the handle will point to a
- new glyph object that contains the rendered bitmap.
-
-
-
-
The second parameter is a standard render mode, that is used to
- specify what kind of bitmap we want. It can be
- FT_RENDER_MODE_DEFAULT for an 8-bit anti-aliased pixmap,
- or FT_RENDER_MODE_MONO for a 1-bit monochrome bitmap.
-
-
-
-
The third parameter is a pointer to a two-dimensional vector
- that is used to translate the source glyph image before the
- conversion. Note that the source image will be translated back to
- its original position (and will thus be left unchanged) after the
- call. If you do not need to translate the source glyph before
- rendering, set this pointer to 0.
-
-
-
-
The last parameter is a boolean that indicates whether the
- source glyph object should be destroyed by the function. If
- false, the original glyph object is never destroyed, even if its
- handle is lost (it is up to client applications to keep it).
-
-
-
-
The new glyph object always contains a bitmap (if no error is
- returned), and you must typecast its handle to the
- FT_BitmapGlyph type in order to access its content. This
- type is a sort of ‘subclass’ of FT_Glyph that
- contains additional fields (see
- FT_BitmapGlyphRec):
-
-
-
-
-
- left
-
-
-
Just like the bitmap_left field of a glyph slot, this
- is the horizontal distance from the glyph origin (0,0) to the
- leftmost pixel of the glyph bitmap. It is expressed in integer
- pixels.
-
-
-
-
- top
-
-
-
Just like the bitmap_top field of a glyph slot, this
- is the vertical distance from the glyph origin (0,0) to the
- topmost pixel of the glyph bitmap (more precise, to the pixel just
- above the bitmap). This distance is expressed in integer pixels,
- and is positive for upwards y.
-
-
-
-
- bitmap
-
-
-
This is a bitmap descriptor for the glyph object, just like the
- bitmap field in a glyph slot.
-
-
-
-
-
-
-
-
- 3. Global glyph metrics
-
-
-
Unlike glyph metrics, global metrics are used to describe distances
- and features of a whole font face. They can be expressed either in 26.6
- pixel format or in design ‘font units’ for scalable
- formats.
-
-
- a. Design global metrics
-
-
-
For scalable formats, all global metrics are expressed in font
- units in order to be later scaled to the device space, according to
- the rules described in the last chapter of this section of the
- tutorial. You can access them directly as simple fields of a
- FT_Face handle.
-
-
However, you need to check that the font face's format is scalable
- before using them. One can do it by using the macro
- FT_IS_SCALABLE which returns true when appropriate.
-
-
In this case, you can access the global design metrics as:
-
-
-
-
-
- units_per_EM
-
-
-
This is the size of the EM square for the font face. It is
- used by scalable formats to scale design coordinates to device
- pixels, as described in the last chapter of this section. Its
- value usually is 2048 (for TrueType) or 1000 (for Type 1),
- but others are possible too. It is set to 1 for fixed-size
- formats like FNT/FON/PCF/BDF.
-
-
-
-
- bbox
-
-
-
The global bounding box is defined as the largest rectangle
- that can enclose all the glyphs in a font face.
-
-
-
-
- ascender
-
-
-
The ascender is the vertical distance from the horizontal
- baseline to the highest ‘character’ coordinate in a
- font face. Unfortunately, font formats define the ascender
- differently. For some, it represents the ascent of all capital
- latin characters (without accents), for others it is the ascent of
- the highest accented character, and finally, other formats define
- it as being equal to bbox.yMax.
-
-
-
-
- descender
-
-
-
The descender is the vertical distance from the horizontal
- baseline to the lowest ‘character’ coordinate in a
- font face. Unfortunately, font formats define the descender
- differently. For some, it represents the descent of all capital
- latin characters (without accents), for others it is the ascent of
- the lowest accented character, and finally, other formats define
- it as being equal to bbox.yMin. This field is
- negative for values below the baseline.
-
-
-
-
- height
-
-
-
This field is simply used to compute a default line
- spacing (i.e., the baseline-to-baseline distance) when writing
- text with this font. Note that it usually is larger than the sum
- of the ascender and descender taken as absolute values. There is
- also no guarantee that no glyphs extend above or below subsequent
- baselines when using this distance.
-
-
-
-
- max_advance_width
-
-
-
This field gives the maximum horizontal cursor advance for all
- glyphs in the font. It can be used to quickly compute the maximum
- advance width of a string of text. It doesn't correspond to
- the maximum glyph image width!
-
-
-
-
- max_advance_height
-
-
-
Same as max_advance_width but for vertical text
- layout.
-
-
-
-
- underline_position
-
-
-
When displaying or rendering underlined text, this value
- corresponds to the vertical position, relative to the baseline, of
- the underline bar's center. It is negative if it is below the
- baseline.
-
-
-
-
- underline_thickness
-
-
-
When displaying or rendering underlined text, this value
- corresponds to the vertical thickness of the underline.
-
-
-
-
-
-
Notice how, unfortunately, the values of the ascender and the
- descender are not reliable (due to various discrepancies in font
- formats).
-
-
- b. Scaled global metrics
-
-
-
Each size object also contains a scaled versions of some of the
- global metrics described above. They can be accessed directly through
- the face->size->metrics structure.
-
-
Note that these values correspond to scaled versions of the design
- global metrics, with no rounding or grid-fitting performed.
- They are also completely independent of any hinting process. In other
- words, don't rely on them to get exact metrics at the pixel level.
- They are expressed in 26.6 pixel format.
-
-
-
-
-
- ascender
-
-
-
The scaled version of the original design ascender.
-
-
-
-
- descender
-
-
-
The scaled version of the original design descender.
-
-
-
-
- height
-
-
-
The scaled version of the original design text height (the
- vertical distance from one baseline to the next). This is
- probably the only field you should really use in this
- structure.
-
-
Be careful not to confuse it with the ‘height’
- field in the
- FT_Glyph_Metrics structure.
-
-
-
-
- max_advance
-
-
-
The scaled version of the original design max advance.
-
-
-
-
-
-
Note that the face->size->metrics structure contains
- other fields that are used to scale design coordinates to device
- space. They are described in the last chapter.
-
-
- c. Kerning
-
-
-
Kerning is the process of adjusting the position of two subsequent
- glyph images in a string of text in order to improve the general
- appearance of text. Basically, it means that when the glyph for an
- ‘A’ is followed by the glyph for a ‘V’, the
- space between them can be slightly reduced to avoid extra
- ‘diagonal whitespace’.
-
-
Note that in theory kerning can happen both in the horizontal and
- vertical direction between two glyphs; however, it only happens in the
- horizontal direction in nearly all cases except really extreme
- ones.
-
-
Not all font formats contain kerning information, and not all
- kerning formats are supported by FreeType; in particular, for TrueType
- fonts, the API can only access kerning via the ‘kern’
- table; OpenType kerning via the ‘GPOS’ table is not
- supported. You need a higher-level library like Pango or ICU to handle that.
-
-
Sometimes, the font file is associated with an additional file that
- contains various glyph metrics, including kerning, but no glyph
- images. A good example is the Type 1 format where glyph images
- are stored in a file with extension .pfa or .pfb,
- and where kerning metrics can be found in a file with extension
- .afm or .pfm.
-
-
FreeType 2 allows you to deal with this, by providing the
- FT_Attach_File and
- FT_Attach_Stream APIs. Both functions are used to load
- additional metrics into a face object by reading them from an
- additional format-specific file. For example, you could open a
- Type 1 font by doing the following:
-
-
- error = FT_New_Face( library, "/usr/shared/fonts/cour.pfb",
- 0, &face );
- if ( error ) { ... }
-
- error = FT_Attach_File( face, "/usr/shared/fonts/cour.afm" );
- if ( error )
- { ... could not read kerning and additional metrics ... }
-
-
-
Note that FT_Attach_Stream is similar to
- FT_Attach_File except that it doesn't take a C string to
- name the extra file but a FT_Stream handle. Also,
- reading a metrics file is in no way mandatory.
-
-
Finally, the file attachment APIs are very generic and can be used
- to load any kind of extra information for a given face. The nature of
- the additional content is entirely font format specific.
-
-
FreeType 2 allows you to retrieve the kerning information for
- two glyphs through the FT_Get_Kerning function, whose
- interface looks like:
-
-
- FT_Vector kerning;
-
-
- ...
- error = FT_Get_Kerning( face, /* handle to face object */
- left, /* left glyph index */
- right, /* right glyph index */
- kerning_mode, /* kerning mode */
- &kerning ); /* target vector */
-
-
-
As you see, the function takes a handle to a face object, the
- indices of the left and right glyph for which the kerning value is
- desired, as well as an integer, called the kerning mode, and
- a pointer to a destination vector that receives the corresponding
- distances.
-
-
The kerning mode is very similar to the bbox mode
- described in a previous chapter. It is a enumeration that indicates
- how the kerning distances are expressed in the target vector.
-
-
The default value is FT_KERNING_DEFAULT which has
- value 0. It corresponds to kerning distances expressed in 26.6
- grid-fitted pixels (which means that the values are multiples of 64).
- For scalable formats, this means that the design kerning distance is
- scaled, then rounded.
-
-
The value FT_KERNING_UNFITTED corresponds to kerning
- distances expressed in 26.6 unfitted pixels (i.e., that do not
- correspond to integer coordinates). It is the design kerning distance
- that is scaled without rounding.
-
-
Finally, the value FT_KERNING_UNSCALED is used to return
- the design kerning distance, expressed in font units. You can later
- scale it to the device space using the computations explained in the
- last chapter of this section.
-
-
Note that the ‘left’ and ‘right’ positions
- correspond to the visual order of the glyphs in the string of
- text. This is important for bidirectional text, or simply when
- writing right-to-left text.
-
-
-
-
- 4. Simple text rendering: kerning + centering
-
-
-
In order to show off what we just learned, we will now demonstrate
- how to modify the example code that was provided in section I to
- render a string of text, and enhance it to support kerning and delayed
- rendering.
-
-
- a. Kerning support
-
-
-
Adding support for kerning to our code is trivial, as long as we
- consider that we are still dealing with a left-to-right script like
- Latin. We simply need to retrieve the kerning distance between two
- glyphs in order to alter the pen position appropriately. The code
- looks like:
-
-
- FT_GlyphSlot slot = face->glyph; /* a small shortcut */
- FT_UInt glyph_index;
- FT_Bool use_kerning;
- FT_UInt previous;
- int pen_x, pen_y, n;
-
-
- ... initialize library ...
- ... create face object ...
- ... set character size ...
-
- pen_x = 300;
- pen_y = 200;
-
- use_kerning = FT_HAS_KERNING( face );
- previous = 0;
-
- for ( n = 0; n < num_chars; n++ )
+ for ( n = 0; n < num_glyphs; n++ )
{
- /* convert character code to glyph index */
- glyph_index = FT_Get_Char_Index( face, text[n] );
-
- /* retrieve kerning distance and move pen position */
- if ( use_kerning && previous && glyph_index )
- {
- FT_Vector delta;
-
-
- FT_Get_Kerning( face, previous, glyph_index,
- FT_KERNING_DEFAULT, &delta );
-
- pen_x += delta.x >> 6;
- }
-
- /* load glyph image into the slot (erase previous one) */
- error = FT_Load_Glyph( face, glyph_index, FT_LOAD_RENDER );
- if ( error )
- continue; /* ignore errors */
-
- /* now draw to our target surface */
- my_draw_bitmap( &slot->bitmap,
- pen_x + slot->bitmap_left,
- pen_y - slot->bitmap_top );
-
- /* increment pen position */
- pen_x += slot->advance.x >> 6;
-
- /* record current glyph index */
- previous = glyph_index;
- }
-
-
-
We are done. Some notes:
-
-
-
-
-
As kerning is determined from glyph indices, we need to
- explicitly convert our character codes into glyph indices, then
- later call FT_Load_Glyph instead of
- FT_Load_Char.
-
-
-
-
We use a boolean named use_kerning which is set with
- the result of the macro FT_HAS_KERNING. It is certainly
- faster not to call FT_Get_Kerning when we know that the
- font face does not contain kerning information.
-
-
-
-
We move the position of the pen before a new glyph is
- drawn.
-
-
-
-
We initialize the variable previous with the
- value 0, which always corresponds to the ‘missing
- glyph’ (also called .notdef in the Postscript
- world). There is never any kerning distance associated with this
- glyph.
-
-
-
-
We do not check the error code returned by
- FT_Get_Kerning. This is because the function always sets
- the content of delta to (0,0) when an error occurs.
-
-
-
-
- b. Centering
-
-
-
Our code begins to become interesting but it is still a bit too
- simple for normal use. For example, the position of the pen is
- determined before we do the rendering; normally, you would rather
- layout the text and measure it before computing its final position
- (centering, etc.) or perform things like word-wrapping.
-
-
Let us now decompose our text rendering function into two distinct
- but successive parts: The first one will position individual glyph
- images on the baseline, while the second one will render the glyphs.
- As we will see, this has many advantages.
-
-
We will thus start by storing individual glyph images, as well as
- their position on the baseline. This can be done with code like:
-
-
- FT_GlyphSlot slot = face->glyph; /* a small shortcut */
- FT_UInt glyph_index;
- FT_Bool use_kerning;
- FT_UInt previous;
- int pen_x, pen_y, n;
-
- FT_Glyph glyphs[MAX_GLYPHS]; /* glyph image */
- FT_Vector pos [MAX_GLYPHS]; /* glyph position */
- FT_UInt num_glyphs;
-
-
- ... initialize library ...
- ... create face object ...
- ... set character size ...
-
- pen_x = 0; /* start at (0,0) */
- pen_y = 0;
-
- num_glyphs = 0;
- use_kerning = FT_HAS_KERNING( face );
- previous = 0;
-
- for ( n = 0; n < num_chars; n++ )
- {
- /* convert character code to glyph index */
- glyph_index = FT_Get_Char_Index( face, text[n] );
-
- /* retrieve kerning distance and move pen position */
- if ( use_kerning && previous && glyph_index )
- {
- FT_Vector delta;
-
-
- FT_Get_Kerning( face, previous, glyph_index,
- FT_KERNING_DEFAULT, &delta );
-
- pen_x += delta.x >> 6;
- }
-
- /* store current pen position */
- pos[num_glyphs].x = pen_x;
- pos[num_glyphs].y = pen_y;
-
- /* load glyph image into the slot without rendering */
- error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
- if ( error )
- continue; /* ignore errors, jump to next glyph */
-
- /* extract glyph image and store it in our table */
- error = FT_Get_Glyph( face->glyph, &glyphs[num_glyphs] );
- if ( error )
- continue; /* ignore errors, jump to next glyph */
-
- /* increment pen position */
- pen_x += slot->advance.x >> 6;
-
- /* record current glyph index */
- previous = glyph_index;
-
- /* increment number of glyphs */
- num_glyphs++;
- }
-
-
-
This is a very slight variation of our previous code where we
- extract each glyph image from the slot, and store it, along with the
- corresponding position, in our tables.
-
-
Note also that pen_x contains the total advance for the
- string of text. We can now compute the bounding box of the text
- string with a simple function like:
The resulting bounding box dimensions are expressed in integer
- pixels and can then be used to compute the final pen position before
- rendering the string as in:
The pen position is expressed in the cartesian space (i.e.,
- y upwards).
-
-
-
-
We call FT_Glyph_To_Bitmap with the destroy
- parameter set to 0 (false), in order to avoid destroying the
- original glyph image. The new glyph bitmap is accessed through
- image after the call and is typecast to
- FT_BitmapGlyph.
-
-
-
-
We use translation when calling FT_Glyph_To_Bitmap.
- This ensures that the left and top fields of the
- bitmap glyph object are already set to the correct pixel
- coordinates in the cartesian space.
-
-
-
-
Of course, we still need to convert pixel coordinates from
- cartesian to device space before rendering, hence the
- my_target_height - bitmap->top in the call to
- my_draw_bitmap.
-
-
-
-
The same loop can be used to render the string anywhere on our
- display surface, without the need to reload our glyph images each
- time. We could also decide to implement word wrapping, and only
- draw
We are now going to modify our code in order to be able to easily
- transform the rendered string, for example to rotate it. We will start
- by performing a few minor improvements:
-
-
- a. packing & translating glyphs
-
-
-
We start by packing the information related to a single glyph image
- into a single structure instead of parallel arrays. We thus define
- the following structure type:
We also translate each glyph image directly after it is loaded to
- its position on the baseline at load time. As we will see, this has
- several advantages. Our glyph sequence loader thus becomes:
-
-
- FT_GlyphSlot slot = face->glyph; /* a small shortcut */
- FT_UInt glyph_index;
- FT_Bool use_kerning;
- FT_UInt previous;
- int pen_x, pen_y, n;
-
- TGlyph glyphs[MAX_GLYPHS]; /* glyphs table */
- PGlyph glyph; /* current glyph in table */
- FT_UInt num_glyphs;
-
-
- ... initialize library ...
- ... create face object ...
- ... set character size ...
-
- pen_x = 0; /* start at (0,0) */
- pen_y = 0;
-
- num_glyphs = 0;
- use_kerning = FT_HAS_KERNING( face );
- previous = 0;
-
- glyph = glyphs;
- for ( n = 0; n < num_chars; n++ )
- {
- glyph->index = FT_Get_Char_Index( face, text[n] );
-
- if ( use_kerning && previous && glyph->index )
- {
- FT_Vector delta;
-
-
- FT_Get_Kerning( face, previous, glyph->index,
- FT_KERNING_MODE_DEFAULT, &delta );
-
- pen_x += delta.x >> 6;
- }
-
- /* store current pen position */
- glyph->pos.x = pen_x;
- glyph->pos.y = pen_y;
-
- error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
- if ( error ) continue;
-
- error = FT_Get_Glyph( face->glyph, &glyph->image );
- if ( error ) continue;
-
- /* translate the glyph image now */
- FT_Glyph_Transform( glyph->image, 0, &glyph->pos );
-
- pen_x += slot->advance.x >> 6;
- previous = glyph->index;
-
- /* increment number of glyphs */
- glyph++;
+ if (glyph_bbox.yMax > bbox.yMax)
+ bbox.yMax = glyph_bbox.yMax;
}
- /* count number of glyphs loaded */
- num_glyphs = glyph - glyphs;
-
-
-
Note that translating glyphs now has several advantages. The first
- one is that we don't need to translate the glyph bbox when we compute
- the string's bounding box. The code becomes:
Now take a closer look: The compute_string_bbox function
- can now compute the bounding box of a transformed glyph string. For
- example, we can do something like:
With the above modifications,
+ the compute_string_bbox function can now compute
+ the bounding box of a transformed glyph string, which
+ allows further code simplications.
+
+
+FT_BBox bbox;
+FT_Matrix matrix;
+FT_Vector delta;
- ... load glyph sequence ...
- ... set up "matrix" and "delta" ...
+... load glyph sequence ...
+... set up `matrix' and `delta' ...
- /* transform glyphs */
- for ( n = 0; n < num_glyphs; n++ )
- FT_Glyph_Transform( glyphs[n].image, &matrix, &delta );
+/* transform glyphs */
+for ( n = 0; n < num_glyphs; n++ )
+ FT_Glyph_Transform( glyphs[n].image, &matrix, &delta );
- /* compute bounding box of transformed glyphs */
- compute_string_bbox( &bbox );
-
However, directly transforming the glyphs in our sequence is not a
- good idea if we want to reuse them in order to draw the text string
- with various angles or transformations. It is better to perform the
- affine transformation just before the glyph is rendered, as in the
- following code:
+
However, directly transforming the glyphs in our sequence
+ is not a good idea if we want to reuse them in order to
+ draw the text string with various angles or
+ transformations. It is better to perform the affine
+ transformation just before the glyph is rendered.
-
- FT_Vector start;
- FT_Matrix matrix;
+
+FT_Vector start;
+FT_Matrix matrix;
- FT_Glyph image;
- FT_Vector pen;
- FT_BBox bbox;
+FT_Glyph image;
+FT_Vector pen;
+FT_BBox bbox;
- /* get bbox of original glyph sequence */
- compute_string_bbox( &string_bbox );
+/* get bbox of original glyph sequence */
+compute_string_bbox( &string_bbox );
- /* compute string dimensions in integer pixels */
- string_width = (string_bbox.xMax - string_bbox.xMin) / 64;
- string_height = (string_bbox.yMax - string_bbox.yMin) / 64;
+/* compute string dimensions in integer pixels */
+string_width = (string_bbox.xMax - string_bbox.xMin) / 64;
+string_height = (string_bbox.yMax - string_bbox.yMin) / 64;
- /* set up start position in 26.6 cartesian space */
- start.x = ( ( my_target_width - string_width ) / 2 ) * 64;
- start.y = ( ( my_target_height - string_height ) / 2 ) * 64;
+/* set up start position in 26.6 Cartesian space */
+start.x = ( ( my_target_width - string_width ) / 2 ) * 64;
+start.y = ( ( my_target_height - string_height ) / 2 ) * 64;
- /* set up transform (a rotation here) */
- matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
- matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
- matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
- matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
+/* set up transform (a rotation here) */
+matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
+matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
+matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
+matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
- pen = start;
+pen = start;
- for ( n = 0; n < num_glyphs; n++ )
+for ( n = 0; n < num_glyphs; n++ )
+{
+ /* create a copy of the original glyph */
+ error = FT_Glyph_Copy( glyphs[n].image, &image );
+ if ( error ) continue;
+
+ /* transform copy (this will also translate it to the */
+ /* correct position */
+ FT_Glyph_Transform( image, &matrix, &pen );
+
+ /* check bounding box; if the transformed glyph image */
+ /* is not in our target surface, we can avoid rendering it */
+ FT_Glyph_Get_CBox( image, ft_glyph_bbox_pixels, &bbox );
+ if ( bbox.xMax <= 0 || bbox.xMin >= my_target_width ||
+ bbox.yMax <= 0 || bbox.yMin >= my_target_height )
+ continue;
+
+ /* convert glyph image to bitmap (destroy the glyph copy!) */
+ error = FT_Glyph_To_Bitmap(
+ &image,
+ FT_RENDER_MODE_NORMAL,
+ 0, /* no additional translation */
+ 1 ); /* destroy copy in "image" */
+ if ( !error )
{
- /* create a copy of the original glyph */
- error = FT_Glyph_Copy( glyphs[n].image, &image );
- if ( error ) continue;
-
- /* transform copy (this will also translate it to the */
- /* correct position */
- FT_Glyph_Transform( image, &matrix, &pen );
-
- /* check bounding box; if the transformed glyph image */
- /* is not in our target surface, we can avoid rendering it */
- FT_Glyph_Get_CBox( image, ft_glyph_bbox_pixels, &bbox );
- if ( bbox.xMax <= 0 || bbox.xMin >= my_target_width ||
- bbox.yMax <= 0 || bbox.yMin >= my_target_height )
- continue;
-
- /* convert glyph image to bitmap (destroy the glyph copy!) */
- error = FT_Glyph_To_Bitmap(
- &image,
- FT_RENDER_MODE_NORMAL,
- 0, /* no additional translation */
- 1 ); /* destroy copy in "image" */
- if ( !error )
- {
- FT_BitmapGlyph bit = (FT_BitmapGlyph)image;
+ FT_BitmapGlyph bit = (FT_BitmapGlyph)image;
- my_draw_bitmap( bit->bitmap,
- bit->left,
- my_target_height - bit->top );
+ my_draw_bitmap( bit->bitmap,
+ bit->left,
+ my_target_height - bit->top );
- /* increment pen position -- */
- /* we don't have access to a slot structure, */
- /* so we have to use advances from glyph structure */
- /* (which are in 16.16 fixed float format) */
- pen.x += image.advance.x >> 10;
- pen.y += image.advance.y >> 10;
+ /* increment pen position -- */
+ /* we don't have access to a slot structure, */
+ /* so we have to use advances from glyph structure */
+ /* (which are in 16.16 fixed float format) */
+ pen.x += image.advance.x >> 10;
+ pen.y += image.advance.y >> 10;
- FT_Done_Glyph( image );
- }
+ FT_Done_Glyph( image );
}
-
+}
-
There are a few changes compared to the original version of this
- code:
+
There are a few changes compared to the original version
+ of this code.
-
-
-
We keep the original glyph images untouched; instead, we
- transform a copy.
-
+
+
We keep the original glyph images untouched; instead,
+ we transform a copy.
-
-
We perform clipping computations in order to avoid rendering
- & drawing glyphs that are not within our target surface
-
+
We perform clipping computations in order to avoid
+ rendering and drawing glyphs that are not within our
+ target surface.
-
-
We always destroy the copy when calling
- FT_Glyph_To_Bitmap in order to get rid of the transformed
- scalable image. Note that the image is not destroyed if the
- function returns an error code (which is why
- FT_Done_Glyph is only called within the compound
- statement.
-
+
We always destroy the copy when calling
+ FT_Glyph_To_Bitmap in order to get rid of the
+ transformed scalable image. Note that the image is not
+ destroyed if the function returns an error code (which
+ is why FT_Done_Glyph is only called within the
+ compound statement).
-
-
The translation of the glyph sequence to the start pen position
- is integrated in the call to FT_Glyph_Transform instead
- of FT_Glyph_To_Bitmap.
-
-
+
The translation of the glyph sequence to the start pen
+ position is integrated into the call
+ to FT_Glyph_Transform instead
+ of FT_Glyph_To_Bitmap.
+
-
It is possible to call this function several times to render the
- string width different angles, or even change the way start
- is computed in order to move it to different place.
+
It is possible to call this function several times to
+ render the string with different angles, or even change
+ the way start is computed in order to move it to
+ different place.
-
This code is the basis of the FreeType 2 demonstration program
- named ftstring.c. It could be easily extended to perform
- advanced text layout or word-wrapping in the first part, without
- changing the second one.
+
This code is the basis of the FreeType 2
+ demonstration program
+ named ftstring.c.
+ It could be easily extended to perform advanced text
+ layout or word-wrapping in the first part, without
+ changing the second one.
-
Note, however, that a normal implementation would use a glyph cache
- in order to reduce memory needs. For example, let us assume that our
- text string is ‘FreeType&rsquo'. We would store three identical
- glyph images in our table for the letter ‘e’, which isn't
- optimal (especially when you consider longer lines of text, or even
- whole pages).
+
Note, however, that a normal implementation would use a
+ glyph cache in order to reduce memory needs. For example,
+ let us assume that our text string is
+ ‘FreeType’. We would store three identical
+ glyph images in our table for the letter ‘e’,
+ which isn't optimal (especially when you consider longer
+ lines of text, or even whole pages).
-
+
A FreeType demo program that shows how glyph caching can
+ be implemented
+ is ftview.c.
+ In general, ‘ftview’ is the main program used
+ by the FreeType developer team to check the validity of
+ loading, parsing, and rendering fonts.
-
- 6. Accessing metrics in design font units, and scaling them
-
-
Scalable font formats usually store a single vectorial image, called
- an outline, for each glyph in a face. Each outline is defined
- in an abstract grid called the design space, with coordinates
- expressed in nominal font units. When a glyph image is loaded,
- the font driver usually scales the outline to device space according to
- the current character pixel size found in a FT_Size object.
- The driver may also modify the scaled outline in order to significantly
- improve its appearance on a pixel-based surface (a process known as
- hinting or grid-fitting).
+
6. Accessing Metrics in Design Font
+ Units, and Scaling Them
-
This chapter describes how design coordinates are scaled to the
- device space, and how to read glyph outlines and metrics in font units.
- This is important for a number of things:
+
Scalable font formats usually store a single vectorial
+ image, called an outline, for each glyph in a
+ face. Each outline is defined in an abstract grid called
+ the design space, with coordinates expressed in
+ font units. When a glyph image is loaded, the
+ font driver usually scales the outline to device space
+ according to the current character pixel size found in
+ an FT_Size
+ object. The driver may also modify the scaled outline in
+ order to significantly improve its appearance on a
+ pixel-based surface (a process known as hinting
+ or grid-fitting).
-
-
-
‘true’ WYSIWYG text layout
-
-
-
accessing font content for conversion or analysis purposes
-
-
+
This section describes how design coordinates are scaled
+ to the device space, and how to read glyph outlines and
+ metrics in font units. This is important for a number of
+ things.
-
- a. Scaling distances to device space
-
+
+
‘True’ WYSIWYG text layout.
+
Accessing font content for conversion or analysis
+ purposes.
+
-
Design coordinates are scaled to the device space using a simple
- scaling transformation whose coefficients are computed with the help
- of the character pixel size:
+
a. Scaling Distances to Device Space
-
+
Design coordinates are scaled to the device space using a
+ simple scaling transformation whose coefficients are
+ computed with the help of the character pixel
+ size.
Here, the value EM_size is font-specific and
+ corresponds to the size of an abstract square of the
+ design space (called the EM), which is used by
+ font designers to create glyph images. It is thus
+ expressed in font units. It is also accessible directly
+ for scalable font formats
+ as face->units_per_EM. You should check that
+ a font face contains scalable glyph images by using
+ the FT_IS_SCALABLE macro, which returns true if
+ appropriate.
+
+
When you call the
+ function FT_Set_Pixel_Sizes,
+ you are specifying the value of pixel_size_x and
+ pixel_size_y FreeType shall use. The library will
+ immediately compute the values of x_scale and
+ y_scale.
+
+
When you call the
+ function FT_Set_Char_Size,
+ you are specifying the character size in
+ physical points, which is used, along with the
+ device's resolutions, to compute the character pixel size
+ and the corresponding scaling factors.
+
+
Note that after calling any of these two functions, you
+ can access the values of the character pixel size and
+ scaling factors as fields of
+ the face->size->metrics structure.
+
+
+
x_ppem
+
The field name stands for ‘x pixels per
+ EM’; this is the horizontal size in integer pixels
+ of the EM square, which also is the horizontal
+ character pixel size, called pixel_size_x
+ in the above example.
+
+
y_ppem
+
The field name stands for ‘y pixels per
+ EM’; this is the vertical size in integer pixels
+ of the EM square, which also is the vertical
+ character pixel size, called pixel_size_y
+ in the above example.
+
+
x_scale
+
This is a 16.16 fixed-point scale to directly scale
+ horizontal distances from design space to 1/64th of
+ device pixels.
+
+
y_scale
+
This is a 16.16 fixed-point scale to directly scale
+ vertical distances from design space to 1/64th of device
+ pixels.
+
+
+
You can scale a distance expressed in font units to 26.6
+ pixel format directly with the help of
+ the FT_MulFix
+ function.
You can access glyph metrics in font units simply by
+ specifying the FT_LOAD_NO_SCALE bit flag
+ in FT_Load_Glyph or FT_Load_Char. The
+ metrics returned in face->glyph->metrics
+ will all be in font units.
+
+
You can access unscaled kerning data using the
+ FT_KERNING_MODE_UNSCALED mode.
+
+
Finally, a few global metrics are available directly in
+ font units as fields of the FT_Face handle, as
+ described in section 3 of
+ this part.
+
+
+
Conclusion
+
+
This is the end of the second part of the FreeType
+ tutorial. You are now able to access glyph metrics,
+ manage glyph images, and render text much more
+ intelligently (kerning, measuring, transforming &
+ caching); this is sufficient knowledge to build a pretty
+ decent text service on top of FreeType.
+
+
The demo programs in the ‘ft2demos’ bundle
+ (especially ‘ftview’) are a kind of reference
+ implementation, and are a good resource to turn to for
+ answers. They also show how to use additional features,
+ such as the glyph stroker and cache.
+
+
+
+
+
+
Last update: 12-Dec-2014
+
-
-
Here, the value EM_size is font-specific and corresponds
- to the size of an abstract square of the design space (called the
- EM), which is used by font designers to create glyph images.
- It is thus expressed in font units. It is also accessible directly
- for scalable font formats as face->units_per_EM. You
- should check that a font face contains scalable glyph images by using
- the FT_IS_SCALABLE macro, which returns true when
- appropriate.
-
-
When you call the function FT_Set_Pixel_Sizes, you are
- specifying the value of pixel_size_x and
- pixel_size_y FreeType shall use. The library will
- immediately compute the values of x_scale and
- y_scale.
-
-
When you call the function FT_Set_Char_Size, you are
- specifying the character size in physical points, which is
- used, along with the device's resolutions, to compute the character
- pixel size and the corresponding scaling factors.
-
-
Note that after calling any of these two functions, you can access
- the values of the character pixel size and scaling factors as fields
- of the face->size->metrics structure. These fields
- are:
-
-
-
-
-
- x_ppem
-
-
-
The field name stands for ‘x pixels per EM’;
- this is the horizontal size in integer pixels of the EM square,
- which also is the horizontal character pixel size, called
- pixel_size_x in the above example.
-
-
-
-
- y_ppem
-
-
-
The field name stands for ‘y pixels per EM’;
- this is the vertical size in integer pixels of the EM square,
- which also is the vertical character pixel size, called
- pixel_size_y in the above example.
-
-
-
-
- x_scale
-
-
-
This is a 16.16 fixed-point scale that is used to directly
- scale horizontal distances from design space to 1/64th of device
- pixels.
-
-
-
-
- y_scale
-
-
-
This is a 16.16 fixed-point scale that is used to directly
- scale vertical distances from design space to 1/64th of device
- pixels.
-
-
-
-
-
-
You can scale a distance expressed in font units to 26.6 pixel
- format directly with the help of the FT_MulFix function, as
- in:
You can access glyph metrics in font units simply by specifying the
- FT_LOAD_NO_SCALE bit flag in FT_Load_Glyph or
- FT_Load_Char. The metrics returned in
- face->glyph->metrics will all be in font units.
+
-
You can access unscaled kerning data using the
- FT_KERNING_MODE_UNSCALED mode.
This is the end of the second section of the FreeType 2
- tutorial. You are now able to access glyph metrics, manage glyph
- images, and render text much more intelligently (kerning, measuring,
- transforming & caching).
+
-
You have now sufficient knowledge to build a pretty decent text
- service on top of FreeType 2, and you could possibly stop here if
- you want.
-
-
The demo programs in the ‘ft2demos’ bundle (especially
- ‘ftview’) are a kind of reference implementation, and are a
- good resource to turn to for answers. They also show how to use
- additional features, such as the glyph stroker and cache.
-
-
The next section will deal with FreeType 2 internals (like
- modules, vector outlines, font drivers, renderers), as well as a few
- font format specific issues (mainly, how to access certain TrueType or
- Type 1 tables).
Erik Möller
+ contributed a very nice C++ example that shows renderer
+ callbacks in action to draw a coloured glyph with a
+ differently coloured outline. The source code can be
+ found here.
+
+
Another example demonstrates
+ how to use FreeType's stand-alone rasterizer,
+ ftraster.c, both in B/W and 5-levels gray mode.
+ You need files from FreeType version 2.3.10 or newer.
+
+
Róbert Márki
+ contributed a small
+ Qt demonstration program
+ (together with its qmake file)
+ that shows both direct rendering with a callback and
+ rendering with a buffer, yielding the same result. You
+ need FreeType 2.4.3 or newer.
+
+
+
+
+
+
Last update: 13-Dec-2014
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
the module interface
-
functions for manipulating vector outlines
-
font driver issues
-
interaction with renderers using callbacks
-
accessing font specific data, for example PostScript font
- dictionaries and TrueType tables
Erik Möller contributed a very
- nice C++ example which shows renderer callbacks in action to draw a
- coloured glyph with a differently coloured outline. The source code can
- be found here.
-
-
Another example demonstrates how to use
- FreeType's stand-alone rasterizer, ftraster.c, both in B/W and
- 5-levels gray mode. You need files from FreeType version 2.3.10 or
- newer.
-
-
Róbert Márki contributed a small
- Qt demonstration program (together with its qmake file) which shows both direct rendering with
- a callback and rendering with a buffer, yielding the same result. You
- need FreeType 2.4.3 or newer.