From b190572be574f04b46bb28b77dc53f44a462a588 Mon Sep 17 00:00:00 2001 From: David Turner Date: Wed, 26 Jul 2000 19:07:15 +0000 Subject: [PATCH] updated documentation --- docs/freetype2.html | 352 ++++++++++ docs/ft2faq.html | 502 ++++++++++++++ docs/tutorial/step1.html | 54 +- docs/tutorial/step2.html | 1399 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 2290 insertions(+), 17 deletions(-) create mode 100644 docs/freetype2.html create mode 100644 docs/ft2faq.html create mode 100644 docs/tutorial/step2.html diff --git a/docs/freetype2.html b/docs/freetype2.html new file mode 100644 index 000000000..3cc94c971 --- /dev/null +++ b/docs/freetype2.html @@ -0,0 +1,352 @@ + + +FreeType 2 Introduction + + + + + + + +http://www.freetype.org

+ +

+ + The FreeType Project +

An Introduction to FreeType 2

+
+ +
+

+ +DOCUMENT INDEX:
+

+ + +


+ +
+

What is FreeType 2 ?

+
+ +

The FreeType project is a team of volunteers who develop free, portable +and high-quality software solutions for digital typography. We specifically +target embedded systems and focus on bringing small, efficient and +ubiquitous products.

+ +

the FreeType 2 library is our new software font engine. It has been + designed to provide the following important features:

+ +
    +
  • + A universal and simple API to manage font files:
    +

      +

      The FreeType 2 API is simple and easy to use. It supports both + bitmapped and scalable fonts and is well-suited to manage font + files of all formats. Unlike other font libraries, FreeType 2 + returns and manages outline font data (images & metrics).

      +
    +

  • + +
  • + Support for several font formats through loadable modules:
    +

      +

      FreeType 2 uses "font drivers". Each driver is a loadable + module used to support one specific font format. Each driver can also + provide specific extensions used to access format-specific features of + the font.

      +
    +

  • + + +
  • + High-quality anti-aliasing:
    +

      +

      FreeType 2 produces etremely smooth outlines at small sizes, with its new + anti-aliasing renderer, which produces bitmaps with 256-levels of gray. + It uses a new algorithm that has been specifically designed to render + small complex shapes (like glyphs) at high speed. Indeed, it's even + faster than the monochrome renderer for small character sizes (under + 20 pixels) !! +

      +
    + + +
  • High portability & performance:
    +
      +

      The FreeType 2 source code is written in ANSI C and runs on any + platform with a compliant compiler. Client applications can + provide their own memory manager or input stream to the library + (which means that font files can come from any place: disk, + memory, compressed file, network, etc..). +

      +
    + +
+ +

Note that the beta of FreeType 2 is available now. For more + info, check our Download page or see the source + and its diffs through our CVS Web interface. +

+ + +
+ +
+

Features

+
+ +

Supported font formats

+ +

FreeType 2 readily supports the following font formats:

+ +
    +
  • TrueType files (.ttf) and collections (.ttc)
  • +
  • Type 1 font files both in ASCII (.pfa) or binary (.pfb) format
  • +
  • Type 1 Multiple Master fonts. The FreeType 2 API also provides + routines to manage design instances easily
  • +
  • Type 1 CID-keyed fonts
  • +
  • OpenType/CFF (.otf) fonts
  • +
  • CFF/Type 2 fonts
  • +
  • Adobe CEF fonts (.cef), used to embed fonts in SVG documents + with the Adobe SVG viewer plugin.
  • +
  • Windows FNT/FON bitmap fonts
  • +
+ +

Note that Apple's TrueType GX fonts are supported as normal TTFs, + (the advanced tables are ignored).

+ +

Besides, it's possible to add support for new font formats by providing + a specific font driver module. Modules can be added either at + build time (when recompiling the library), or at run-time; + this allows, for example, applications to register their own + font driver to support program-specific formats.

+ + +

Patent-free automatic hinter

+ +

TrueType fonts are normally renderered (hinted) with the help of a + specific bytecode where the behaviour of a few opcodes is patented by + Apple. We're currently in contact with Apple to discuss the importance + of such patents and their use in open source projects like FreeType. +

+ +

In the meantime, we have developped our own alternative technology that + is capable of automatically hinting scalable glyph images. It is + now part of the FreeType 2 source tree as the "autohint" module, + and is used to hint glyphs when the bytecode interpreter is disabled + (through a configuration macro when building the engine). Note that + the auto-hinter is also used to handle glyphs in other formats like + CFF and Type 1.

+ +

The auto-hinter provides pretty good results (in some cases, it even + significantly improves the output of poorly hinted fonts) but we'll + continue to improve it with each new release of FreeType to achieve + the highest possible quality.

+ + +

Modular design:

+ +

The design of FreeType 2 is extremely modular as most features are + supported through optional modules. This means it's easily possible to + only compile the features you need. As each module is between + 10 and 20 Kb in size, it's possible to build a bare-bones + font engine that supports anti-aliasing in about 30 Kb !!

+ +

Configuration is performed by modifications of only two header + files (one to select global features, another one to select modules) + and don't need tweaking of source code. Note that it is however + possible to provide your own implementation of certain components.

+ +

For example, when building on Unix, the engine will automatically + use memory-mapped files when available on the target platform, + thus significantly increasing font file i/o.

+ + +

Due to its very flexible design, it is possible to add, remove and + upgrade modules at run-time.

+ + + +

Advanced glyph management

+ +

The API comes with a standard extension used to extract individual + glyph images from font files. These images can be bitmaps, scalable + bezier outlines or even anything else. (e.g. bi-color or metafont + glyphs, as long as they're supported by a module).

+ +

Each scalable glyph image can be transformed, measured and + rendered into a monochrome or anti-aliased bitmaps easily + through a uniform interface. + + This allows client applications to easily cache glyphs or + perform text rendering effects with minimal difficulty + (look at the FreeType 2 Tutorial to see how to render + rotated text with very few lines of code). +

+ + + +

Advanced font access

+ +

The FreeType 2 API is useful to retrieve advanced information from + various fonts:

+ +
    +
  • vertical metrics are available whenever found in the font file
  • + +
  • kerning distances are available when found in the font file. It + is also possible to "attach" a given additional file to a given + font face. This is useful to load kerning distances from an + .afm file into a Type 1 face for example.
  • + +
  • provides ASCII glyph names whenever available in the font + (TrueType, OpenType, Type1, etc..)
  • + +
  • provides access to important tables for SFNT-based font formats + (i.e. TrueType, OpenType, CEF, etc..), like the name table, + font header, maximum profile, etc...
  • + +
  • automatic synthesis of Unicode-based character maps for + those fonts or formats that do not provide one. This is + extremely useful with Type 1 fonts which are normally + limited to a stupid 256-characters encoding.
  • +
+ + +

Simple & clean API

+ +

The FreeType 2 high-level API is simple and straightforward, as it + has been specifically designed to make the most commmon font operations + easy

+ +

As a comparison, the number of function calls needed to perform a + the tasks of font face creation/opening and glyph loading/rendering + has been reduced by a factor of 4 !!

+ +

The API is also independent of any font-format specific issue, though + it provides standard extensions to access format-specific tables and + information. More extensions can also be easily added through new + modules

+ + +

Robust & Portable code

+ +

Because it is written in industry-standard ANSI C, FreeType 2 compiles + on all platforms with a compliant compiler. Because the default build + only relies on the C library, it is free of any system-specific + dependencies, even if it is possible to "enhance" certain components + by providing a specific implementation.

+ +

The code doesn't use global or static variables. Client applications + can provide their own memory manager. Font files can be read from + a disk file, memory, or through a client-provided input stream. This + allows to support compressed font files, remote fonts, fonts embedded + in other streams (e.g. Type42 fonts), etc..

+ +

An advanced i/o sub-system is used to optimise file access, as well + as reduce memory usage of the library when the file is memory-based + ( ROM, RAM, memory-mapped ).

+ + +

Open Source & Vendor Independence

+ +

Finally, FreeType 2 is released under its own BSD-like open source + license, one of the less restricting licenses available, and this + means that:

+ +
    +
  • + It can be included in all kinds of products, be they proprietary + or not. +

  • + +
  • + As any module can be added or replaced anytime, any third party + vendor has the ability to provide its own set of modules (under + its own license) in order to support proprietary font formats or + more advanced features (e.g. a new auto-hinter, or a new + anti-aliasing renderer for LCDs or TV screens). +

  • +
+ +

One could even imagine an application using the FreeType 2 API with + a "wrapper" module used to access system-specific fonts (like through + the Windows GDI). This would mean native font support with more portable + application code (as simply changing the wrapper module would be required + to port the application to another system).

+ +
+ +
+

Requirements

+
+ +

FreeType 2 is written in ANSI C and should compile with no problems + on a great variety of platforms. We have taken care of removing all + compilation warnings from major compliant compilers. Detailed compilation + instructions are provided in the software archive.

+ +

This version of the library has been succesfully compiled and run + under the following systems: Dos, OS/2, Windows, Macintosh, Unix + (including the 64-bits DEC Unix, a.k.a. "True64"). You should not + encounter major problems compiling it on any other kind of platform. + In all cases, contact us if you do.

+ +

Note that a small set of demonstration programs is also separately + available. They include a tiny graphics sub-system that is used to + display and show-off the library's capabilities on the following + platforms: X11, MacOS, OS/2 & Windows.

+ +

Please visit our + Download section to access the software archives.

+ + + +
+ +
+

Patents issues

+
+ +

The FreeType 2 source code includes a TrueType bytecode interpreter that + is covered by the Apple patents. However, this piece of code is never + compiled by default in this release (unlike in previous betas) making + a default build of the library entirely patent-free !!

+ +

Note that in order to compile the interpreter, one needs to define + the configuration macro TT_CONFIG_OPTION_BYTECODE_INTERPRETER configuration + macro in the file "ftoption.h". More details are available in + the software archive. Note that the use of the interpreter is normally + protected by US, UK and French patents. In the event you'd absolutely + need it, you may have to contact + Apple legal department for licensing conditions, depending on your + location and the places you distribute/sell your products.

+ +

Please do not ask us any detailed information regarding licensing, as + we're still discussing with Apple this issue, we're unable to inform + the public of what's currently going on..

+ +
+ +


+

+Back to FreeType homepage

+ +

+ + diff --git a/docs/ft2faq.html b/docs/ft2faq.html new file mode 100644 index 000000000..6b9cc9bdb --- /dev/null +++ b/docs/ft2faq.html @@ -0,0 +1,502 @@ + + +FreeType 2 FAQ + + + + + + + +http://www.freetype.org

+ +

+ + The FreeType Project +

The FreeType 2 FAQ

+
+ +
+

+ +DOCUMENT INDEX:
+

+ + +


+ +
+

General questions & answers

+
+ + +

I.1. I though the FreeType project was dead. Is this true?

+
    +

    Well, not exactly :-) It's true that the TrueType patents issues + have been less than a graceful event to handle but it didn't not + really killed the project per se, as Apple hasn't made an official + statement yet regarding the use of the patented "technology" in + open source projects (or other products).

    + +

    We have thus continued updating FreeType 1.x, and started developping + FreeType 2 with the idea of providing this time a completely patent + free font engine. However, we largely preferred not to broadly + communicate about it until we've got a satisfying implementation + to show.

    +
+ + +
+

I.2. Why did it take so long to release FreeType 2?

+
+ + +

I.3. Is FreeType 2 a Unix-only project?

+
+ + +

I.4. When will X11/XFree support anti-aliased text?

+
    +

    This question isn't exactly related to FreeType as we have no direct + connection to the XFree people, but we've been asked so frequently + about it that it deserves a prominent place in this FAQ :-)

    + +

    FreeType has been capable of anti-aliasing since version 1.0. The + reason why XFree doesn't support it is directly related to the + limitations of the design and specification of X11. More specifically:

    + +
      +
    • + X11 assumes that all glyph images are monochrome bitmaps, + hence the X font library and server are unable to send anything + else to the X server. +

    • + +
    • + Even if the X font library/server was able to generate anti-aliased + bitmaps (and this has been already done through extensions), the X + rendering model doesn't allow translucent composition of "gray" pixmaps + onto an arbitrary drawable. +

    • +
    + +

    As both the font and rendering models of X11 are limited, it's basically + impossible to draw anti-aliased glyphs without performing huge + hacks within the server.

    + +

    Note that Keith Packard, from XFree fame, has recently started working + on a new rendering model for X11 in order to support new features + (mainly transparency and anti-aliased fonts). This will be provided + through protocol extensions. The question of knowing wether legacy X + applications will be able to display anti-aliased text is still very + uncertain. +

    +
+ +
+

I.5. Is FreeType 2 backwards compatible with FreeType 1.x?

+
    +

    Not directly, though we had the project to provide an optional binary + compatibility layer on top of it in order to easily re-link applications + with the new version. However, this idea has been dropped as it is + possible to install and use the two versions independtly on any + system (read: no namespace conflicts).

    + +

    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.

    + +
+ +
+

I.6. Can I use FreeType 2 to edit fonts or create new ones?

+
    +

    The answer is a definitive NO, because the library was specifically + designed to read font files with small code size and very + low memory usage.

    + +

    We thus do not plan to support editing or creation in the font + engine in any way, as this would imply a complete rewrite. This + doesn't mean that we won't introduce a font editing/creation library + in the future, as this really depends on how many people are asking + for it (or how much they would be willing to pay for it), as well as + the time of the FreeType developers.

    + +

    Do not expect anything in this direction until we officially announce + something though. There are other axis of development for this project + (like text-layout capabilities, glyph caching, etc..) that may be more + important to us at the moment..

    +
+ +
+ +
+

Compilation & Configuration

+
+ + +

II.1. How do I compile the FreeType 2 library?

+
    +

    The library can be compiled in various ways, and a detailed documentation + is available in the file "freetype2/docs/BUILD". However, we'll + summarize the process to a few cases:

    + +

    a. by using the command-line 2 build system

    + +

    The engine comes with a sophisticated build system that is used + to configure and compile a build of the library. You'll need + GNU Make installed on your platform (NOTE: It will not + work with other Make tools).

    + +

    Basically, you'll need to invoke make a first time in the + top-level FreeType 2 directory in order to setup the build. This will + detect your current platform and choose a configuration sub-makefile to + drive the build. A specific compiler can be selected on some platforms + by providing an additional target. For example, on Win32:

    + +
      +
    • make visualc will select the Visual C++ compiler
    • +
    • make lcc will select the Win32-lcc compiler
    • +
    + +

    Note that on Unix, the first time make is called, a configure script + located in "freetype2/builds/unix" will be run in order to + automatically detect the platform & compiler.

    + +

    A summary will be displayed showing the detected platform and compiler + selected. You'll then be able to start the build by invoking make + a second time. In case of problem, consult the BUILD document.

    + + +

    b. by direct compilation

    + +

    You can also directly compile the library from the command line by + using these simple rules:

    + +
      +
    • + You should place the directories "freetype2/include" and + "freetype2/src" in your include path in order to compile + any component of the library. You can also add the system-specific + build directory (i.e. "builds/system/") in the + case where an alternate implementation of some of the components + is available there (e.g. the memory-mapped i/o implementation + on some Unix systems). +

    • + +
    • + The components of the library are located in sub-directories of + "src", for example: "src/base", + "src/truetype", etc.. +

    • + +
    • + Each component is normally compiled through a single C file that + "wraps" other sources in the component's directory. For example, + your should compile the TrueType font driver by compiling the + file "src/truetype/truetype.c". The list of C files to + compile for a feature-complete build of the library is given in + the BUILD document. +

    • +
    + +

    c. in a graphical IDE

    +
      +

      Well, the process is vastly similar to the one described in b., + except that you need to set the include paths, source code paths, + etc.. in dialog boxes before running the compilation. +

      +
    + +
+ +
+

II.2. How do I configure my build of the library?

+
    +

    Each build of the library is configured through two header files + located in "include/freetype/config":

    + +
      +
    • ftoption.h
      + This file contains various configuration macros whose definition + can be toggled on a per-build basis. Each macro is heavily + commented in this file's comment, and we invite you to refer + to it directly.

    • + +
    • ftmodule.h
      + This file contains the list of all the modules that are initially + registered (added) when the function FT_Init_FreeType + is called. See the next answer to know how to change it and + why it may be important.

    • +
    + +

    Alternatively, some specific implementations of some FT2 components + can be provided in a "builds/system/" directory + (e.g. the Unix-specific ftsystem.c that uses memory-mapped + file for i/o).

    +
