📄 convntns.txt
字号:
. 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, empty parameters, and the closing semicolon, parentheses are surrounded with space: x = (char*)( foo + bar ); y = rand(); . 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(); Exception: for (;;) { ... . 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 ---
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -