📄 convntns.txt
字号:
Conventions and Design in the FreeType 2 library ------------------------------------------------Table of ContentsIntroductionI. Style and Formatting 1. Naming 2. Declarations & Statements 3. Blocks 4. Macros 5. ConventionsII. Design conventions 1. Modularity and Components Layout 2. Configuration and DebuggingIII. Usage conventions 1. Error handling 2. Font File I/O 3. Memory management 4. Support for threaded environments 5. Object ManagementIntroduction============This text introduces the many conventions used within the FreeType 2library code. Please read it before trying any modifications orextensions of the source code.I. Style and Formatting=======================The following coding rules are extremely important to keep thelibrary's source code homogeneously. Keep in mind the followingpoints: - `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; However, when declaring resp. defining an `output' parameter (i.e. a pointer which will be assigned by the function), the last `*' must be placed on the right in order to denote this, as in: FT_New_Face( FT_Library library, FT_Face *aface ); where the `*' is used to indicate that `aface' is returned. In most cases, the name of such an output variable starts with `a' or `an' (`aface' instead of `face', `anlru' instead of `lru', etc.), following the English rules of the indefinite article. . As mentioned above, multiple declarations are vertically aligned: FT_Short foo; FT_Long bar; FT_GlyphSlot slot;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -