FreeType 1.31.1
799
docs/FAQ
Normal 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
@@ -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
864
docs/apirefx.txt
Normal 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
999
docs/glyphs.txt
Normal 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
@@ -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
|
After Width: | Height: | Size: 1.3 KiB |
BIN
docs/image/baseline.gif
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
docs/image/emsquare.gif
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
docs/image/freetype.gif
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
docs/image/freetype.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
docs/image/grid1.gif
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
docs/image/grid2.gif
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
docs/image/grid3.gif
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
docs/image/metrics.gif
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
docs/image/metrics2.gif
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
docs/image/small2.gif
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
docs/image/tfp-back.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
158
docs/optimize.txt
Normal 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
577
docs/raster.txt
Normal 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
@@ -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
@@ -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
@@ -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 ---
|
||||