+ +
+

II.3. How do I select the modules I need in my build?

+
    +

    The function FT_Init_FreeType creates a new instance + of the FT2 library and registers a set of "default" modules before + returning to the calling application. Its default implementation + is in the file "src/base/ftinit.c".

    + +

    The list of default modules used by ftinit.c is located in + the configuration file "include/freetype/config/ftmodule.h". + It is normally automatically generated by the build system by + invoking the "make modules" command in the top + level FT2 directory (note: only works with GNU Make, you can + edit the file by hand otherwise). It does so by parsing all + sub-directories of "src" that contain a file named + module.mk.

    + +

    Note that a specific port or project is free to provide its own + implementation of ftinit.c in order to ensure a different + initialisation sequence. For example, one could do something like:

    + +
      +
    • compile each module as a shared library (DLL or .so) with + a common "entry point" to retrieve a pointer to its + module class (there is already some code that allows this + when compiling each module).

    • + +
    • place these modules in a directory like + "/usr/lib/freetype2/modules/"

    • + +
    • provide an implementation of ftinit.c that would + scan the directory for valid modules.

    • +
    + +

    This example only emphasize the flexibility that is left to + developers when building the library.

    + +
+ +
+

II.4. How do I compile all FreeType 2 files in a single directory?

+
    +

    Some projects may need, for the sake of simplicity or ease of + building, to compile the FT2 library with all source files + copied to a single directory. This is possible.

    + +

    To do so, you'll need to copy all source files located under + "src" to your own directory (you must retain the + include files in a distinct hierarchy though), then compile + each of the FreeType 2 component with the macro + FT_FLAT_COMPILE. This will change the way + #include works during the build.

    +
+ +
+ +
+

Using the FreeType 2 library

+
+ +
+ +
+

The FreeType 2 auto-hinter

+
+ + +

IV.1. Under which license is the FreeType 2 auto-hinter released

+
    +

    The auto-hinter was initially designed and implemented under contract + for Catharon Productions, Inc + which gladly accepted to released it under an open-source license + compatible with the FreeType one.

    + +

    This license can be found in "src/autohint/CatharonLicense.txt" + and requires that you cite Catharon Productions in your documentation + (just like you do with FreeType) when using the auto-hinting module.

    + +

    Other than that, you still have the same freedom than with the good old + FreeType license. Enjoy !

    +
+ + +

IV.2. How does the auto-hinter works ?

+
    +

    Well, a complete description would be difficult. Have a look at the + dedicated auto-hinter pages on the FreeType + site, as they describe most of its details with graphics and explanations. + You could also look at the source code if you want to :-)

    + +

    To give a few details, the auto-hinter is used to perform grid-fitting + on scalable font formats that use bezier outlines as their primary glyph + image format (this means nearly all scalable font formats today). When + a given font driver doesn't provide its own hinter, the auto-hinter is + used by default. When 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.

    + +

    The auto-hinter currently 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. Note that + we plan the ability to specify external hints, given that it is based + on a constraint system. That could be used to support native hints + in Type 1/Type 2 fonts, for example.

    +
+ + +

IV.3. Why does the auto-hinter doesn't work correctly with CJK fonts ?

+
    +

    The auto-hinter was first designed to manage and hint latin-based fonts, + as they consist of most of the fonts available today. It doesn't hint + asian fonts, as well as a few other complex scripts, because we didn't + put enough research on the topic yet. Hinting CJK isn't really more + difficult than latin, just different with a set of different constraints + (basically, more distortion of glyphs is acceptable as long as certain + features like triple-stem positions are respected more strictly..).

    + +

    We thus plan to handle such a case rather rapidly.. Please be patient.

    +
+ + +
+ +
+

Other questions

+
+ + +

V.1. What is the anti-aliasing algorithm 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 absolutely now sub-sampling/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; while libArt shines + at general shape/polygon processing, especially large ones.

    + +

    The FT2 anti-aliasing renderer is indeed faster than the + monochrome renderer for small character sizes (typically < 20 pixels). + This is explained because the monochrome renderer must perform two + passes on the outline in order to perform drop-out control according + to the TrueType spec (we could drop this requirement later though).

    + +

    We'll try to document its design in a later document, though this is + not a priority for now.

    +
+ + +

V.2. When will FreeType 2 support OpenType ?

+
    +

    Well, the engine already reads OpenType/CFF files perfectly. What it + doesn't do is handle "OpenType Layout" tables yet.

    + +

    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" used to demonstrate its capabilities that + runs pretty smooth.

    + +

    For FreeType 2, we have decided that the layout operations provided + through these tables is better placed in a specific text-layout library, + (many people having asked for such a thing). This new engine would not + depend on FT2 explicitely and will be developed as a separate project. + We plan to announce it in a few weeks with all gory details, + once the definitive 2.0 release of FreeType has been made.

    +
+ +
+ +


+

+Back to FreeType homepage

+ +

+ + diff --git a/docs/tutorial/step1.html b/docs/tutorial/step1.html index 5b3a4c650..e184be7b9 100644 --- a/docs/tutorial/step1.html +++ b/docs/tutorial/step1.html @@ -542,10 +542,11 @@

The parameter render_mode is a set of bit flags used - to specify how to render the glyph image. Set it to 0 to render - a monochrome bitmap, or to ft_render_mode_antialias to - generate a high-quality (256 gray levels) anti-aliased bitmap - from the glyph image.

+ to specify how to render the glyph image. Set it to 0, or the + equivalent 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), @@ -675,10 +676,23 @@ of (0,0) will be used). The vector coordinates are expressed in 1/64th of a pixel (also known as 26.6 fixed floats).

-

NOTA BENE: The transform is applied every glyph that is loaded - through FT_Load_Glyph. Note that loading a glyph bitmap - with a non-trivial transform will produce an error..

- + +

NOTA BENE: The transform 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 at 12 pixels scaled by 2 through a transform, because the + hints will have been computed differently (unless, of course you + disabled hints).

+ +

If you ever need to use a non-orthogonal transform with optimal + hints, you first need to decompose your transform 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.

+ +

Note also that loading a glyph bitmap with a non-identity transform + will produce an error..


@@ -721,7 +735,7 @@ if (error) continue; // ignore errors // convert to an anti-aliased bitmap - error = FT_Render_Glyph( face->glyph, ft_render_mode_antialias ); + error = FT_Render_Glyph( face->glyph, ft_render_mode_normal ); if (error) continue; // now, draw to our target surface @@ -790,7 +804,7 @@ 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 | FT_LOAD_ANTI_ALIAS ); + error = FT_Load_Char( face, text[n], FT_LOAD_RENDER ); if (error) continue; // ignore errors // now, draw to our target surface @@ -815,12 +829,15 @@
  • We do not use FT_LOAD_DEFAULT for the loading mode, but - the two bit flags FT_LOAD_RENDER and - FT_LOAD_ANTI_ALIAS. The first flag indicates that - the glyph image must be immediately converted to a bitmap, and - the second that it should be renderer anti-aliased. Of course, this - is also a shortcut that avoids calling FT_Render_Glyph - explicitely but is strictly equivalent.. + 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 explicitely 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.

  • @@ -857,7 +874,7 @@ FT_Set_Transform( face, &matrix, &pen ); // load glyph image into the slot (erase previous one) - error = FT_Load_Char( face, text[n], FT_LOAD_RENDER | FT_LOAD_ANTI_ALIAS ); + error = FT_Load_Char( face, text[n], FT_LOAD_RENDER ); if (error) continue; // ignore errors // now, draw to our target surface (convert position) @@ -909,6 +926,9 @@ 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 short comings that we will explain, and solve, + in the next part of this tutorial.

    +

    diff --git a/docs/tutorial/step2.html b/docs/tutorial/step2.html new file mode 100644 index 000000000..d8cc1505c --- /dev/null +++ b/docs/tutorial/step2.html @@ -0,0 +1,1399 @@ + + + + + + FreeType 2 Tutorial + + + + +

    + FreeType 2.0 Tutorial
    + Step 2 - managing glyphs +

    + +

    + © 2000 David Turner + (david@freetype.org)
    + © 2000 The FreeType Development Team + (www.freetype.org) +

    + +
    + + +
    + +
    + +

    + Introduction +

    + +

    This is the second section of the FreeType 2 tutorial. It will teach + you the following:

    + +
      +
    • how to retrieve glyph metrics
    • +
    • how to easily manage glyph images
    • +
    • how to retrieve global metrics (including kerning)
    • +
    • how to render a simple string of text, with kerning
    • +
    • how to render a centered string of text (with kerning)
    • +
    • how to render a transformed string of text (with centering)
    • +
    • finally, how to 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 + to 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 (like latin, cyrillic, + arabic, hebrew, etc..), and those used to layout the glyph in vertical + text layouts (like some layouts of Chinese, Japanese, Korean, and + others..).

    + +

    Note that only a few font formats provide vertical metrics. You can + test wether a given face object contains them by using the macro + FT_HAS_VERTICAL(face), 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. This will be detailed + later, for now, we'll see that it contains the following fields:

    + +
    + width + +

    This is the width of the glyph image's bounding box. It is independent + of layout direction.

    +
    + height + +

    This is the height of the glyph image's bounding box. It is independent + of layout direction.

    +
    + horiBearingX + +

    For horizontal text layouts, this is the horizontal distance from + the current cursor position to the left-most 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 top-most 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 left-most 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 top-most 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.

    +
    + +

    NOTA BENE: As all fonts do not contain vertical + metrics, the values of vertBearingX, vertBearingY + and vertAdvance should not be considered reliable when + FT_HAS_VERTICAL(face) 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 and is the + vertical axis:

    + +
    + + +

    The metrics found in face->glyph->metrics are normally + expressed in 26.6 pixels (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 though + face->glyph->??? :

    + +
    + advance + +

    This field is a FT_Vector which holds the transformed + advance for the glyph. That's useful when you're 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 float + 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 same thing as linearHoriAdvance 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 times 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 transforms 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 "ftglyph.h" header file, as in:

    + +
    
    +      #include <freetype/ftglyph.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's some code + that shows how to do it:

    + +
    
    +       FT_Glyph    glyph;    // handle to glyph image
    +       
    +       ....
    +       error = FT_Load_Glyph( face, glyph, FT_LOAD_NORMAL );
    +       if (error) { .... }
    +       
    +       error = FT_Get_Glyph( face->glyph, &glyph );
    +       if (error) { .... }
    +  
    + +

    As you see, we have:

    + +
      +
    • + 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 + than the original one that is still in the slot. For example, if we're + 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 float coordinates. + The latter can be accessed directly as glyph->advance +

    + +

    Note that unlike + other FreeType objects, the library doesn't keeps a list of all + allocated glyph objects. This means you'll need 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's some example code:

    + +
    
    +    FT_Glyph  glyph, glyph2;
    +    FT_Matrix matrix;
    +    FT_Vector delta;
    +    
    +    ......
    +    .. load glyph image in "glyph" ..
    +    
    +    // copy glyph to glyph2
    +    //
    +    error = FT_Glyph_Copy( glyph, &glyph2 );
    +    if (error) { ... could not copy (out of memory) }
    +    
    +    // translate "glyph"
    +    //    
    +    delta.x = -100 * 64;   // coordinates are in 26.6 pixels
    +    delta.y =  50  * 64;
    +    
    +    FT_Glyph_Transform( glyph, 0, &delta );
    +    
    +    // transform glyph2 (horizontal shear)
    +    //
    +    matrix.xx = 0x10000;
    +    matrix.xy = 0;
    +    matrix.yx = 0.12 * 0x10000;
    +    matrix.yy = 0x10000;
    +    
    +    FT_Glyph_Transform( glyph2, &matrix, 0 );
    +  
    + +

    Note that the 2x2 transform matrix is always applied to the 16.16 + advance vector in the glyph, you thus don't need to recompute it..

    + +

    c. Measuring the glyph image

    + +

    You can also retrieve the control (bounding) box of any glyph image + (scalable or not), through the FT_Glyph_Get_CBox function, + as in: +

    + +
    
    +     FT_BBox   bbox;
    +     ...
    +     FT_Glyph_BBox(  glyph, bbox_mode, &bbox );
    +  
    + +

    Coordinates are relative to the glyph origin, i.e. (0,0), using the + Y_upwards convention. This function takes a special argument, the + "bbox mode", that is a set of bit flags used to indicate how + box coordinates are expressed. If ft_glyph_bbox_subpixels + is set in the bbox mode, the coordinates are returned in 26.6 pixels + (i.e. 1/64th of pixels). Otherwise, they're in integer pixels.

    + +

    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:

    + +
         
    +     width  = bbox.xMax - bbox.xMin;
    +     height = bbox.yMax - bbox.yMin;
    +  
    + +

    Note also that for 26.6 coordinates, if + ft_glyph_bbox_gridfit is set in the bbox mode, + the coordinates will also be grid-fitted, which corresponds to:

    + +
    
    +     bbox.xMin = FLOOR(bbox.xMin)
    +     bbox.yMin = FLOOR(bbox.yMin)
    +     bbox.xMax = CEILING(bbox.xMax)
    +     bbox.yMax = CEILING(bbox.yMax)
    +  
    + +

    The default value for the bbox mode, which is 0, corresponds to + ft_glyph_bbox_pixels (i.e. integer pixel coordinates).

    + + +

    d. Converting the glyph image to a bitmap

    + +

    You may need to convert the glyph object to a bitmap once you have + convienently cached or transformed it. This can be done easily with + the FT_Glyph_To_Bitmap function. It is chared of + converting any glyph object into a bitmap, as in:

    + +
    
    +    FT_Vector  origin;
    +    
    +    origin.x = 32;   /* 1/2 pixel in 26.26 format */
    +    origin.y = 0;
    +    
    +    error = FT_Glyph_To_Bitmap( &glyph,
    +                                render_mode,
    +                                &origin,
    +                                1 );        // destroy original image == true
    +  
    + +

    We will know details this function's parameters:

    + +
      +
    • + 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 2D 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 wether the source + glyph object should be destroyed by the function. By default, the + original glyph object is never destroyed, even if its handle is + lost (it's up to client applications to keep it). +

    • +
    + +

    The new glyph object always contain a bitmap (when 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:

    + +
    + left + +

    Just like the bitmap_left field of a glyph slot, this is the + horizontal distance from the glyph origin (0,0) to the left-most 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 top-most pixel + of the glyph bitmap (more exactly, 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 ones are used to describe distances + and features of a whole font face. They can be expressed either in + 26.6 pixels 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 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(face) 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 by the + last chapter of this section. Its value usually is 2048 (for TrueType) + or 1000 (for Type1), but others are possible too. It is set to 1 for + fixed-size formats like FNT/FON/PCF/BDF.

    +
    + global_bbox + +

    The global bounding box is defined as the largest rectangle that can + enclose all the glyphs in a font face. It is defined for horizontal + layouts only.

    +
    + 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's the ascent of the highest accented character, and finally, other + formats define it as being equal to global_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's the ascent of the lowest accented character, and finally, other + formats define it as being equal to global_bbox.yMin. + This field is usually negative

    +
    + text_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 in + absolute value. There is also no guarantee that no glyphs can 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. It is + only available in fonts providing vertical glyph metrics.

    +
    + underline_position + +

    When displaying or rendering underlined text, this value corresponds to + the vertical position, relative to the baseline, of the underline bar. It + noramlly is negative (as it's 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/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're expressed in 26.6 pixels.

    + +
    + ascender + +

    This is the scaled version of the original design ascender.

    +
    + descender + +

    This is the scaled version of the original design descender.

    +
    + height + +

    This is the scaled version of the original design text height. + That probably is the only field you should really use in this structure.

    +
    + max_advance + +

    Thi is 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're + 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.

    + +

    Note all font formats contain kerning information. Instead, they sometimes + rely on an additional file that contains various glyph metrics, including + kerning, but no glyph images. A good example would be 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 an additional 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 between + 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 glyphs 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's a enumeration that indicates how the + kerning distances are expressed in the target vector.

    + +

    The default value is ft_kerning_mode_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_mode_unfitted corresponds to kerning + distances expressed in 26.6 unfitted pixels (i.e. that do not correspond + to integer coordinates). It's the design kerning distance that is simply + scaled without rounding.

    + +

    Finally, the value ft_kerning_mode_unscaled is used to + return the design kerning distance, expressed in font units. You can + later scale it to 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 + + bi-directional 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 show 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're 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;
    +
    +      .. initialise 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_mode_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
    +      }
    +   
    + +

    That's it. You'll notice that:

    + +
      +
    • + As kerning is determined from glyph indices, we need to explicitely + convert our character code into a glyph index, then later call + FT_Load_Glyph instead of FT_Load_Char. No big + deal, if you ask me :-) +

    • + +
    • + We use a boolean named use_kerning which is set with the + result of the macro FT_HAS_KERNING(face). It's + 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 did initialize the variable previous with the value 0, + which always correspond 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 set the content of delta + to (0,0) when an error occurs. +

    • +
    + +

    As you see, this is not terribly complex :-)

    + +

    + b. Centering: +

    + +

    Our code begins to become interesting but it's still a bit too simple + for normal uses. For example, the position of the pen is determined + before we do the rendering when in a normal situation, you would want + to layout the text and measure it before computing its final position + (e.g. centering) or perform things like word-wrapping.

    + +

    We're thus now going to 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'll 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;
    +
    +      .. initialise 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_mode_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. DO NOT RENDER IT !!
    +        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++;
    +      }
    +   
    + +

    As you see, this is a very simple 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:

    + + +
    +      void   compute_string_bbox( FT_BBox  *abbox )
    +      {
    +        FT_BBox  bbox;
    +        
    +        // initialise string bbox to "empty" values
    +        bbox.xMin = bbox.yMin =  32000;
    +        bbox.xMax = bbox.yMax = -32000;
    +        
    +        // for each glyph image, compute its bounding box, translate it,
    +        // and grow the string bbox
    +        for ( n = 0; n < num_glyphs; n++ )
    +        {
    +          FT_BBox   glyph_bbox;
    +
    +          FT_Glyph_Get_CBox( glyphs[n], &glyph_bbox );
    +
    +          glyph_bbox.xMin += pos[n].x;
    +          glyph_bbox.xMax += pos[n].x;
    +          glyph_bbox.yMin += pos[n].y;
    +          glyph_bbox.yMax += pos[n].y;
    +
    +          if (glyph_bbox.xMin < bbox.xMin)
    +            bbox.xMin = glyph_bbox.xMin;
    +
    +          if (glyph_bbox.yMin < bbox.yMin)
    +            bbox.yMin = glyph_bbox.yMin;
    +
    +          if (glyph_bbox.xMax > bbox.xMax)
    +            bbox.xMax = glyph_bbox.xMax;
    +
    +          if (glyph_bbox.yMax &gy; bbox.yMax)
    +            bbox.yMax = glyph_bbox.yMax;
    +        }
    +        
    +        // check that we really grew the string bbox
    +        if ( bbox.xMin > bbox.xMax )
    +        {
    +          bbox.xMin = 0;
    +          bbox.yMin = 0;
    +          bbox.xMax = 0;
    +          bbox.yMax = 0;
    +        }
    +        
    +        // return string bbox
    +        *abbox = bbox;
    +      }
    +   
    + +

    The resulting bounding box dimensions can then be used to compute the + final pen position before rendering the string as in:

    + +
    +      // 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 start pen position in 26.6 cartesian pixels
    +      start_x = (( my_target_width  - string_width )/2)*64;
    +      start_y = (( my_target_height - string_height)/2)*64;
    +      
    +      for ( n = 0; n < num_glyphs; n++ )
    +      {
    +        FT_Glyph  image;
    +        FT_Vector pen;
    +        
    +        image = glyphs[n];
    +        
    +        pen.x = start_x + pos[n].x;
    +        pen.y = start_y + pos[n].y;
    +        
    +        error = FT_Glyph_To_Bitmap( &image, ft_render_mode_normal,
    +                                    &pen.x, 0 );
    +        if (!error)
    +        {
    +          FT_BitmapGlyph  bit = (FT_BitmapGlyph)image;
    +          
    +          my_draw_bitmap( bitmap->bitmap,
    +                          bitmap->left,
    +                          my_target_height - bitmap->top );
    +                          
    +          FT_Done_Glyph( image );
    +        }
    +      }
    +   
    + +

    You'll take note that:

    + +
      +
    • + 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 typecasted to a 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

    + +
    +

    + 5. Advanced text rendering: transform + centering + 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. We will + start by performing a few minor improvements:

    + +

    a. packing & translating glyphs:

    + +

    We'll 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:

    + +
    +     typedef struct TGlyph_
    +     {
    +       FT_UInt    index;    // glyph index
    +       FT_Vector  pos;      // glyph origin on the baseline
    +       FT_Glyph   image;    // glyph image
    +     
    +     } TGlyph, *PGlyph;
    +  
    + +

    We will also translate each glyph image directly after it is loaded + to its position on the baseline at load time. As we'll see, this + as 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;
    +
    +      .. initialise 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. The code becomes:

    + +
    +      void   compute_string_bbox( FT_BBox  *abbox )
    +      {
    +        FT_BBox  bbox;
    +        
    +        bbox.xMin = bbox.yMin =  32000;
    +        bbox.xMax = bbox.yMax = -32000;
    +        
    +        for ( n = 0; n < num_glyphs; n++ )
    +        {
    +          FT_BBox   glyph_bbox;
    +
    +          FT_Glyph_Get_CBox( glyphs[n], &glyph_bbox );
    +
    +          if (glyph_bbox.xMin < bbox.xMin)
    +            bbox.xMin = glyph_bbox.xMin;
    +
    +          if (glyph_bbox.yMin < bbox.yMin)
    +            bbox.yMin = glyph_bbox.yMin;
    +
    +          if (glyph_bbox.xMax > bbox.xMax)
    +            bbox.xMax = glyph_bbox.xMax;
    +
    +          if (glyph_bbox.yMax &gy; bbox.yMax)
    +            bbox.yMax = glyph_bbox.yMax;
    +        }
    +        
    +        if ( bbox.xMin > bbox.xMax )
    +        {
    +          bbox.xMin = 0;
    +          bbox.yMin = 0;
    +          bbox.xMax = 0;
    +          bbox.yMax = 0;
    +        }
    +        
    +        *abbox = bbox;
    +      }
    +   
    + +

    Now take a closer look, the compute_string_bbox can now + compute the bounding box of a transformed glyph string. For example, + we can do something like:

    + +
    
    +      FT_BBox    bbox;
    +      FT_Matrix  matrix;
    +      FT_Vector  delta;
    +   
    +      ... load glyph sequence
    +      
    +      ... setup "matrix" and "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 );
    +   
    + +

    + b. Rendering a transformed glyph sequence: +

    + +

    However, directly transforming the glyphs in our sequence is not an idea + if we want to re-use them in order to draw the text string with various + angles or transforms. It's better to perform the affine transformation + just before the glyph is rendered, as in the following code:

    + +
    +      FT_Vector  start;
    +      FT_Matrix  transform;
    +   
    +      // 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;
    +   
    +      // 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)*0x10000);
    +      matrix.xy = (FT_Fixed)(-sin(angle)*0x10000);
    +      matrix.yx = (FT_Fixed)( sin(angle)*0x10000);
    +      matrix.yy = (FT_Fixed)( cos(angle)*0x10000);
    +      
    +      for ( n = 0; n < num_glyphs; n++ )
    +      {
    +        FT_Glyph  image;
    +        FT_Vector pen;
    +        FT_BBox   bbox;
    +        
    +        // 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, &start );
    +        
    +        // 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;
    +          
    +          my_draw_bitmap( bitmap->bitmap,
    +                          bitmap->left,
    +                          my_target_height - bitmap->top );
    +                          
    +          FT_Done_Glyph( image );
    +        }
    +      }
    +   
    + +

    You'll notice a few changes compared to the original version of this + code:

    + +
      +
    • + We keep the original glyph images untouched, by transforming a + copy. +

    • + +
    • + We perform clipping computations, in order to avoid rendering & + 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 destroyed even when 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 intead of + FT_Glyph_To_Bitmap. +

    • +
    + +

    It's 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.

    + +

    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's 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..). +

    + +
    + +

    + 6. Accessing metrics in design font units, and scaling them: +

    + +

    Scalable font formats usually store a single vectorial image, called + an "outline", for each 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").

    + +

    This chapter describes how design coordinates are scaled to device + space, and how to read glyph outlines and metrics in font units. This + is important for a number of things:

    + +
      +
    • + In order to perform "true" WYSIWYG text layout +

    • + +
    • + In order to access font content for conversion or analysis purposes +

    • +
    + +

    a.Scaling distances to device space:

    + +

    Design coordinates are scaled to device space using a simple scaling + transform, whose coefficients are computed with the help of the + character pixel size:

    + +
    
    +     device_x = design_x * x_scale
    +     device_y = design_y * y_scale
    +
    +     x_scale  = pixel_size_x / EM_size
    +     y_scale  = pixel_size_y / EM_size
    +  
    + +

    Here, the value EM_size is font-specific and correspond + 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(face) macro, which returns true when + appropriate.

    + +

    When you call the function FT_Set_Pixel_Sizes, you're + specifying the value of pixel_size_x and pixel_size_y + you want to use to FreeType, which will immediately compute the values + of x_scale and y_scale.

    + +

    When you call the function FT_Set_Char_Size, you're + specifying the character size in physical "points", which is used, + along with the device's resolutions, to compute the character pixel + size, then the 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 + +

    Which stands for "X Pixels Per EM", this is the 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 + +

    Which stands for "Y Pixels Per EM", this is the 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 float 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 float scale that is used to directly scale + vertical distances from design space to 1/64th of device pixels.

    +
    +
    + +

    Basically, this means that you can scale a distance expressed in + font units to 26.6 pixels directly with the help of the FT_MulFix + function, as in:

    + +
    
    +      // convert design distances to 1/64th of pixels
    +      //
    +      pixels_x = FT_MulFix( design_x, face->size->metrics.x_scale );
    +      pixels_y = FT_MulFix( design_y, face->size->metrics.y_scale );
    +  
    + +

    However, you can also scale the value directly with more accuracy + by using doubles and the equations:

    + +
    
    +      FT_Size_Metrics*  metrics = &face->size->metrics;    // shortcut
    +      double            pixels_x, pixels_y;
    +      double            em_size, x_scale, y_scale;
    +
    +      // compute floating point scale factors
    +      //
    +      em_size = 1.0 * face->units_per_EM;
    +      x_scale = metrics->x_ppem / em_size;
    +      y_scale = metrics->y_ppem / em_size;
    +      
    +      // convert design distances to floating point pixels
    +      //
    +      pixels_x = design_x * x_scale;
    +      pixels_y = design_y * y_scale;
    +  
    + +

    + b. Accessing design metrics (glyph & global): +

    + +

    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 chapter 3 + of this section.

    + +
    + +

    + Conclusion +

    + +

    This is the end of the second section of the FreeType 2 tutorial, + you're 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 there if you want.

    + +

    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). +

    +
    +
    + + +