contrib/OWB: add correct SDL dependency, fix compilers used
[AROS-Contrib.git] / freetype1 / docs / convntns.txt
blob01177854f3d15e4846e2c322afcef4bdd8091b46
2            Conventions and Design in the FreeType library
3            ----------------------------------------------
6 Table of Contents
8 Introduction
10 I. Style and Formatting
12   1. Naming
13   2. Declarations & Statements
14   3. Blocks
15   4. Macros
17 II. Design conventions
19   1. Modularity and Components Layout
20   2. Configuration and Debugging
22 III. Usage conventions
24   1. Error handling
25   2. Font File I/O
26   3. Memory management (due to change soon)
27   4. Support for threaded environments
28   5. Object Management
31 Introduction
32 ============
34 This text  introduces the many conventions used  within the FreeType
35 library  code.  Please read  it before  trying any  modifications or
36 extensions of the source code.
40 I. Style and Formatting
41 =======================
43 The  following coding  rules  are extremely  important  to keep  the
44 library's  source code  homogeneously.  Keep  in mind  the following
45 points:
47   - `Humans read source code, not machines' (Donald Knuth)
49     The library source code should  be as readable as possible, even
50     by non-C experts.  With `readable', two things are meant: First,
51     the source code  should be pleasant to the  eye, with sufficient
52     whitespace  and newlines,  to not  look like  a boring  stack of
53     characters stuck  to each other.   Second, the source  should be
54     _expressive_ enough  about its goals.   This convention contains
55     rules that  can help the source  focus on its purpose,  not on a
56     particular implementation.
58   - `Paper is the _ultimate_ debugger' (David Turner :-)
60     There is  nothing like  sheets of paper  (and a large  floor) to
61     help you understand the design of a library you're new to, or to
62     debug it.   The formatting style  presented here is  targeted at
63     printing.  For  example, it is  more than highly  recommended to
64     never produce a source line that is wider than 78 columns.  More
65     on this below.
68 1. Naming
69 ---------
71   a. Components
73     A unit of  the library is called a  `component'.  Each component
74     has at least an interface,  and often a body.  The library comes
75     in two language  flavors, C and Pascal (the  latter severely out
76     of  date unfortunately).   A component  in C  is defined  by two
77     files,  one  `.h' header  and  one  `.c'  body, while  a  Pascal
78     component is contained in a single `.pas' file.
80     All component source file names begin with the `tt' prefix, with
81     the  exception of  the `FreeType'  component.  For  example, the
82     file   component  is  implemented   by  the   files  `ttfile.h',
83     `ttfile.c', and `ttfile.pas'.   Only lowercase letters should be
84     used, following  the 8+3 naming convention  to allow compilation
85     under DOS.
87     In the C  version, a single component can  have multiple bodies.
88     For  example, `ttfile.c'  provides stream  i/o  through standard
89     ANSI  libc calls,  while `ttfile2.c'  implements the  same thing
90     using a Unix memory-mapping API.
92     The FreeType component is an interface-only component.
94   b. Long and expressive labels
96     Never  hesitate to use  long labels  for your  types, variables,
97     etc.!   Except maybe  for things  like very  trivial  types, the
98     longest   is   the   best,   as  it   increases   the   source's
99     _expressiveness_.  Never forget  that the role of a  label is to
100     express  the `function'  of the  entity it  represents,  not its
101     implementation!
103     NOTE: Hungarian  notation is  NOT expressive,  as it  sticks the
104           `type' of  a variable to  its name.  A label  like `usFoo'
105           rarely tells the use of the variable it represents.
107           And  the state  of  a variable  (global, static,  dynamic)
108           isn't helpful anymore.
110     Avoid Hungarian Notation like the *plague*!
113     When     forging      a     name     with      several     nouns
114     (e.g. `number-of-points'), use an uppercase letter for the first
115     letter of each word (except the first), like:
117       numberOfPoints
119     You  are also  welcomed  to introduce  underscores  `_' in  your
120     labels,  especially when  sticking large  nouns together,  as it
121     `airs' the code greatly.  E.g.:
123       `numberOfPoints' or `number_Of_Points'
125       `IncredibleFunction' or `Incredible_Function'
126        
127     And finally,  always put a  capital letter after  an underscore,
128     except in variable labels that are all lowercase:
130      `number_of_points' is OK for a variable (_all_ lowercase label)
132      `incredible_function' is NOT for a function!
133       ^          ^
135      `Microsoft_windows' is a *shame*!
136       ^         ^
138      `Microsoft_Windows' isn't  really better,  but at  least  its a
139       ^         ^        correct   function    label   within   this
140                          convention ;-)
142   c. Types
144     All  types   that  are  defined  for  use   by  FreeType  client
145     applications are  defined in the FreeType  component.  All types
146     defined there have a label beginning with `TT_'.  Examples:
148       TT_Face, TT_F26Dot6, etc.
150     However, the library uses a  lot more of internal types that are
151     defined in  the Types, Tables, and Objs  components (`tttypes' &
152     `tttables' files).
154     By convention, all internal types, except the simplest ones like
155     integers, have their name beginning  with a capital `T', like in
156     'TFoo'.   Note   that  the  first   letter  of  `foo'   is  also
157     capitalized.  The corresponding pointer  type uses a capital `P'
158     instead, i.e. (TFoo*) is simply named 'PFoo'.  Examples:
160       typedef struct  _TTableDir
161       {
162         TT_Fixed  version;      /* should be 0x10000 */
163         UShort    numTables;    /* Tables number     */
164     
165         UShort    searchRange;  /* These parameters are only used */
166         UShort    entrySelector;/* for a dichotomy search in the  */
167         UShort    rangeShift;   /* directory.  We ignore them.    */
168       } TTableDir;
169     
170       typedef TTableDir*  PTableDir;
171     
172     Note  that we  _always_ define  a typedef  for  structures.  The
173     original struct label starts with `_T'.
175     This convention is a famous one from the Pascal world.
177     Try  to use  C  or Pascal  types  to the  very  least!  Rely  on
178     internally defined  equivalent types instead.   For example, not
179     all compilers agree on the sign  of `char'; the size of `int' is
180     platform-specific, etc.
182     There are  equivalents to the  most common types in  the `Types'
183     components,  like `Short',  `UShort', etc.   Using  the internal
184     types  will  guarantee that  you  won't  need  to replace  every
185     occurence  of `short'  or  wathever when  compiling  on a  weird
186     platform or with a weird  compiler, and there are many more than
187     you could think of...
189   d. Functions
191     The  name of  a  function  should always  begin  with a  capital
192     letter, as  lowercase first letters are  reserved for variables.
193     The name  of a function  should be, again,  _expressive_!  Never
194     hesitate to put  long function names in your  code: It will make
195     the code much more readable.
197     Expressiveness doesn't necessarily imply lengthiness though; for
198     instance, reading  shorts from a file stream  is performed using
199     the following functions defined in the `File' component:
201       Get_Byte, Get_Short, Get_UShort, Get_Long, etc.
203     Which is somewhat more readable than:
205       cget, sget, usget, lget, etc.
207   e. Variables
209     Variable  names should  always  begin with  a lowercase  letter.
210     Lowercase  first  letters are  reserved  for  variables in  this
211     convention,  as it  has  been already  explained above.   You're
212     still welcome to use long and expressive variable names.
214     Something  like `numP' can  express a  number of  pixels, porks,
215     pancakes, and much more... Something like `num_points' won't.
217     Today, we are still using short variable labels in some parts of
218     the library.  We're working on removing them however...
220     As a side note, a field name of a structure counts as a variable
221     name  too.  There are  exceptions to  the first-lowercase-letter
222     rule, but these are only  related to fields within the structure
223     defined  by  the  TrueType  specification  (well,  at  least  it
224     _should_ be that way).
227 2. Declarations & Statements
228 ----------------------------
230   a. Columning
232     Try  to align  declarations and  assignments in  columns,  if it
233     proves logical.  For example (taken from `ttraster.c'):
235     struct _TProfile
236     {                                                                     
237       Int        flow;        /* Profile orientation : Asc/Descending     */
238       Int        height;      /* profile's height in scanlines            */
239       Int        start;       /* profile's start scanline                 */
240       ULong      offset;      /* offset of profile's data in render pool  */
241       PProfile   link;        /* link to next profile                     */
242       Int        index;       /* index of profile's entry in trace table  */
243       Int        count_lines; /* count of lines having to be drawn        */
244       Int        start_line;  /* lines to be rendered before this profile */
245       PTraceRec  trace;       /* pointer to profile's current trace table */
246     };
248     instead of
250     struct _TProfile {
251       Int flow;         /* Profile orientation : Asc/Descending     */
252       Int height;       /* profile's height in scanlines            */
253       Int start;        /* profile's start scanline                 */
254       ULong offset;     /* offset of profile's data in render pool  */
255       PProfile link;    /* link to next profile                     */
256       Int index;        /* index of profile's entry in trace table  */
257       Int count_lines;  /* count of lines having to be drawn        */
258       Int start_line;   /* lines to be rendered before this profile */
259       PTraceRec  trace; /* pointer to profile's current trace table */
260     };
262     This  comes from  the fact  that you're  more interested  by the
263     field and its function than by its type.
265     Or:
267       x   = i + 1;
268       y  += j;
269       min = 100;
271     instead of
273       x=i+1;
274       y+=j;
275       min=100;
277     And  don't  hesitate to  separate  blocks  of declarations  with
278     newlines to `distinguish' logical sections.
280     E.g., taken from an old source file, in the declarations of the CMap
281     loader:
283       long             n, num_SH;
284       unsigned short   u;
285       long             off;
286       unsigned short   l;
287       long             num_Seg;
288       unsigned short*  glArray;
289       long             table_start;
290       int              limit, i;
292       TCMapDir         cmap_dir;
293       TCMapDirEntry    entry_;
294       PCMapTable       Plcmt;
295       PCMap2SubHeader  Plcmsub;
296       PCMap4           Plcm4;
297       PCMap4Segment    segments;
299     instead of
301       long n, num_SH;
302       unsigned short u;
303       long off;
304       unsigned short l;
305       long num_Seg;
306       unsigned short *glArray;
307       long table_start;
308       int limit, i;
309       TCMapDir cmap_dir;
310       TCMapDirEntry entry_;
311       PCMapTable Plcmt;
312       PCMap2SubHeader Plcmsub;
313       PCMap4 Plcm4;
314       PCMap4Segment segments;
316   b. Aliases and the `with' clause
318     The Pascal language  comes with a very handy  `with' clause that
319     is often  used when  dealing with the  fields of a  same record.
320     The following Pascal source extract
322       with table[incredibly_long_index] do
323       begin
324         x := some_x;
325         y := some_y;
326         z := wathever_the_hell;
327       end;
329     is usually translated to:
331       table[incredibly_long_index].x = some_x;
332       table[incredibly_long_index].y = some_y;
333       table[incredibly_long_index].z = wathever_the_hell;
335     When  a lot of  fields are  involved, it  is usually  helpful to
336     define an `alias' for the record, like in:
338       alias = table + incredibly_long_index;
340       alias->x = some_x;
341       alias->y = some_y;
342       alias->z = wathever_the_hell;
344     which  gives  cleaner  source  code, and  eases  the  compiler's
345     optimization work.
347     Though the use of aliases  is currently not fixed in the current
348     library source, it is useful to follow one of these rules:
350     - Avoid an alias with a stupid, or cryptic name, something like:
352       TFooRecord  tfr;
353       ....
354       [lots of lines snipped]
355       ....
357       tfr = weird_table + weird_index;
359       ...
361       tfr->num = n;  
363       It doesn't really help to  guess what 'tfr' stands for several
364       lines  after   its  declaration,  even  if   it's  an  extreme
365       contraction of one particular type.
367       Something  like `cur_record' or  `alias_cmap' is  better.  The
368       current source  also uses  a prefix of  `Pl' for  such aliases
369       (like  Pointer  to  Local   alias),  but  this  use  is  _not_
370       encouraged.  If you want  to use prefixes, use `loc_', `cur_',
371       or `al_' at the very least, with a descriptive name following.
373     - Or simply use a local variable with a semi-expressive name:
375         { 
376           THorizontalHeader  hheader;
377           TVerticalHeader    vheader;
380           hheader = instance->fontRes->horizontalHeader;
381           vheader = instance->fontRes->verticalHeader;
383           hheader->foo = bar;
384           vheader->foo = bar2;
385           ...
386         }
388       which is much better than
390         { 
391           THorizontalHeader Plhhead;
392           TVerticalHeader Plvhead;
394           Plhhead = instance->fontRes->horizontalHeader;
395           Plvhead = instance->fontRes->verticalHeader;
397           Plhhead->foo = bar;
398           Plvhead->foo = bar2;
399           ...
400         }
403 3. Blocks
404 ---------
406   Block separation is done with `{'  and `}'.  We do not use the K&R
407   convention  which becomes  only useful  with an  extensive  use of
408   tabs.  The `{'  and its corresponding `}' should  always be on the
409   same column.  It makes it easier to separate a block from the rest
410   of the source, and it  helps your _brain_ associates the accolades
411   easily (ask any Lisp programmer on the topic!).
412   
413   Use two spaces for the next indentation level.
415   Never use  tabs in your code,  their widths may  vary with editors
416   and systems.
418   Example:
420     if (condition_test) {
421             waow mamma;
422             I'm doing K&R format;
423             just like the Linux kernel;
424     } else {
425             This test failed poorly;
426     }
428   is _OUT_!
430     if ( condition_test )
431     {
432        This code isn't stuck to the condition;
433        read it on paper, you'll find it more;
434        pleasant to the eye;
435     }
436     else
437     {
438        Of course, this is a matter of taste;
439        That's just the way it is in this convention;
440        and you should follow it to be homogenous with;
441        the rest of the FreeType code;
442     }
444   is _IN_!
447 4. Macros
448 ---------
450   Macros should be made of uppercase letters.  When a macro label is
451   forged from several words, it  is possible to only uppercasify the
452   first word,  using an underscore  to separate the nouns.   This is
453   used in ttload.c, ttgload.c and ttfile.c with macros like
455     ACCESS_Frame, GET_UShort, CUR_Stream
457   The role  of the  macros used throughout  the engine  is explained
458   later in this document.
462 II. Design Conventions
463 ======================
466 1. Modularity and Components Layout
467 -----------------------------------
469   The FreeType  engine has been  designed with portability  in mind.
470   This implies the ability to compile  and run it on a great variety
471   of systems and weird  environments, unlike many packages where the
472   word strictly  means `runs on  a bunch of Unix-like  systems'.  We
473   have thus decided to stick to the following restrictions:
475   - The C version is written  in ANSI C. The Pascal version compiles
476     and run under Turbo Pascal 5.0 and compatible compilers.
477   
478   - The library,  if compiled with gcc, doesn't  produce any warning
479     with the  `-ansi -pedantic' flags.  Other  compilers with better
480     checks  may produce  ANSI warnings  that  we'd be  happy to  now
481     about.
482      
483     (NOTE: It can of course  be compiled by an `average' C compiler,
484            and even by a C++ one.)
486   - It only requires  in its simplest form an  ANSI libc to compile,
487     and  no utilities other  than a  C pre-processor,  compiler, and
488     linker.
490   - It is  written in  a modular fashion.   Each module is  called a
491     `component'  and is  made  of two  files  in the  C version  (an
492     interface with suffix  `.h' and body with suffix  `.c' ) and one
493     file in the Pascal one.
495   - The  very  low-level  components   can  be  easily  replaced  by
496     system-specific  ones that  do not  rely on  the  standard libc.
497     These  components  deal  mainly  with  i/o,  memory,  and  mutex
498     operations.
500   - A client application must  only include one interface file named
501     `freetype.h' resp. `freetype.pas' to  use the engine.  All other
502     components  should   never  be   used  or  accessed   by  client
503     applications, and their name always begin with a `tt' prefix:
505       ttmemory, ttobjs, ttinterp, ttapi, etc.
507   - All  configuration  options  are  gathered in  two  files.   One
508     contains  the processor and  OS specific  configuration options,
509     while the other  treats options that may be  enabled or disabled
510     by  the developer  to test  specific features  (like assertions,
511     debugging, etc).
513   IMPORTANT NOTES:
515     These restrictions  only apply to the core  engine.  The package
516     that comes  with it contains several test  programs sources that
517     are much  less portable,  even if they  present a  modular model
518     inspired from the engine's layout.
520   The components currently found in the `lib' directory are:
522     -------- high-level interface ----------------------------------
524     freetype.h    High-level API, to be used by client applications.
526     ttapi.c       Implementation of the api found in `freetype.h'.
528     -------- configuration -----------------------------------------
530     ttconfig.h    Engine configuration options.  These are commented
531                   and  switched  by  hand  by  the  developer.   See
532                   section 2 below for more info.
534     ft-conf.h     Included  by ttconfig.h, this  file isn't  part of
535                   the  `lib' directory,  but depends  on  the target
536                   environment.  See section 2 blow for more info.
537                  
538     -------- definitions -------------------------------------------
540     tttypes.h     The engine's internal types definitions.
541     tttables.h    The TrueType tables definitions, per se the Specs.
542     tttags.h      The TrueType table tags definitions.
543     tterror.[ch]  The error and debugging component.
545     ttdebug.[ch]  Only used  by the  debugger, should not  be linked
546                   into a release build.
548     ttcalc.[ch]   Math component  used to perform  some computations
549                   with an intermediate 64-bit precision.
551     -------- replaceable components --------------------------------
553     ttmemory.[ch] Memory component.  This version uses the ANSI libc
554                   but can be replaced easily by your own version.
556     ttfile.[ch]   Stream i/o component.   This version uses the ANSI
557                   libc  but  can  be  replaced easily  by  your  own
558                   version.   Compiled only  if  file  memory mapping
559                   isn't available on your system.
561     ttfile2.[ch]  Unix-specific file  memory mapping version  of the
562                   file  component.    It  won't  compile   on  other
563                   systems.   Usually  results  in much  faster  file
564                   access (about 2x on a SCSI P166 system)
566     ttmutex.[ch]  Generic mutex component.   This version is a dummy
567                   and should only be used for a single-thread build.
568                   You _need_  to replace this  component's body with
569                   your  own implementation  to  be able  to build  a
570                   threaded version of the engine.
572     -------- data management ---------------------------------------
574     ttengine.h    The engine instance record definition, root of all
575                   engine data.
577     ttlists.[ch]  Generic lists manager.
578     ttcache.[ch]  Generic cache manager.
580     ttobjs.[ch]   The     engine's     object    definitions     and
581                   implementations    module   contains   structures,
582                   constructors,  destructors  and  methods  for  the
583                   following objects:
585                     face, instance, glyph, execution_context
587     ttload.[c]    The TrueType tables loader.
589     ttgload.[ch]  The glyph  loader.  A component in  itself, due to
590                   the task's complexity.
592     ttindex.[ch]  The  character mapping  to glyph  index conversion
593                   routines.    Implements   functions   defined   in
594                   `freetype.h'.
596     ttinterp.[ch] The  TrueType instructions  interpreter.  Probably
597                   the  nicest source  in  this engine.   Apparently,
598                   many have  failed to produce a  comparable one due
599                   to the very poorly written specification!  It took
600                   David Turner three months of his spare time to get
601                   it working correctly! :-)
603     ttraster.[ch] The  engine's  second  best  piece.  This  is  the
604                   scan-line    converter.     Performs    gray-level
605                   rendering (also  known as font-smoothing)  as well
606                   as dropout-control.
609 2. Configuration and Debugging
610 ------------------------------
612   As stated above, configuration depends on two files:
614   The environment configuration file `ft-conf.h':
616     This file contains the definitions of many configuration options
617     that are processor and OS-dependent.  On Unix systems, this file
618     is generated automatically by  the `configure' script that comes
619     with the released package.
620     
621     On other environments, it is  located in one of the architecture
622     directories found in `arch' (e.g. `arch/os2/ft-conf.h').
623   
624     The  path to this  file should  be passed  to the  compiler when
625     compiling _each_ component. (typically with an -I option).
627   The engine configuration file `ttconfig.h':
629     This file contains many configuration options that the developer
630     can turn  on or  off to experiment  with some `features'  of the
631     engine that  are not part  of its `simplest' form.   The options
632     are commented.
634   Note that the makefiles are compiler-specific.
636   It is possible  to enable the dumping of  debugging information by
637   compiling the  components with  the various debug  macros.  Please
638   consult the file `ttconfig.h' for details.
640   If you  want to port the  engine to another  environment, you will
641   need to
643   - Write a  new `ft-conf.h'  file for it.   Just copy one  of those
644     available  and   change  the  flags   accordingly  (they're  all
645     commented).
646     
647   - Replace  the  memory, file,  and  mutex  components with  yours,
648     presenting the same interface and behaviour.
649     
650   - Eventually   add   some    code   in   ttapi.c   to   initialize
651     system-specific data with the engine.
655 III. Usage conventions
656 ======================
659 1. Error Handling
660 -----------------
662   Error handling has  been refined to allow reentrant  builds of the
663   library, available  only in the C  version.  We thus  have now two
664   different conventions.
666   In Pascal:
668     A global error  variable is used to report  errors when they are
669     detected.  All functions return a boolean that indicates success
670     or  failure of  the call.   If an  error occurs  within  a given
671     function,  the latter  must set  the error  variable  and return
672     `false' (which means failure).
673   
674     It  is then  possible to  make several  calls in  a  single `if'
675     statement like:
676   
677        if  not Perform_Action_1( parms_of_1 )  or
678            not Perform_Action_2( parms_of_2 )  or
679            not Perform_Action_3( parms_of_3 )  then goto Fail;
680   
681     where execution will jump to  the `Fail' label whenever an error
682     occurs in the sequence of actions invoked in the condition.
684   In C:
686     Global errors are forbidden in re-entrant builds.  Each function
687     thus returns directly an error  code.  A return value of 0 means
688     that no error occured, while  a non-zero other value indicates a
689     failure of any kind.
691     This convention  is more constraining  than the one used  in the
692     Pascal source.  The above  Pascal statement should be translated
693     into the following C fragment:
695       rc = Perform_Action_1( parms_of_1 );
696       if ( rc )
697         goto Fail;
699       rc = Perform_Action_2( parms_of_2 );
700       if ( rc )
701         goto Fail;
703       rc = Perform_Action_3( parms_of_3 );
704       if ( rc )
705         goto Fail;
707     which, while being equivalent, isn't as pleasantly readable.
709     One  `simple' way  to match  the original  fragment would  be to
710     write:
712       if ( (rc = Perform_Action_1( parms_of_1 )) ||
713            (rc = Perform_Action_2( parms_of_2 )) ||
714            (rc = Perform_Action_3( parms_of_3 )) )
715         goto Fail;
717     which is  better but uses assignments  within expressions, which
718     are always delicate to manipulate in C (the risk of writing `=='
719     exists, and  would go unnoticed  by a compiler).   Moreover, the
720     assignments are  a bit redundant  and don't express  much things
721     about  the  actions performed  (they  only  speak  of the  error
722     management issue).
724     That  is  why  some  macros  have  been  defined  for  the  most
725     frequently  used functions.  They  relate to  low-level routines
726     that  are  called very  often  (mainly  i/o,  mutex, and  memory
727     handling functions).  Each macro produces an implicit assignment
728     to a variable called `error' and can be used instead as a simple
729     function call.  Example:
731       if ( PERFORM_Action_1( parms_of_1 ) ||
732            PERFORM_Action_2( parms_of_2 ) ||
733            PERFORM_Action_3( parms_of_3 ) )
734         goto Fail;
736     with
737       
738       #define PERFORM_Action_1( parms_1 ) \
739                 ( error = Perform_Action_1( parms_1 ) )
740       #define PERFORM_Action_2( parms_1 ) \
741                 ( error = Perform_Action_2( parms_1 ) )
742       #define PERFORM_Action_3( parms_1 ) \
743                 ( error = Perform_Action_3( parms_1 ) )
745     defined at the beginning of the file.
747     There,  the  developer only  needs  to  define  a local  `error'
748     variable and use the macros directly in the code, without caring
749     about the  actual error handling performed.  Examples  of such a
750     usage can be found in `ttload.c' and `ttgload.c'.  Moreover, the
751     structure of  the source files remain very  similar, even though
752     the error handling is very different.
753     
754     This  convention is  very  close  to the  use  of exceptions  in
755     languages  like C++,  Pascal,  Java, etc.   where the  developer
756     focuses on the actions to perform, and not on every little error
757     checking.
760 2. Font File I/O
761 ----------------
763   a. Streams
765     The engine uses `streams' to access the font files.  A stream is
766     a   structure  defined  in   the  `File'   component  containing
767     information used  to access files through  a system-specific i/o
768     library.
770     The current  implementation of the File component  uses the ANSI
771     libc i/o functions.  However, for the sake of embedding in light
772     systems and independence  of a complete libc, it  is possible to
773     re-implement the component for  a specific system or OS, letting
774     it use system calls.
775     
776     A stream is of type `TStream' defined in the `TTObjs' interface.
777     The type is `(void*)' but actually points to a structure defined
778     within the File component.
780     A stream is created, managed and closed through the interface of
781     the  `File'  component.   Several  implementations of  the  same
782     component can co-exist, each taking advantage of specific system
783     features  (the  file `ttfile2.c'  uses  memory-mapped files  for
784     instance) as long as it respects the interface.
786   b. Frames
788     TrueType is  tied to the  big-endian format, which  implies that
789     reading shorts or longs from  the font file may need conversions
790     depending on the target processor.   To be able to easily detect
791     read  errors and allow  simple conversion  calls or  macros, the
792     engine is able to access a font file using `frames'.
794     A frame is simply a  sequence of successive bytes taken from the
795     input file at the current  position.  A frame is pre-loaded into
796     memory by a `TT_Access_Frame()' call of the `File' component.
798     It  is then  possible  to read  all  sizes of  data through  the
799     `Get_xxx()'    functions,    like    Get_Byte(),    Get_Short(),
800     Get_UShort(), etc.
802     When all important data is read,  the frame can be released by a
803     call to `TT_Forget_Frame()'.
805     The  benefits  of  frames   are  various.   Consider  these  two
806     approaches at extracting values:
808       if ( (error = Read_Short( &var1 )) ||
809            (error = Read_Long ( &var2 )) ||
810            (error = Read_Long ( &var3 )) ||
811            (error = Read_Short( &var4 )) )
813         return FAILURE;
815     and
817                             /* Read the next 16 bytes */
818       if ( (error = TT_Access_Frame( 16L )) )
819         return error;       /* The Frame could not be read */
821       var1 = Get_Short();   /* extract values from the frame */
822       var2 = Get_Long();
823       var3 = Get_Long();
824       var4 = Get_Short();
826       TT_Forget_Frame();   /* release the frame */
828     In the  first case, there  are four error assignments  with four
829     checks of the file  read.  This unnecessarily increases the size
830     of the generated  code.  Moreover, you must be  sure that `var1'
831     and `var4' are short variables,  `var2' and `var3' long ones, if
832     you want to avoid bugs and/or compiler warnings.
834     In the second case, you perform only one check for the read, and
835     exit immediately on failure.  Then the values are extracted from
836     the frame, as the result of function calls.  This means that you
837     can  use  automatic type  conversion;  there  is  no problem  if
838     e.g. `var1' and `var4' are longs, unlike previously.
840     On big-endian machines, the  `Get_xxx()' functions could also be
841     simple  macros that  merely peek  the values  directly  from the
842     frame, which speeds up and simplifies the generated code!
844     And finally,  frames are ideal when you  are using memory-mapped
845     files, as  the frame is  not really `pre-loaded' and  never uses
846     any `heap' space.
848     IMPORTANT: You  CANNOT nest  several frame  accesses.   There is
849                only  one frame available  at a  time for  a specific
850                instance.
852                It is  also the programmer's  responsibility to never
853                extract more  data than was pre-loaded  in the frame!
854                (But  you usually know  how many  values you  want to
855                extract from the file before doing so).
858 3. Memory Management
859 --------------------
861   The library  now uses  a component which  interface is  similar to
862   malloc()/free().  It defines only two functions.
864   * Alloc()
866     To be used like malloc(),  except that it returns an error code,
867     not an  address.  Its  arguments are the  size of  the requested
868     block  and the  address of  the  target pointer  to the  `fresh'
869     block.  An error  code is returned in case  of failure (and this
870     will also set the target pointer to NULL), 0 in case of success.
872     Alloc() should always respect the following rules:
874     - Requesting a block of size  0 should set the target pointer to
875       NULL and return no error code (i.e., return 0).
877     - The  returned block is  always zeroed.   This is  an important
878       assumption of other parts of the library.
880     If  you wish  to replace  the  memory component  with your  own,
881     please  respect  this  behaviour,  or  your  engine  won't  work
882     correctly.
884   * Free()
886     As   you  may   have  already   guessed,  Free()   is  Alloc()'s
887     counterpart.   It  takes   as  argument  the  _target  pointer's
888     address_!  You should _never_ pass the block's address directly,
889     i.e. the pointer, to Free().
891     Free should always respect the following rules:
893     - Calling  it with a  NULL argument,  or the  address of  a NULL
894       pointer is valid, and should return success.
896     - The  pointer   is  always  set  to  NULL   after  the  block's
897       deallocation.  This  is also  an important assumption  of many
898       other parts of the library.
900     If  you wish  to replace  the  memory component  with your  own,
901     please  respect  this  behaviour,  or  your  engine  won't  work
902     correctly.
904   As the pointers addresses  needed as arguments are typed `void**',
905   the  component's interface  also provides  in the  C  version some
906   macros to help use them more easily, these are:
908     MEM_Alloc     A version of Alloc that casts the argument pointer
909                   to (void**).
911     ALLOC         Same  as MEM_Alloc,  but with  an assignment  to a
912                   variable called  `error'.  See the  section `error
913                   handling' above for more info on this.
915     FREE          A  version  of  Free()  that  casts  the  argument
916                   pointer to (void**).   There is currently no error
917                   handling by with this macro.
919     MEM_Set       An  alias  for  `memset()',  which can  be  easily
920                   changed  to anything  else if  you wish  to  use a
921                   different   memory  manager  than   the  functions
922                   provided by the ANSI libc.
924     MEM_Copy      An alias  of `memcpy()' or `bcopy()'  used to move
925                   blocks of memory.  You  may change it to something
926                   different if  you wish to use  something else that
927                   your standard libc.
930 4. Support for threaded environments
931 ------------------------------------
933   Support  for  threaded  environments  have  been added  to  the  C
934   sources, and  only to  these.  It is  now theorically  possible to
935   build three distinct versions of the library:
937     single-thread build:
939       The  default build.   This one  doesn't known  about different
940       threads.  Hence, no code is generated to perform coherent data
941       sharing and locking.
943     thread-safe build:
945       With this  build, several threads  can use the library  at the
946       same time.  However,  some key components can only  be used by
947       one single  thread at a time,  and use a  mutex to synchronize
948       access to their functions.   These are mainly the file, raster
949       and interpreter components.
951     re-entrant build:
953       A  re-entrant version is  able to  perform certain  actions in
954       parallel  that  a   thread-safe  one  cannot.   This  includes
955       accessing   file(s)   in   parallel,  interpreting   different
956       instruction streams in  parallel, or even scan-line converting
957       distinct glyphs at the same time.
959   Note that most of the latest  changes in the engine are making the
960   distinction between the  thread-safe and re-entrant builds thinner
961   than ever.
963   There is  a `ttmutex' component that presents  a generic interface
964   to  mutex  operations.  It   should  be  re-implemented  for  each
965   platform.
967 <to be continued>
970 --- end of convntns.txt ---