FreeType 1.31.1

This commit is contained in:
2023-08-27 18:03:45 +02:00
commit 5edbb7a80a
454 changed files with 173977 additions and 0 deletions

799
docs/FAQ Normal file
View File

@@ -0,0 +1,799 @@
FreeType User FAQ
--------------------------------------------------------------------
Table of contents
1. How do I compile the test programs?
2. What are the test programs?
3. How do I use them?
4. How do I only compile the FreeType library?
5. The library compiles fine on my system, unfortunately it seems
the test programs won't. What can I do?
6. What is FreeType, and what is it not?
7. Can FreeType be ported to other platforms?
8. My TrueType font only works on a Mac/in Windows. Will I be able
to use it with FreeType?
9. What are the most common character mappings?
10. How do I render text with FreeType?
11. How do I render rotated/slanted text with FreeType?
12. How do I compute a glyph bitmap's dimensions?
13. Why is text rendering so slow? Does FreeType cache glyphs?
14. Do you always render the same glyphs as Windows or the Mac?
15. The program `ftlint' reports errors with one of my fonts, though
it works perfectly under Windows. What does this mean?
16. What does the `fttimer' test program benchmarks?
17. Is it possible to perform styling (like oblique, italic, bold,
underline, etc.) with FreeType?
18. When does glyph hinting takes place? Is it when the glyph is
loaded, or when it is converted to a bitmap/pixmap?
19. Which is the best, caching outlines or bitmaps?
20. Can I open OpenType and/or TrueType GX fonts with FreeType?
21. How can I access additional TrueType tables that FreeType
doesn't support?
22. When will I be able to use FreeType to display TrueType fonts in
X11, Wine, or OS/2, or even other systems?
23. What does the `free' in FreeType really means?
24. Does FreeType support threads? Is it re-entrant?
25. Does FreeType support `foreign languages'?
26. I'm using fractional char sizes, but the glyphs stay at the same
integer size. Why?
27. Hinting doesn't work at very small sizes. Why?
--------------------------------------------------------------------
1. How do I compile the test programs?
Detailed compilation steps are given in the `freetype/HOWTO.txt'
file, as well as system and compiler specific hints in the
`freetype/howto' directory. What follows is a _very_ simple
guide:
For Unix:
Do the following on the prompt while in the base directory of
the FreeType package:
% ./configure
% make
% make install
This will build and install the library (shared, if supported)
together with the test programs. Say `./configure --help' to
see the available configuring options.
This should work with any ANSI C compiler.
For other platforms:
Go to the `test' directory. Look at one of the makefiles
located in the `arch/<system>' directory, and use the
appropriate makefile from there.
For example:
make -f arch/msdos/makefile.gcc (DJGPP or emx)
wmake -f=arch\msdos\makefile.wat (Watcom DOS)
nmake -f arch\os2\makefile.icc (Visual Age OS/2)
make -f arch/amigaos/makefile.gcc (GCC Amiga)
This will compile both the library and the test programs.
--------------------------------------------------------------------
2. What are the test programs?
The test programs are simple sources that `show off' the FreeType
library. They are located in the `test' directory. They make use
of a small graphics sub-system which is able to display bitmaps
and pixmaps on a variety of platforms through the use of
system-specific `drivers'.
The test programs are:
ftdump: A simple TTF information dumper. Also prints the
memory used by each opened font file with FreeType.
Doesn't use the graphics sub-system.
ftlint: A simple TrueType bytecode verifier. It simply hints
all glyphs of one or more font files at a given size
and reports errors. Doesn't use the graphics
sub-system.
ftview: A simple font viewer. Displays all glyphs in a font
file in a window.
ftstring: Renders a simple string to the screen. Demonstrates
how to produce text with FreeType.
fttimer: A simple benchmark, used to profile the scan-line
conversion routines (and only them). Supports also
display.
ftstrpnm: A version of `ftstring' which saves a bit/pixmap to a
PNM file rather than to the screen. No graphics
sub-system needed.
ftzoom: A simple glyph viewer, useful to view, zoom and rotate
individual glyphs in a font file.
fterror: This program demonstrates how to use the ftxerr18
extension. Note that internationalized strings will
be available on some platforms only (e.g. Linux).
ftmetric: A simple metric/glyph dumper. No graphics sub-system
needed.
ftsbit: Displays data about embedded bitmaps in a TrueType
font.
ftstrtto: Renders a string to screen, using TrueType Open
features.
NOTE: The file `ftdebug.c' isn't part of the test suite. It is
used only by the developers team to debug the engine at a
higher level. It won't work with a standard library
compile.
The tiny graphics subsystem is defined in the following files:
gmain.h/gmain.c: The subsystem's main body/interface.
gevents.h: The definition of events defined for the
subsystem
gdriver.h: The generic interface of all system-specific
drivers.
System-specific drivers are in the `test/arch/<system>'
directories, like:
test/arch/msdos/gfs_dos.c Full-Screen DOS driver
test/arch/os2/gpm_os2.c PM (Windowed) OS/2 driver
test/arch/unix/gwin_x11.c X11 Windowed driver
etc.
--------------------------------------------------------------------
3. How do I use them?
Please read the file freetype/README for a full description.
--------------------------------------------------------------------
4. How do I only compile the FreeType library?
For Unix:
Do a `configure' run as described in section 1. Then change to
the lib subdirectory and say `make' and `make install'.
For other platforms:
Go to the `lib' directory. Look at one of the makefiles located
in the `arch/<system>' directory, and use it from `lib'.
For example:
make -f arch/msdos/makefile.gcc (DJGPP or emx)
wmake -f=arch\msdos\makefile.wat (Watcom DOS)
nmake -f arch\os2\makefile.icc (Visual Age OS/2)
make -f arch/amigaos/makefile.gcc (GCC Amiga)
The library is pure ANSI C and doesn't depend on any
system-specific package. You need not gcc to compile it.
--------------------------------------------------------------------
5. The library compiles fine on my system, unfortunately it seems
the test programs won't. What can I do?
As said before, the test programs rely on a small graphics
sub-system to display the bitmaps and pixmaps produced by the
library. The following systems are currently supported:
DOS Full-Screen
Amiga Full-Screen Note that the windowed graphics
Amiga Windowed driver are very 'basic', they do
OS/2 Full-Screen not provide menus, dialog boxes,
OS/2 Windowed etc. Rather, they provide one
X11 Windowed windowed bitmap/pixmap and translate
Win32 Windowed events to the ones defined in
`test/gevents'.
If you want to add support to your system, you should write a new
graphics driver. To do that, read the file `test/gdriver.h' which
contains the driver generic interface, then browse the drivers
that are already provided.
The graphics drivers are located in the `test/arch/<system>'
directories. They're not part of the library proper.
IMPORTANT NOTE:
You can also directly link the library to your own application
and render glyphs directly into your own bitmaps with very few
efforts.
--------------------------------------------------------------------
6. What is FreeType, and what is it not?
FreeType is a rather low-level font engine. It has been designed
primarily to be the basis of several font servers, for very
different systems which all have their own metrics and graphics
models. This means that it focuses on the following points:
- Opening and loading font files in memory.
- Giving access to most important font properties and TrueType
tables.
- Providing a simple way to translate system-specific character
codes into glyph indexes, according to the TrueType `cmap'
specification.
- Loading and rendering _individual_ glyphs as nicely as possible
(either in outlines, bitmaps, or pixmaps), and performing
excellent hinting.
It isn't a high-level text rendering library, and many tasks will
have to be performed by higher level layers like:
- glyph caching (outlines and/or maps)
- text rendering
- justification, kerning
- font mapping
- rotated/slanted text
However, its API provides many functions that ease these
operations considerably:
- Glyph outlines can be copied and transformed easily with the API
functions, then rendered to bitmaps or pixmaps with FreeType's
scan-line converter, which is very fast.
- The glyph loader places the outlines in order to ease the
process of text rendering. See the documentation file named
`glyphs.htm' (resp. `glyphs.txt') or `ftstring's source for more
details.
- The engine gives you access to several TrueType tables that can
be processed by your application to provide more powerful
rendering (e.g. kerning).
- It is possible, and rather simple, to write separately
compilable extensions to the engine to access other TrueType
tables that are not supported by the engine in this release.
This can be handy if one wants to access data in TrueType GX or
OpenType fonts (as these formats comply to the TrueType `sfnt'
file storage format, they can be opened by the FreeType engine
as a normal TrueType file).
--------------------------------------------------------------------
7. Can FreeType be ported to other platforms?
FreeType is written in pure ANSI C and should compile well on all
16, 32, and 64 bits processors. Note, however, that the 16-bit
port requires a large memory model, as some tables found in
TrueType programs could exceed 64kByte (this is really true for
CJK and Unicode fonts. Nearly all others should work fine with
it).
It doesn't support some very exotic platforms though, like a
32-bit only processor (where the only word size is 32-bit, even
for chars and shorts). However, nothing prevents you to test it
by yourself...
The memory management and file access routines have been gathered
in two components, namely `ttmemory' and `ttfile', which can be
specialized for a specific system. Their standard version, found
in the `lib' directory, uses simply the ANSI libc. However,
examples are given of alternative file components for OS/2 and
Unix in:
lib/arch/os2/ttfile.c
(accessing the low-level OS/2 file API directly)
lib/arch/unix/ttmmap.c
(using memory-mapped files for improved access)
You would certainly need to rewrite these components if you intend
to use FreeType in an embedded system.
--------------------------------------------------------------------
8. My TrueType font only works on a Mac/in Windows. Will I be able
to use it with FreeType?
Short Answer: YES, but be cautious!
If you have read section 9 or 25, you know that a font file might
have different charMaps entries, used to translate character codes
to glyph indexes. The problem of most `system-specific' TrueType
fonts (sigh) is that they only contain one single mapping, like
Apple Roman, or Windows Glyph List, making it usable only on the
platform it was `designed' for.
The test program `ftdump' can be used to display the character
encodings supported in a font file. Most fonts come with Apple
Roman and Windows Unicode.
FreeType can use every charmap found in a font file, so it is up
to your application to choose the one that fits its task best. If
you use a font which only provides an Apple Roman charcode, you'll
probably have a hard time rendering Unicode strings without an
additional translation.
Note that the tool `ttf_edit' can actually add missing cmaps to a
TrueType font file. More info on this can be found at:
http://www.truetex.com
Another possibility is to use Just van Rossum's TTX compiler
(still beta) which can convert a TrueType font into an XML
description and vice versa; it can be found at
http://www.letterror.com/ttx/
--------------------------------------------------------------------
9. What are the most common character mappings?
If you don't want to read the TrueType specification, here is some
information about the most used char maps. Each map is designed
by a `platform ID', followed by a platform-specific `encoding ID':
Examples:
0, 0 : Apple Unicode
1, 0 : Apple Roman
3, 0 : Windows Symbol
3, 1 : Windows Unicode
Windows and Apple Unicode charmaps differ only in internal storage
layout. Both can be used transparently with FreeType.
Many fonts come also with both Apple Roman and Windows Unicode.
--------------------------------------------------------------------
10. How do I render text with FreeType?
This is explained with great detail in the glyphs documentation
file available in both text (glyphs.txt) and HTML (glyphs.htm,
including schematics).
Text rendering isn't difficult. One can also look at the code for
`ftstring' or `ftstrtto' to see how it is done.
--------------------------------------------------------------------
11. How do I render rotated/slanted text with FreeType?
It is possible to transform the outlines returned by the glyph
loader, hence producing rotated or slanted text. Please read the
`glyphs' documentation file, which explains this in great detail,
as well as some other important things.
--------------------------------------------------------------------
12. How do I compute a glyph bitmap's dimensions?
You should grid-fit its bounding box, then compute its width and
height. This is explained in the `bitmaps.txt' documentation
file.
--------------------------------------------------------------------
13. Why is text rendering so slow?
Does FreeType cache glyphs?
The FreeType engine doesn't cache anything, be it outlines or
bitmaps. Hence, a program that renders text by calling the glyph
loader on each letter is slow.
Because caching cannot be performed in both an _easy_ and
_portable_ way it is left to the application. Moreover, some
graphics systems already provide some sort of caching, and it is
better to take advantage of it rather than re-implementing it.
The `how's and `when's of caching are explained in the `glyphs'
documentation file. The `bitmaps' documentation file is also a
good source of information if you intend to render individual
glyph bitmaps.
--------------------------------------------------------------------
14. Do you always render the same glyphs as Windows or the Mac?
Short answer: No for rare cases.
There are a lot of technical details, too numerous and lengthy to
be put here, that prevents the FreeType library from matching 100%
the glyphs produced by the Windows or Macintosh rasterizers.
This engine is a clean-room implementation, and most of the
reasons why its development took so much time is the largely
deficient TrueType specification published by Apple and Microsoft.
A number of key technical aspects are missing, and we found many
`undocumented' features in the TrueType bytecode, after several
months of testing and trying. We are now very satisfied with the
current quality, though still try to improve it.
The glyph metrics (bearings and advances) also match significantly
those computed by Windows, or found in the TrueType pre-calc
tables.
As hinting glyphs also makes use of several rounding operations,
we will be unable to provide a perfect clone unless we implement
the exact same computations _and_ rounding errors -- this is
very unlikely...
--------------------------------------------------------------------
15. The program `ftlint' reports errors with one of my fonts, though
it works perfectly under Windows. What does this mean?
Associated to each glyph is a small `program', written in a
specific bytecode language, which is in charge of hinting the
glyph's outline to make it perfect on screen as on paper. Some of
these programs can be broken (e.g., accessing invalid areas of
memory, performing a divide by zero, etc.), and these are the
errors that are reported by `ftlint'.
They can also mean a bug in the TrueType bytecode interpreter (or
more likely an `undocumented' feature we haven't discovered yet),
but should now be extremely rare.
Surprisingly, even largely distributed fonts can contain broken
glyph programs. For example:
- antqua.ttf, glyph 163 (MS Office 4.2):
The program tries to access point number 0x127, which is too
much.
- timesbs, arialbs, courbs (MS Office International):
The back-slanted versions of the MS core fonts produce stack
overflows in many glyphs, and other oddities. It seems their
`maximum profile' table is invalid.
- a ton of `free' fonts, apparently designed with mediocre tools.
It seems the Windows TrueType engine doesn't check its arguments
often, and let all overflows run, possibly writing to critical
portions of memory. Please, don't ask us what this could do to
NT 4 :-)
The FreeType engine performs checks on every opcode. We cannot
guarantee that it is bullet proof, of course, but it seems to work
well and catch font bugs accordingly.
We also have artificially `enlarged' some allocated tables to make
the engine work with the back-slanted fonts without compromising
security, but it's clearly a hack we would have preferred to
avoid!
--------------------------------------------------------------------
16. What does the `fttimer' test program benchmarks?
This test program is only dedicated to profiling FreeType's
scan-line converter, a component also called `rasterizer', which
is in charge of converting a vectorial outline into a bitmap, or a
pixmap.
It simply loads all glyphs of a font file (by slices of 512 at
once), then converts them. Only the conversion is actually
benchmarked.
The glyphs are rendered at size 400pt at a resolution of 96dpi
(this is about 500 pixels high!). As you'll see by running
`fttimer', the rasterizer is very fast.
--------------------------------------------------------------------
17. Is it possible to perform styling (like oblique, italic, bold,
underline, etc.) with FreeType?
Actually, these refer to very different things:
- Italic and Bold styles usually mean many variations from the
`Regular' font. This is why you normally need a proper font
file for each of these. For example, the MS core font Times
comes in the following TrueType files:
TIMES.TTF Times New Roman Regular
TIMESI.TTF Times New Roman Italic
TIMESB.TTF Times New Roman Bold
TIMESBI.TTF Times New Roman Bold Italic
(sometimes named TIMESZ.TTF)
With FreeType, you simply need the required font file to use it.
- Oblique style refers to a transformation that is applied to a
regular font in order to make it `slanted', likes italics do.
However, an italic font very frequently contains small but
important variations that cannot be produced by this method and
make the font more appealing.
Slanting can easily be done with a transformation under
FreeType, with the exact same process as rendering rotated text.
Please read the `glyphs' documentation file where it is
explained in details.
Usually, Windows or the Macintosh produce oblique versions of a
regular font if the corresponding italic TrueType file isn't
available. They also stretch regular fonts horizontally if the
bold one isn't available. All of this can be done with trivial
transformations.
- Underlining and stroking are not really part of the glyphs.
They're simply lines that are printed on the glyph after it has
been rendered. Each TrueType file provides, in its OS/2 table
(which is accessible through the face object properties in
FreeType), several values that define the position and width of
those lines, in notional font units.
If you want to use them, you'll have to scale these values to
your current instance/point size, then draw the lines yourself.
--------------------------------------------------------------------
18. When does glyph hinting takes place? Is it when the glyph is
loaded, or when it is converted to a bitmap/pixmap?
The glyph loader returns fitted outlines by default (it can be
asked to return a non-fitted one, or simply the original outline
in notional coordinates too).
This is important to have a glyph's correct metrics, even if it is
not to be rendered immediately, like when caching outlines for
rotated text.
--------------------------------------------------------------------
19. Which is the best, caching outlines or bitmaps?
It depends on your application, and what it does with text.
Usually, if all you need is render some simple text at specific
point sizes, then simply cache the bitmaps or pixmaps.
However, if you want to do more advanced things, like rotated
text, which require sub-pixel placement to look good, you should
then only cache the outlines, and transform/place them as needed
before sending them to the scan-line converter.
It's always possible to produce a bitmap from an outline, and the
scan-converter is very fast. It's up to you then...
--------------------------------------------------------------------
20. Can I open OpenType and/or TrueType GX fonts with FreeType?
TrueType GX fonts are normal TrueType fonts with enhanced tables
and capabilities. They can always be opened by a normal TrueType
engine (like Windows, the Mac, or FreeType), but their improved
features won't be available.
On the contrary, OpenType fonts may vary. While some may contain
legal TrueType glyphs, an `otf' file may only contain glyphs
encoded in the Type 2 format. You won't be able to produce any
glyphs from such a font file without a dedicated font engine (like
the ones promised in NT 5 and Java 2D).
FreeType is a TrueType glyph engine and doesn't support Type 2
fonts. Supporting them would require a very different philosophy
and a different core engine (even though they could share an API).
Note that you can write extensions to the engine to access
supplemental tables defined in these formats (see next question).
Note that FreeType version 2 (which is in alpha stage currently)
already includes a PostScript Type 1 interpreter...
--------------------------------------------------------------------
21. How can I access additional TrueType tables that FreeType
doesn't support?
You can write an `engine extension'. This is a separately
compilable component which can enhance the base library's
functionalities, without recompiling it. Some important
extensions are provided in the `lib/extend' directory.
You'll need of course to know the TrueType specification
precisely, as well as some of the conventions used to access
tables and to manage memory. Read the documentation files for
more details, or contact the developers at:
devel@freetype.org
--------------------------------------------------------------------
22. When will I be able to use FreeType to display TrueType fonts in
X11, Wine or OS/2, or even other systems?
Actually, an OS/2 replacement for TRUETYPE.DLL based on FreeType
is part of this package (to be found in contrib/ftos2). Thanks go
to Michal Mecasek (mike@mendelu.cz) for his excellent work!
At least three X11 TrueType font servers are available; two of
them (xfsft and xtt) are based on FreeType, whereas the third
(xfstt) uses a separately developed TrueType engine.
More information about these servers is available at the FreeType
homepage (http://www.freetype.org).
Don't hesitate to contact us if you plan to use or port the engine
to exotic platforms, we're always interested in helping out.
--------------------------------------------------------------------
23. What does the `free' in FreeType really means?
The previous releases of FreeType (alphas and beta) were placed
under the LGPL. FreeType 1.0, and later releases, come with an an
alternate license, inspired from the BSD, Artistic, and IJG's
(Independent JPEG Group) ones. In short:
- You are encouraged to use and distribute this program in all
kinds of products, including commercial ones.
- You don't have to pay us anything for it (royalty-free).
- You may not pretend you wrote it, or part of it that you may use
in one of your product, and you have to state clearly that you
use the FreeType code if you distribute products based on it, or
parts of it (credits clause).
- This source code is provided AS IS, with no warranty whatsoever,
and we cannot promise support for it.
The exact and legal terms are in the file `license.txt'.
Enjoy ;-)
--------------------------------------------------------------------
24. Does FreeType support threads? Is it re-entrant?
Short answer: Basically yes, but not fully tested.
We have changed some code since FreeType 1.0 in order to support
multi-threaded environments. However, these have not been tested
yet. Apparently, the thread-safe and reentrant builds now work
well perfectly once compiled; however, no serious concurrency
testing has been performed (of course, a serious lock analysis was
done in order to modify the source).
Right now, the mutex management functions are all gathered in the
component `ttmutex', which has to be specialized for your own
system if a thread build will be necessary.
--------------------------------------------------------------------
25. Does FreeType support `foreign languages'?
Short Answer: YES, it does!
From a TrueType font file point of view, there are several parts
to the file, one of them being the `glyphs', i.e., picture
representations of the symbols.
Another part is the mapping table, also called `charMap'.
For example, glyph #1 could be letter `A', and glyph #2 could be
letter `Z'. Glyphs can be stored in any order in a font file.
The mapping tables contain at least one char-map entry. For
example, you could have an ASCII-map that maps character code 0x41
to glyph #1, and code 0x5A to glyph #2, etc. FreeType provides a
`charMap' object class to access and use this information easily.
There are several character encodings recognized and defined by
the TrueType specification, like Latin-1, Unicode, Apple Scripts,
WGL, etc., but a font file might only contain one or two of them.
When using a more `exotic' character encoding like EBCDIC (this is
IBM mainframe stuff!), you would need to translate it to one of
the available formats (or to add a charmap table to the font).
Cf. section 8.
--------------------------------------------------------------------
26. I'm using fractional char sizes, but the glyphs stay at the same
integer size. Why?
Because hinting only works well with integer pixel sizes. There
is a flag that can be set in a TrueType font file to force integer
pixel size scaling, even if you ask for fractional sizes with an
API function like TT_Set_Instance_CharSize(). Needless to say,
nearly all fonts have the flag set. So this is normal.
Also, notice that when giving a charsize in fractional points,
this will be converted to integer pixels with the formula:
pixel_size = char_size * y_resolution / 72
For example, using a resolution of 96 dpi, we would have:
9.5 pts => 12.666 pixels => 13 pixels
10.0 pts => 13.333 pixels => 13 pixels, i.e. same size
10.5 pts => 14 pixels => 14 pixels
11.0 pts => 14.666 pixels => 15 pixels
11.5 pts => 15.333 pixels => 15 pixels, i.e. same size
If you want to control the exact size in pixels of your glyphs,
simply use a resolution of 72dpi, where char_size = pixel_size.
--------------------------------------------------------------------
27. Hinting doesn't work at very small sizes. Why?
This is normal. There are very good technical reasons why hinting
doesn't work well at sizes under 7 ppem, usually meaning the
appearance of ugly spikes and glyph distortions. This is why the
engine disables hinting by default at such low sizes.
--- end of FAQ ---

23
docs/TODO Normal file
View File

@@ -0,0 +1,23 @@
FreeType TODO list
. Handle various PostScript glyph names in ftxpost.c:
Omega vs. Ohm
Delta vs. increment
macron vs. overscore
my vs. mu1
periodcentered vs. middot
with a new flag.
. Adaption of FreeType for non-ANSI compilers (wow, I'm heretic :-)
. More 16bit stuff to support _cdecl etc. Maybe something like this
may be used in place of the current EXPORT_DEF/EXPORT_FUNC:
NEW_EXPORT_DEF( TT_Error )
Cache_Create( PEngine_Instance engine, ... )
--- end of TODO ---

1867
docs/apiref.txt Normal file

File diff suppressed because it is too large Load Diff

864
docs/apirefx.txt Normal file
View File

@@ -0,0 +1,864 @@
The FreeType Engine
Extension Library Reference
-----------------------------------
Table of Contents:
I. Engine extensions
1. kerning (ftxkern)
2. PostScript names (ftxpost)
3. TrueType Open (ftxopen)
a. The `BASE' table (baseline data)
b. The `GDEF' table (glyph definitions)
c. The `GPOS' table (glyph positions)
d. The `GSUB' table (glyph substitions)
e. The `JSTF' table (justification data)
f. auxiliary functions
4. embedded bitmaps (ftxsbit)
II. API extensions
1. cmap iteration (ftxcmap)
2. internationalized error messages (ftxerr18)
3. access to the `gasp' table (ftxgasp)
4. fast retrieval of glyph widths and heights (ftxwidth)
III. Error codes
--------------------
Please read the file `user.txt' for an introduction into FreeType's
extension mechanism and the difference between engine and API
extensions.
I. Engine extensions
====================
To use engine extensions you have to compile the library with the
macro TT_CONFIG_OPTION_EXTEND_ENGINE. By default, this macro is set
and all engine extensions are linked to the FreeType library.
1. kerning (ftxkern)
--------------------
TT_Init_Kerning_Extension( TT_Engine engine )
Initializes the kerning extension for a given engine. This must
be called just after the engine creation, and before any face
object allocation. Example:
TT_Init_FreeType( &engine );
TT_Init_Kerning_Extension( engine );
..................................................................
TT_Get_Kerning_Directory( TT_Face face,
TT_Kerning* directory )
Queries the kerning directory found in a face object. If no
kerning table is found in the TrueType file, the error
TT_Err_Table_Is_Missing will be returned.
You can access the subtables through the pointers of the
directory. However, by default, the directory is only loaded if
a face object is created. You must load the subtables that
interest you with a call to TT_Load_Kerning_Table().
The layout of all kerning structures is defined in the file
`lib/extend/ftxkern.h'. Formats 0 and 2 (as defined in the
Microsoft TrueType specification) are exposed by this API.
NOTE:
This function must be called after the kerning extension has
been initialized.
..................................................................
TT_Load_Kerning_Table( TT_Face face,
TT_UShort kernIndex )
Loads the kerning subtable number `kern_index' into memory. The
subtable can be accessed through the pointers provided by the
kerning directory, obtained from a call to the function
TT_Get_Kerning_Directory().
Note that the interpretation of the kerning data is left to the
client application. Read the TrueType specification for more
information on kerning encoding.
NOTE 1:
This function must be called after the kerning extension were
initialized.
NOTE 2:
An example can be found in the file `test/ftstrtto.c'.
====================================================================
2. PostScript names (ftxpost)
-----------------------------
TT_Init_Post_Extension( TT_Engine engine )
Initializes the PostScript name extension to load the PostScript
glyph names given in the `post' table. This must be called just
after creation of the engine, and before any face object
allocation. See description of TT_Get_PS_Name() for an example.
..................................................................
TT_Load_PS_Names( TT_Face face,
TT_Post* post )
Loads the PostScript glyph names into memory. This must be done
before TT_Get_PS_Name() is called. In case of error, either
TT_Err_Invalid_Post_Table or TT_Err_Invalid_Post_Table_Format is
returned. See description of TT_Get_PS_Name() for an example.
..................................................................
TT_Get_PS_Name( TT_Face face,
TT_UShort index,
TT_String** PSname )
Get the PostScript glyph name for a given glyph index. A
pointer to the name is returned in `PSname'. Example:
...
TT_Post post;
char* PSname;
...
TT_Init_Post_Extension( engine );
TT_Load_PS_Names( face, &post );
...
TT_Get_PS_Name( face, index, &PSname );
NOTE:
You must not alter the PostScript glyph name string returned
in `PSname'.
====================================================================
3. TrueType Open (ftxopen)
--------------------------
Please note that TrueType Open specific error codes have the
prefix `TTO_Err_' instead of `TT_Err_'.
a. The `BASE' table (baseline data)
Not yet supported.
b. The `GDEF' table (glyph definitions)
TT_Init_GDEF_Extension( TT_Engine engine )
Initializes the GDEF extension to load the glyph definition
data given in the `GDEF' table. This must be called just
after creation of the engine, and before any face object
allocation. See the file `ftstrtto.c' for an example.
................................................................
TT_Load_GDEF_Table( TT_Face face,
TTO_GDEFHeader* gdef )
Loads the GDEF table into `gdef' for a given face `face'.
This must be done before any queries about glyph properties
with TT_GSUB_Get_Property(). Returns TT_Err_Table_Missing if
there is no GDEF table in the font.
................................................................
TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader* gdef,
TT_UShort glyphID,
TT_UShort* property )
Use this function to get glyph properties in the variable
`property' for the glyph with index `glyphID' stored in the
`gdef' table. This data is essential for many fonts to
correctly apply contextual substitution (both GSUB and GPOS).
As a special case, zero is assigned to `property' if `gdef' is
NULL or the glyph has no special glyph property assigned to
it. The other return values of `property' are TTO_BASE,
TTO_LIGATURE, TTO_MARK, and TTO_COMPONENT; you can directly
apply the `LookupFlag' mask to check for certain properties:
TTO_GDEFHeader* gdef;
TTO_Lookup* lo;
TT_UShort glyph_ID;
TT_UShort p;
TT_GDEF_Get_Property( gdef, glyph_ID, &p );
if ( p & lo->LookupFlag )
return TTO_Err_Not_Covered;
Usually, you don't need to take care of glyph properties by
yourself since TT_GSUB_Apply_String() will do this for you by
calling TT_GDEF_Get_Property().
Some fonts need GDEF-like data even if no GDEF table is
provided (for example, the Arabic script needs information
which glyphs are base glyphs and which are mark glyphs). In
such cases, you should use TT_GDEF_Build_ClassDefinition() to
build the necessary structures so that TT_GDEF_Get_Property()
returns meaningful values.
See also TT_Load_GSUB_Table() and TT_Load_GPOS_Table().
................................................................
TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader* gdef,
TT_UShort num_glyphs,
TT_UShort glyph_count,
TT_UShort* glyph_array,
TT_UShort* class_array )
Fills a `gdef' structure with data to make
TT_GDEF_Get_Property() work in case no GDEF table is
available. `num_glyphs' is the number of glyphs in the font.
`glyph_count' is the number of glyphs resp. class values (as
specified in the GDEF specification) given in the arrays
`glyph_array' and `class_array', respectively. The glyph
indices in `glyph_array' must be all different and sorted in
ascending order; the function expects that glyph index
`glyph_array[n]' has its class value in `class_array[n]'.
Note that mark attach classes as defined in OpenType 1.2 are
not supported for constructed GDEF tables.
See `arabic.c' for an example.
c. The `GPOS' table (glyph positions)
Not yet supported.
d. The `GSUB' table (glyph substitions)
For glyph substitution, a string object of type TTO_GSUB_String
is used. The field `length' holds the length of the string,
`pos' points to the actual position in the glyph string `string'
(for input strings) resp. the position where the substituted
glyphs should be placed at (for output strings).
Within the `properties' array (which must always have the same
length as `string' if set), you can define properties for glyphs
-- `string[n]' is associated with `properties[n]'. The idea is
that some features apply to specific glyphs only. As an
example, the `fina' feature for Arabic applies only to glyphs
which appear at the end of a word (strictly speaking, this
feature is used only for glyphs which have a `final' property;
such glyphs can occur in the middle of a word also under certain
circumstances which is dependent on Arabic script rules). The
relationship between properties and features can be set up with
the function TT_GSUB_Add_Feature(). If `properties' is set to
NULL, all selected features apply to all glyphs in the given
string object. If `properties' is non-NULL, the elements of the
array are treated as bit fields. A set flag means that the
corresponding feature (as set with the TT_GSUB_Add_Feature()
function) should not be applied to the particular glyph. As a
consequence, a zero value for these 16 bits means that all
features should be applied, and a value of 0xFFFF implies that
no feature at all should be used for the glyph.
The field `allocated' is for internal use only and must not be
modified. If its value is larger than zero, you should use
free() to deallocate the memory used by `string' (and
`properties' if set) in case you want to destroy a
TTO_GSUB_String object (memory for `string' and `properties' is
allocated automatically e.g. by TT_GSUB_Apply_String() for
output string objects).
struct TTO_GSUB_String_
{
TT_ULong length;
TT_ULong pos;
TT_ULong allocated;
TT_UShort* string;
TT_UShort* properties;
};
typedef struct TTO_GSUB_String_ TTO_GSUB_String;
Note that the `string' field must contain glyph indices, not
character codes.
For initializing an input string object, you should set the
`length', `string', and `properties' fields (the last one only
if necessary) to appropriate values. `pos' has to be set to the
position where the substitution lookups should start (usually
zero). The `allocated' field will be ignored.
For initializing an output string object, all fields (except
`length' which will be ignored) must be set to zero. If you
want to reuse the object, set `pos' to the position where the
substituted glyphs should be placed at (usually zero), but don't
touch the `allocated', `string', and `properties' fields.
................................................................
TT_Init_GSUB_Extension( TT_Engine engine )
Initializes the GSUB extension to load the glyph substitution
data given in the `GSUB' table. This must be called just
after creation of the engine, and before any face object
allocation. See the files `ftstrtto.c' and `ftdump.c' for
detailed examples.
................................................................
TT_Load_GSUB_Table( TT_Face face,
TTO_GSUBHeader* gsub,
TTO_GDEFHeader* gdef )
Loads the GSUB table into `gsub' for a given face `face'.
This must be done before any queries about or selection of
scripts, languages, and features. Returns
TT_Err_Table_Missing if there is no GSUB table in the font.
`gdef' should contain a pointer to an associated GDEF table,
either a native one loaded with TT_Load_GDEF_Table() or
emulated with TT_GDEF_Build_ClassDefinition(). If `gdef' is
set to NULL, no GDEF data will be used.
................................................................
TT_GSUB_Select_Script( TTO_GSUBHeader* gsub,
TT_ULong script_tag,
TT_UShort* script_index )
This function sets the script index of a given script tag
`script_tag' in the variable `script_index' for the GSUB table
`gsub'. Returns TTO_Err_Not_Covered if the script tag cannot
be found. The available script tags can be queried with the
function TT_GSUB_Query_Scripts().
................................................................
TT_GSUB_Select_Language( TTO_GSUBHeader* gsub,
TT_ULong language_tag,
TT_UShort script_index,
TT_UShort* language_index,
TT_UShort* req_feature_index )
This function sets the language index of a given language tag
`language_tag' and script index `script_index' in the variable
`language_index' for the GSUB table `gsub'. Returns
TTO_Err_Not_Covered if the language tag cannot be found. The
available language tags can be queried with the function
TT_GSUB_Query_Languages().
Additionally, the index of the required feature for this
language system is returned in `req_feature_index'; it must be
later registered for use with TT_GSUB_Add_Feature().
................................................................
TT_GSUB_Select_Feature( TTO_GSUBHeader* gsub,
TT_ULong feature_tag,
TT_UShort script_index,
TT_UShort language_index,
TT_UShort* feature_index )
This function sets the feature index of a feature tag
`feature_tag', script index `script_index', and language index
`language_index' in the variable `feature_index' for the GSUB
table `gsub'. Returns TTO_Err_Not_Covered if the feature tag
cannot be found. The available feature tags can be queried
with the function TT_GSUB_Query_Features(). Setting
language_index to 0xFFFF selects the default language system.
................................................................
TT_GSUB_Query_Scripts( TTO_GSUBHeader* gsub,
TT_ULong** script_tag_list )
Returns the available script tags for a given GSUB table
`gsub' in the array `script_tag_list'. The array can be later
deallocated with free().
................................................................
TT_GSUB_Query_Languages( TTO_GSUBHeader* gsub,
TT_UShort script_index,
TT_ULong** language_tag_list )
Returns the available language tags for a given GSUB table
`gsub' and script index `script_index' in the array
`language_tag_list'. The array can be later deallocated with
free().
................................................................
TT_GSUB_Query_Features( TTO_GSUBHeader* gsub,
TT_UShort script_index,
TT_UShort language_index,
TT_ULong** feature_tag_list )
Returns the available feature tags for a given GSUB table
`gsub', script index `script_index', and language index
`language_index' in the array `feature_tag_list'. If language
index is set to 0xFFFF, the values for the default language
system are returned. The array can be later deallocated with
free().
................................................................
TT_GSUB_Add_Feature( TTO_GSUBHeader* gsub,
TT_UShort feature_index,
TT_UShort property )
To prepare a call to TT_GSUB_Apply_String() which should
process a given feature with index `feature_index' and the
property `property', you must use this function. Its task is
to mark the lookup tables used by the feature for further
processing.
`property' defines a relationship between the input string
object and the specific feature. The client must handle this
variable as a bit field, i.e., up to 16 user properties can be
defined. If `property' is set to ALL_GLYPHS (0xFFFF, the only
predefined value), or if the input string object has no set
bits in the `properties' field, the feature applies to all
glyphs. If bit `x' is set in `property', the feature applies
only to glyphs which have bit `x' not set in glyph's
`properties' field in the input string object. See
TT_GSUB_Apply_String() for an example.
Returns TT_Err_Invalid_Argument in case of error.
................................................................
TT_GSUB_Clear_Features( TTO_GSUBHeader* gsub )
Clears the list of used features and properties. No lookup
tables will be processed.
................................................................
TT_GSUB_Register_Alternate_Function( TTO_GSUBHeader* gsub,
TTO_AltFunction alt,
void* data )
Installs a callback function to handle alternate
substitutions. `data' is a generic pointer to a user-defined
structure which will be completely ignored by the ftxopen
extension. `alt' is a function pointer defined as
typedef TT_UShort
(*TTO_AltFunction)(TT_ULong pos,
TT_UShort glyphID,
TT_UShort num_alternates,
TT_UShort* alternates,
void* data );
If TT_GSUB_Apply_String() encounters an alternate lookup while
processing the input string, it will call the function `alt'
to find out which alternate glyph it should use. `pos' gives
the position in the string, `glyphID' the glyph ID of the
glyph to be replaced with an alternate glyph, and
`num_alternates' the number of alternate glyphs in the
`alternates' array. A pointer to the user-defined `data'
structure is also available. `alt' must return an index into
`alternates'.
If `alt' is NULL or if this function isn't called at all,
TT_GSUB_Apply_String() will always use the first alternate
glyph.
Please note that theoretically an alternate lookup can happen
during any other lookup! For example, a lookup chain like
single subst -> alternate subst -> ligature subst
*is* possible (albeit rather unlikely). Thus be warned that
`pos' does not necessarily reflect the position of a glyph to
be displayed at all, nor does `glyphID' specifies a glyph
which will be in the final output string.
................................................................
TT_GSUB_Apply_String( TTO_GSUBHeader* gsub,
TTO_GSUB_String* in,
TTO_GSUB_String* out )
This is the very function which handles glyph substitution
according to the features set up with TT_GSUB_Add_Feature(),
using both GSUB and GDEF data (if defined). Two
TTO_GSUB_String objects `in' and `out' (as described above)
are taken for input and output; after successful excecution,
the converted glyph string can been found in `out', and
`out.length' gives the actual length of the output string
(counted from the begin of the array).
Example:
/* We assume that the feature `xxxx' has index 5, and */
/* feature `yyyy' has index 8, applying only to glyphs */
/* with the property `FINAL_GLYPHS' set (0x1000 is an */
/* ad-hoc value just for this example). */
/* The order of calls to TT_GSUB_Add_Feature() is not */
/* significant. */
#define FINAL_GLYPHS 0x1000
TT_GSUB_Clear_Features( &gsub );
TT_GSUB_Add_Feature( &gsub, 8, FINAL_GLYPHS );
TT_GSUB_Add_Feature( &gsub, 5, ALL_GLYPHS );
TT_GSUB_Apply_String( &gsub, &in, &out );
You must initialize both `in' and `out' structures; allocation
necessary for the `out' object will be handled automatically.
In case you don't register a function to handle alternate
substitutions (GSUB lookup 3), always the first alternate
glyph will be used. See TT_GSUB_Register_Alternate_Function()
above for more details.
e. The `JSTF' table (justification data)
Not yet supported.
f. auxiliary functions
TT_GSUB_Add_String( TTO_GSUB_String* in,
TT_UShort num_in,
TTO_GSUB_String* out,
TT_UShort num_out,
TT_UShort* data )
This function copies `num_out' elements from `data' to `out',
advancing the array pointer `in.pos' by `num_in' elements and
`out.pos' by `num_out' elements. If the string (resp. the
properties) array in `out' is empty or too small, it allocates
resp. reallocates the string (and properties) array.
Finally, it sets `out.length' equal to `out.pos'.
The properties for all replaced glyphs are taken from the
glyph at position `in->pos'.
TT_GSUB_Add_String() is normally used in
TT_GSUB_Apply_String(); you will need it for the special case
to skip some glyphs (i.e., copy glyphs directly from the `in'
to the `out' object), bypassing a possible GSUB substitution.
Here an example which copies one glyph:
TT_GSUB_Add_String( in, 1,
out, 1,
&in->string[in->pos] );
====================================================================
4. embedded bitmaps (ftxsbit)
-----------------------------
TT_Init_SBit_Extension( TT_Engine engine )
Initializes the embedded bitmap extension to load the bitmap
glyphs given in the various sbit tables: `EBLC', `bloc', `EBDT',
and `bdat' (`bloc' and `bdat' tables are only in Apple fonts;
the former is equivalent to `EBLC', the latter equivalent to
`EBDT'). This must be called just after creation of the engine,
and before any face object allocation. See description of
TT_Load_Glyph_Bitmap() for an example.
..................................................................
TT_Get_Face_Bitmaps( TT_Face face,
TT_EBLC* eblc_table )
Loads the `EBLC' (resp. `bloc') table from a font file into the
`eblc_table' structure. Use this function for testing whether
embedded bitmaps are available or not.
This function returns TT_Err_Table_Missing if the font contains
no embedded bitmaps. All fields in `eblc_table' will then be
set to 0.
..................................................................
TT_New_SBit_Image( TT_SBit_Image** image )
Allocates a new embedded bitmap container, pointed to by
`image'.
..................................................................
void TT_Done_SBit_Image( TT_SBit_Image* image )
^^^^
Releases the embedded bitmap container `image'.
..................................................................
TT_Get_SBit_Strike( TT_Face face,
TT_Instance instance,
TT_SBit_Strike* strike )
Loads a suitable strike (i.e. bitmap sizetable) for the given
instance. Will return TT_Err_Invalid_PPem if there is no strike
for the current x_ppem and y_ppem values.
..................................................................
TT_Load_Glyph_Bitmap( TT_Face face,
TT_Instance instance,
TT_UShort glyph_index,
TT_SBit_Image* bitmap );
Loads a glyph bitmap for a given glyph index `glyph_index' (in
face `face' and instance `instance') into `bitmap'. It calls
TT_Get_SBit_Strike() internally for checking the current x_ppem
and y_ppem values.
This function returns an error if there is no embedded bitmap
for the glyph at the given instance.
Example (omitting the error handling):
...
TT_SBit_Image* bitmap;
...
TT_Init_SBit_Extension( engine );
TT_New_SBit_Image( &bitmap );
...
TT_Load_Glyph_Bitmap( face, instance, glyph_index, bitmap );
--------------------------------------------------------------------
--------------------------------------------------------------------
II. API extensions
==================
To use API extensions, simply compile the specific extension file
and link it to the library or your program. By default, all
extensions described below are linked to the library.
1. cmap iteration (ftxcmap)
---------------------------
TT_Long TT_CharMap_First( TT_CharMap charMap,
^^^^^^^ TT_UShort* glyph_index )
Returns the first valid character code in a given character map
`charMap'. Also returns the corresponding glyph index (in the
parameter `*glyph_index'). In case of failure, -1 is returned,
and `*glyph_index' is undefined.
..................................................................
TT_Long TT_CharMap_Next( TT_CharMap charMap,
^^^^^^^ TT_UShort last_char,
TT_UShort* glyph_index )
Returns the next valid character code in a given character map
`charMap' which follows `last_char'. Also returns the
corresponding glyph index (in the parameter `*glyph_index'). In
case of failure, -1 is returned, and `glyph_index' is undefined.
..................................................................
TT_Long TT_CharMap_Last( TT_CharMap charMap,
^^^^^^^ TT_UShort* glyph_index )
Returns the last valid character code in a given character map
`charMap'. Also returns the corresponding glyph index (in the
parameter `*glyph_index'). In case of failure, -1 is returned,
and `*glyph_index' is undefined.
====================================================================
2. internationalized error messages (ftxerr18)
----------------------------------------------
This extension provides internationalized error strings from the
various error messages. It uses the `gettext' package if
available or returns English/American message strings if not.
Currently, the gettext package is only available on UNIX-like
systems like Linux; this means that for other platforms only
English error strings are returned.
If the gettext package is found on your system, the configure
script automatically includes it by default. In case you don't
want to use it, or if you encounter some problems compiling this
file, try to disable nls support by configuring FreeType with
`./configure --disable-nls'.
Please read the gettext info files for more information how to set
up your system for internationalized messages. A short
introduction is also given in the file `i18n.txt'.
TT_String* TT_ErrToString18( TT_Error i )
^^^^^^^^^^
This function returns an error string for a given error code
`i'. The type `TT_String' usually defaults to `char'; see
apiref.txt for more details.
An example how to use this function (in connection with the
gettext interface) is given e.g. in test/ftdump.c.
====================================================================
3. access to the `gasp' table (ftxgasp)
---------------------------------------
The `gasp' table is currently loaded by the core engine, but the
standard API doesn't give access to it.
TT_Get_Face_Gasp_Flags( TT_Face face,
TT_UShort point_size,
TT_Bool* grid_fit,
TT_Bool* smooth_font )
This function returns for a given `point_size' the values of the
gasp flags `grid_fit' and `smooth_font'. The returned values
are booleans (where 0 = NO, and 1 = YES).
Note that this function will return TT_Err_Table_Missing if the
font file doesn't contain any gasp table.
====================================================================
4. fast retrieval of glyph widths and heights (ftxwidth)
--------------------------------------------------------
This extension is used to parse the `glyf' table of a TrueType
file in order to extract the bounding box of a given range of
glyphs.
The bounding box is then used to build font unit widths and
heights that are returned in two parallel arrays.
This extension is needed by the FreeType/2 OS/2 Font Driver.
TT_Get_Face_Widths( TT_Face face,
TT_UShort first_glyph,
TT_UShort last_glyph,
TT_UShort* widths,
TT_UShort* heights )
Returns the widths (in array `widths') and heights (in array
`heights') of a glyph range which starts at `first_glyph' and
ends at `last_glyph'. All returned values are returned in font
units. If either `widths' or `heights' is set to a NULL
pointer, no data will be returned for that particular array.
Note: TT_Get_Face_Widths() does *not* allocate the two arrays!
--------------------------------------------------------------------
--------------------------------------------------------------------
III. Error Messages
===================
Most functions return an error code, typed to TT_Error. A return
value of zero indicates no error. The error values are defined in
the various extension header files (e.g. ftxkern.h). In the
following table, the prefix `TT_Err_' is omitted, e.g. `Ok' ->
`TT_Err_Ok'.
Error Unprefixed Error
Code Macro Name Description
------------------------------------------------------------------
0x0A00 Invalid_Kerning_Table_Format
An invalid kerning subtable
format was found in this font.
0x0A01 Invalid_Kerning_Table A kerning table contains illegal
glyph indices.
0x0B00 Invalid_Post_Table_Format
The post table format specified
in the font is invalid.
0x0B01 Invalid_Post_Table The post table contains illegal
entries.
Here the TrueType Open error codes. In the following table, the
prefix `TTO_Err_' is omitted.
Error Unprefixed Error
Code Macro Name Description
------------------------------------------------------------------
0x1000 Invalid_SubTable_Format The TrueType Open subtable format
specified in the font is invalid.
0x1001 Invalid_SubTable A TrueType Open subtable contains
illegal entries.
0x1002 Not_Covered The requested feature, glyph,
etc. isn't covered by the actual
function.
0x1010 Invalid_GSUB_SubTable_Format
The GSUB subtable format
specified in the font is invalid.
0x1011 Invalid_GSUB_SubTable The GSUB subtable contains
illegal entries.
0x1020 Invalid_GPOS_SubTable_Format
The GPOS subtable format
specified in the font is invalid.
0x1021 Invalid_GPOS_SubTable The GPOS subtable contains
illegal entries.
--- end of apirefx.txt ---

771
docs/bitmaps.txt Normal file
View File

@@ -0,0 +1,771 @@
Bitmap and Pixmap generation with FreeType
------------------------------------------
Table of Contents
Introduction
I. The rasterizer component
II. Bitmap & pixmap descriptors
III. Rendering an outline
IV. Anti-aliasing palette and other concerns
Conclusion
Introduction
------------
This document describes the steps that are needed to render a
glyph outline into a bitmap or a pixmap with the FreeType library.
It contains several important details needed to generate bitmaps
correctly in all situations, including if an outline has been
transformed or translated.
--------------------------------------------------------------------
I. The rasterizer component
---------------------------
In FreeType, the component in charge of performing bitmap and
pixmap rendering is called the `rasterizer'. Generation is
performed through a traditional process called `scan-line
conversion', but exhibits certain properties:
- The rasterizer doesn't allocate bitmaps:
In fact, it is only able to render an outline into an existing
bitmap or pixmap, which is passed to one of its rendering
functions. This means that the target bitmap/pixmap must be set
up correctly by the caller to achieve desired results. Setting
up bitmap and pixmap descriptors is explained in section II.
- It is able to render anti-aliased pixmaps directly:
This is unlike other graphics packages, which render to a
`large' bitmap which is then filtered down. Putting the
anti-aliasing logic within the rasterizer improves performance
and reduces memory usage, as well as lets us use better
algorithms which couldn't work in a `two-phase' process.
The rasterizer is located in the files `ttraster.h' and
`ttraster.c' (or `ttraster.pas' for the Pascal version --
unfortunately, this is severely out of date).
The format of outlines isn't important for most developers and
won't be discussed here. However, a few conventions must be
explained regarding the vector outlines:
1. Units
All point coordinates within an outline are stored in 32-bit
fractional pixel values, using the 26.6 fixed float format
(which uses 26 bits for the integer part, and 6 bits for the
fractional part). The following table gives some examples of
real versus 26.6 coordinates:
-----------------------------------------
real real coord 26.6 coord
coord. * 2^6
-----------------------------------------
0 0*64 = 0.0 0
2.4 2.4*64 = 153.6 154
3 3*64 = 192.0 192
-1.7 -1.7*64 = -108.8 -109
As you can see, conversion is relatively simple -- basically a
multiplication by 64.
In order to differentiate coordinates expressed in real or 26.6
systems, we'll use in the following lines brackets (`[' and `]')
for real coordinates, and simple parentheses (`(' and `)') for
fractional coordinates so that
[1.0,2.5] equals (64,160)
[0,0] equals (0,0)
[-2,3] equals (-128,192)
2. Orientation
The rasterizer uses the traditional convention of an X axis
oriented from left to right, and of a Y axis oriented from
bottom to top.
^ Y
|
|
|
-*-----> X
|
You've probably already used it at school when doing math :-)
Though the orientation of bitmap lines has the opposite
direction on nearly all graphics systems, the former convention
is the _right_ one when it comes to vector graphics. The reason
is simply that for managing angles and vector cross-products
resp. orientations in complex algorithms, a single convention,
used in math as well as computing alike solves many headaches.
And due to education, most people expect a 45 degrees angle to
be in the top right quadrant, at coordinate (1,1).
3. Pixels and the grid
In a vector outline, a point is immaterial and has no size or
width, just like in usual geometry. A `pixel' is an element of
a computer image called a `map' (like a bitmap or a pixmap).
The FreeType rasterizer follows the convention defined by the
TrueType specification regarding pixel placement:
- The map can be seen as a `grid' placed in the vector plane.
The grid lines are set on integer real coordinates (i.e., on
multiples of 64 in 26.6 fractional notation).
Each pixel is one `cell' of the grid, and can be `lit' with
any color. Hence, each pixel has a width and a height of
[1.0] units, (i.e., 64 fixed float units).
^ Y
|
| The pixel grid with two
| points (not pixels!)
+-----+-----+-----+-----+-----+ at coordinates [0,0]
| | | | | | and [2,2].
| | | | | |
| | | | |[2,2]|
+-----+-----+-----+-----@-----+ The pixels are the
| | |11111|22222| | grid's cells, and this
| | |11111|22222| | example show the four
| | |11111|22222| | pixels enclosed within
+-----+-----+-----+-----+-----+ the rectangle delimited
| | |33333|44444| | by these two points.
| | |33333|44444| |
| | |33333|44444| |
--+-----+-----@-----+-----+-----+----> X
| | |[0,0]| | |
| | | | | | Note that the numbering
| | | | | | of pixels isn't
+-----+-----+-----+-----+-----+ meaningful here, it's
| | | | | | only used to distinguish
| | | | | | them.
| | | | | |
+-----+-----+-----+-----+-----+
|
|
- The `center' of each pixel is always located on a
`half-integer' coordinate, i.e., at -1.5, -0.5, 0.5, 1.5, etc.
- When drawing a shape, the rasterizer only `lits' a pixel when
its center is placed _within_ the shape. This is important
because an outline point may not be necessarily be on a grid
line.
- When a pixel center falls on the shape, the pixel is lit too.
For example, the following graphics show the `lit' pixels
corresponding to the rectangle enclosed by the points:
[-0.2, 0] and [2.4, 2.7]
^ Y As one can see, the
| newest pixels `1'
| and `2' are now lit,
| because its centers
+-----+-----+-----+-----+--[2.4,2.7] are located at
| | |11111|22222| @ | coordinates
| . | . |11.11|22.22| . | [0.5,2.5] and
| | |11111|22222| | [1.5,2.5],
+-----+-----+-----+-----+-----+ respectively.
| | |33333|44444| |
| . | . |33.33|44.44| . | Note that pixel
| | |33333|44444| | centers are
+-----+-----+-----+-----+-----+ represented with a
| | |55555|66666| | dot in the graphics.
| . | . |55.55|66.66| . |
| | |55555|66666| |
--+-----+----@+-----+-----+-----+----> X
| | [-0.2,0] | | |
| . | . | . | . | . |
| | | | | | Note also that pixel
+-----+-----+-----+-----+-----+ numbering is still
| | | | | | meaningless there.
| . | . | . | . | . |
| | | | | |
+-----+-----+-----+-----+-----+
|
|
4. Drop-out control
Sometimes, a stroke is too thin to even contain a single pixel
center. This results in `lost continuity' in the resulting
bitmap, i.e., some unpleasant `holes' or `breaks' in the
rendered shape, which are called a `drop-out'.
Because a glyph representation uses curves (Bezier arcs), this
case is not easily controllable during the `hinting' of glyph
outlines by the font driver, which means that the rasterizer
must be able to correct these `artefacts'.
This processing is called `drop-out control', and can be
performed in several modes, defined by the TrueType
specification, and which details do not belong to this document.
However, the important idea is that, in _some_ cases, a pixel
may be lit even if its center isn't part of the shape.
This case is relatively rare, but is mentioned because it has
consequences of the rendering of maps. More precisely, in the
way an outline's extent is computed (see below).
--------------------------------------------------------------------
II. Bitmap and pixmap descriptors
---------------------------------
The Freetype rasterizer only supports bitmaps and 8-bit pixmaps.
In order to render an outline, a map descriptor must be sent to
its rendering functions, along with a vectorial outline.
1. Bitmap properties
This section explains how to set up a bitmap descriptor, and how
vector coordinates in the outline plane relate to pixel
positions within the bitmap buffer.
A bitmap's `raw data' is made of a simple bit buffer where each
bit corresponds to a monochrome pixel. For the sake of
simplicity, the FreeType rasterizer uses the following
conventions to store bitmaps in a buffer:
- The value 0 is used for `unlit' pixels, usually the
`background' when rendering text. Hence 1 is used for `lit'.
- Lines are padded to 8 bits, i.e. bytes. A bitmap row thus
takes an integral number of bytes in its buffer. No further
alignment is required.
(Some systems compress bitmaps by _not_ padding bit rows to
byte boundaries. It is not possible to render into such a
bitmap buffer with FreeType.)
- In a bitmap buffer byte, the left-most pixel is represented by
the most significant bit (i.e., 0x80).
The opposite convention is not supported by the FreeType
rasterizer, though it may possibly be implemented too if this
ever comes useful (ask the developers -- for now, nobody did).
- Increasing offsets within a row correspond to right-most
positions in the bitmap (i.e., byte 1 contains the
8 bits/pixels that are located on the right of the
8 bits/pixels of byte 0).
- A bitmap can be oriented in two ways:
o If increasing row addresses within the buffer correspond to
lower vertical lines, the bitmap is said to go `down'. This
is, for example, the case of nearly all video RAMs.
o If increasing row addresses within the buffer correspond to
higher vertical lines, the bitmap is said to go `up'. This
is the case, for example, for OS/2 bitmaps.
The `direction' of a bitmap is called `flow' to avoid any
confusion. In both cases, the rasterizer ALWAYS matches the
vector coordinate (0,0) with the lower-left corner of the
*lower-left* pixel in the bitmap.
The following graphics illustrate these ideas:
Y ^
| A `down-flow' bitmap.
+--+--+--+--+--+--+--+--+ On the left is each
| | | | | | | | | row's number and its
0: 0 | | | | | | | | | offset in the bitmap
+--+--+--+--+--+--+--+--+ buffer (where `w' is
| | | | | | | | | the width, in bytes,
1: w | | | | | | | | | of a single bitmap
+--+--+--+--+--+--+--+--+ row). Note that the
| | | | | | | | | origin is located at
2: 2*w | | | | | | | | | the lower left, i.e.,
+--+--+--+--+--+--+--+--+ near the leftmost bit
| | | | | | | | | of the last bitmap
3: 3*w | | | | | | | | | row.
-@--+--+--+--+--+--+--+-----> X
|[0,0]
Y ^
| An `up-flow' bitmap.
+--+--+--+--+--+--+--+--+ On the left is each
| | | | | | | | | row's number and its
3: 3*w | | | | | | | | | offset in the bitmap
+--+--+--+--+--+--+--+--+ buffer (where `w' is
| | | | | | | | | the width, in bytes,
2: 2*w | | | | | | | | | of a single bitmap
+--+--+--+--+--+--+--+--+ row). Note that the
| | | | | | | | | origin is located at
1: w | | | | | | | | | the lower left, i.e.,
+--+--+--+--+--+--+--+--+ near the first bit in
| | | | | | | | | the buffer.
0: 0 | | | | | | | | | The first buffer bit
-@--+--+--+--+--+--+--+-----> X corresponds to the
|[0,0] rectangle [0,0]-[1,1]
in the vector plane.
2. Bitmap descriptors
Now that you understand all these details, a bitmap can be
described to the rasterizer engine through a map, which
structure must be set up by client application:
struct TT_Raster_Map_
{
int rows; /* number of rows */
int cols; /* number of columns (bytes) per row */
int width; /* number of pixels per line */
int flow; /* bitmap orientation */
void* bitmap; /* bit/pixmap buffer */
long size; /* bit/pixmap size in bytes */
};
typedef struct TT_Raster_Map_ TT_Raster_Map;
where the fields stand for:
rows:
The number of rows within the bitmap buffer.
cols:
The number of columns, i.e. bytes per row within the
buffer. It corresponds to the `w' value used in the above
graphics.
width:
The number of pixels (i.e. bits) per row in the buffer. The
rasterizer always clips its rendering to the bit width
specified in this field, even if the `cols' fields
corresponds to a larger width.
flow:
The bitmap flow. Use the constants TT_Flow_Up and
TT_Flow_Down exclusively for this field.
bitmap:
A typeless pointer to the bit buffer.
size:
The total size of the bit buffer in bytes. This is not used
directly by the rasterizer, so applications can use it.
Note that the `cols' field should always be bigger than the
value of `width' multiplied by 8. The rasterizer clips the
generated bitmap to the `width' first bits in a row.
Note also that it is of course allowed to create, for example, a
Windows or X11 bitmap through a normal system-specific API call,
using a TT_Raster_Map that describes it to the rasterizer. It
is thus possible to draw directly into such OS specific
structures.
IMPORTANT: *****************************************************
When rendering a bitmap, the rasterizer always OR-es the shape
on the target bitmap. It is thus possible to draw several
shapes into a single surface which successive calls to the
render functions.
****************************************************************
3. Pixmap properties
The rasterizer only supports 8-bit pixmaps, where one pixel is
represented by a single byte. They must conform to the
following rules:
- A 5-entries palette is used to generate an outline's pixmap in
the buffer. They correspond to:
palette[0] -> background
palette[1] -> `light'
palette[2] -> `medium'
palette[3] -> `dark'
palette[4] -> foreground
where the terms `light', `medium', and `dark' correspond to
intermediate values between the first (background) and last
(foreground) entry.
The upcoming FreeType 2.0 will feature an additional
anti-aliasing logic with a 17-entries palette.
- Lines are padded to 32 bits, i.e. 4 bytes. A pixmap row thus
takes a multiple of 4 bytes in its buffer.
- Increasing offsets within a row correspond to right-most
positions in the bitmap (i.e., byte/pixel 1 is to the right of
byte/pixel 0).
- A pixmap can be oriented in two ways, following the same rules
as a bitmap regarding its flow.
IMPORTANT: *****************************************************
In order to improve performance when rendering large outlines
with anti-aliasing, the rasterizer draws pixels in runs of
4-bytes ONLY when at least one of their `colour' isn't 0
(background).
This means that you should ALWAYS CLEAR the pixmap buffer before
calling the rendering function, you may otherwise experience
ugly artefacts, which are possibly left from a previous
rendering!
In general, it is not possible to do colour compositing with the
FreeType rasterizer (compositing is if you want to superpose a
transparent coloured layer on top of an image). This is mainly
due to the fact that:
- There are too many pixel formats to support.
- There is not a single portable way to do it anyway.
- It really is a graphics processing question, not one that
should be solved by a text rendering engine.
****************************************************************
4. Pixmap descriptors
Pixmaps use the same descriptor structure as bitmaps, with a few
differences in interpretation:
- The `cols' field is used to indicate the number of _bytes_ in
a pixmap row. It must thus be a multiple of 4!
- The rasterizer clips the outline to the first `width'
pixels/width within each buffer row.
As usual, it should be possible to use a system-specific pixmap
and render directly into it, as long as you set up a descriptor
for it.
-------------------------------------------------------------------------
III. Rendering an outline
-------------------------
Now that you understand how the rasterizer sees the target bitmaps
and pixmaps it renders to, this section will explain how the
rendering eventually happen.
1. Outline coordinates and extents
Let's first consider the case where we're rendering text
directly into a huge single bitmap. To do that, we simply
translate each glyph outline before calling the rasterizer.
Here the roadmap:
- Vectorial coordinates [0,0] are mapped to the lower left
`corner' (in the grid) of the lower left pixel in the bitmap
(whatever its flow is).
- When the glyph loader returns an outline, the latter is placed
so that the coordinate [0,0] corresponds to the current cursor
position.
This means that:
- If we use our own cursor (cx,cy) within the bitmap during text
rendering, we must translate the outline to its position
before rendering it, e.g. with
TT_Translate_Outline( outline, cx, cy )
(and the cursor position must be incremented after rendering
each glyph).
- Before translation (i.e., when it is returned by the glyph
loader), the glyph outline doesn't necessarily lie on any of
the coordinate axes, nor is it limited to the first quadrant
(i.e., x>0 and y>0 is not true in general).
Its extent can be computed with the function
TT_Get_Outline_BBox(), which returns the minimum and maximum
values of its X and Y point coordinates (in 26.6 format, of
course).
2. Computing an outline's dimensions in pixels
In many cases, however, it is much better to render individual
glyph bitmaps, then cache them with appropriate metrics in order
to render text much more quickly at a given point size.
To be able to render the smallest possible bitmap, the exact
outline's extent dimensions in pixel are required. Again a
roadmap:
- Get the outline's bounding box in vector coordinates:
Simply call the TT_Get_Outline_BBox() function which will
return the values of xMin, yMin, xMax, and yMax in vector
(i.e. fractional) coordinates.
- Grid-fit the bounding box:
Because of the way pixels are lit in the bitmaps relative to
the position of their `centers' within the shape (see
section I), it is necessary to align the values of xMin, xMax,
yMin, and yMax to the pixel grid in order to compute the width
and height of the resulting bitmap. This can be done with:
xMin = FLOOR ( xMin ); with FLOOR(x) == (x & -64)
xMax = CEILING( xMax ); CEILING(x) == ((x+63) & -64)
yMin = FLOOR ( yMin );
yMax = CEILING( yMax );
The extents in pixels can then be simply computed as:
pixel_width = (xMax - xMin) / 64;
pixel_height = (yMax - yMin) / 64;
Note that because of drop-out control, and because the
bounding box computed currently includes all Bezier control
points from the outline, the bitmap may be slightly larger
than necessary in some cases.
Some improvements are planned for FreeType 2.0; for now, you
should consider that finding the `exact' bitmap bounding box
requires to scan all `borders' to detect null columns or rows.
However, the values are right in most cases.
NOTE: It seems that in some *rare* cases, which relate to
weird drop-out control situations, the above dimensions
are not enough to store all bits from the outline (there
are one or more bits `cut' on the edge).
This being hard to study (it only appears in very poorly
hinted fonts), we leave this problem to FreeType 2.0.
- Create/setup a bitmap with the computed dimensions. DON'T
FORGET TO CLEAR ITS BUFFER TOO!
- Translate the outline to stick within the bitmap space. This
is done easily by translating it by (-xMin,-yMin), where you
should ALWAYS USE THE GRID-FITTED VALUES computed above for
xMin and yMin:
TT_Translate_Outline( outline, -xMin, -yMin );
IMPORTANT: ***************************************************
For technical reasons, you should never translate a HINTED
outline by a non-integer vector (i.e., a vector which
coordinates aren't multiples of 64)! This would CERTAINLY
completely RUIN the delicate HINTING of the glyph, and will
result probably in pure GARBAGE at small point sizes.
Of course, if you're not interested in hinting, like when
displaying rotated text, you can ignore this rule and
translate to any position freely.
**************************************************************
- Render the bitmap (or pixmap).
DON'T FORGET TO STORE THE GRID-FITTED xMin and yMin WITH THE
BITMAP! This will allow you later to place it correctly
relative to your cursor position.
Here's some example pseudo code:
{
... load the glyph ...
TT_Outline outline;
TT_BBox bbox;
TT_Raster_Map bitmap;
/* get the outline */
TT_Get_Glyph_Outline( glyph, &outline );
/* compute its extent */
TT_Get_Outline_BBox( &outline, &bbox );
/* Grid-fit it */
bbox.xMin &= -64;
bbox.xMax = ( bbox.xMax + 63 ) & -64;
bbox.yMin &= -64;
bbox.yMax = ( bbox.yMax + 63 ) & -64;
/* compute pixel dimensions */
width = (bbox.xMax - bbox.xMin) / 64;
height = (bbox.yMax - bbox.yMin) / 64;
/* set up bitmap */
bitmap.rows = height;
bitmap.width = width;
bitmap.cols = (width + 7) / 8;
bitmap.size = bitmap.rows * bitmap.cols;
bitmap.bitmap = malloc( bitmap.size );
if ( !bitmap.bitmap )
return error_memory...
/* clear the bitmap buffer! */
memset( bitmap.bitmap, 0, bitmap.size );
/* translate outline */
TT_Translate_Outline( &outline, -bbox.xMin, -bbox.yMin );
/* render it within the bitmap */
TT_Get_Outline_Bitmap( engine, &outline, &bitmap );
/* We're done; don't forget to save bbox.xMin and */
/* bbox.yMin to adjust the bitmap position when */
/* rendering text with it */
...
}
3. The case of transformed/rotated glyphs:
You may want to apply a transformation other than a translation
to your glyph outlines before rendering them. For example, a
simple slant to synthesize italics, or a slight rotation.
In all cases, it is possible to render individual glyph bitmaps.
Just make sure to follow the same process AFTER you have
transformed you outline!
DON'T FORGET THAT YOU NEED TO RE-COMPUTE THE BBOX TO GET THE
CORRECT PIXEL DIMENSIONS AFTER A TRANSFORMATION.
--------------------------------------------------------------------
IV. Anti-aliasing palette and other concerns
When rendering pixmaps, using the TT_Get_Outline_Pixmap() or
TT_Get_Glyph_Pixmap() functions, the rasterizer uses a 5-entries
palette of 8-bit deep `colors'.
By default, this palette is set to ( 0, 1, 2, 3, 4 ), but one can
change it to suit your needs with TT_Set_Raster_Palette().
While in bitmap mode, it simply OR-es the pixel values to the
target bitmap that has been passed to TT_Get_Outline_Bitmap().
For pixmaps it simply writes directly the palette entries
corresponding to the `color' of the `lit' pixels it has computed.
This means that it is NOT POSSIBLE to render text in a single
pixmap with multiple calls to TT_Get_Outline_Pixmaps() within the
same target!
The reason is that `gray' pixels of two distinct outlines are not
`added' when they overlap (the operation called 'compositing'), as
it could be expected by applications.
The following graphic shows this effect when rendering two
overlapping anti-aliased shapes:
*** ***
.** .**
** **. **. **
.*. .*.. .*..*.
.*. + .*. = ---> ..*.
.*. ** | .*. **
** | **
**. | **.
*** | ***
|
missing black pixel after second
rendering...
There is no simple way to perform a composition within the
rasterizer. This would not be portable; moreover, it would be
extremely slow if it is too general. This operation is thus left
to client applications which can use their own system-specific API
for transparently blitting the glyph pixmaps into a surface to
form text.
NOTE:
If your system doesn't support transparent/alpha blits, you can
still have a look at the source file `freetype/test/display.c'.
It uses a large pixmap, with a special palette trick to render all
text quickly, then convert everything to `real' colors for
display.
--------------------------------------------------------------------
Conclusion
----------
We've seen how the FreeType rasterizer sees bitmaps through
descriptors, as well as the mapping which exists between the
vector coordinate space and the pixel position space.
You should now be able to render outlines into bitmaps and pixmaps
while applying transformations like translation, slanting, or
rotation. Don't forget a few rules, however:
- Always clear the bitmap/pixmap buffer before rendering (unless
you want to render several glyphs in a single _bitmap_; it won't
work on a pixmap).
- A pixmap `cols' field, i.e. the size in bytes of each rows, must
be a multiple of 4.
- Never translate a hinted outline by a non-integer vector if you
want to preserve the hints (i.e., the vector's coordinates must
be multiples of 64).
- Finally, don't expect the rasterizer to composite transparent
`grays' for you in a single target pixmap through multiple
calls.
--- end of bitmaps.txt ---

851
docs/changes.txt Normal file
View File

@@ -0,0 +1,851 @@
Changes between FreeType version 1.3 and version 1.3.1
======================================================
Bug fixes.
Changes between FreeType version 1.2 and version 1.3
====================================================
Documentation
-------------
Improved installation instructions.
Complete revision of almost all documentation files.
**
** Added the file apirefx.txt to document all extensions to the
** FreeType library. Consequently, errstr.txt has been removed.
**
Added the file optimize.txt, explaining how to improve FreeType
on a given architecture.
**
** Documentation about possible patent restrictions added.
**
Added howto/mac.txt (stating basically that the FreeType team
can't support the Macintosh platform because of lack of
knowledge).
Added howto/msdos.txt, documenting compilation for various 16bit
and 32bit compilers.
API functions
-------------
TT_Load_Kerning_Table() now returns TT_Err_Invalid_Argument
instead of TT_Err_Bad_Argument (which is used for an internal
error only) for an invalid argument. The same holds for
TT_Get_Face_Widths() and TT_Get_Glyph_Big_Metrics().
If the glyf table is missing, the new error code
TT_Err_Glyf_Table_Missing is returned instead of
TT_Err_Table_Missing. This affects TT_Get_Face_Widths(),
TT_Load_Glyph(), and TT_Open_Face().
**
** New function TT_FreeType_Version() to get the major and minor
** version dynamically.
**
TT_Load_Glyph() has now two additional flags. TTLOAD_PEDANTIC
will force pedantic handling of the glyph instructions, and
TTLOAD_IGNORE_GLOBAL_ADVANCE_WIDTH is needed for some fonts
which have correct advance width values for the glyphs but an
incorrect global advance width value.
TT_Get_Glyph_Big_Metrics() now returns correct vertical bearing
values (both linear and pixel values).
New error code TT_Err_Glyf_Table_Missing (0x89) used to indicate
a missing `glyf' table.
The following macros have been shortened to stay within the
limit of 32 characters (the longer macro names are still
available if HAVE_LIMITS_ON_IDENTS is not defined).
TT_UCR_ARABIC_PRESENTATION_FORMS_A ->
TT_UCR_ARABIC_PRESENTATIONS_A
TT_UCR_ARABIC_PRESENTATION_FORMS_B ->
TT_UCR_ARABIC_PRESENTATIONS_B
TT_UCR_COMBINING_DIACRITICAL_MARKS ->
TT_UCR_COMBINING_DIACRITICS
TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB ->
TT_UCR_COMBINING_DIACRITICS_SYMB
freetype.h:
TT_Bool is now typedef'ed as `typedef int'.
New typedefs: TT_Int and TT_UInt.
Declarations of TT_Matrix_Multiply() and TT_Matrix_Invert()
have been removed since these functions were never
implemented.
Architectures
-------------
Added `ansi' directory to the supported architectures -- any
ANSI C compiler should compile FreeType with these files.
Added `debugger' directory to the architectures. Use this to
build a special version of FreeType for bytecode debugging
(tested with OS/2 and Unix).
Added more files to the `mac' architecture directory to make
basic support complete.
Support for VMS added (to compile the library only).
Contributed by Jouk Jansen <joukj@hrem.stm.tudelft.nl>.
Added `win16' architecture directory for older Windows versions.
A graphics driver (gw_win16.c) for the example programs is
available also.
**
** Antoine Leca contributed support for many MS-DOS and Windows
** compilers (including library fixes to make it 16bit compliant):
**
Borland C++ for MS-DOS (tested with v. 3.1, 4.02, 5.0),
Microsoft C for MS-DOS,
Turbo C (versions 1.5 and 2.0 -- version 1.0 is too old),
Borland C++ 4.0 and 5.0 for Windows (both 16bit and 32bit
versions),
gcc under Win32 (Cygwin32 or MinGW32),
Microsoft Visual C++ 2.x, 4.x, 5.0, and 6.0 for Windows
Support for the gettext package with DJGPP compiler has been
added.
Since many older compilers on both MS-DOS and Windows platforms
have problems to build dependency files automatically, scripts
for gcc under Unix have been added to do this. Similarly, a
script to produce a DLL definition file is now included in the
distribution.
Moved old win32 support to contrib/win32, replacing all CR/LF
with LF, and using only lowercase file names for consistency.
Additionally, some missing files in the FreeType 1.2
distribution have been added. Antoine Leca has written a new,
light-weight graphics driver (gw_win32.c) which fits better into
the current scheme.
Small additions have been made to the Amiga graphics driver.
The use of the ARM macro (intended for this architecture) has
been completely removed due to lack of support.
Checks for endianness have been removed completely since
FreeType isn't dependent on it.
Global compilation macros
-------------------------
The TT_HUGE_PTR macro has been added to support fonts with more
than 16000 characters or so with 16bit MS-DOS compilers.
Consequently, the files hugefile.c and hugemem.c have been added
which provide special versions for these compilers.
HAVE_LIMITS_ON_IDENTS has been introduced to overcome
restrictions with old compilers which can't digest identifiers
longer than 32 characters.
**
** Added option TT_CONFIG_OPTION_NO_INTERPRETER to desactivate the
** bytecode interpreter completely. This option is off by default.
**
Added options TT_CONFIG_OPTION_STATIC_RASTER and
TT_CONFIG_OPTION_STATIC_INTERPRETER to build static versions of
the respective components. Off by default. (It was formerly
called TT_STATIC_RASTER.)
Better debugging support (see ttconfig.h for details):
DEBUG_LEVEL_TRACE, DEBUG_LEVEL_ERROR, DEBUG_INTERPRETER,
DEBUG_MEMORY, DEBUG_FILE.
Added TT_MAX_EXTENSIONS to define the maximal number of
extensions (currently set to 8 -- this macro was previously in
ttextend.c).
Extensions
----------
**
** Full support for TrueType Open resp. OpenType GSUB tables has
** been implemented. It uses a GDEF table if available; otherwise,
** a method to construct an artificial GDEF table has been added
** (note that GDEF parts not related to GSUB are loaded but not
** further handled). An example how to use it can be found in the
** new test program ftstrtto.
**
Rudimentary GPOS support -- currently, you can load the GPOS
subtables but nothing more.
**
** Documentation for all extensions can be found in the file
** apirefx.txt.
**
Fixed a bug in TT_Load_PS_Names() which returned a local, thus
invalid pointer.
**
** Support for embedded bitmaps has been added (thanks to
** YAMANO'UCHI Hidetoshi <mer@interlink.or.jp> who has contributed
** a lot of the code). It can handle `bloc', `bdat', `EBLC', and
** `EBDT' tables. [TrueType embedded bitmaps are also called
** `sbits' (for `scaler bitmaps').]
**
Test programs
-------------
**
** A new test program called ftstrtto has been added to test
** TrueType Open features. Almost all available FreeType
** extensions are used in this program -- it displays a UTF 8
** encoded string on screen, allowing to toggle kerning, embedded
** bitmaps, GSUB support, and hinting. Additionally, it has a
** special module to handle the Arabic script properly (in
** arabic.c), i.e., it treats initial, medial, final, and isolated
** glyphs correctly.
**
The new module `blitter.c' provides the blitting function
Blit_Bitmap() for bitmaps of various depth.
The debugging program `fdebug' has been rewritten to provide a
better user interface.
ftdump has been extended to show information about embedded
bitmaps and GSUB data. It will now also show the PostScript
name of the font.
The new test program ftmetric can dump metrics and glyphs -- it
uses the gettext package for i18n support.
Another new test program is ftsbit to dump embedded bitmaps
contained in a font.
A small bug has been fixed in ftstring to compute the right
bounding box of the string.
ftview has been extended to display embedded bitmaps also
(switch `-B').
The maximal point size of glyphs in ftview has been increased to
5000pt -- this has shown some clipping bugs in the engine which
has been fixed meanwhile. As a demonstration, it also activates
tracing of the raster and gload component if DEBUG_LEVEL_TRACE
(see above) is defined.
Miscellaneous
-------------
The library has been updated to use autoconf 2.13 and libtool
1.3.3 throughout.
**
** FreeType will now install its header files in
** <prefix>/freetype/... since the number of files has grown again.
**
Added a lot of EXPORT_FUNC/EXPORT_DEF macros to functions for
correct exporting in DLLs.
**
** FreeType can now successfully load Mac fonts which don't have an
** `OS/2' table.
**
Fixed a bug in handling composite glyphs where the composite
elements use attached points.
Better debugging support for instructions.
Various workarounds have been implemented to support slightly
broken fonts (or rather, fonts not following exactly the
TrueType specifications).
Contributed programs
--------------------
ttf2bdf:
**
** Swapped all the columns in the mapping files.
**
Changed the mapping table loader to index on the second column
instead of the first.
Changed the includes to deal with compilation on Windows.
Added some new mapping tables.
Fixed an incorrect parameter for Traditional C compilers.
Added generation of the _XFREE86_GLYPH_RANGES properties.
Change all CRLF's, CR's, or LF's in copyright strings to
double spaces.
Changed it so gcc 2.8.1 likes the return type of main() again.
Changed Makefile.in a bit to make installation more
consistent.
Changed the lower limit for the vertical and horizontal
resolutions to be 10dpi instead of 50dpi.
ttf2pfb:
Has now rudimentary support for mapping tables (switch `-m')
and better PostScript name support for ordinary Type 1 fonts
-- nevertheless, it is far from finished, and there are some
plans to merge it with ttf2pt1.
configure script added.
Option `-k' added to keep output file in case of error.
`-v' is now really verbose.
ttf2pk:
**
** Support for MiKTeX's file searching mechanism added (ttf2pk
** and ttf2tfm are now part of the MiKTeX).
**
**
** Support for rotated glyphs added (only for subfonts; switches
** `-x' and `-y' to activate rotation resp. controlling the y
** offset). If a GSUB table with the `vert' feature is available
** in the font, vertical glyph presentation forms are used.
**
Added warning message to the configure script in case the
kpathsea library isn't used.
Fixed an omission in Bg5.sfd.
**
** Added UBg5plus.sfd for mapping Unicode to Bg5+ encoding.
** Similar SFD files now available: UBg5.sfd, UGB.sfd, UGBK.sfd,
** UJIS.sfd, UKS.sfd.
**
Added documentation for dvidrv.btm.
Will now compile with kpathsea version 3.3 or newer also.
Subfont ligature support added as needed in the HLaTeX package
for Korean (switch `-l').
**
** Since ttf2pk support has been added to teTeX version 1.0 and
** newer, no patch are necessary.
**
Fixed a string initialization bug in buildtfm() (file
tfmaux.c).
Added more documentation about file searching and a full
example how to use ttf2tfm.
Fixed a small bug in ttf2tfm.c which printed `(null)' instead
of nothing for the ttfonts.map entry if the font name prefix
string was empty.
ttf2tfm will now use the first type 0 kerning table only
(instead of the first kerning table only).
Both ttf2pk and ttf2tfm will now apply stretching and slanting
directly to the outline. This usually yields smaller bounding
boxes.
ttf2tfm will now output a comment string to the VPL file to
illustrate the meaning of the `HEADER' lines.
ttfbanner:
Added Makefile for emx+gcc compiler.
Added autoconf support.
Fixed a lot of compilation warnings.
Pascal source code
------------------
The Pascal source code has been seriously updated since 1.2.
Here are the most important changes.
**
** A. Support for charmaps and the name table
**
**
** The Charmap functions were not correctly implemented before
** 1.3. They are now available in the Pascal API.
**
**
** Similarly, the `name' table was not loaded, and the
** TT_Get_Name function wasn't implemented before 1.3. It is now
** done.
**
**
** The Pascal engine is now feature-complete, except that it
** provides no extensions like the C source code.
**
B. Improvements in the glyph loader and the interpreter
Several changes were made in order to be able to load more
broken fonts, as well as old Apple fonts which happened to use
some very rarely-used aspects of the specification.
Note that the Pascal bytecode interpreter, contrary to the C
version, is not able to silently accept broken glyphs yet, or
even use the flag TTLOAD_PEDANTIC. Implementing this in
Pascal would require some serious work (unlike to C, where
this feature was introduced easily with the use of a few
macros to minimize source changes). So TT_Load_Glyph might
return an error with the Pascal engine while the C one accept
the same request successfully.
C. Ports to Delphi and Free Pascal
This release has been compiled on the following compilers:
- Free Pascal 0.9 (Dos,Linux,Win32,OS/2)
- Virtual Pascal 1.1 and 2.0 (Win32 and OS/2)
- Turbo Pascal 6.0 and Borland Pascal 7.0 (Dos)
- Delphi 1, 2, and 3. It should work with D4 and D5 also.
(Windows)
Note that most of the test programs will not compile on
anything except MS-DOS or OS/2. The debugger also needs the
Turbo Vision library. The library, however, should compile
fine with all tools cited above.
Changes between FreeType 1.1 and 1.2
====================================
Mostly bug fixes and build fixes.
Changes between FreeType 1.0 and 1.1
====================================
There were various changes since the 1.0 release. Here they are
summarized:
- Added vertical layout support
The engine now loads the vertical header and metrics if available
and makes them visible through the new `vertical' field of the
face properties (it is set to NULL if no vertical data was found
in the font file).
The glyph loader now loads all metrics (horizontal and vertical),
but still returns the horizontal ones only with the API
TT_Get_Glyph_Metrics(). However, TT_Get_Glyph_Bit_Metrics() has
been added to extract them from a glyph container.
- Serialization of coordinates arrays in TT_Outline()
As announced in the previous API reference, the structure of
TT_Outline changed slightly, as well as the naming of its fields.
The points are now stored in a single array of TT_Vector, instead
of two parallel arrays (one for the Xs, the other for the Ys).
- New API function TT_Get_Face_Metrics()
Useful to access unscaled metrics like left side bearings, advance
widths, top side bearings, and advance height, for a given range
of glyphs.
- New extension: ftxcmap.c
Used by some applications to enumerate and parse the charmap
tables in an easier way.
- New extension: ftxpost.c
With this extension you can access the PostScript glyph names
given in the `post' table.
- New extension: ftxwidth.c
This extension is used to parse the `glyf' table to extract the
bounding boxes of a given range of glyphs. This is much faster
than loading individual glyphs.
- The FreeType engine is now THREAD-SAFE and REENTRANT
However, the implementation of ttmutex must be refined for your
system -- the default one is a dummy and doesn't do anything!
Beware! THIS IS STILL IN BETA.
The thread-safe and reentrant builds now compile and seem to run
well when used with a single thread. Some efforts have been spent
to check the coherency of the lock contentions within the engine,
but we haven't tested multi-threading heavily.
- Large internal re-organization
Too technical to explain shortly, but results in a much better
memory footprint and smaller code, especially when opening
multiple faces.
- Fixes/enhancements to the interpreter
The infamous Monotype.com bug (a new free font released by
Microsoft Typography a few days after the FreeType 1.0 release!)
is fixed, of course, as well as few other little and unpleasant
artifacts...
The interpreter was also seriously re-organized to allow the use
of a very large `switch' statement, instead of a jump table, which
results in smaller and faster code on some systems (depending of
the compiler too). Users of the library can experiment with the
TT_CONFIG_OPTION_INTERPRETER_SWITCH configuration macro to test
this.
- Single object compilation mode
The core engine can now be compiled into a single object file.
This allows optimizing compilers to do more global optimizations,
and get rid of many of the `intermediate' internal symbols used to
link internal engine components together.
The engine now takes only 48kByte of stripped Intel object code!
- DLL compilation mode
In order to allow the compilation of the library as a DLL, the
keyword EXPORT has been added as a prefix to all high-level API
functions found in `freetype.h'. Define it to the value you need
before `#include "freetype.h"' when building the DLL (if undefined
it will default to nothing within this header file).
(Apparently, this is only useful on Win32, maybe on OS/2.)
- Renamed configuration macros
These were renamed to forms of TT_CONFIG_OPTION_XXXXX_YYYYY.
They're located in ttconfig.h and can be defined/undefined
manually by developers who want to tune the compilation of the
engine:
TT_CONFIG_OPTION_EXTEND_ENGINE
Allows extensions to be linked with the single object engine.
If you don't need any of them, you may save one or more
kilobytes by undefining it.
TT_CONFIG_OPTION_GRAY_SCALING
Allows the compilation of the gray-scaling (font smoothing)
code in ttraster. If undefined, some APIs won't be available:
TT_Set_Raster_Palette(),
TT_Get_Glyph_Pixmap(),
TT_Get_Outline_Pixmap()
TT_CONFIG_OPTION_INTERPRETER_SWITCH
Uses a large `switch' statement in the bytecode interpreter
instead of a constant call-table. Depending on your processor
and compiler, this can lead to significant reduction of code
size and/or increase of performance.
TT_CONFIG_OPTION_THREAD_SAFE
When defined, a thread-safe version of the engine is built. A
thread-safe version is a bit bigger, probably not slower, than
a non-threaded build. ATTENTION: You must redefine the file
`lib/ttmutex.c' for your own platform to get it to work
correctly.
Some more options may come in the future...
- New API functions TT_MulDiv() and TT_MulFix()"
To help you compute `a*b/c' with 64-bit intermediate precision, or
`a*b/0x10000' with the same one...
These are not necessarily the fastest functions but they are
clearly portable and overflow-safe. Your runtime/compiler may
provide better replacements, though...
Changes between FreeType Beta and 1.0
=====================================
There were a number of changes since the public beta:
I. Bug fixes
------------
The following bugs have been fixed in this release:
- Incorrect advance width and left side bearings
The glyph loader has been re-designed to match the values found
in the pre-calc tables...
- Problems when opening multiple fonts
Fixed. A stupid bug in the i/o component.
- Problems with some Georgian fonts
Fixed. Discovered some new undocumented opcodes behaviour...
- Buglets in the test programs which made them return invalid
error codes
Fixed.
- Memory leaks when trying to open broken some font files
Fixed. Waiting for more broken fonts to test...
- Non-square resolutions don't work or display correctly
They now work very well!
- The scan-line converter, while in font-smoothing mode, doesn't
perform horizontal drop-out control
This wasn't really bug, but the feature has been correctly
added.
The remaining `features' persist, as they're not essential yet:
- The `rotated' and `stretched' flags do not work (glyph loading
will then return errors). However, it is still possible to
rotate or transform any outline without setting these flags.
- We always use drop-out mode number 2, as some of the values
returned by some `cvt programs' seem invalid for now...
Note also that an `event hook/callback' has been introduced in this
release, but is still under alpha (not even beta; it is commented
out currently). You should not rely on this...
II. Code changes
----------------
1. API Changes
A few API changes were necessary in order to support important
features, or future improvements which will come in later
releases.
- TT_Set_Instance_Resolution() was renamed to
TT_Set_Instance_Resolutions().
- TT_Set_Instance_PointSize() has disappeared. Instead, the
following APIs have been defined:
TT_Set_Instance_CharSize()
TT_Set_Instance_CharSizes()
TT_Set_Instance_PixelSizes()
- The TT_Engine class has been introduced. It models one
instance of the library, and is used to allow re-entrance and
shared library code. The functions which now depend on a
TT_Engine parameter are:
TT_Init_FreeType()
TT_Done_FreeType()
TT_Open_Face()
TT_Open_Collection()
TT_Set_Raster_Palette()
TT_Get_Outline_Bitmap()
TT_Get_Outline_Pixmap()
Note that there is _no_ sharing of objects between distinct
engines.
- Each face and instance object have an inside pointer which use
is reserved to client application. Several functions are
defined to set and read it:
TT_Set_Face_Pointer() / TT_Get_Face_Pointer()
TT_Set_Instance_Pointer() / TT_Get_Instance_Pointer()
- TT_Apply_Outline_Matrix() has been renamed to
TT_Transform_Outline().
TT_Apply_Outline_Translation() has been renamed to
TT_Translate_Outline()
TT_Apply_Vector_Matrix() has been renamed to
TT_Transform_Vector()
all for the sake of clarity.
2. Structural changes
Some structures have evolved.
- The instance metrics have now two new fields which are
`x_scale' and `y_scale'. Each one is a scaling factor,
expressed in the 16.16 fixed float format (TT_Fixed), used to
convert one distance expressed in font units into the same
distance in fractional (26.6) pixels.
- A new structure TT_BBox has been defined to describe an
outline's bounding box.
- The outlines are now full-class citizen. It is possible to
create new outlines, copy, clone, transform, translate and
render them through specific methods of the TT_Outline class
(previously called TT_Glyph_Outline). Read the API reference
for a complete listing.
- The glyph metrics have a new structure: they contain a TT_BBox
field, a TT_Outline field, as well as three metrics values,
which are `bearingX', `bearingY', and `advance'. Read the
file `glyphs.txt' for more information about their definitions
and uses.
3. Small but IMPORTANT changes
- The `max_Faces' field of a face's properties has disappeared.
It is replaced by `num_Faces' which gives the total number of
fonts embedded in a collection (the previous field gave the
total minus one).
- TT_Load_Glyph() now returns correctly placed outlines, and
computes advance widths which match the pre-calc values in the
"hdmx" table in nearly all cases.
- TT_Get_Glyph_Metrics() returns grid-fitted metrics for hinted
glyphs (i.e., loaded with the TTLOAD_HINT_GLYPH, or
TTLOAD_DEFAULT, flags). This includes the bounding box. To
get the exact bounding box of a hinted glyph, you should
extract its outline, then call TT_Get_Outline_BBox().
- Some improvements in the glyph loader, which improves
drastically the placement of glyphs (especially composite
ones) which previously caused trouble for some fonts
(e.g. goudy.ttf).
- Several minor improvements in the interpreter to improve
rendering and bounds checking...
- Up-to-date Pascal source code, with output equivalent to the C
tree...
--- END ---

970
docs/convntns.txt Normal file
View File

@@ -0,0 +1,970 @@
Conventions and Design in the FreeType library
----------------------------------------------
Table of Contents
Introduction
I. Style and Formatting
1. Naming
2. Declarations & Statements
3. Blocks
4. Macros
II. Design conventions
1. Modularity and Components Layout
2. Configuration and Debugging
III. Usage conventions
1. Error handling
2. Font File I/O
3. Memory management (due to change soon)
4. Support for threaded environments
5. Object Management
Introduction
============
This text introduces the many conventions used within the FreeType
library code. Please read it before trying any modifications or
extensions of the source code.
I. Style and Formatting
=======================
The following coding rules are extremely important to keep the
library's source code homogeneously. Keep in mind the following
points:
- `Humans read source code, not machines' (Donald Knuth)
The library source code should be as readable as possible, even
by non-C experts. With `readable', two things are meant: First,
the source code should be pleasant to the eye, with sufficient
whitespace and newlines, to not look like a boring stack of
characters stuck to each other. Second, the source should be
_expressive_ enough about its goals. This convention contains
rules that can help the source focus on its purpose, not on a
particular implementation.
- `Paper is the _ultimate_ debugger' (David Turner :-)
There is nothing like sheets of paper (and a large floor) to
help you understand the design of a library you're new to, or to
debug it. The formatting style presented here is targeted at
printing. For example, it is more than highly recommended to
never produce a source line that is wider than 78 columns. More
on this below.
1. Naming
---------
a. Components
A unit of the library is called a `component'. Each component
has at least an interface, and often a body. The library comes
in two language flavors, C and Pascal (the latter severely out
of date unfortunately). A component in C is defined by two
files, one `.h' header and one `.c' body, while a Pascal
component is contained in a single `.pas' file.
All component source file names begin with the `tt' prefix, with
the exception of the `FreeType' component. For example, the
file component is implemented by the files `ttfile.h',
`ttfile.c', and `ttfile.pas'. Only lowercase letters should be
used, following the 8+3 naming convention to allow compilation
under DOS.
In the C version, a single component can have multiple bodies.
For example, `ttfile.c' provides stream i/o through standard
ANSI libc calls, while `ttfile2.c' implements the same thing
using a Unix memory-mapping API.
The FreeType component is an interface-only component.
b. Long and expressive labels
Never hesitate to use long labels for your types, variables,
etc.! Except maybe for things like very trivial types, the
longest is the best, as it increases the source's
_expressiveness_. Never forget that the role of a label is to
express the `function' of the entity it represents, not its
implementation!
NOTE: Hungarian notation is NOT expressive, as it sticks the
`type' of a variable to its name. A label like `usFoo'
rarely tells the use of the variable it represents.
And the state of a variable (global, static, dynamic)
isn't helpful anymore.
Avoid Hungarian Notation like the *plague*!
When forging a name with several nouns
(e.g. `number-of-points'), use an uppercase letter for the first
letter of each word (except the first), like:
numberOfPoints
You are also welcomed to introduce underscores `_' in your
labels, especially when sticking large nouns together, as it
`airs' the code greatly. E.g.:
`numberOfPoints' or `number_Of_Points'
`IncredibleFunction' or `Incredible_Function'
And finally, always put a capital letter after an underscore,
except in variable labels that are all lowercase:
`number_of_points' is OK for a variable (_all_ lowercase label)
`incredible_function' is NOT for a function!
^ ^
`Microsoft_windows' is a *shame*!
^ ^
`Microsoft_Windows' isn't really better, but at least its a
^ ^ correct function label within this
convention ;-)
c. Types
All types that are defined for use by FreeType client
applications are defined in the FreeType component. All types
defined there have a label beginning with `TT_'. Examples:
TT_Face, TT_F26Dot6, etc.
However, the library uses a lot more of internal types that are
defined in the Types, Tables, and Objs components (`tttypes' &
`tttables' files).
By convention, all internal types, except the simplest ones like
integers, have their name beginning with a capital `T', like in
'TFoo'. Note that the first letter of `foo' is also
capitalized. The corresponding pointer type uses a capital `P'
instead, i.e. (TFoo*) is simply named 'PFoo'. Examples:
typedef struct _TTableDir
{
TT_Fixed version; /* should be 0x10000 */
UShort numTables; /* Tables number */
UShort searchRange; /* These parameters are only used */
UShort entrySelector;/* for a dichotomy search in the */
UShort rangeShift; /* directory. We ignore them. */
} TTableDir;
typedef TTableDir* PTableDir;
Note that we _always_ define a typedef for structures. The
original struct label starts with `_T'.
This convention is a famous one from the Pascal world.
Try to use C or Pascal types to the very least! Rely on
internally defined equivalent types instead. For example, not
all compilers agree on the sign of `char'; the size of `int' is
platform-specific, etc.
There are equivalents to the most common types in the `Types'
components, like `Short', `UShort', etc. Using the internal
types will guarantee that you won't need to replace every
occurence of `short' or wathever when compiling on a weird
platform or with a weird compiler, and there are many more than
you could think of...
d. Functions
The name of a function should always begin with a capital
letter, as lowercase first letters are reserved for variables.
The name of a function should be, again, _expressive_! Never
hesitate to put long function names in your code: It will make
the code much more readable.
Expressiveness doesn't necessarily imply lengthiness though; for
instance, reading shorts from a file stream is performed using
the following functions defined in the `File' component:
Get_Byte, Get_Short, Get_UShort, Get_Long, etc.
Which is somewhat more readable than:
cget, sget, usget, lget, etc.
e. Variables
Variable names should always begin with a lowercase letter.
Lowercase first letters are reserved for variables in this
convention, as it has been already explained above. You're
still welcome to use long and expressive variable names.
Something like `numP' can express a number of pixels, porks,
pancakes, and much more... Something like `num_points' won't.
Today, we are still using short variable labels in some parts of
the library. We're working on removing them however...
As a side note, a field name of a structure counts as a variable
name too. There are exceptions to the first-lowercase-letter
rule, but these are only related to fields within the structure
defined by the TrueType specification (well, at least it
_should_ be that way).
2. Declarations & Statements
----------------------------
a. Columning
Try to align declarations and assignments in columns, if it
proves logical. For example (taken from `ttraster.c'):
struct _TProfile
{
Int flow; /* Profile orientation : Asc/Descending */
Int height; /* profile's height in scanlines */
Int start; /* profile's start scanline */
ULong offset; /* offset of profile's data in render pool */
PProfile link; /* link to next profile */
Int index; /* index of profile's entry in trace table */
Int count_lines; /* count of lines having to be drawn */
Int start_line; /* lines to be rendered before this profile */
PTraceRec trace; /* pointer to profile's current trace table */
};
instead of
struct _TProfile {
Int flow; /* Profile orientation : Asc/Descending */
Int height; /* profile's height in scanlines */
Int start; /* profile's start scanline */
ULong offset; /* offset of profile's data in render pool */
PProfile link; /* link to next profile */
Int index; /* index of profile's entry in trace table */
Int count_lines; /* count of lines having to be drawn */
Int start_line; /* lines to be rendered before this profile */
PTraceRec trace; /* pointer to profile's current trace table */
};
This comes from the fact that you're more interested by the
field and its function than by its type.
Or:
x = i + 1;
y += j;
min = 100;
instead of
x=i+1;
y+=j;
min=100;
And don't hesitate to separate blocks of declarations with
newlines to `distinguish' logical sections.
E.g., taken from an old source file, in the declarations of the CMap
loader:
long n, num_SH;
unsigned short u;
long off;
unsigned short l;
long num_Seg;
unsigned short* glArray;
long table_start;
int limit, i;
TCMapDir cmap_dir;
TCMapDirEntry entry_;
PCMapTable Plcmt;
PCMap2SubHeader Plcmsub;
PCMap4 Plcm4;
PCMap4Segment segments;
instead of
long n, num_SH;
unsigned short u;
long off;
unsigned short l;
long num_Seg;
unsigned short *glArray;
long table_start;
int limit, i;
TCMapDir cmap_dir;
TCMapDirEntry entry_;
PCMapTable Plcmt;
PCMap2SubHeader Plcmsub;
PCMap4 Plcm4;
PCMap4Segment segments;
b. Aliases and the `with' clause
The Pascal language comes with a very handy `with' clause that
is often used when dealing with the fields of a same record.
The following Pascal source extract
with table[incredibly_long_index] do
begin
x := some_x;
y := some_y;
z := wathever_the_hell;
end;
is usually translated to:
table[incredibly_long_index].x = some_x;
table[incredibly_long_index].y = some_y;
table[incredibly_long_index].z = wathever_the_hell;
When a lot of fields are involved, it is usually helpful to
define an `alias' for the record, like in:
alias = table + incredibly_long_index;
alias->x = some_x;
alias->y = some_y;
alias->z = wathever_the_hell;
which gives cleaner source code, and eases the compiler's
optimization work.
Though the use of aliases is currently not fixed in the current
library source, it is useful to follow one of these rules:
- Avoid an alias with a stupid, or cryptic name, something like:
TFooRecord tfr;
....
[lots of lines snipped]
....
tfr = weird_table + weird_index;
...
tfr->num = n;
It doesn't really help to guess what 'tfr' stands for several
lines after its declaration, even if it's an extreme
contraction of one particular type.
Something like `cur_record' or `alias_cmap' is better. The
current source also uses a prefix of `Pl' for such aliases
(like Pointer to Local alias), but this use is _not_
encouraged. If you want to use prefixes, use `loc_', `cur_',
or `al_' at the very least, with a descriptive name following.
- Or simply use a local variable with a semi-expressive name:
{
THorizontalHeader hheader;
TVerticalHeader vheader;
hheader = instance->fontRes->horizontalHeader;
vheader = instance->fontRes->verticalHeader;
hheader->foo = bar;
vheader->foo = bar2;
...
}
which is much better than
{
THorizontalHeader Plhhead;
TVerticalHeader Plvhead;
Plhhead = instance->fontRes->horizontalHeader;
Plvhead = instance->fontRes->verticalHeader;
Plhhead->foo = bar;
Plvhead->foo = bar2;
...
}
3. Blocks
---------
Block separation is done with `{' and `}'. We do not use the K&R
convention which becomes only useful with an extensive use of
tabs. The `{' and its corresponding `}' should always be on the
same column. It makes it easier to separate a block from the rest
of the source, and it helps your _brain_ associates the accolades
easily (ask any Lisp programmer on the topic!).
Use two spaces for the next indentation level.
Never use tabs in your code, their widths may vary with editors
and systems.
Example:
if (condition_test) {
waow mamma;
I'm doing K&R format;
just like the Linux kernel;
} else {
This test failed poorly;
}
is _OUT_!
if ( condition_test )
{
This code isn't stuck to the condition;
read it on paper, you'll find it more;
pleasant to the eye;
}
else
{
Of course, this is a matter of taste;
That's just the way it is in this convention;
and you should follow it to be homogenous with;
the rest of the FreeType code;
}
is _IN_!
4. Macros
---------
Macros should be made of uppercase letters. When a macro label is
forged from several words, it is possible to only uppercasify the
first word, using an underscore to separate the nouns. This is
used in ttload.c, ttgload.c and ttfile.c with macros like
ACCESS_Frame, GET_UShort, CUR_Stream
The role of the macros used throughout the engine is explained
later in this document.
II. Design Conventions
======================
1. Modularity and Components Layout
-----------------------------------
The FreeType engine has been designed with portability in mind.
This implies the ability to compile and run it on a great variety
of systems and weird environments, unlike many packages where the
word strictly means `runs on a bunch of Unix-like systems'. We
have thus decided to stick to the following restrictions:
- The C version is written in ANSI C. The Pascal version compiles
and run under Turbo Pascal 5.0 and compatible compilers.
- The library, if compiled with gcc, doesn't produce any warning
with the `-ansi -pedantic' flags. Other compilers with better
checks may produce ANSI warnings that we'd be happy to now
about.
(NOTE: It can of course be compiled by an `average' C compiler,
and even by a C++ one.)
- It only requires in its simplest form an ANSI libc to compile,
and no utilities other than a C pre-processor, compiler, and
linker.
- It is written in a modular fashion. Each module is called a
`component' and is made of two files in the C version (an
interface with suffix `.h' and body with suffix `.c' ) and one
file in the Pascal one.
- The very low-level components can be easily replaced by
system-specific ones that do not rely on the standard libc.
These components deal mainly with i/o, memory, and mutex
operations.
- A client application must only include one interface file named
`freetype.h' resp. `freetype.pas' to use the engine. All other
components should never be used or accessed by client
applications, and their name always begin with a `tt' prefix:
ttmemory, ttobjs, ttinterp, ttapi, etc.
- All configuration options are gathered in two files. One
contains the processor and OS specific configuration options,
while the other treats options that may be enabled or disabled
by the developer to test specific features (like assertions,
debugging, etc).
IMPORTANT NOTES:
These restrictions only apply to the core engine. The package
that comes with it contains several test programs sources that
are much less portable, even if they present a modular model
inspired from the engine's layout.
The components currently found in the `lib' directory are:
-------- high-level interface ----------------------------------
freetype.h High-level API, to be used by client applications.
ttapi.c Implementation of the api found in `freetype.h'.
-------- configuration -----------------------------------------
ttconfig.h Engine configuration options. These are commented
and switched by hand by the developer. See
section 2 below for more info.
ft-conf.h Included by ttconfig.h, this file isn't part of
the `lib' directory, but depends on the target
environment. See section 2 blow for more info.
-------- definitions -------------------------------------------
tttypes.h The engine's internal types definitions.
tttables.h The TrueType tables definitions, per se the Specs.
tttags.h The TrueType table tags definitions.
tterror.[ch] The error and debugging component.
ttdebug.[ch] Only used by the debugger, should not be linked
into a release build.
ttcalc.[ch] Math component used to perform some computations
with an intermediate 64-bit precision.
-------- replaceable components --------------------------------
ttmemory.[ch] Memory component. This version uses the ANSI libc
but can be replaced easily by your own version.
ttfile.[ch] Stream i/o component. This version uses the ANSI
libc but can be replaced easily by your own
version. Compiled only if file memory mapping
isn't available on your system.
ttfile2.[ch] Unix-specific file memory mapping version of the
file component. It won't compile on other
systems. Usually results in much faster file
access (about 2x on a SCSI P166 system)
ttmutex.[ch] Generic mutex component. This version is a dummy
and should only be used for a single-thread build.
You _need_ to replace this component's body with
your own implementation to be able to build a
threaded version of the engine.
-------- data management ---------------------------------------
ttengine.h The engine instance record definition, root of all
engine data.
ttlists.[ch] Generic lists manager.
ttcache.[ch] Generic cache manager.
ttobjs.[ch] The engine's object definitions and
implementations module contains structures,
constructors, destructors and methods for the
following objects:
face, instance, glyph, execution_context
ttload.[c] The TrueType tables loader.
ttgload.[ch] The glyph loader. A component in itself, due to
the task's complexity.
ttindex.[ch] The character mapping to glyph index conversion
routines. Implements functions defined in
`freetype.h'.
ttinterp.[ch] The TrueType instructions interpreter. Probably
the nicest source in this engine. Apparently,
many have failed to produce a comparable one due
to the very poorly written specification! It took
David Turner three months of his spare time to get
it working correctly! :-)
ttraster.[ch] The engine's second best piece. This is the
scan-line converter. Performs gray-level
rendering (also known as font-smoothing) as well
as dropout-control.
2. Configuration and Debugging
------------------------------
As stated above, configuration depends on two files:
The environment configuration file `ft-conf.h':
This file contains the definitions of many configuration options
that are processor and OS-dependent. On Unix systems, this file
is generated automatically by the `configure' script that comes
with the released package.
On other environments, it is located in one of the architecture
directories found in `arch' (e.g. `arch/os2/ft-conf.h').
The path to this file should be passed to the compiler when
compiling _each_ component. (typically with an -I option).
The engine configuration file `ttconfig.h':
This file contains many configuration options that the developer
can turn on or off to experiment with some `features' of the
engine that are not part of its `simplest' form. The options
are commented.
Note that the makefiles are compiler-specific.
It is possible to enable the dumping of debugging information by
compiling the components with the various debug macros. Please
consult the file `ttconfig.h' for details.
If you want to port the engine to another environment, you will
need to
- Write a new `ft-conf.h' file for it. Just copy one of those
available and change the flags accordingly (they're all
commented).
- Replace the memory, file, and mutex components with yours,
presenting the same interface and behaviour.
- Eventually add some code in ttapi.c to initialize
system-specific data with the engine.
III. Usage conventions
======================
1. Error Handling
-----------------
Error handling has been refined to allow reentrant builds of the
library, available only in the C version. We thus have now two
different conventions.
In Pascal:
A global error variable is used to report errors when they are
detected. All functions return a boolean that indicates success
or failure of the call. If an error occurs within a given
function, the latter must set the error variable and return
`false' (which means failure).
It is then possible to make several calls in a single `if'
statement like:
if not Perform_Action_1( parms_of_1 ) or
not Perform_Action_2( parms_of_2 ) or
not Perform_Action_3( parms_of_3 ) then goto Fail;
where execution will jump to the `Fail' label whenever an error
occurs in the sequence of actions invoked in the condition.
In C:
Global errors are forbidden in re-entrant builds. Each function
thus returns directly an error code. A return value of 0 means
that no error occured, while a non-zero other value indicates a
failure of any kind.
This convention is more constraining than the one used in the
Pascal source. The above Pascal statement should be translated
into the following C fragment:
rc = Perform_Action_1( parms_of_1 );
if ( rc )
goto Fail;
rc = Perform_Action_2( parms_of_2 );
if ( rc )
goto Fail;
rc = Perform_Action_3( parms_of_3 );
if ( rc )
goto Fail;
which, while being equivalent, isn't as pleasantly readable.
One `simple' way to match the original fragment would be to
write:
if ( (rc = Perform_Action_1( parms_of_1 )) ||
(rc = Perform_Action_2( parms_of_2 )) ||
(rc = Perform_Action_3( parms_of_3 )) )
goto Fail;
which is better but uses assignments within expressions, which
are always delicate to manipulate in C (the risk of writing `=='
exists, and would go unnoticed by a compiler). Moreover, the
assignments are a bit redundant and don't express much things
about the actions performed (they only speak of the error
management issue).
That is why some macros have been defined for the most
frequently used functions. They relate to low-level routines
that are called very often (mainly i/o, mutex, and memory
handling functions). Each macro produces an implicit assignment
to a variable called `error' and can be used instead as a simple
function call. Example:
if ( PERFORM_Action_1( parms_of_1 ) ||
PERFORM_Action_2( parms_of_2 ) ||
PERFORM_Action_3( parms_of_3 ) )
goto Fail;
with
#define PERFORM_Action_1( parms_1 ) \
( error = Perform_Action_1( parms_1 ) )
#define PERFORM_Action_2( parms_1 ) \
( error = Perform_Action_2( parms_1 ) )
#define PERFORM_Action_3( parms_1 ) \
( error = Perform_Action_3( parms_1 ) )
defined at the beginning of the file.
There, the developer only needs to define a local `error'
variable and use the macros directly in the code, without caring
about the actual error handling performed. Examples of such a
usage can be found in `ttload.c' and `ttgload.c'. Moreover, the
structure of the source files remain very similar, even though
the error handling is very different.
This convention is very close to the use of exceptions in
languages like C++, Pascal, Java, etc. where the developer
focuses on the actions to perform, and not on every little error
checking.
2. Font File I/O
----------------
a. Streams
The engine uses `streams' to access the font files. A stream is
a structure defined in the `File' component containing
information used to access files through a system-specific i/o
library.
The current implementation of the File component uses the ANSI
libc i/o functions. However, for the sake of embedding in light
systems and independence of a complete libc, it is possible to
re-implement the component for a specific system or OS, letting
it use system calls.
A stream is of type `TStream' defined in the `TTObjs' interface.
The type is `(void*)' but actually points to a structure defined
within the File component.
A stream is created, managed and closed through the interface of
the `File' component. Several implementations of the same
component can co-exist, each taking advantage of specific system
features (the file `ttfile2.c' uses memory-mapped files for
instance) as long as it respects the interface.
b. Frames
TrueType is tied to the big-endian format, which implies that
reading shorts or longs from the font file may need conversions
depending on the target processor. To be able to easily detect
read errors and allow simple conversion calls or macros, the
engine is able to access a font file using `frames'.
A frame is simply a sequence of successive bytes taken from the
input file at the current position. A frame is pre-loaded into
memory by a `TT_Access_Frame()' call of the `File' component.
It is then possible to read all sizes of data through the
`Get_xxx()' functions, like Get_Byte(), Get_Short(),
Get_UShort(), etc.
When all important data is read, the frame can be released by a
call to `TT_Forget_Frame()'.
The benefits of frames are various. Consider these two
approaches at extracting values:
if ( (error = Read_Short( &var1 )) ||
(error = Read_Long ( &var2 )) ||
(error = Read_Long ( &var3 )) ||
(error = Read_Short( &var4 )) )
return FAILURE;
and
/* Read the next 16 bytes */
if ( (error = TT_Access_Frame( 16L )) )
return error; /* The Frame could not be read */
var1 = Get_Short(); /* extract values from the frame */
var2 = Get_Long();
var3 = Get_Long();
var4 = Get_Short();
TT_Forget_Frame(); /* release the frame */
In the first case, there are four error assignments with four
checks of the file read. This unnecessarily increases the size
of the generated code. Moreover, you must be sure that `var1'
and `var4' are short variables, `var2' and `var3' long ones, if
you want to avoid bugs and/or compiler warnings.
In the second case, you perform only one check for the read, and
exit immediately on failure. Then the values are extracted from
the frame, as the result of function calls. This means that you
can use automatic type conversion; there is no problem if
e.g. `var1' and `var4' are longs, unlike previously.
On big-endian machines, the `Get_xxx()' functions could also be
simple macros that merely peek the values directly from the
frame, which speeds up and simplifies the generated code!
And finally, frames are ideal when you are using memory-mapped
files, as the frame is not really `pre-loaded' and never uses
any `heap' space.
IMPORTANT: You CANNOT nest several frame accesses. There is
only one frame available at a time for a specific
instance.
It is also the programmer's responsibility to never
extract more data than was pre-loaded in the frame!
(But you usually know how many values you want to
extract from the file before doing so).
3. Memory Management
--------------------
The library now uses a component which interface is similar to
malloc()/free(). It defines only two functions.
* Alloc()
To be used like malloc(), except that it returns an error code,
not an address. Its arguments are the size of the requested
block and the address of the target pointer to the `fresh'
block. An error code is returned in case of failure (and this
will also set the target pointer to NULL), 0 in case of success.
Alloc() should always respect the following rules:
- Requesting a block of size 0 should set the target pointer to
NULL and return no error code (i.e., return 0).
- The returned block is always zeroed. This is an important
assumption of other parts of the library.
If you wish to replace the memory component with your own,
please respect this behaviour, or your engine won't work
correctly.
* Free()
As you may have already guessed, Free() is Alloc()'s
counterpart. It takes as argument the _target pointer's
address_! You should _never_ pass the block's address directly,
i.e. the pointer, to Free().
Free should always respect the following rules:
- Calling it with a NULL argument, or the address of a NULL
pointer is valid, and should return success.
- The pointer is always set to NULL after the block's
deallocation. This is also an important assumption of many
other parts of the library.
If you wish to replace the memory component with your own,
please respect this behaviour, or your engine won't work
correctly.
As the pointers addresses needed as arguments are typed `void**',
the component's interface also provides in the C version some
macros to help use them more easily, these are:
MEM_Alloc A version of Alloc that casts the argument pointer
to (void**).
ALLOC Same as MEM_Alloc, but with an assignment to a
variable called `error'. See the section `error
handling' above for more info on this.
FREE A version of Free() that casts the argument
pointer to (void**). There is currently no error
handling by with this macro.
MEM_Set An alias for `memset()', which can be easily
changed to anything else if you wish to use a
different memory manager than the functions
provided by the ANSI libc.
MEM_Copy An alias of `memcpy()' or `bcopy()' used to move
blocks of memory. You may change it to something
different if you wish to use something else that
your standard libc.
4. Support for threaded environments
------------------------------------
Support for threaded environments have been added to the C
sources, and only to these. It is now theorically possible to
build three distinct versions of the library:
single-thread build:
The default build. This one doesn't known about different
threads. Hence, no code is generated to perform coherent data
sharing and locking.
thread-safe build:
With this build, several threads can use the library at the
same time. However, some key components can only be used by
one single thread at a time, and use a mutex to synchronize
access to their functions. These are mainly the file, raster
and interpreter components.
re-entrant build:
A re-entrant version is able to perform certain actions in
parallel that a thread-safe one cannot. This includes
accessing file(s) in parallel, interpreting different
instruction streams in parallel, or even scan-line converting
distinct glyphs at the same time.
Note that most of the latest changes in the engine are making the
distinction between the thread-safe and re-entrant builds thinner
than ever.
There is a `ttmutex' component that presents a generic interface
to mutex operations. It should be re-implemented for each
platform.
<to be continued>
--- end of convntns.txt ---

94
docs/credits Normal file
View File

@@ -0,0 +1,94 @@
NOTE: This list is far from being complete. Please send a mail if
you want to be included.
David TURNER (david.turner@freetype.org)
Main engine design and coding. Pascal source maintainer.
Robert WILHELM (robert.wilhelm@freetype.org)
Web, FTP and CVS wizard & administrator. C source maintainer.
Incredible bug and spell fixer!
Werner LEMBERG (werner.lemberg@freetype.org)
Internationalization and CJK guru. ttf2pk author.
Antoine LECA (antoine.leca@renault.fr)
16bit support for various compilersamd platforms.
Mark LEISHER (mleisher@crl.nmsu.edu)
Internationalization. X11 font server prototype author. ttf2bdf
author.
Pavel KANKOVSKY (peak@argo.troja.mff.cuni.cz)
Old logo, internationalization, on-line demo, humor, and
remarkable bug hunter!
Erwin DIETERICH (erwin.dieterich.ed@bayer-ag.de)
*Real* internationalization :-) Author of the ftxerr18 and gettext
support.
Michal NECASEK (mike@mendelu.cz)
Author and maintainer of the OS/2 font driver based on FreeType.
Munagala V. S. RAMANATH, CurveSoft, Inc. (ram@curvesoft.com)
Contributor of many bug fixes and code improvements.
Williss, Dave (dwilliss@tnt.microimages.com)
GSUB support. Author of the Mac port.
Yamano-uchi, Hidetoshi
embedded bitmap support
The following people have also contributed to the development of
FreeType:
Beebe, Nelson H. F.: Tested FreeType on many platforms.
Benett, Kendall
Choi, Junho
Chong, Chin Soon
Chroboczek, Juliusz: Author of the xfsft Truetype font server.
Cohen, Marc L.
Davis, Jack
Demaille, Akim
Ellis, Duane
Feinberg, Matthew
Furr, Anthony
Hoo, Dave: 16bit support
Jamme, Thibault
Lewis, Kevin
Long, Jeff
Marukawa, Kazushi
Nijtmans, Jan
Olson, Eric
Paterson-Jones, Roland
Pommnitz, Joerg
Quigley, Ian
Steger, Helmut
Taggart, Scott
--- end of credits ---

16
docs/freetype.lsm Normal file
View File

@@ -0,0 +1,16 @@
Begin3
Title: freetype
Version: 1.3
Entered-date: 01SEP99
Description: truetype font rasterizer
Keywords: font truetype rasterizer
Author: David Turner <david.turner@freetype.org>,
Werner Lemberg <werner.lemberg@freetype.org>
Robert Wilhelm <robert.wilhelm@freetype.org>
Maintained-by: Robert Wilhelm <robert.wilhelm@freetype.org>
Primary-site: ftp://sunsite.unc.edu/pub/Linux/X11/fonts/
Alternate-site:
Original-site: ftp://ftp.freetype.org/pub/freetype
Platforms: Linux, OS/2, MSDOS, Amiga OS, Unix, Mac, Windows
Copying-policy: BSD-like
End

1257
docs/glyphs.htm Normal file

File diff suppressed because it is too large Load Diff

999
docs/glyphs.txt Normal file
View File

@@ -0,0 +1,999 @@
http://www.freetype.org
Glyph Hell
An introduction to glyphs, as used and defined in the FreeType engine
------------------------------------------------------------------------
Introduction
This article discusses in great detail the definition of glyph metrics, per
se the TrueType specification, and the way they are managed and used by the
FreeType engine. This information is crucial when it comes to rendering text
strings, either in a conventional (i.e. Roman) layout, or with vertical or
right-to-left ones. Some aspects like glyph rotation and transformation are
explained too.
Comments and corrections are highly welcome, and can be sent to the FreeType
developers list.
------------------------------------------------------------------------
I. An overview of font files
In TrueType, a single font file is used to contain information related to
classification, modeling and rendering of text using a given typeface. This
data is located in various independent `tables', which can be sorted in four
simple classes, as described below:
* Face Data
We call face data the amount of information related to a given
typeface, independently of any particular scaling, transformation,
and/or glyph index. This usually means some typeface-global metrics and
attributes, like family and styles, PANOSE number, typographic
ascenders and descenders, as well as some very TrueType specific items
like the font `programs' found in the fpgm and prep tables, the gasp
table, character mappings, etc.
In FreeType, a face object is used to model a font file's face data.
* Instance Data
We call instance a given pointsize/transformation, at a given device
resolution (e.g. 8pt at 96x96dpi, or 12pt at 300x600dpi, etc). Some
tables found in the font files are used to produce instance-specific
data, like the cvt table, or the prep program. Though they are often
part of the face data, their processing results in information called
instance data.
In FreeType, it is modeled through an instance object, which is always
created from an existing face object.
* Glyph Data
We call glyph data the piece of information related to specific glyphs.
This includes the following things that are described in more details
in the next sections:
o The glyph's vectorial representation, also called its outline.
o Various metrics, like the glyph's bounding box, its bearings and
advance values.
o TrueType specifies a specific instruction bytecode, used to
associate each glyph with a small program, called the glyph code.
Its purpose is to grid-fit the outline to any target instance, in
order to produce excellent output at small pixel sizes.
The FreeType engine doesn't map each glyph to a single structure, as
this would waste memory for no good reason. Rather, a glyph object is a
container, created from any active face, which can be used to load
and/or process any font glyph at any instance (or even no instance at
all). Of course, the glyph properties (outline, metrics, bitmaps, etc.)
can be extracted independently from an object once it has been loaded
or processed.
* Text and Layout Data
Finally, there is a last class of data that doesn't really fit in all
others, and that can be called text data. It comprises information
related to the grouping of glyphs together to form text. Simple
examples are the kerning table, which controls the spacing between
adjacent glyphs, as well as some of the extensions introduced in
TrueType Open, OpenType, and TrueType GX like glyph substitution
(ligatures, vertical representations), baseline management,
justification, etc.
This article focuses on the basic TrueType tables, and hence, will only
talk about kerning, as FreeType doesn't support OpenType nor GX (yet).
[Support for TrueType Open is already partially available.]
------------------------------------------------------------------------
II. Glyph Outlines
TrueType is a scalable font format; it is thus possible to render glyphs at
any scale, and under any affine transform, from a single source
representation. However, simply scaling vectorial shapes exhibits at small
sizes (where `small' refers here to anything smaller than at least
150 pixels) a collection of un-harmonious artifacts, like widths and/or
heights degradations.
Because of this, the format also provides a complete programming language
used to design small programs associated to each glyph. Its role is to align
the point positions on the pixel grid after the scaling. This operation is
hence called grid-fitting, or even hinting.
1. Vectorial representation
The source format of outlines is a collection of closed paths called
contours. Each contour delimits an outer or inner region of the glyph,
and can be made of either line segments and/or second-order beziers
(also called conic beziers or quadratics).
It is described internally as a series of successive points, with each
point having an associated flag indicating whether it is `on' or `off'
the curve. These rules are applied to decompose the contour:
o Two successive `on' points indicate a line segment joining them.
o One `off' point amidst two `on' points indicates a conic bezier,
the `off' point being the control point, and the `on' ones the
start and end points.
o Finally, two successive `off' points forces the rasterizer to
create (only during bitmap rendering) a virtual `on' point amidst
them, at their exact middle. This greatly facilitates the
definition of successive Bezier arcs.
* # on
* off
__---__
#-__ _-- -_
--__ _- -
--__ # \
--__ #
-#
Two `on' points
Two `on' points and one `off' point
between them
*
# __ Two `on' points with two `off'
\ - - points between them. The point
\ / \ marked `0' is the middle of the
- 0 \ `off' points, and is a `virtual
-_ _- # on' point where the curve passes.
-- It does not appear in the point
list.
*
Each glyph's original outline points are located on a grid of
indivisible units. The points are stored in the font file as
16-bit integer grid coordinates, with the grid origin's being at (0,0);
they thus range from -16384 to 16383.
In creating the glyph outlines, a type designer uses an imaginary
square called the EM square. Typically, the EM square encloses the
capital letter `M' and most other letters of a typical roman alphabet.
The square's size, i.e., the number of grid units on its sides, is very
important for two reasons:
o It is the reference used to scale the outlines to a given
instance. For example, a size of 12pt at 300x300dpi corresponds to
12*300/72 = 50 pixels. This is the size the EM square would appear
on the output device if it was rendered directly. In other words,
scaling from grid units to pixels uses the formula
pixel_size = point_size * resolution / 72
pixel_coordinate = grid_coordinate * pixel_size / EM_size
o The greater the EM size is, the larger resolution the designer can
use when digitizing outlines. For example, in the extreme example
of an EM size of 4 units, there are only 25 point positions
available within the EM square which is clearly not enough.
Typical TrueType fonts use an EM size of 2048 units (note: with
Type 1 PostScript fonts, the EM size is fixed to 1000 grid units.
However, point coordinates can be expressed in floating values).
Note that glyphs can freely extend beyond the EM square if the font
designer wants this. The EM is used as a convenience, and is a valuable
convenience from traditional typography.
Grid units are very often called font units or EM units.
-----------------------------------------------------------------------
IMPORTANT NOTE:
Under FreeType, scaled pixel positions are all expressed in the 26.6
fixed float format (made of a 26-bit integer mantissa, and a 6-bit
fractional part). In other words, all coordinates are multiplied by 64.
The grid lines along the integer pixel positions, are multiples of 64,
like (0,0), (64,0), (0,64), (128,128), etc., while the pixel centers
lie at middle coordinates (32 modulo 64) like (32,32), (96,32), etc.
-----------------------------------------------------------------------
2. Hinting and Bitmap rendering
As said before, simply scaling outlines to a specific instance always
creates undesirable artifacts, like stems of different widths or
heights in letters like `E' or `H'. Proper glyph rendering needs that
the scaled points are aligned along the pixel grid (hence the name
grid-fitting), and that important widths and heights are respected
throughout the whole font (for example, it is very often desirable that
the letters `I' and `T' have their central vertical line of the same
pixel width).
Type 1 PostScript font files include with each glyph a small series of
distances called hints, which are later used by the type manager to try
grid-fitting the outlines as cleverly as possible. On one hand, it has
the consequence that upgrading your font engine can enhance the visual
aspects of all fonts of your system; on the other hand, the quality of
even the best version of Adobe's Type Manager isn't always very
pleasing at small sizes (notwithstanding font smoothing).
TrueType takes a radically different approach: Each glyph has an
associated `program', designed in a specific geometrical language,
which is used to align explicitly each outline point to the pixel grid,
preserving important distances and metrics. A stack-based low-level
bytecode is used to store it in the font file, and is interpreted later
when rendering the scaled glyphs.
This means that even very complex glyphs can be rendered perfectly at
very small sizes, as long as the corresponding glyph code is designed
correctly. Moreover, a glyph can loose some of its details, like
serifs, at small sizes to become more readable, because the bytecode
provides interesting features.
However, this also have the sad implication that an ill-designed glyph
code will always render junk, whatever the font engine's version, and
that it's very difficult to produce quality glyph code. There are about
200 TrueType opcodes, and no known `high-level language' for it. Most
type artists aren't programmers at all and the only tools able to
produce quality code from vectorial representation have been
distributed to only a few font foundries, while tools available to the
public, e.g. Fontographer, are usually expensive though generating
average to mediocre glyph code.
All this explains why an enormous number of broken or ugly `free' fonts
have appeared on the TrueType scene, and that this format is now
mistakenly thought as `crap' by many people. Funnily, these are often
the same who stare at the `beauty' of the classic `Times New Roman' and
`Arial/Helvetica' at 8 points.
Once a glyph's code has been executed, the scan-line converter converts
the fitted outline into a bitmap (or a pixmap with font-smoothing).
------------------------------------------------------------------------
III. Glyph metrics
1. Baseline, Pens and Layouts
The baseline is an imaginary line that is used to `guide' glyphs when
rendering text. It can be horizontal (e.g. Roman, Cyrillic, Arabic,
etc.) or vertical (e.g. Chinese, Japanese, etc). Moreover, to render
text, a virtual point, located on the baseline, called the pen
position, is used to locate glyphs.
Each layout uses a different convention for glyph placement:
o 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.
[Image]
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
alphabets, like Arabic. This introduces some differences in the
way text is rendered.
------------------------------------------------------------------
IMPORTANT NOTE:
The pen position is always placed on the baseline in TrueType,
unlike the convention used by some graphics systems, like Windows,
to always put the pen above the line, at the ascender's position.
------------------------------------------------------------------
o With vertical layout, glyphs are centered around the baseline:
[Image]
2. Typographic metrics and bounding boxes
A various number of face metrics are defined for all glyphs in a given
font. Three of them have a rather curious status in the TrueType
specification; they only apply to horizontal layouts:
o The ascent
This is the distance from the baseline to the highest/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.
o The descent
The distance from the baseline to the lowest grid coordinate used
to place an outline point. This is a negative value, due to the
grid's orientation.
o The linegap
The distance that must be placed between two lines of text. The
baseline-to-baseline distance should be computed as
ascent - descent + linegap
if you use the typographic values.
The problem with these metrics is that they appear three times in a
single font file, each version having a slightly different meaning:
1. The font's horizontal header provides the ascent, descent and
linegap fields, which are used to express the designer's intents,
rather than the real values that may be computed from all glyphs
in the outline. These are used by the Macintosh font engine to
perform font mapping (i.e. font substitution).
2. The OS/2 table provides the usWinAscent and usWinDescent fields.
These values are computed for glyphs of the Windows ANSI charset
only, which means that they are wrong for any other glyph. Note
that usWinDescent is always positive (i.e. looks like `-descent').
3. The OS/2 table provides the typoAscender, typoDescender and
typoLinegap values, which hopefully concern the whole font file.
These are the correct system-independent values!
All metrics are expressed in font units. If you want to use any of the
two first versions of these metrics, the TrueType specification
contains some considerations and computing tips that might help you.
Other, simpler metrics are:
o The glyph's bounding box, also called bbox
This is an imaginary box that encloses any glyph (usually as
tightly as possible). It is represented by four fields, namely
xMin, yMin, xMax, and yMax, that can be computed for any outline.
In FreeType, their values can be in font units (if measured in the
original outline) or in 26.6 pixel units (if measured on scaled
outlines).
Note that if it wasn't for grid-fitting, you wouldn't need to know
a box's complete values, but only its dimensions to know how big
is a glyph outline/bitmapa. However, correct rendering of hinted
glyphs needs the preservation of important grid alignment on each
glyph translation/placement on the baseline, which is why FreeType
always returns the complete glyph outline.
Note also that the font's header contains a global font bounding
box in font units which should enclose all glyphs in a font. This
can be used to pre-compute the maximum dimensions of any glyph at
a given instance.
o The 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
o The external leading
This is another name for the linegap.
3. Bearings and Advances
Each glyph has also distances called bearings and advances. Their
definition is constant, but their values depend on the layout, as the
same glyph can be used to render text either horizontally or
vertically.
1. The left side bearing: a.k.a. bearingX
This is the horizontal distance from the current pen position to
the glyph's left bounding box edge. It is positive for horizontal
layouts, and most generally negative for vertical one.
2. The top side bearing: a.k.a. bearingY
This is the vertical distance from the baseline to the top of the
glyph's bounding box. It is usually positive for horizontal
layouts, and negative for vertical ones
3. The advance width: a.k.a. advanceX
This is the horizontal distance the pen position must be
incremented (for left-to-right writing) or decremented (for
right-to-left writing) by after each glyph is rendered when
processing text. It is always positive for horizontal layouts, and
null for vertical ones.
4. The advance height: a.k.a. advanceY
This is the vertical distance the pen position must be decremented
by after each glyph is rendered. It is always null for horizontal
layouts, and positive for vertical layouts.
5. The glyph width
The glyph's horizontal extent. More simply, it is (bbox.xMax -
bbox.xMin) for unscaled font coordinates. For scaled glyphs, its
computation requests specific care, described in the grid-fitting
chapter below.
6. The glyph height
The glyph's vertical extent. More simply, it is (bbox.yMax -
bbox.yMin) for unscaled font coordinates. For scaled glyphs, its
computation requests specific care, described in the grid-fitting
chapter below.
7. The right side bearing
Only used for horizontal layouts to describe the distance from the
bbox's right edge to the advance width. It is in most cases a
non-negative number. The FreeType library doesn't provide this
metric directly, as it isn't really part of the TrueType
specification. It can be computed simply as
advance_width - left_side_bearing - (xMax-xMin)
[Image]
[Image]
Finally, if you use `ABC widths' under Windows and OS/2, the following
relations apply:
A = left side bearing
B = width
C = right side bearing
A+B+C = advance width
4. The effects of grid-fitting
All these metrics are stored in font units in the font file. They must
be scaled and grid-fitted properly to be used at a specific instance.
This implies several things:
o First, a glyph program not only aligns the outline along the grid
pixel, it also processes the left side bearing and the advance
width. Other grid-fitted metrics are usually available in optional
TrueType tables if you need them.
o A glyph program may decide to extend or stretch any of these two
metrics if it has a need for it. This means that you cannot assume
that the fitted metrics are simply equal to the scaled one plus or
minus a liberal distance < 1 pixel (i.e., less than 64 fractional
pixel units). For example, it is often necessary to stretch the
letter `m' horizontally at small pixel sizes to make all vertical
stems visible, while the same glyph can be perfectly `square' at
larger sizes.
o Querying the fitted metrics of all glyphs at a given instance is
very slow, as it needs to load and process each glyph
independently. For this reason, some optional TrueType tables are
defined in the specification, containing pre-computed metrics for
specific instances (the most commonly used, like 8, 9, 10, 11, 12,
and 14 points at 96dpi, for example). These tables aren't always
present in a TrueType font.
If you don't need the exact fitted value, it's much faster to
query the metrics in font units, then scale them to the instance's
dimensions.
-----------------------------------------------------------------------
IMPORTANT NOTE:
Another very important consequence of grid-fitting is the fact that
moving a fitted outline by a non-integer pixel distance will simply
ruin the hinter's work, as alignments won't be preserved. The
translated glyph will then look `ugly' when converted to a bitmap!
In other words, each time you want to translate a fitted glyph outline,
you must take care of only using integer pixel distances (the x and
y offsets must be multiples of 64, which equals to 1.0 in the 26.6
fixed float format). If you don't care about grid-fitting (typically
when rendering rotated text), you can use any offset you want and use
sub-pixel glyph placement.
-----------------------------------------------------------------------
------------------------------------------------------------------------
IV. Text processing
This section demonstrates how to use the concepts previously defined to
render text, whatever the layout you use.
1. Writing simple text strings
We will start by generating a simple string with a Roman alphabet. The
layout is thus horizontal, left to right.
For now, we will assume all glyphs are rendered in a single target
bitmap. The case of generating individual glyph bitmaps, then placing
them on demand on a device is presented in a later chapter of this
section.
Rendering the string needs to place each glyph on the baseline; this
process looks like the following:
1. Place the pen to the cursor position. The pen is always located on
the baseline. Its coordinates must be grid-fitted (i.e. multiples
of 64)!
pen_x = cursor_x;
pen_y = cursor_y;
2. Load the glyph outline and its metrics. Using the flag
TTLOAD_DEFAULT will scale and hint the glyph:
TT_Load_Glyph( instance,
glyph,
glyph_index,
TTLOAD_DEFAULT );
TT_Get_Glyph_Metrics( glyph, &metrics );
TT_Get_Glyph_Outline( glyph, &outline );
3. The loader always places the glyph outline relative to the
imaginary pen position (0,0). You thus simply need to translate
the outline by the vector:
( pen_x, pen_y )
To place it on its correct position, you can use the call
TT_Translate_Outline( outline, pen_x, pen_y );
4. Render the outline in the target bitmap, the glyph will be
surimposed on it with a binary `or' operation (FreeType never
creates glyph bitmaps by itself, it simply renders glyphs in the
arrays you pass to it. See the API reference for a complete
description of bitmaps and pixmaps).
TT_Get_Outline_Bitmap( outline, &target_bitmap );
------------------------------------------------------------------
IMPORTANT NOTE:
If you don't want to access the outline in your code, you can also
use the API function TT_Get_Glyph_Bitmap() which does the same as
the previous lines:
TT_Get_Glyph_Outline( glyph, &outline );
TT_Translate_Outline( outline, x_offset, y_offset );
TT_Get_Outline_Bitmap( outline, &target_bitmap );
TT_Translate_Outline( outline, -x_offset, -y_offset );
is equivalent to:
TT_Get_Glyph_Bitmap( glyph,
x_offset,
y_offset,
&target_bitmap );
------------------------------------------------------------------
5. Now advance the pen to its next position. The advance is always
grid-fitted when the glyph was hinted:
pen_x += metrics.advance;
The advance being grid-fitted, the pen position remains aligned on
the grid.
6. Start over on item 2 until string completion. That's it!
2. Writing right-to-left and vertical text
Generating strings for different layouts is very similar. Here are the
most important differences.
o For right-to-left text (like Arabic)
The main difference here is that, as the advance width and left
side bearings are oriented against the flow of text, the pen
position must be decremented by the advance width, before placing
and rendering the glyph. Other than that, the rest is strictly
similar.
o For vertical text (like Chinese or Japanese)
In this case, the baseline is vertical, which means that the pen
position must be shifted in the vertical direction. You need the
vertical glyph metrics to do that (using the
TT_Get_Big_Glyph_Metrics() function).
Once you get these, the rest of the process is very similar. The
glyph outline is placed relative to an imaginary origin of (0,0),
and you should translate it to the pen position before rendering
it.
The big difference is that you must decrement pen_y, rather than
increment pen_x (this is for the TrueType convention of y oriented
upwards).
pen_y -= metrics.advance;
3. Generating individual glyph bitmaps and using them to render text
Loading each glyph when rendering text is slow, and it's much more
efficient to render each one in a standalone bitmap to place it in a
cache. Text can then be rendered fast by applying simple blit
operations on the target device.
To be able to render text correctly with the bitmaps, you must record
and associate with them its fitted bearings and advances. Hence the
following process:
1. Generate the bitmaps.
+ Load the glyph and get its metrics.
TT_Load_Glyph( instance,
glyph,
glyph_index,
TTLOAD_DEFAULT );
TT_Get_Glyph_Metrics( glyph, &metrics );
The bbox is always fitted when calling TT_Get_Glyph_Metrics()
on a hinted glyph. You can then easily compute the glyph's
dimension in pixels as:
width = (bbox.xMax - bbox.xMin) / 64;
height = (bbox.yMax - bbox.yMin) / 64;
NOTE 1:
The fitted bounding box always contains all the dropouts that
may be produced by the scan-line converter. This width and
height are thus valid for all kinds of glyphs).
NOTE 2:
If you want to compute the dimensions of a rotated outline's
bitmap, compute its bounding box with TT_Get_Outline_BBox(),
then grid-fit the bbox manually:
#define FLOOR(x) ((x) & -64)
#define CEILING(x) (((x)+63) & -64)
xMin = FLOOR(xMin);
yMin = FLOOR(yMin);
yMin = CEILING(xMax);
yMax = CEILING(yMax);
then compute width and height as above.
+ Create a bitmap of the given dimension, e.g.:
bitmap.width = width;
bitmap.cols = (width+7) & -8;
bitmap.rows = height;
bitmap.flow = TT_Flow_Up;
bitmap.size = bitmap.cols * bitmap.rows;
bitmap.buffer = malloc( bitmap.size );
+ Render the glyph into the bitmap.
Don't forget to shift it by (-xMin, -yMin) to fit it in the
bitmap:
/* Note that the offsets must be grid-fitted to */
/* preserve hinting! */
TT_Get_Glyph_Bitmap( glyph,
&bitmap,
-bbox.xMin,
-bbox.yMin );
2. Store the bitmap with the following values:
bearingX / 64 = left side bearing in pixels
advance / 64 = advance width/height in pixels
When your cache is set up, you can then render text using a scheme
similar to the ones describe in 1. and 2., with the exception that
now pen positions and metrics are expressed in pixel values. We
are done!
pen_x = cursor_x;
pen_y = cursor_y;
while ( glyph_to_render )
{
access_cache( glyph_index, metrics, bitmap );
blit_bitmap_to_position
( pen_x + bearingX,
pen_y (+ bearingY depending on orientation ) );
pen_x += advance;
}
4. Device-independent text rendering
The previously described rendering processes all align glyphs on the
baseline according to metrics fitted for the display's distance. In
some cases, the display isn't the final output, and placing the glyphs
in a device-independent way is more important than anything.
A typical case is a word processor which displays text as it should
appear on paper when printed. As you've probably noticed, the glyphs
aren't always spaced uniformly on the screen as you type them,
sometimes the space between an `m' and a `t' is too small, some other
it is too large, etc.
These differences are simply due to the fact that the word processor
aligns glyphs in an device-independent way, using original metrics in
font units to do it, then scale them as it can to display text on
screen, usually at a very smaller resolution than your printer's one.
Device-independence is a crucial part of document portability, and it
is very saddening to see that most professional word processors don't
do it correctly. For example, MS Word uses the fitted metrics of the
printer's resolution, rather than the originals in font units.
This is great to get sure that your text prints very well on your
printer, but it also implies that someone printing the exact same
document on a device with different output resolutions (e.g. bubble-jet
vs. laser printers) may encounter trouble.
As the differences in advances accumulate on one line, they can sum to
the width of one or more glyphs in extreme cases, which is enough to
`overflow' the automatic justification algorithm. This may add
additional lines of printed text, or even remove some. Moreover,
supplemental lines can produce unexpected page breaks and `blank'
pages. This can be extremely painful when working with large documents,
as this `feature' may require you to redesign completely your
formatting to re-print it.
In conclusion, if you want portable document rendering, never hesitate
to use and apply device-independent terms! For example, a simple way to
produce text would be:
1. Get a scale to convert from your device-independent units to 26.6
pixels.
2. Get another scale to convert from original font units to
device-independent units.
3. Perform pen placement and advances in device-independent units.
4. To render each glyph, compute the pen's rounded position, as well
as the rounded glyph left side bearing, both expressed in 26.6
pixels (don't use the fitted metrics). You will then be able to
place the glyph and/or blit its bitmap.
5. Kerning glyphs
An interesting effect that most people appreciate is kerning. It
consists of modifying the spacing between two successive glyphs
according to their outlines. For example, the letters `T' and a `y' can
be easily moved closer, as the top of the `y' fits nicely under the
`T's upper right bar.
To perform kerning, the TrueType specification provides a specific
table (its tag being `kern'), with several storage formats. This
section doesn't explain how to access this information; however, you
can have a look at the standard extension called `ttkern.h' which comes
with FreeType.
The kerning distance between two glyphs is a value expressed in font
units which indicates whether their outline can be moved together or
apart when one follows the other. The distance isn't reflexive, which
means that the kerning for the glyph pair (`T',`y') isn't the same as
the one for (`y',`T').
The value is positive when the glyphs must be moved apart, and negative
when they must be moved closer. You can implement kerning simply by
adding its scaled and rounded value to the advance width when moving
the pen position. Here an example for horizontal kerning:
#define ROUND( x ) ( (x + 32) & -64 )
scaled_kerning = kerning * imetrics.x_scale / 0x10000;
pen_x += metrics.advance + ROUND( scaled_kerning );
6. Rotated and stretched/slanted text
In order to produce rotated glyphs with FreeType, one must understand a
few things:
o The engine doesn't apply specific transformations to the glyphs it
loads and processes (other than the simpler resolution-base
scaling and grid-fitting). If you want to rotate glyphs, you will
have to load their outline, then apply the geometric
transformations that please you (a number of APIs are there to
help you to do it easily).
o Even if the glyph loader hints `straight' glyphs, it is possible
to inform the font and glyph programs that you're going to later
transform the resulting outlines. Two flags can be passed to the
bytecode interpreter:
+ The `rotated' flag indicates that you are going to rotate the
glyphs in a non-trivial direction (i.e., on neither of the
two coordinate axis). You are advised not to set it when
writing 90 degrees-rotated text for example.
+ The `stretched' flag indicates that you are going to apply a
transformation that will distort distances. While rotations
and symmetries keep distances constant, slanting and
stretching do modify them.
These flags can be interpreted by the glyph code to toggle certain
processings which vary from one font to the other. However, most of the
TrueType fonts that were tested with FreeType, if not all of them,
simply change the dropout-mode when any of these flags is set, and/or
disable hinting when rotation is detected. We advise you to never set
these flags, even when rotating text. For what it's worth, hinted
rotated text is no uglier than un-hinted one.
You can use the function TT_Set_Instance_Transform_Flags() to set them.
Then, rendering can be done with the following calls:
/* set the flags */
TT_Set_Instance_Transforms( instance,
rotated,
stretched );
/* load a given glyph */
TT_Get_Glyph_Outline( instance,
glyph,
index,
TTLOAD_DEFAULT );
/* access its outline */
TT_Get_Glyph_Outline( instance, &outline );
/* in order to transform it */
TT_Transform_Outline( outline, &matrix );
/* and/or */
TT_Translate_Outline( outline,
x_offset, y_offset );
/* to render it */
TT_Get_Outline_Bitmap( outline, &bitmap );
Here is an example, assuming that the following variables
TT_Matrix matrix; /* 2x2 matrix */
TT_Pos x_off, y_off; /* corrective offsets */
define a transformation that can be correctly applied to a glyph
outline which have been previously placed relative to the imaginary
point position (0,0) with bearings preserved. Rendering text can now be
done as follows:
1. Initialize the pen position; when rotating, it is extremely well
advised to use sub-pixel placement as you don't care about
hinting.
pen_x = cursor_x;
pen_y = cursor_y;
2. Transform the glyph as needed, then translate it to the current
pen position:
TT_Transform_Outline( outline, &matrix );
TT_Translate_Outline( outline,
pen_x + x_off,
pen_y + y_off );
(Note that the transformation offsets have been included in the
translation.)
3. Render the bitmap, as it has now been placed correctly.
4. To change the pen position, transform the vector (0,advance) with
your matrix, and add it:
vec_x = metrics.advance;
vec_y = 0;
TT_Transform_Vector( &vec_x, &vec_y, &matrix );
pen_x += vec_x;
pen_y += vec_y;
5. Start over at 2. until completion.
-----------------------------------------------------------------------
IMPORTANT NOTE:
Do not grid-fit the pen position before rendering your glyph when
rendering rotated text. If you do, your transformed baseline won't be
preserved on each glyph, and the text will look like it's `hopping'
randomly. This is particularly visible at small sizes.
Sub-pixel precision placement is very important for clean rotated text.
-----------------------------------------------------------------------
7. Font-smoothing, a.k.a. gray-levels rendering
The FreeType engine's scan-line converter (the component also called
the rasterizer) is able to convert a vectorial glyph outline into
either a normal bitmap, or an 8-bit pixmap (a.k.a. colored bitmaps on
some systems). This last feature is called gray-level rendering or
font-smoothing, because it uses a user-supplied palette to produce
anti-aliased versions of the glyphs.
Its principle is to render a bitmap which is twice as large than the
target pixmap, then simply filtering it using a 2x2 summation.
-----------------------------------------------------------------------
NOTE:
FreeType's scan-line converter doesn't use or need an intermediate
second bitmap. Rather, filtering is performed in a single pass during
the sweep (see the file `raster.txt' for more information about it).
-----------------------------------------------------------------------
You'll notice that, as with Windows 95, FreeType's rasterizer only
grays those parts of the glyph which need it, i.e., diagonals and
curves, while keeping horizontal and vertical stems straight `black'.
This greatly improves the legibility of text, while avoiding the
`blurry' look anti-aliased fonts typically found with Adobe's Type
Manager or Acrobat.
There are thus five available gray-levels, ranging from 0 to 4, where
level 0 and level 4 are the background and foreground colors,
respectively, and where levels 1, 2, 3 are intermediate. For example,
to render black text on a white background, one can use a palette like:
palette[0] = white (background)
palette[1] = light gray
palette[2] = medium gray
palette[3] = dark gray
palette[4] = black (foreground)
To set the engine's gray-level palette, simply use the API function
TT_Set_Raster_Palette() after initialization. It expects an array of
5 chars which will be used to render the pixmaps.
Note that the rasterizer doesn't create bitmaps or pixmaps. Rather, it
simply renders glyphs in the arrays you pass to it. The generated glyph
bitmaps are simply `or'-ed to the target (with 0 being the background
as a convention); in the case of pixmaps, pixels are simply written to
the buffer, in spans of four aligned bytes.
-----------------------------------------------------------------------
NOTE:
The raster isn't able to superpose `transparent' glyphs on the target
pixmap. This means that you should always call the API functions
TT_Get_Glyph_Pixmap() and TT_Get_Outline_Pixmap() with an empty map,
and perform the superposition yourself.
This can be more or less tricky, depending on the palette you are using
and your target graphics resolution. One of the components found in the
test directory, called `display.c', has large comments on the way it
implements it for the test programs. You are encouraged to read the
test program sources to understand how one can take advantage of font
smoothing.
Pixmap surimposition is too system-specific a feature to be part of the
FreeType engine. Moreover, not everybody needs it!
-----------------------------------------------------------------------
Finally, the question of sur-imposing anti-aliased colored text on any
texture, since being even more tricky, is left as an exercise to the
reader ;-) If this topic really interests you, the FreeType mailing
list may host some helpful enthusiasts ready to answer your questions.
Who knows :-)
8. Other interesting text processes
o Glyph substitution
Substitution is used to replace one glyph by another when some
specific condition is met in the text string. Its most common
examples are ligatures (like replacing the `f' followed by `i' by
the single glyph `fi' if available in the font), as well as
positional selection as performed in the Arabic script (for those
not aware of this, each letter of the Arabic alphabet can be
written differently according to its position on words: starting,
ending, intermediate, or isolated).
The base TrueType format doesn't define any table for glyph
substitution. However, GX, TrueType Open, and OpenType provide
(incompatible) extensions to perform it. Of course, it isn't
supported by the engine, but an extension could be easily written
to access the required tables.
[Support for TrueType Open is already partially available.]
o Justification
...
To be continued...

161
docs/i18n.txt Normal file
View File

@@ -0,0 +1,161 @@
Using national language support (NLS) in FreeType
=================================================
21. 1. 1998
Erwin Dieterich
1) Introduction
2) Using gettext (user's view)
3) Using gettext (programmer's view)
4) Using gettext (maintainer's view)
5) How can I switch off NLS? I don't need/want it.
Only Unix NLS using gettext() is covered here. If you are able to
help with internationalization (i18n) for different operating
systems, please e-mail me at Erwin.Dieterich.ED@Bayer-AG.de.
1) Introduction
If a program is to be used by people who are not fluent speakers of
English, the first thing they will ask for is communication in their
native language. If someone tries to implement NLS in a program
using only #ifdefs and other such programming strategies, it's
likely that this someone will get nowhere.
Gettext() is a possible way to help. Only minimal extra programming
effort is needed; the translations are implemented separately from
the program, and it is not necessary to recompile a program if you
want to switch the messages to a different language. If you wouldd
like to know more about gettext(), I recommend reading the GNU
gettext tools manual, written by Ulrich Drepper, Jim Meyering, and
Francois Pinard.
Currently supported languages are:
Czech (cz) translator: Pavel Kankovsky
<peak@kerberos.troja.mff.cuni.cz>
Dutch (nl) translator: Gertjan de Back <gertjan.de.back@pi.net>
French (fr) translator: David Turner <david.turner@freetype.org>
German (de) translator: Erwin Dieterich
<erwin.dieterich.ed@bayer-ag.de>
Spain (es) translator: Miguel A. Perez Valdenebro
<map@fujitsu.es>
Currently supported programs in the `test' directory are:
ftlint
ftdump
fterror
ftmetric
ftsbit
2) Using gettext (user's view)
Using gettext as an end user is very simple. If FreeType is
correctly installed on your computer, you can simply issue an
`export LANG=<language id>' in your Bourne shell or `setenv
LANG=<language id>' if you are using csh. That's all. In order to
switch back to English, just use `export LANG=' or `setenv LANG='.
<language id> is a two character code describing your language:
de=German, fr=French etc. Every supported language has its own
<language id>.po file in the `po' directory of FreeType. If your
language is not there you should consider contributing a
translation. Just e-mail me. Here is a transcript of what `export
LANG=<language id>' does:
test> ftlint 24 furiosot.ttf
Could not find or open furiosot.ttf.
FreeType error message: OS/2 table missing.
test> export LANG=de
test> ftlint 24 furiosot.ttf
Datei `furiosot.ttf' konnte nicht gefunden oder ge<67>ffnet werden.
FreeType Fehlermeldung: `OS/2'-Tabelle fehlt.
test> export LANG=
test> ftlint 24 furiosot.ttf
Could not find or open file furioso.ttf.
FreeType error message: OS/2 table missing.
Doesn't this look good? But what if nothing happens if you set
LANG? Here are some hints:
First: Is your language really supported? If it is, you need to be
sure that you have gettext() installed (if you are sitting at a
Linux box, chances are very good that you have). If you compiled
FreeType yourself and nothing strange happened, then your version of
FreeType has NLS compiled in, as this is the default, unless you
forgot to install the translation files in the right places (`make
install' in the po/ directory should be enough, but you need root
permissions as these files are installed somewhere in /usr/local) --
good luck :-)
3) Using gettext (programmer's view)
If you intend to use NLS in your program, you just need to make a
few simple changes. Here I only describe how NLS is enabled in the
programs that come with FreeType in test/. If you would like to add
NLS to other programs using FreeType as well, take a look at
FreeType's installation files; you can probably use these files as a
model.
Every string that should be translated needs gettext() around it.
So
Message( "Usage: %s fontname[.ttf|.ttc]\n\n",
execname );
becomes
Message( gettext( "Usage: %s fontname[.ttf|.ttc]\n\n" ),
execname );
Yes, it's that simple. Next you need to initialize gettext. Put
the following in the header section of your file:
#include "ft_conf.h"
#ifdef HAVE_LIBINTL_H
#include <libintl.h>
#endif
#ifndef HAVE_LIBINTL_H
#define gettext( x ) ( x )
#endif
and this at the very beginning of your main program:
#ifdef HAVE_LIBINTL_H
setlocale(LC_ALL, "");
bindtextdomain( "freetype", LOCALEDIR );
textdomain( "freetype" );
#endif
That's all. Just have a look at fterror.c in test/.
4) Using gettext (maintainer's view)
I am too lazy today :-) If something isn't clear, just ask me.
5) How can I switch off NLS? I don't need/want it.
Just say `configure --disable-nls' and recompile FreeType.
If you have any questions or comments regarding this short
introduction to NLS & FreeType, feel free to email me at
Erwin.Dieterich.ED@Bayer-AG.de.
--- end of i18n.txt ---

BIN
docs/image/baselin2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
docs/image/baseline.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
docs/image/emsquare.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
docs/image/freetype.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
docs/image/freetype.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
docs/image/grid1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
docs/image/grid2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
docs/image/grid3.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
docs/image/metrics.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
docs/image/metrics2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
docs/image/small2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
docs/image/tfp-back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

158
docs/optimize.txt Normal file
View File

@@ -0,0 +1,158 @@
FreeType Optimization HOWTO
Introduction
============
This file describes several ways to improve the performance of the
FreeType engine on specific builds. Each `trick' has some
drawbacks, be it on code size or portability.
The performance improvement cannot be quantified here simply
because id depends significantly on platforms _and_ compilers.
I. Tweaking the configuration file
==================================
The FreeType configuration file is named `ft_conf.h' and contains
the definition of various macros that are used to configure the
engine at build time.
Apart from the Unix configuration file, which is generated when
calling the `configure' script from the template called
freetype/ft_conf.h.in ,
all configuration files are located in
freetype/lib/arch/<system>/ft_conf.h ,
where <system> stands for your platform. This release also
provides an `ansi' build, i.e., the directory `lib/arch/ansi' used
to compile with any ANSI-compliant compiler.
The configuration macros that relate to performance are described
next.
1. TT_CONFIG_OPTION_INTERPRETER_SWITCH
--------------------------------------
If set, this macro builds a bytecode interpreter which uses a
huge `switch' statement to parse the bytecode stream during
glyph hinting.
If unset, the interpreter uses a big jump table to call each
bytecode's routine.
This macro is *set* by default. However, it may be worthwile on
some platforms to unset it.
Note that this macro is ignored if
TT_CONFIG_OPTION_NO_INTERPRETER is set.
2. TT_CONFIG_OPTION_STATIC_INTERPRETER
--------------------------------------
If set, this macro builds a bytecode interpreter which uses a
static variable to store its state. On some processors, this
will produce code which is bigger but slightly faster.
Note that you should NOT DEFINE this macro when building a
thread-safe version of the engine.
This macro is *unset* by default.
3. TT_CONFIG_OPTION_STATIC_RASTER
---------------------------------
If set, this macro builds a scan-line converter which uses a
static variable to store its state. On some processors, though
depending on the compiler used, this will produce code which is
bigger but moderately faster.
Note that you should NOT DEFINE this macro when building a
thread-safe version of the engine.
This macro is *unset* by default. We do not recommend using it
except for extreme cases where a performance `edge' is needed.
II. Replacing some components with optimized versions
=====================================================
You can also, in order to improve performance, replace one or more
components from the original source files. Here are our
suggestions.
1. Use memory-mapped files whenever available
---------------------------------------------
Loading a glyph from a TrueType file needs many random seeks,
which take a lot of time when using disk-based files.
Whenever possible, use memory-mappings to improve load
performance dramatically. For an example, see the source file
freetype/lib/arch/unix/ttmmap.c
which uses Unix memory-mapped files.
2. Replace the computation routines in `ttcalc.c'
---------------------------------------------------
This file contains many computation routines that can easily be
replaced by inline-assembly, tailored for a specific processor
and/or compiler.
After heavy testing, we have found that these functions,
especially TT_MulDiv(), are the ones that are most extensively
used and called when loading glyphs from a font file.
We do not provide inline-assembly with this release, as we want
to emphasize the portability of our library. However, when
working on a specific project where the hardware is known to be
fixed (like on an embedded system), great performance gains
could be achieved by replacing these routines.
(By the way, the square root function is not optimal, but it is
very seldom called. However, its accuracy is _critical_.
Replacing it with a fast but inaccurate algorithm will ruin the
rendering of glyphs at small sizes.)
III. Measuring performance improvements
=======================================
Once you have chosen some improvements and rebuilt the library,
some quick ways to measure the `new' speed are:
- Run the test program `ftlint' on a directory containing many
TrueType fonts, and measure the time it takes. On Unix, you can
use the shell command `time' to do it like in
% time test/ftlint 10 /ttfonts/*.ttf
This will measure the performance improvement of the TrueType
interpreter.
- Run the test program `fttimer' on a font containing many complex
glyphs (the latest available versions of Times or Arial should
do it), probaby using anti-aliasing, as in:
% time test/fttimer -g /ttfonts/arial.ttf
Compare the results of several of these runs for each build.
--- end of OPTIMIZE ---

1078
docs/porting.txt Normal file

File diff suppressed because it is too large Load Diff

577
docs/raster.txt Normal file
View File

@@ -0,0 +1,577 @@
This file is an attempt at explaining the internals of the FreeType
rasterizer. This component is quite general purpose and could
easily be integrated into other programs (but still under the
current license).
--------------------------------------------------------------------
The HOWs and WHYs of the FreeType rasterizer
by David Turner
I. Introduction
II. Rendering Technology
III. Implementation Details
IV. Gray-Level Support
I. Introduction
===============
A rasterizer is a library in charge of converting a vectorial
representation of a shape into a bitmap. The FreeType rasterizer
has been developed to render the glyphs found in TrueType files,
made up of segments and second-order Beziers. This document is an
explanation of its design and implementation.
Though these explanations start from the basics, a knowledge of
common rasterization techniques is assumed.
--------------------------------------------------------------------
II. Rendering Technology
========================
1. Requirements
---------------
We will assume that all scaling/rotating/hinting/whatever has been
already done. The glyph is thus described, as in the TrueType
specification, by a list of points. Each point has an x and y
coordinate, as well as a flag that indicates whether the point is
_on_ or _off_ the curve.
More precisely:
- All point coordinates are in the 26.6 fixed float format as
defined by the specification. The orientation used is:
^ y
| reference orientation
|
*----> x
0
This means that the `distance' between two neighbouring pixels
is 64 `units' (1 unit = 1/64th of a pixel).
Note that, for the rasterizer, pixel centers are located at
integer coordinates, i.e., (0.0, 0.0) is the coordinate of the
origin's center (unlike what happens within the TrueType
bytecode interpreter where this point's center lies at (0.5,
0.5)).
A pixel line in the target bitmap is called a `scanline'.
- A glyph is usually made of several contours, also called
outlines. A contour is simply a closed curve that delimits an
outer or inner region of the glyph. It is described by a series
of successive points of the points table.
Each point of the glyph has an associated flag that indicates
whether it is `on' or `off' the curve. Two successive `on'
points indicate a line segment joining the two points.
One `off' point amidst two `on' points indicates a second degree
Bezier parametric arc, defined by these three points (the `off'
point being the control point, and the `on' ones the start and
end points).
Finally, two successive `off' points forces the rasterizer to
create, during rendering, an `on' point amidst them, at their
exact middle. This greatly facilitates the definition of
successive Bezier arcs.
* # on curve
* off curve
__---__
#-__ _-- -_
--__ _- -
--__ # \
--__ #
-#
Two `on' points
Two `on' points and one `off' point
between them
*
# __ Two `on' points with two `off'
\ - - points between them. The point
\ / \ marked `0' is the middle of the
- 0 \ `off' points, and is a `virtual
-_ _- # on' point where the curve passes.
-- It does not appear in the point
* list.
The FreeType rasterizer, as intended to render TrueType glyphs,
does not support third order Beziers, usually found in Type 1
fonts. Type 1 support may lead to further development of the
engine (it is already part of FreeType 2.0).
The parametric form of a second-order Bezier is:
P(t) = (1-t)^2*P1 + 2*t*(1-t)*P2 + t^2*P3
with t a real number in the range [0..1]
P1 and P3 are the endpoints, P2 the control point.
Note that the rasterizer does not use this formula. It exhibits,
however, one very useful property of Bezier arcs: Each point of
the curve is a weighted average of the control points.
As all weights are positive and always sum up to 1, whatever the
value of t, each arc point lies within the triangle defined by the
arc's three control points.
2. Profiles and Spans
---------------------
The following is a basic explanation of the _kind_ of computations
made by the rasterizer to build a bitmap from a vector
representation. Note that the actual implementation is slightly
different, due to performance tuning and other factors.
However, the following ideas remain in the same category, and are
more convenient to understand.
a. Sweeping the shape
The best way to fill a shape is to decompose it into a number of
simple horizontal segments, then turn them on in the target
bitmap. These segments are called `spans'.
__---__
_-- -_
_- -
- \
/ \
/ \
| \
__---__ Example: filling a shape
_----------_ with spans.
_--------------
----------------\
/-----------------\ This is typically done from the top
/ \ to the bottom of the shape, in a
| | \ movement called a `sweep".
V
__---__
_----------_
_--------------
----------------\
/-----------------\
/-------------------\
|---------------------\
In order to draw a span, the rasterizer must compute its
coordinates, which are simply the shape's contours'
x-coordinates taken on the y-scanlines.
/---/ |---| Note that there are usually
/---/ |---| several spans per scanline.
| /---/ |---|
| /---/_______|---| When rendering this shape to the
V /----------------| current scanline y, we must
/-----------------| compute the x values of the
a /----| |---| points a, b, c, and d.
- - - * * - - - - * * - - y -
/ / b c| |d
/---/ |---|
/---/ |---| And then turn on the spans a-b
/---/ |---| and c-d.
/---/_______|---|
/----------------|
/-----------------|
a /----| |---|
- - - ####### - - - - ##### - - y -
/ / b c| |d
b. Decomposing outlines into profiles
For each scanline during the sweep, we need the following
information:
o The number of spans on the current scanline, given by the
number of shape points intersecting the scanline (these are
the points a, b, c, and d in the above example).
o The x coordinates of these points.
These are computed before the sweep, in a phase called
`decomposition' which converts the glyph into *profiles*.
Put it simply, a `profile' is a contour's portion that can only
be either ascending or descending, i.e., it is monotonic in the
vertical direction (we will also say y-monotonic). There is no
such thing as a horizontal profile, as we shall see.
Here are a few examples:
this square
1 2
---->---- is made of two
| | | |
| | profiles | |
^ v ^ + v
| | | |
| | | |
----<----
up down
this triangle
P2 1 2
|\ is made of two | \
^ | \ \ | \
| | \ \ profiles | \ |
| | \ v ^ | \ |
| \ | | + \ v
| \ | | \
P1 ---___ \ ---___ \
---_\ ---_ \
<--__ P3 up down
A more general contour can be made of more than two profiles:
__ ^
/ | / ___ / |
/ | / | / | / |
| | / / => | v / /
| | | | | | ^ |
^ | |___| | | ^ + | + | + v
| | | v | |
| | | up |
|___________| | down |
<-- up down
Successive profiles are always joined by horizontal segments
that are not part of the profiles themselves.
Note that for the rasterizer, a profile is simply an *array*
that associates one horizontal *pixel* coordinate to each bitmap
*scanline* crossed by the contour's section containing the
profile. Note also that profiles are *oriented* up or down
along the glyph's original flow orientation.
In other graphics libraries, profiles are also called `edges' or
`edgelists'.
c. The Render Pool
FreeType has been designed to be able to run well on _very_
light systems, including embedded systems with very few memory.
A render pool will be allocated once; the rasterizer uses this
pool for all its needs by managing this memory directly in it.
The algorithms that are used for profile computation make it
possible to use the pool as a simple growing heap. This means
that this memory management is actually easy, and faster than
any kind of malloc()/free() combination.
Moreover, we'll see later that the rasterizer is able, when
dealing with profiles too large and numerous to lie all at once
in the render pool, to immediately decompose recursively the
rendering process into independent sub-tasks, each taking less
memory to be performed (see `sub-banding' below).
The render pool doesn't need to be large. A 4kByte pool is
enough for nearly all renditions, though nearly 100% slower than
a more confortable 16 or 32kByte pool (that was tested with
complex glyphs at sizes over 500 pixels).
d. Computing Profiles Extents
Remember that a profile is an array, associating a _scanline_ to
the x pixel coordinate of its intersection with a contour.
Though it's not exactly how the FreeType rasterizer works, it is
convenient to think that we need a profile's height before
allocating it in the pool and computing its coordinates.
The profile's height is the number of scanlines crossed by the
y-monotonic section of a contour. We thus need to compute these
sections from the vectorial description. In order to do that,
we are obliged to compute all (local and global) y-extrema of
the glyph (minima and maxima).
P2 For instance, this triangle has only
two y-extrema, which are simply
|\
| \ P2.y as an y-maximum
| \ P3.y as an y-minimum
| \
| \ P1.y is not an y-extremum (though it is
| \ a x-minimum, which we don't need).
P1 ---___ \
---_\
P3
Note that the extrema are expressed in pixel units, not in
scanlines. The triangle's height is certainly (P3.y-P2.y+1)
pixel units, but its profiles' heights are computed in
scanlines. The exact conversion is simply:
- min scanline = FLOOR ( min y )
- max scanline = CEILING( max y )
A problem arises with Bezier Arcs. While a segment is always
necessarily y-monotonic (i.e., flat, ascending, or descending),
which makes extrema computations easy, the ascent of an arc can
vary between its control points.
P2
*
# on curve
* off curve
__-x--_
_-- -_
P1 _- - A non y-monotonic Bezier arc.
# \
- The arc goes from P1 to P3.
\
\ P3
#
We first need to be able to easily detect non-monotonic arcs,
according to their control points. I will state here, without
proof, that the monotony condition can be expressed as:
P1.y <= P2.y <= P3.y for an ever-ascending arc
P1.y >= P2.y >= P3.y for an ever-descending arc
with the special case of
P1.y = P2.y = P3.y where the arc is said to be `flat'.
As you can see, these conditions can be very easily tested.
They are, however, extremely important, as any arc that does not
satisfy them necessarily contains an extremum.
Note also that a monotonic arc can contain an extremum too,
which is then one of its `on' points:
P1 P2
#---__ * P1P2P3 is ever-descending, but P1
-_ is an y-extremum.
-
---_ \
-> \
\ P3
#
Let's go back to our previous example:
P2
*
# on curve
* off curve
__-x--_
_-- -_
P1 _- - A non-y-monotonic Bezier arc.
# \
- Here we have
\ P2.y >= P1.y &&
\ P3 P2.y >= P3.y (!)
#
We need to compute the y-maximum of this arc to be able to
compute a profile's height (the point marked by an `x'). The
arc's equation indicates that a direct computation is possible,
but we'll rely on a different technique, which use will become
apparent a bit later.
Bezier arcs have the special property of being very easily
decomposed into two other sub-arcs, which are themselves Beziers
arcs. Moreover, it is easy to prove that there is at most one
y-extremum on each Bezier arc (for second degree ones).
For instance, the following arc P1P2P3 can be decomposed into
two sub-arcs Q1Q2Q3 and R1R2R3 that look like:
P2
*
# on curve
* off curve
Original Bezier Arc P1P2P3.
__---__
_-- --_
_- -_
- -
/ \
/ \
# #
P1 P3
P2
*
Q3 Decomposed into two subarcs
Q2 R2 Q1Q2Q3 and R1R2R3
* __-#-__ *
_-- --_
_- R1 -_ Q1 = P1 R3 = P3
- - Q2 = (P1+P2)/2 R2 = (P2+P3)/2
/ \
/ \ Q3 = R1 = (Q2+R2)/2
# #
Q1 R3 Note that Q2, R2, and Q3=R1
are on a single line which is
tangent to the curve.
We have then decomposed a non-y-monotonic bezier into two
smaller sub-arcs. Note that in the above drawing, both sub-arcs
are monotonic, and that the extremum is then Q3=R1. However, in
a more general case, only one sub-arc is guaranteed to be
monotonic. Getting back to our former example:
Q2
*
__-x--_ R1
_-- #_
Q1 _- Q3 - R2
# \ *
-
\
\ R3
#
Here, we see that, though Q1Q2Q3 is still non-monotonic, R1R2R3
is ever descending: we thus know that it doesn't contain the
extremum. We can then re-subdivide Q1Q2Q3 into two sub-arcs and
go on recursively, stopping when we encounter two monotonic
subarcs, or when the subarcs become simply too small.
We will finally find the y-extremum. Note that the iterative
process of finding an extremum is called `flattening'.
e. Computing Profiles coordinates
Once we have the height of each profile, we are able to allocate
it in the render pool. We now have to compute its coordinate
for each scanline.
In the case of segments, the computation is straightforward, and
uses good old Euclide (also known as Bresenham ;-). However,
for Bezier arcs, things get a little more complicated.
We assume that all Beziers that are part of a profile are the
result of `flattening' the curve, which means that they are all
y-monotonic (ascending or descending, and never flat). We now
have to compute the arcs' intersections with the profile's
scanlines. One way is to use a similar scheme to `flattening',
called `stepping'.
Consider this arc, going from P1 to
--------------------- P3. Suppose that we need to
compute its intersections with the
drawn scanlines. Again, this is
--------------------- feasible directly, if we dare
to compute one square root per
* P2 _---# P3 scanline (how great!).
------------- _-- --
_-
_/ Rather, it is still possible to use
---------/----------- the decomposition property in the
/ same recursive way, i.e. subdivide
| the arc into subarcs until these
------|-------------- get too small to cross more than
| one scanline!
|
-----|--------------- This is very easily done using a
| rasterizer-managed stack of
| subarcs.
# P1
f. Sweeping and Sorting the spans
Once all our profiles have been computed, we begin the sweep to
build (and fill) the spans.
As the TrueType specification uses the winding fill rule, we
place on each scanline the profiles present in two separate
lists.
One list, called the `left' one, only contains ascending
profiles, while the other `right' list contains the descending
profiles.
As each glyph is made of closed curves, a simple geometric
property is that the two lists necessarily contain the same
number of elements.
Creating spans is there straightforward:
1. We sort each list in increasing x order.
2. We pair each value of the left list, with its corresponding
value in the right one.
/ / | | For example, we have here
/ / | | four profiles. Two of
>/ / | | | them are ascending (1 &
1// / ^ | | | 2 3), while the two others
// // 3| | | v are descending (2 & 4).
/ //4 | | | On the given scanline,
a / /< | | the left list is (1,3),
- - - *-----* - - - - *---* - - y - and the right one is
/ / b c| |d (4,2) (sorted).
There are then two spans, joining
1 to 4 (i.e. a-b) and 3 to 2
(i.e. c-d)!
Sorting doesn't necessarily take much time, as in 99 cases out
of 100, the lists' order is kept from one scanline to the next.
We can thus implement it with two simple singly-linked lists,
sorted by a classic bubble-sort, which takes a minimum amount of
time when the lists are already sorted.
A previous version of the rasterizer used more elaborate
structures, like arrays to perform `faster' sorting. It turned
out that this old scheme is not faster than the one described
above.
Once the spans have been `created', we can simply draw them in
the target bitmap.
g. Drop-out control
To be continued.
--- end of raster.txt ---

106
docs/readme.txt Normal file
View File

@@ -0,0 +1,106 @@
Welcome to the documentation directory of FreeType.
Here are short overview where you can find which information.
apiref.txt FreeType high-level API reference. All the types,
functions, and error codes of FreeType.
..................................................................
apirefx.txt The API reference of FreeType extensions which come
with the library itself.
..................................................................
bitmaps.txt How to render a glyph outline into a bitmap.
..................................................................
changes.txt Guess what :-)
..................................................................
convntns.txt The FreeType developer's conventions guide. Lists
the design and coding conventions used in the
engine's source code. This file is incomplete but
contains information that should be read by any
person willing to hack the FreeType code.
..................................................................
credits A list of persons who have contributed to FreeType.
..................................................................
glyphs.htm An introduction to glyphs in general, its usage in
glyphs.txt TrueType, and how FreeType handles them. The file
`glyphs.txt' is a simple text dump (done with
Netscape) of glyphs.htm.
..................................................................
i18n.txt A short introduction to the GNU gettext package.
..................................................................
porting.txt The FreeType porting guide. All you need to
configure and adapt very easily FreeType's source
code to tailor it to your own platform.
Learn how to provide your own memory, i/o, and mutex
components, optimally fitted to your system. See
how you can build a singly-threaded, thread-safe, or
re-entrant version of the engine from the same
source code!
..................................................................
raster.txt The scan-line converter's internals explained. The
document is still incomplete but presents many key
concepts.
..................................................................
threads.txt How to use threads with FreeType.
..................................................................
user.txt FreeType's user guide. A guide to FreeType's
concepts, a step by step example, and a note about
future works and projects.
..................................................................
FAQ The new up-to-date FreeType FAQ. Look here first if
you have problems with the library.
..................................................................
TODO Things which probably will come, which would be nice
to have, problems still here, etc.
These documents will probably come later.
develop.txt The FreeType developer's guide. All you need to know
in order to be able to understand and even hack the
engine's core source code.
extend.txt The FreeType extension writer's how-to. All you need
to be able to provide new extensions to the engine.
undoc.txt Undocumented TrueType!
Yes, ladies and gentlemen, the TrueType
specification is fuzzy and misleading enough to
disband some serious commercial developers, but that
wasn't enough for us. Even though it took some time
(aaargh...), we finally discovered through hard work
the real meanings of the specs, fixed some errors
and even found surprising undocumented behaviour or
features!
--- end of readme.txt ---

117
docs/threads.txt Normal file
View File

@@ -0,0 +1,117 @@
Threads with FreeType
=====================
The FreeType engine can now be compiled in thread-safe mode.
Because we want to keep the engine small and fast, the thread
protection is simple. This file gives an overview of what you can
do, and what you should strictly never do.
How to enable thread-safe support?
A. You must have a valid replacement for the file `lib/ttmutex.c'
which calls your system's API to create, lock, and release
mutexes or semaphores. The current implementation is a dummy and
doesn't do anything.
B. You must re-define the configuration macro
TT_CONFIG_OPTION_THREAD_SAFE located in `ttconfig.h'. Then
recompile.
IMPORTANT NOTE:
If two threads create and use their own TT_Engine structure, they
can freely call the library concurrently on each of them (as well
as all their related objects), even in the non-threaded build.
The following remarks only apply to concurrent requests performed
on a single TT_Engine shared by multiple threads.
--------------------------------------------------------------------
- What you can do:
With the exceptions listed below (in `What you can't do'), you can
call all API functions concurrently with two different threads.
This includes:
Creating two or more faces from the same engine (i.e. concurrent
calls to TT_Open_Face()/TT_Open_Collection()).
Creating two or more instances from the same face object
(i.e. concurrent calls to TT_New_Instance()).
Creating two or more glyph containers from the same face object
(i.e. concurrent calls to TT_New_Glyph()).
The same holds for destruction of objects.
Load two or more glyphs concurrently for the same face or
instance (i.e. concurrent TT_Load_Glyph() calls).
Render two or more glyphs at the same time, in the same engine
(i.e. calling TT_Get_Glyph_Bitmap()/TT_Get_Glyph_Pixmap() or
TT_Get_Outline_Bitmap()/TT_GetOutline_Pixmap() concurrently).
NOTE: The scan-line converter can only render one glyph at a
time, for a given TT_Engine. Concurrent calls are
synchronized through a mutex, though.
If you really, _really_, need to generate bitmaps or
pixmaps concurrently, create an additional engine and use
it with TT_Get_Outline_Bitmap()/TT_Get_Outline_Pixmap()
(you don't need to create any object in it, the outline
can come from any source too).
This is, however, not recommended (it works perfectly, but
this could change in the future for various technical
reasons).
---------------------------------------------------------------------------
- What you cannot do:
- You shouldn't try to delete an object while still using it with
another thread. The engine doesn't protect you from stupidity!
For example, these concurrent calls:
TT_Close_Face( face );
TT_Get_Glyph_Bitmap( glyph, &bitmap );
will act unexpectedly if the glyph is a child of the face (i.e.,
was created with TT_New_Glyph( face, &glyph ))
^^^^
same face
Here are some other examples:
TT_Get_Glyph_Outline( glyph1, ... );
TT_Load_Glyph( instance, glyph1, ... );
or
TT_Get_Outline_BBox( outline, &bbox );
TT_Transform_Outline( outline );
etc.
You get the idea: Only the face and instances are protected --
glyph containers and outlines should be thread-specific.
- You shouldn't initialize extensions in an engine concurrently
(which is what every mere mortal will do anyway :-).
That's about it. Now enjoy the lib ;-)
PS: See the `MT-Note' and `MT-Safe' remarks in ttapi.c for more
detailed information on each specific function.
--- end of threads.txt ---

916
docs/user.txt Normal file
View File

@@ -0,0 +1,916 @@
The FreeType Engine
Core Library User Guide
or
How to use the engine in your applications and font servers
---------------------------------------------------
Introduction
I. Basic Concepts
1. Concepts
2. Handles
3. Conventions of use
4. Object classes
II. Extensions
1. What is an extension?
2. Where to find them
3. Writing your own extension
Conclusion
--------------------------------------------------------------------
Introduction
============
This file has been written to present the FreeType core library to
would-be writers of applications and font servers. It first
describes the concepts on which the engine is based, then how to
use it to obtain glyph metrics, outlines and bitmaps.
The last part discusses the ability to add and use extensions to
the core library to get access to supplemental TrueType tables
which are not currently provided by the core engine. If you would
like to write your own extensions, read also the FreeType
developer's guide.
I. Basic Concepts
=================
1. Concepts
-----------
FreeType defines several kinds of structures called `objects',
that are used to manage the various abstractions required to
access and display fonts.
In care of good encapsulation, these objects are not directly
accessible from a client application. Rather, the user receives
a `handle' for each object he or she queries and wants to use.
This handle is a stand-alone reference; it cannot be used like a
pointer to access directly the object's data.
2. Properties
-------------
It is however possible to obtain and set object properties
through several functions of the API. For example, you can
query a face object's properties with only a handle for it,
using the function TT_Get_Face_Properties().
Note that the data will be returned in a user-allocated
structure, but will also contain pointers addressing directly
some data found within the object.
A client application should never modify the data through these
pointers! In order to set new properties' values, the user must
always call a specific API function to do so, as a certain
number of other related data might not appear in the returned
structure and imply various non-visible coherency and coercion
rules.
3. Conventions of use
---------------------
o All API functions have their label prefixed by `TT_', as well
as all external (i.e. client-side) types.
o To allow the use of FreeType's core engine in threaded
environments, nearly all API functions return an error code,
which is always set to 0 in case of success.
The error codes' type is `TT_Error', and a listing of them is
given in the API references (see `apiref.txt' and
`apirefx.txt').
Some functions do not return an error code. Their result is
usually a value that becomes negative in case of error (this
is used for functions where only one kind of error can be
reported, like an invalid glyph index).
An important note is that the engine should not leak memory
when returning an error, e.g., querying the creation of an
object will allocate several internal tables that will be
freed if a disk error occurs during a load.
o A handle is acquired through API functions labeled along the
names:
TT_Open_xxxx(), TT_New_xxxx()
where `xxxx' is the object's class (Face, Instance, etc).
Examples:
TT_Open_Face(), TT_Open_Collection(),
TT_New_Instance(), TT_New_Glyph()
o A handle is closed through an API labeled
TT_Close_xxxx() or TT_Done_xxxx()
where `xxxx' is the object's class (Face, Instance, etc).
Examples:
TT_Close_Face(), TT_Done_Instance(), TT_Done_Glyph()
o Properties are obtained through an API labeled
TT_Get_xxxx_yyyy()
where `xxxx' is the object's class, and `yyyy' its property.
Examples:
TT_Get_Face_Properties(), TT_Get_Instance_Metrics()
TT_Get_Glyph_Outline(), TT_Get_Glyph_Bitmap()
o Properties are set through an API labeled
TT_Set_xxxx_yyyy()
where `xxxx' is the object's class, and `yyyy' its property.
Examples:
TT_Set_Instance_Resolutions(),
TT_Set_Instance_CharSize()
4. Object Classes
-----------------
The following object classes are defined in this release of the
engine:
o The Engine objects
The FreeType library can be built to be completely re-entrant,
even though its default build doesn't support threads (more on
this in the `threads.txt').
As a consequence, it is possible to open several instances of
the library, called `engines'. Each engine has its own set of
current objects (faces, instances, etc.), and there is no
sharing between them.
The idea is that the library could be compiled as a shared
library or DLL, and then be able to provide several distinct
engines to independent client applications. In this case,
each client program must create its own engine with
TT_Init_FreeType() to hold its data.
Closing an engine will destroy _all_ objects that were
allocated since its opening, releasing all resources, etc.,
with the exception of user-allocated outline objects.
o The Face objects
A face contains the data that is specific to a single TrueType
font file. It presents information common to all glyphs and
all point sizes like font-specific metrics and properties.
You can open a face object by simply giving a pathname to the
TrueType file. You can later close (i.e. discard) the face
object.
You can also open a single face embedded in a TrueType
collection.
See also:
TT_Open_Face(), TT_Open_Collection(), TT_Close_Face(),
TT_Get_face_Properties()
o The Instance objects
An instance is also called a `pointsize' or a `fontsize' in
some windowing systems. An instance holds the information
used to render glyphs on a specific device at a given point
size; it is always related to an opened face object.
For instance, if you want to generate glyphs for text from the
same typeface at `sizes' of 10 and 12 points, all you need is
one face object, from which you will create two distinct
instances.
A device is defined by its horizontal and vertical resolution,
usually specified in dots per inch (dpi). A point size is a
scaling number, given as _absolute_ values in points, where 1
point = 1/72 inch.
The `pixel' size, also known as the `ppem' value (for Points
Per EM square) is computed from both the device resolution and
the point size. It determines the size of the resulting glyph
bitmaps on your screen or sheet of paper.
The default device resolution for any new instance is 96dpi in
both directions, which corresponds to VGA screens. The
default point size is 10pt. The high-level API allows you to
change this whenever you want for any given instance object.
Note that closing a face object will automatically destroy all
its child instances (even though you can release them yourself
to free memory).
See also:
TT_New_Instance(), TT_Done_Instance(),
TT_Get_Instance_Metrics(), TT_Set_Instance_Resolutions(),
TT_Set_Instance_Pointsize()
o The Glyph objects
A Glyph object is a _container_ for the data that describes
any glyph of a given font. This means that it typically
holds:
- Glyph metrics information, like bounding box or advance
width.
- Outline arrays sized large enough to hold any glyph from the
face. This size is extracted from the face's internal
`maxProfile' table to optimize memory costs.
- Other important parameters related to the `fine' rendering
of the glyphs. This includes things like the
dropout-control mode used at low sizes.
- And it doesn't contain a bitmap or a pixmap!
A glyph object is used to load, hint, and rasterize a single
glyph, as taken from the font file.
See also:
TT_New_Glyph(), TT_Done_Glyph(), TT_Get_Glyph_Metrics(),
TT_Get_Glyph_Outline(), TT_Get_Glyph_Bitmap(),
TT_Get_Glyph_Pixmap()
o The Character Map (CharMap) handle
Glyphs can be indexed in a TrueType file in any order,
independently of any standard character encoding, like ASCII
or Unicode. For this reason, each file comes with one or more
character mapping tables, used to translate from one specific
encoding's character codes to font glyph indices.
There are many encoding formats, and each one can be
distinguished by two values:
- its platform ID
- its platform-specific encoding ID
Their values are defined in the TrueType specification and
won't be commented there. The FAQ lists the most commonly
used (platform,encoding) pairs.
It is possible to enumerate the charmaps provided by a
TrueType font and to use any of these to perform translations.
The charmaps are loaded into memory only on demand to save the
space taken by the maps that are not needed on your system.
They are part of the face object, however.
This means that even though a charmap can be accessed through
a handle (obtained through the TT_Get_CharMap() function), it
isn't a stand-alone object. For example, you never need to
de-allocate it; this is automatically done by the engine when
its face object expires.
See also:
TT_Get_CharMap_Count(), TT_Get_CharMap_ID(),
TT_Get_CharMap(), TT_Char_Index().
o The Outline Objects
An outline is a vector representation of a glyph. It is made
of several control points joined by line segments and Bezier
arcs, themselves gathered in closed paths called `contours'.
The outline have also several flags, or attributes, which are
used by the scan-line converter to select the best rendering
algorithms to convert the glyph's bitmap.
Unlike other objects in FreeType, outlines aren't managed
through handles, but directly with the structure `TT_Outline',
defined for client applications. Each glyph container
contains an outline sized large enough to hold any glyph from
its parent face. Client applications can access it with
TT_Get_Glyph_Outline(). However, one can also create its own
outlines if needed with TT_New_Outline() and
TT_Clone_Outline().
Note that user-created outlines are NOT tracked by the
library. Hence, the client must release them himself with one
or more calls to TT_Done_Outline().
A various number of methods/operations are defined for the
outline class to simplify its management.
IMPORTANT NOTE: **********************************************
The definition of TT_Outline may change in the future.
Developers are thus advised to always use the outline
methods provided by the API rather than reading or setting
data themselves.
**************************************************************
See also:
TT_New_Outline(), TT_Clone_Outline(), TT_Copy_Outline(),
TT_Done_Outline(), TT_Get_Outline_BBox(),
TT_Get_Outline_Bitmap(), TT_Get_Outline_Pixmap(),
TT_Translate_Outline(), TT_Transform_Outline()
o Bitmaps and Pixmaps
One very important aspect of FreeType is that it is unable to
create bitmaps on its own. Rather, it is up to the client
application to do it, and pass a reference, in the form of a
TT_Raster_Map, to the scan-line converter (the component in
charge of generating bitmaps from outlines).
Hence the importance of the TT_Raster_Map structure, which
layout is:
struct
{
int rows; /* number of rows */
int cols; /* number of columns (bytes) per row */
int width; /* number of pixels per line */
int flow; /* bitmap orientation */
void* bitmap; /* bit/pixmap buffer */
long size; /* bit/pixmap size in bytes */
} TT_Raster_Map;
- The `rows' field contains the total number of rows in the
bitmap.
- The `width' field gives the number of pixels per row (a bit
or a byte, depending on the map's nature).
- The `cols' field gives the number of columns, i.e. bytes,
taken by each row in the map buffer.
IMPORTANT: The `cols' field must be a multiple of 4 for
pixmaps!
Typically, its value should be `(width+7)/8' for bitmaps,
and `(width+3) & -4' for pixmaps.
- The `flow' field gives the map's vertical orientation.
For example, if the first bytes of the bitmap buffer pertain
to its upper row, the flow is said to be going `down', and
the field should take the value `TT_Flow_Down'. If these
bytes pertain to its lowest row, the flow is going `up', and
the value is `TT_Flow_Up'.
As an example, the PC video modes use a `down' flow, where
the first VRAM byte corresponds to the upper and leftmost
corner of the screen.
- The `bitmap' field is a typeless pointer to the map's
buffer.
- The `size' field contains the buffer's size in bytes. It is
usually computed as follows:
size = rows * cols;
NOTE: For bitmaps, the leftmost-pixel is related to the
highest (i.e. most significant) bit of its byte.
There is currently no support for the opposite
convention found in some systems.
(It can be easily added if you really need it, just
ask the development team.)
II. Step-by-step Example
========================
Here is an example to show, step by step, how a client application
can open a font file, set one or several instances, load any
glyph, then render it to a bitmap.
1. Initialize the engine
------------------------
This is the first thing to do. You need to initialize an engine
through a call to TT_Init_FreeType(). This function will set up
a various number of structures needed by the library.
This allocates about 68kByte, of which 64kByte are dedicated to
the scan-line converter's `render pool', a workspace used for
bitmap generation. Note that even though this space is bounded,
the raster is able to render a glyph to any size or bitmap, even
horribly huge ones.
NOTE: You can reduce the size of this pool by modifying the
constant RASTER_RENDER_POOL in the file `ttraster.c'. A
smaller pool will result in slower rendering at large
sizes. Take care of never assigning a value smaller than
4kByte however, as bugs may start to lurk in!
Example:
TT_Engine engine;
error = TT_Init_FreeType( &engine );
if ( error )
{
printf( "could not create engine instance\n");
...
}
2. Initialize the extensions you need
-------------------------------------
FreeType provides several extensions which are optional,
separately compilable components to add some rare features to
the engine and its API.
You need to explicitly initialize the extensions you want to
use. Each extension must provide an initialization function,
following the naming convention:
TT_Init_xxx_Extension( engine );
where `xxx' is the extension's `kind'.
Example:
error = TT_Init_Kerning_Extension( engine );
if ( error )
...
3. Open the font file
---------------------
There are two ways to open a font face, depending on its file
format:
- If it is a TrueType file (ttf), you can simply use the API
named TT_Open_Face(), which takes the file's pathname as
argument, as well as the address of the returned face handle.
Check the returned error code to see if the file could be
opened and accessed successfully.
TT_Face face; /* face handle */
error = TT_Open_Face( engine, "/fonts/arial.ttf", &face );
if ( error )
{
printf( "could not open the file\n" );
...
}
- If the font is embedded in a TrueType collection (ttc), you
can use the API named TT_Open_Collection(), which takes also
the font's index within the collection's directory.
TT_Face face; /* face handle */
/* Load the collection's second face (index=1) */
error = TT_Open_Collection( engine, "/fonts/mingli.ttc",
1, &face );
if ( error )
{
printf( "could not open the file\n" );
...
}
- Finally, when you do not know the number of faces embedded in
a TrueType collection, the following technique can be used:
o Call TT_Open_Face() with the collection file's pathname.
This API recognizes collections automatically and always
return a handle for its first embedded font.
o Get the face's properties through TT_Get_Face_Properties().
These contain, among other things, the total number of fonts
embedded in the collection, in its field `num_Faces'.
TT_Face face; /* face handle */
TT_Face_Properties props; /* face properties */
/* open the first collection font */
error = TT_Open_Face( engine, "/fonts/mingli.ttc",
&face );
if ( error )
{
printf( "could not open the file\n" );
...
}
/* Get the face properties */
TT_Get_Face_Properties( face, &props );
/* Now print the number of faces */
printf( "there are %d faces in this collection file\n",
props->num_Faces );
4. Create an instance from the face object
------------------------------------------
You must create an instance (also known as a `pointsize') which
contains information relative to the target output device's
resolutions and a given point size.
o The instance object is created through TT_New_Instance():
TT_Instance instance;
error = TT_New_Instance( face, &instance );
if ( error )
{
printf( "could not create instance\n" );
...
}
TECHNICAL NOTE: Creating a new instance executes its font
program. This can fail if the font is broken.
Never assume that the error code returned here
is always 0.
o You must set the instance's properties to suit your needs.
These are simply its device resolutions, set through
TT_Set_Instance_Resolutions(), and its point size, set through
TT_Set_Instance_CharSize():
/* Set the target horizontal and vertical resolution to */
/* 300dpi in each direction (typically for a printer). */
/* A fresh instance's default resolutions are 96dpi in */
/* both directions. */
error = TT_Set_Instance_Resolutions( instance, 300, 300 );
if ( error )
{
printf( "could not set resolution\n" );
...
}
/* Now set the point size to 12pt. Default is 10pt. */
/* Don't forget that the size is expressed in 26.6 fixed */
/* float format, so multiply by 64. */
error = TT_Set_Instance_CharSize( instance, 12 * 64 );
if ( error )
{
printf( "could not set point size\n" );
...
}
TECHNICAL NOTE: These calls may execute the font's `prep'
program, which can fail if the font is broken.
Never assume that the error code returned is
are always 0.
o You can also set the instance's transformation flags to tell
the glyph loading function that you are going to perform a
transformation (like rotation or slanting) on the glyph. Note
that the glyph loader doesn't perform the transformation. It
only informs the glyphs' hinting instruction streams about
these flags which may use it to disable or enable various
features (grid-fitting, drop-out control, etc).
Use e.g.
TT_Set_Instance_Transforms( FALSE, TRUE );
to indicate that you're going to stretch, but not rotate, this
instance's glyphs. Default is, of course, both FALSE.
5. Create a glyph container
---------------------------
You need a glyph object to serve as a container for the glyphs
you want to load from the face. This is done simply by
TT_Glyph glyph; /* glyph object handle */
error = TT_New_Glyph( face, &glyph );
if ( error )
{
printf( "could not create glyph\n" );
...
}
6. Find your platform's character mappings
------------------------------------------
Each font file can come with one or more character mapping
tables, used to convert character codes to glyph indices. You
must know the values of the `platformID' and `encodingID' as
defined in the TrueType specification for your platform. For
example, Windows Unicode encoding is (platform:3,encoding:1),
while Apple Unicode is (platform:0,encoding:0). Both formats
differ in internal storage layout and can be used transparently
with the same inputs with FreeType.
The function TT_Get_CharMap_Count() returns the number of
character mappings present in a face. You can then enumerate
these with the function TT_Get_CharMap_ID(). Once you've found
a mapping usable for your platform, use TT_Get_CharMap() to
return a TT_CharMap handle that will be used later to get glyph
indices.
7. Load the glyph
-----------------
The glyph loader is easily queried through TT_Load_Glyph().
This API function takes several arguments:
o An instance handle to specify at which point size and
resolution the loaded glyph should be scaled and grid-fitted.
o A glyph container, used to hold the glyph's data in memory.
Note that the instance and the glyph must relate to the _same_
font file. An error would be produced immediately otherwise.
o A glyph index, used to reference the glyph within the font
file. This index is not a platform specific character code,
and a character's glyph index may vary from one font to
another. To compute glyph indices from character codes, use
the TT_CharMap handle created in section 6 with
TT_Char_Index().
We strongly recommend using the Unicode charmap whenever
possible.
o A load mode, indicating what kind of operations you need.
There are only two defined for the moment:
TTLOAD_SCALE_GLYPH:
If set, this flag indicates that the loaded glyph will be
scaled (according to the instance specified as an
argument) to fractional pixel coordinates (26.6). If not,
the coordinates will remain integer FUnits. Please refer
to the TrueType specification and the FreeType header
files for more details on the 26.6 format and other data
types.
TTLOAD_HINT_GLYPH:
This flag is only in effect if the TTLOAD_SCALE_GLYPH flag
is set. It indicates that the glyph must also be `hinted'
resp. `grid-fitted' for better display results. Note that
this also means that the glyph metrics will be
grid-fitted, including the bounding box.
You can simply `or' the flags. As most applications will
require both flags to be set, the constant TTLOAD_DEFAULT is
defined as:
#define TTLOAD_DEFAULT (TTLOAD_SCALE_GLYPH | \
TTLOAD_HINT_GLYPH )
Example:
error = TT_Load_Glyph( instance, glyph, 36,
TTLOAD_DEFAULT );
if ( error )
{
printf("could not load the glyph\n");
...
}
8. Query glyph properties
-------------------------
You're then able to query various glyph properties:
o The glyph metrics can be obtained through
TT_Get_Glyph_Metrics(). The data returned in the metrics
structure is:
- the glyph's left side bearing (bearingX)
- the glyph's top side bearing (bearingY)
- the glyph's advance width (advance)
- the glyph's bounding box (bbox)
These values are expressed in 26.6 pixel units when the glyph
was loaded with scaling, or in FUnits if not. To obtain
vertical metrics you should use the function
TT_Get_Glyph_Big_Metrics().
o The glyph outline can be queried through
TT_Get_Glyph_Outline(). This can be useful to process the
point coordinates (e.g. applying stretching or rotation) with
functions like TT_Apply_Outline_Matrix() or
TT_Apply_Outline_Translation(). Note that these functions do
not recompute a glyph's metrics after the transformation!
The outline's structure is described in the reference
`apiref.txt'.
A bitmap or pixmap for the glyph can be queried with the API
functions TT_Get_Glyph_Bitmap() and TT_Get_Glyph_Pixmap().
These functions take a glyph handle as an argument, as well as
a bitmap/pixmap description block and two offsets.
The target map is described through a TT_Raster_Map object,
which structure is defined in the reference (see
`apiref.txt'). The offsets are given in the same units as the
points coordinates and glyph metrics: 26.6 pixel units for a
scaled glyph, and FUnits for an unscaled one.
IMPORTANT TECHNICAL NOTE: If the glyph has been scaled and
hinted, the offsets _must_ be
multiples of 64 (i.e. integer pixel
offsets). Otherwise, you would ruin
the grid fitting (which usually
results in ugly glyphs).
Example:
TT_Glyph_Metrics metrics;
TT_Outline outline;
TT_Raster_Map bitmap;
TT_Get_Glyph_Metrics( glyph, &metrics );
TT_Get_Glyph_Outline( glyph, &outline );
/* set up the bitmap */
...
TT_Get_Glyph_Bitmap( glyph, &bitmap, 0, 0 );
9. When you are done
--------------------
o You can close any font face object with TT_Close_Face(). This
call will automatically discard its child instances, glyphs
and charmaps.
o You can also close the engine with a single call to
TT_Done_FreeType(). This will release _all_ objects that were
previously allocated (with the exception of user-created
outlines), and close all font files, as well as extensions
that were inited for it.
III. Extensions
===============
1. What is an extension?
------------------------
FreeType allows you to access a various number of TrueType
tables, as well as to render individual glyphs. However:
1. It doesn't perform some high-level operations, like
generating a string text from many individual glyphs.
2. It doesn't perform kerning (which can be needed by operations
mentioned in item 1).
3. It doesn't give access to all the defined TrueType tables,
especially the optional ones.
While item 1 is a feature that will never go into FreeType's
core engine, which goal is to provide easy access to font data
and rendering _individual_ glyphs, point 2 and 3 can be added to
the engine's features through extensions.
An extension is simply a small piece of code that extends the
engine's abilities and APIs. It is possible to extend the
engine without touching the core's source code, this is
described in chapter 3 below.
2. The two kinds of extensions
------------------------------
There are basically two kinds of extensions, which require
different implementations.
a. API extensions
An API extension is a set of functions that extend the
FreeType core API to give access to tables that are already
loaded by the engine, but not provided for now. An example of
such data can be:
- the horizontal metrics table (hmtx)
- the `gasp' table
This kind of extension is made of:
o an API extension header file, following the usage convention
introduced here (all labels prefixed with `TT_'), and which
will be included by the clients which want to use the
extension. By convention, such header names begin with
`ftx' (for FreeType eXtension).
Examples: ftxgasp.h, ftxhmtx.h
o One or more functions used to give access to the tables that
are already loaded and managed by the engine. They usually
only copy pointers to the target structure given by the
client application since these structures are not accessible
through the 'normal' API. An API extension doesn't need to
be initialized before being used.
b. Engine extensions
It can sometimes be useful to load and manage several tables
that are not considered by the core engine. These extensions
need to provide additional functions to fit into FreeType's
internal object management model, and are more sophisticated
than API extensions.
An example is given in this distribution to provide kerning
support (or more technically spoken, access to the kerning
tables found within the TrueType files). It is made of:
o An API extension providing new interfaces to the client
applications that need it. See the file `ftxkern.h'
resp. `apirefx.txt'.
o A specific implementation, providing services to create,
load, and manage kerning tables as additional parts of a
face object. In the case of kerning, the directory of
tables is loaded when the face is opened, and tables
themselves are fetched from the file on demand. This
implies several `hooks' in the core engine. See the files
`ttkern.h' and `ttkern.c'. These are called `engine
extensions'.
o A specific extension initialization function, namely
TT_Init_Kerning_Extension(), that must be called after an
engine's creation, and before any face object allocation.
This function will `register' the extension within the
engine and make its API workable.
3. Writing your own extensions
------------------------------
As it was suggested earlier, writing an engine extension is a
delicate process, as the additional code must follow a certain
number of design rules, presented in the FreeType developer's
guide. Unfortunately, there is currently no extension writer's
guide.
By writing your own extensions, it will be possible to support
more advanced TrueType formats like TrueType GX or OpenType in a
near future, without having to torture the engine core source at
each iteration.
If you encounter some difficulties when trying to create your
own extension, please read the core source file carefully, and
in the event that you may need changes that are not fitted to
the current extension mechanism, do not hesitate to contact the
authors at `devel@freetype.org'.
Conclusion
==========
The engine source code has become rather stable since now, and
its quality compares very favorably to Windows and the Macintosh
rasterizers. Its internals will continue to change, though very
slowly, even if the API isn't expected to grow much in a near
future.
FreeType is really a glyph-oriented TrueType driver. Its
purpose is to open and manage font files in order to load single
glyphs and render them as cleanly as possible. A number of
features, important to developers, like text string rendering,
font mapping and underlining/stroking, to name a few, aren't
provided there even though they'd be highly appreciated.
We hope you have success and fun using this engine. Much time
has been taken to make it one of the best in its genre.
Remember that it is not intended to be a complete font server or
text rendering library, but a pretty solid base for these kinds
of applications, as well as others.
We thank you for your time and consideration.
David Turner, Robert Wilhelm, Werner Lemberg,
and all the FreeType enthusiasts...
--- End of user.txt ---