Converting tabs to spaces in z1load.
Edited FT1's convntns.txt and added it to FT2.
This commit is contained in:
parent
40822003da
commit
05f0ad098f
689
docs/convntns.txt
Normal file
689
docs/convntns.txt
Normal file
@ -0,0 +1,689 @@
|
||||
|
||||
Conventions and Design in the FreeType 2 library
|
||||
------------------------------------------------
|
||||
|
||||
|
||||
Table of Contents
|
||||
|
||||
Introduction
|
||||
|
||||
I. Style and Formatting
|
||||
|
||||
1. Naming
|
||||
2. Declarations & Statements
|
||||
3. Blocks
|
||||
4. Macros
|
||||
5. Conventions
|
||||
|
||||
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
|
||||
4. Support for threaded environments
|
||||
5. Object Management
|
||||
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This text introduces the many conventions used within the FreeType 2
|
||||
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. 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.
|
||||
|
||||
Conclusion: Avoid Hungarian Notation in FreeType 2.
|
||||
|
||||
|
||||
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 welcome 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 ;-)
|
||||
|
||||
b. Data types
|
||||
|
||||
Try to use C 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
|
||||
`fttypes.h' public header file, like `FT_Short', `FT_UShort',
|
||||
etc. Using the internal types will guarantee that you won't
|
||||
need to replace every occurence of `short' or whatever when
|
||||
compiling on a weird platform or with a weird compiler, and
|
||||
there are many more than you could think of...
|
||||
|
||||
c. 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 various data types from a file stream is
|
||||
performed using the following functions defined in the
|
||||
`ftstream.c' file of the `base' module:
|
||||
|
||||
FT_Get_Char(), FT_Get_Short(), FT_Get_Long(), etc.
|
||||
|
||||
Which is somewhat more readable than:
|
||||
|
||||
cget, sget, usget, lget, etc.
|
||||
|
||||
d. Variables
|
||||
|
||||
Variable names (at least meant for the public interface) 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 are 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.
|
||||
|
||||
Unfortunately (mostly due to the lazyness of the developers),
|
||||
short variable names are still used in many parts of the
|
||||
library. Volunteers are highly welcome to improve this...
|
||||
|
||||
As a side note, a field name of a structure counts as a variable
|
||||
name too.
|
||||
|
||||
|
||||
2. Declarations & Statements
|
||||
----------------------------
|
||||
|
||||
Try to align declarations and assignments in columns, if it proves
|
||||
logically. For example (taken from `ttraster.c'):
|
||||
|
||||
struct TProfile_
|
||||
{
|
||||
FT_F26Dot6 X; /* current coordinate during sweep */
|
||||
PProfile link; /* link to next profile - various purpose */
|
||||
PLong offset; /* start of profile's data in render pool */
|
||||
Int flow; /* profile orientation: asc/descending */
|
||||
Long height; /* profile's height in scanlines */
|
||||
Long start; /* profile's starting scanline */
|
||||
|
||||
UShort countL; /* number of lines to step before this */
|
||||
/* profile becomes drawable */
|
||||
|
||||
PProfile next; /* next profile in same contour, used */
|
||||
/* during drop-out control */
|
||||
};
|
||||
|
||||
instead of
|
||||
|
||||
struct TProfile_
|
||||
{
|
||||
FT_F26Dot6 X; /* current coordinate during sweep */
|
||||
PProfile link; /* link to next profile - various purpose */
|
||||
PLong offset; /* start of profile's data in render pool */
|
||||
Int flow; /* profile orientation: asc/descending */
|
||||
Long height; /* profile's height in scanlines */
|
||||
Long start; /* profile's starting scanline */
|
||||
UShort countL; /* number of lines to step before this */
|
||||
/* profile becomes drawable */
|
||||
PProfile next; /* next profile in same contour, used */
|
||||
/* during drop-out control */
|
||||
};
|
||||
|
||||
This comes from the fact that you are more interested in the field
|
||||
and its function than in 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;
|
||||
|
||||
|
||||
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_ associate the accolades
|
||||
easily (ask any Lisp programmer on the topic!).
|
||||
|
||||
Use two spaces for the next indentation level.
|
||||
|
||||
Never use tabs in FreeType 2 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;
|
||||
}
|
||||
|
||||
should be rather formatted as
|
||||
|
||||
if ( condition_test )
|
||||
{
|
||||
This code isn't stuck to the condition;
|
||||
read it on paper, you will find it more;
|
||||
pleasant to the eye;
|
||||
}
|
||||
else
|
||||
{
|
||||
Of course, this is a matter of taste;
|
||||
This is just the way it is in this convention;
|
||||
and you should follow it to be homogenuous with;
|
||||
the rest of the FreeType code;
|
||||
}
|
||||
|
||||
|
||||
4. Macros
|
||||
---------
|
||||
|
||||
Macros should be made of uppercase letters. If 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 in some files for macros like
|
||||
|
||||
GET_UShort(), USE_Stream(), etc.
|
||||
|
||||
The role of macros used throughout the engine is explained later
|
||||
in this document.
|
||||
|
||||
|
||||
5. Conventions
|
||||
--------------
|
||||
|
||||
Currently, FreeType 2 source code uses the following formatting
|
||||
rules:
|
||||
|
||||
. The data type is separated with two spaces from the variable,
|
||||
structure, or function name:
|
||||
|
||||
const char foo;
|
||||
|
||||
Usually, the `*' operator is concatenated to the data type:
|
||||
|
||||
FT_Int* pointer;
|
||||
|
||||
As mentioned above, multiple declarations are vertically
|
||||
aligned:
|
||||
|
||||
FT_Short foo;
|
||||
FT_Long bar;
|
||||
FT_GlyphSlot slot;
|
||||
|
||||
. Declarations are separated with two blank lines from the
|
||||
following code. This intentionally disturbs the code flow to
|
||||
make variable definitions more visible.
|
||||
|
||||
{
|
||||
char x, y;
|
||||
|
||||
|
||||
x = 3;
|
||||
y = 5;
|
||||
}
|
||||
|
||||
. An opening parenthesis follows a function directly without
|
||||
space; after a built-in C keyword, one space is used:
|
||||
|
||||
x = sin( y );
|
||||
y = sizeof ( long );
|
||||
|
||||
Except for casts, parentheses are surrounded with space:
|
||||
|
||||
x = (char*)( foo + bar );
|
||||
|
||||
. Binary operators are surrounded by spaces; unary operators have
|
||||
no space after it:
|
||||
|
||||
x = ( 3 + 4 ) / ( 7 - 2 );
|
||||
y = -( 3 + 4 ) * 7;
|
||||
|
||||
. Array arguments are not surrounded by spaces:
|
||||
|
||||
array[3] = array[1] + array[2];
|
||||
array[4] = array[1 + 3];
|
||||
|
||||
. Comma and semicolon have only space at the right side:
|
||||
|
||||
if ( x = 0; x < y; x++, y-- )
|
||||
do_something();
|
||||
|
||||
. Don't use
|
||||
|
||||
if ( x == y ) a = b;
|
||||
|
||||
but
|
||||
|
||||
if ( x == y )
|
||||
a = b;
|
||||
|
||||
in general.
|
||||
|
||||
. Preprocessor directives are never indented and always start in
|
||||
the first column.
|
||||
|
||||
. All function/structure/variable definitions start at column
|
||||
three.
|
||||
|
||||
. All full-line comments (except the header of a file) start at
|
||||
column three (even comments for preprocessor directives).
|
||||
|
||||
. Labels are sticking out two positions to the left:
|
||||
|
||||
switch ( x )
|
||||
{
|
||||
case 1:
|
||||
do_something();
|
||||
break;
|
||||
default:
|
||||
do_nothing();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
II. Design Conventions
|
||||
======================
|
||||
|
||||
|
||||
1. Modularity and Components Layout
|
||||
-----------------------------------
|
||||
|
||||
The FreeType 2 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 entirely in ANSI C.
|
||||
|
||||
- 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 -- please report.
|
||||
|
||||
(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 preprocessor, compiler, and
|
||||
linker.
|
||||
|
||||
- It consists of modules, starting with a `base' module which
|
||||
provides the API, some auxiliary modules used by the font
|
||||
drivers, the font driver modules itself, and the rasterizer
|
||||
modules.
|
||||
|
||||
- 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 only needs to include one header file named
|
||||
`freetype.h' to use the engine. Other public header files like
|
||||
`ftglyph.h' or `ftimage.h' provide functional extensions.
|
||||
|
||||
- All configuration options are gathered in two files,
|
||||
`ftconfig.h' and `ftoption.h'. The former contains the
|
||||
processor and OS specific configuration options, while the
|
||||
latter treats options that may be enabled or disabled by the
|
||||
user to enable and disable various features.
|
||||
|
||||
|
||||
2. Configuration and Debugging
|
||||
------------------------------
|
||||
|
||||
Configuration is covered by the `BUILD' documentation file.
|
||||
|
||||
Debugging is controlled by two macros in `ftoption.h',
|
||||
FT_DEBUG_LEVEL_ERROR and FT_DEBUG_LEVEL_TRACE; don't use them in
|
||||
code to be released. Check the source code of the `ftview.c'
|
||||
demonstration program (in the `ft2demos' package) how tracing can
|
||||
be used and activated.
|
||||
|
||||
|
||||
|
||||
III. Usage conventions
|
||||
======================
|
||||
|
||||
|
||||
1. Error Handling
|
||||
-----------------
|
||||
|
||||
Most functions directly return an error code. A return value of 0
|
||||
(FT_Err_Ok) means that no error occured, while a non-zero other
|
||||
value indicates a failure of any kind.
|
||||
|
||||
We use code like this in FreeType 2:
|
||||
|
||||
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 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 in some header 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. Another advantage is that the
|
||||
structure of source files remain very similar, even though the
|
||||
error handling may be 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 containing information used to access files through
|
||||
a system-specific i/o library.
|
||||
|
||||
The default implementation of streams uses the ANSI libc i/o
|
||||
functions. However, for the sake of embedding in light systems
|
||||
and independence of a complete C library, it is possible to
|
||||
re-implement the component for a specific system or OS, letting
|
||||
it use system calls.
|
||||
|
||||
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 call to the `ACCESS_Frame()' macro.
|
||||
|
||||
It is then possible to read all sizes of data through the
|
||||
`GET_xxx()' macros described above.
|
||||
|
||||
When all important data is read, the frame can be released by a
|
||||
call to `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 ( 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();
|
||||
|
||||
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.
|
||||
|
||||
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 has a component which uses an interface similar to
|
||||
malloc()/free().
|
||||
|
||||
* FT_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.
|
||||
|
||||
FT_Alloc() internally calls the ft_alloc() function defined in
|
||||
an FT_Memory object. All error checking is done by FT_Alloc()
|
||||
itself so that ft_alloc() directly calls malloc().
|
||||
|
||||
* FT_Realloc()
|
||||
|
||||
Similar to FT_Alloc(); it calls realloc() by default.
|
||||
|
||||
* FT_Free()
|
||||
|
||||
As you may have already guessed, FT_Free() is FT_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 FT_Free().
|
||||
|
||||
Similar to FT_Alloc(), FT_Free() does the necessary error
|
||||
checking and calls free() by default.
|
||||
|
||||
As the pointers addresses needed as arguments are typed `void**',
|
||||
ftmemory.h provides some macros to help use the above functions
|
||||
more easily, these are:
|
||||
|
||||
MEM_Alloc() A version of FT_Alloc() that casts the argument
|
||||
pointer to (void**). Similar functions are
|
||||
MEM_Alloc_Array(), MEM_Realloc(), and
|
||||
MEM_Realloc_Array()
|
||||
|
||||
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. Similar
|
||||
functions are REALLOC(), ALLOC_ARRAY(), and
|
||||
REALLOC_ARRAY().
|
||||
|
||||
FREE() A version of FT_Free() that casts the argument
|
||||
pointer to (void**).
|
||||
|
||||
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 necessary (e.g. not using libc).
|
||||
|
||||
MEM_Move() An alias of `memmove().' Change its definition if
|
||||
necessary.
|
||||
|
||||
|
||||
4. Support for threaded environments
|
||||
------------------------------------
|
||||
|
||||
Thread synchronisation has been dropped in FreeType 2. The
|
||||
library is already re-entrant, and if you really need two threads
|
||||
accessing the same FT_Library object, you should synchronize
|
||||
access to it yourself with a simple mutex.
|
||||
|
||||
|
||||
--- end of convntns.txt ---
|
@ -970,10 +970,12 @@
|
||||
}
|
||||
|
||||
/* We need to `zero' out encoding_table.elements */
|
||||
for ( n = 0 ; n < count ; n++ )
|
||||
for ( n = 0; n < count; n++ )
|
||||
{
|
||||
char *notdef = ".notdef";
|
||||
Z1_Add_Table( char_table, n, notdef, 8 );
|
||||
char* notdef = ".notdef";
|
||||
|
||||
|
||||
Z1_Add_Table( char_table, n, notdef, 8 );
|
||||
}
|
||||
|
||||
/* Now, we will need to read a record of the form */
|
||||
@ -1180,6 +1182,7 @@
|
||||
FT_UInt notdef_index = 0;
|
||||
FT_Byte notdef_found = 0;
|
||||
|
||||
|
||||
if ( loader->num_glyphs )
|
||||
/* with synthetic fonts, it's possible we get here twice */
|
||||
return;
|
||||
@ -1207,6 +1210,7 @@
|
||||
FT_Int size;
|
||||
FT_Byte* base;
|
||||
|
||||
|
||||
/* the format is simple: */
|
||||
/* `/glyphname' + binary data */
|
||||
/* */
|
||||
@ -1250,12 +1254,12 @@
|
||||
/* add a trailing zero to the name table */
|
||||
name_table->elements[n][len] = '\0';
|
||||
|
||||
/* record index of /.notdef */
|
||||
if ( strcmp( (const char*)".notdef",
|
||||
(const char*)(name_table->elements[n]) ) == 0 )
|
||||
{
|
||||
notdef_index = n;
|
||||
notdef_found = 1;
|
||||
/* record index of /.notdef */
|
||||
if ( strcmp( (const char*)".notdef",
|
||||
(const char*)(name_table->elements[n]) ) == 0 )
|
||||
{
|
||||
notdef_index = n;
|
||||
notdef_found = 1;
|
||||
}
|
||||
|
||||
parser->root.cursor = cur2;
|
||||
@ -1283,8 +1287,8 @@
|
||||
|
||||
/* if /.notdef is found but does not occupy index 0, do our magic. */
|
||||
if ( strcmp( (const char*)".notdef",
|
||||
(const char*)name_table->elements[0] ) &&
|
||||
notdef_found )
|
||||
(const char*)name_table->elements[0] ) &&
|
||||
notdef_found )
|
||||
{
|
||||
|
||||
/* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */
|
||||
@ -1293,39 +1297,39 @@
|
||||
/* notdef_index. */
|
||||
|
||||
error = Z1_Add_Table( name_table, n,
|
||||
name_table->elements[0],
|
||||
name_table->lengths [0] );
|
||||
name_table->elements[0],
|
||||
name_table->lengths [0] );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
goto Fail;
|
||||
error = Z1_Add_Table( code_table, n,
|
||||
code_table->elements[0],
|
||||
code_table->lengths [0] );
|
||||
code_table->elements[0],
|
||||
code_table->lengths [0] );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
goto Fail;
|
||||
|
||||
error = Z1_Add_Table( name_table, 0,
|
||||
name_table->elements[notdef_index],
|
||||
name_table->lengths [notdef_index] );
|
||||
name_table->elements[notdef_index],
|
||||
name_table->lengths [notdef_index] );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
goto Fail;
|
||||
|
||||
error = Z1_Add_Table( code_table, 0,
|
||||
code_table->elements[notdef_index],
|
||||
code_table->lengths [notdef_index] );
|
||||
code_table->elements[notdef_index],
|
||||
code_table->lengths [notdef_index] );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
goto Fail;
|
||||
|
||||
error = Z1_Add_Table( name_table, notdef_index,
|
||||
name_table->elements[n],
|
||||
name_table->lengths [n] );
|
||||
name_table->elements[n],
|
||||
name_table->lengths [n] );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
goto Fail;
|
||||
|
||||
error = Z1_Add_Table( code_table, notdef_index,
|
||||
code_table->elements[n],
|
||||
code_table->lengths [n] );
|
||||
code_table->elements[n],
|
||||
code_table->lengths [n] );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
goto Fail;
|
||||
|
||||
}
|
||||
else if ( !notdef_found )
|
||||
@ -1337,8 +1341,9 @@
|
||||
/* and add our own /.notdef glyph to index 0. */
|
||||
|
||||
/* 0 333 hsbw endchar */
|
||||
FT_Byte notdef_glyph[] = {0x8B,0xF7,0xE1,0x0D,0x0E};
|
||||
char *notdef_name = ".notdef";
|
||||
FT_Byte notdef_glyph[] = {0x8B, 0xF7, 0xE1, 0x0D, 0x0E};
|
||||
char* notdef_name = ".notdef";
|
||||
|
||||
|
||||
error = Z1_Add_Table( name_table, n,
|
||||
name_table->elements[0],
|
||||
@ -1671,14 +1676,14 @@
|
||||
type1->encoding.char_index[charcode] = index;
|
||||
type1->encoding.char_name [charcode] = (char*)glyph_name;
|
||||
|
||||
/* Change min/max encoded char only if glyph name is */
|
||||
/* not /.notdef */
|
||||
if ( strcmp( (const char*)".notdef",
|
||||
(const char*)glyph_name ) != 0 )
|
||||
{
|
||||
if (charcode < min_char) min_char = charcode;
|
||||
if (charcode > max_char) max_char = charcode;
|
||||
}
|
||||
/* Change min/max encoded char only if glyph name is */
|
||||
/* not /.notdef */
|
||||
if ( strcmp( (const char*)".notdef",
|
||||
(const char*)glyph_name ) != 0 )
|
||||
{
|
||||
if (charcode < min_char) min_char = charcode;
|
||||
if (charcode > max_char) max_char = charcode;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user