ref: 05f0ad098fc1486410426eca2c32bd784b021ef9
parent: 40822003da490f6897d7068591e428bc83648dac
author: Werner Lemberg <[email protected]>
date: Thu Oct 19 01:12:00 EDT 2000
Converting tabs to spaces in z1load. Edited FT1's convntns.txt and added it to FT2.
--- /dev/null
+++ b/docs/convntns.txt
@@ -1,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 ---
--- a/src/type1z/z1load.c
+++ b/src/type1z/z1load.c
@@ -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,9 +1341,10 @@
/* 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],
name_table->lengths [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;
}
}