* src/tools/glnames.py: Formatted.

Format output to be in sync with other FreeType code.
Import `re' and `os.path'.
(StringTable) <__init__>: Add parameter to initialize master table
name.
(StringTable) <dump>: Don't pass master table name.
(StringTable) <dump_sublist>: Emit explanatory comment.
Simplify and make output more human readable.
(t1_bias, glyph_list, adobe_glyph_names): Removed.  Unused.
(main): Use `basename' for file name in header.

* src/psnames/pstables.h: Regenerated.

Other formatting.
This commit is contained in:
Werner Lemberg 2005-03-10 06:28:07 +00:00
parent 705620beeb
commit 56ef6bc4d6
5 changed files with 4523 additions and 4303 deletions

View File

@ -1,16 +1,33 @@
2005-03-10 Werner Lemberg <wl@gnu.org>
* src/tools/glnames.py: Formatted.
Format output to be in sync with other FreeType code.
Import `re' and `os.path'.
(StringTable) <__init__>: Add parameter to initialize master table
name.
(StringTable) <dump>: Don't pass master table name.
(StringTable) <dump_sublist>: Emit explanatory comment.
Simplify and make output more human readable.
(t1_bias, glyph_list, adobe_glyph_names): Removed. Unused.
(main): Use `basename' for file name in header.
* src/psnames/pstables.h: Regenerated.
2005-03-09 David Turner <david@freetype.org> 2005-03-09 David Turner <david@freetype.org>
* src/tools/glnames.py: rewrote the generator for the 'pstables.h' * src/tools/glnames.py: Rewrite the generator for the `pstables.h'
header, which contains various constant tables related to glyph header file which contains various constant tables related to glyph
names. It now uses a different storage scheme that saves about 20 names. It now uses a different, more compact storage scheme that
Kb and closes bug #12262 saves about 20KB. This also closes Savannah bug #12262.
* src/psnames/pstables.h: re-generated header file * src/psnames/pstables.h: Regenerated.
* src/psnames/psmodule.c: rewrote some parts to comply with recent * src/psnames/psmodule.c (ps_unicode_value): Use
changes in 'pstables.h' `ft_get_adobe_glyph_index', a new function defined in `pstables.h'.
(ps_get_macintosh_name, ps_get_standard_strings): Updated.
* src/base/ftobjs.c (FT_Set_Char_Sizes): fix for bug #12263 * src/base/ftobjs.c (FT_Set_Char_Sizes): Handle fractional sizes
more carefully. This fixes Savannah bug #12263.
2005-03-06 David Turner <david@freetype.org> 2005-03-06 David Turner <david@freetype.org>

View File

@ -2011,11 +2011,16 @@
FT_UShort x_ppem = (FT_UShort)( ( dim_x + 32 ) >> 6 ); FT_UShort x_ppem = (FT_UShort)( ( dim_x + 32 ) >> 6 );
FT_UShort y_ppem = (FT_UShort)( ( dim_y + 32 ) >> 6 ); FT_UShort y_ppem = (FT_UShort)( ( dim_y + 32 ) >> 6 );
/* this code is disabled, for an explanation, see bug#12263 */
/* Don't take, say, 12.5x12.5 equal to 13x13. If working with */
/* fractional font sizes this would hide slightly different */
/* font metrics. Consequently, the next two lines are */
/* disabled. */
#if 0 #if 0
if ( x_ppem == metrics->x_ppem && y_ppem == metrics->y_ppem ) if ( x_ppem == metrics->x_ppem && y_ppem == metrics->y_ppem )
return FT_Err_Ok; return FT_Err_Ok;
#endif #endif
metrics->x_ppem = x_ppem; metrics->x_ppem = x_ppem;
metrics->y_ppem = y_ppem; metrics->y_ppem = y_ppem;
} }

View File

@ -4,7 +4,7 @@
/* */ /* */
/* PSNames module implementation (body). */ /* PSNames module implementation (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003 by */ /* Copyright 1996-2001, 2002, 2003, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -32,9 +32,9 @@
#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
/* return the Unicode value corresponding to a given glyph. Note that */ /* Return the Unicode value corresponding to a given glyph. Note that */
/* we do deal with glyph variants by detecting a non-initial dot in */ /* we do deal with glyph variants by detecting a non-initial dot in */
/* the name, as in `A.swash' or `e.final', etc. */ /* the name, as in `A.swash' or `e.final'. */
/* */ /* */
static FT_UInt32 static FT_UInt32
ps_unicode_value( const char* glyph_name ) ps_unicode_value( const char* glyph_name )

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
# #
# Copyright 1996-2000, 2003 by # Copyright 1996-2000, 2003, 2005 by
# David Turner, Robert Wilhelm, and Werner Lemberg. # David Turner, Robert Wilhelm, and Werner Lemberg.
# #
# This file is part of the FreeType project, and may only be used, modified, # This file is part of the FreeType project, and may only be used, modified,
@ -20,20 +20,23 @@
usage: %s <output-file> usage: %s <output-file>
This very simple python script is used to generate the glyph names This python script generates the glyph names tables defined in the
tables defined in the PSNames module. PSNames module.
Its single argument is the name of the header file to be created. Its single argument is the name of the header file to be created.
""" """
import sys, string, struct import sys, string, struct, re, os.path
# This table is used to name the glyphs according to the Macintosh # This table lists the glyphs according to the Macintosh specification.
# specification. It is used by the TrueType Postscript names table. # It is used by the TrueType Postscript names table.
#
# See
#
# http://fonts.apple.com/TTRefMan/RM06/Chap6post.html
# #
# See http://fonts.apple.com/TTRefMan/RM06/Chap6post.html
# for the official list. # for the official list.
# #
mac_standard_names = \ mac_standard_names = \
@ -145,9 +148,10 @@ mac_standard_names = \
] ]
# The list of standard "SID" glyph names. For the official list, # The list of standard `SID' glyph names. For the official list,
# see Annex A of document at # see Annex A of document at
# http://partners.adobe.com/asn/developer/pdfs/tn/5176.CFF.pdf. #
# http://partners.adobe.com/asn/developer/pdfs/tn/5176.CFF.pdf.
# #
sid_standard_names = \ sid_standard_names = \
[ [
@ -4702,128 +4706,127 @@ zukatakana;30BA
# string table management # string table management
# #
class StringTable: class StringTable:
def __init__(self,name_list): def __init__( self, name_list, master_table_name ):
self.names = name_list self.names = name_list
self.indices = {} self.master_table = master_table_name
index = 0 self.indices = {}
index = 0
for name in name_list: for name in name_list:
self.indices[name] = index self.indices[name] = index
index += len(name) + 1 index += len( name ) + 1
self.total = index self.total = index
def dump(self,file,table_name): def dump( self, file ):
write = file.write write = file.write
write( "static const char " + table_name + "["+repr(self.total)+"] =\n" ) write( " static const char " + self.master_table +
write( "{\n" ) "[" + repr( self.total ) + "] =\n" )
column = 0 write( " {\n" )
line = " "
comma = "" line = ""
for name in self.names: for name in self.names:
for n in range(len(name)): line += " '"
line += comma line += string.join( ( re.findall( ".", name ) ), "','" )
line += "'%c'" % name[n] line += "', 0,\n"
comma = ","
column += 1
if column == 16:
column = 0
comma = ",\n "
line += comma
line += " 0 "
comma = ","
column += 1
if column == 16:
column = 0
comma = ",\n "
if column != 0: write( line + " };\n\n\n" )
line += "\n"
write( line + "};\n\n" ) def dump_sublist( self, file, table_name, macro_name, sublist ):
def dump_sublist(self,file,table_name,macro_name,sublist):
write = file.write write = file.write
write( "#define "+macro_name+" "+repr(len(sublist))+"\n\n" ) write( "#define " + macro_name + " " + repr( len( sublist ) ) + "\n\n" )
write( "static const short " + table_name + "["+repr(len(sublist))+"] =\n" )
write( "{\n" ) write( " /* Values are offsets into the `" +
line = " " self.master_table + "' table */\n\n" )
write( " static const short " + table_name +
"[" + macro_name + "] =\n" )
write( " {\n" )
line = " "
comma = "" comma = ""
col = 0 col = 0
for name in sublist: for name in sublist:
line += comma line += comma
line += "%4d" % self.indices[name] line += "%4d" % self.indices[name]
col += 1 col += 1
comma = "," comma = ","
if col == 14: if col == 14:
col = 0 col = 0
comma = ",\n " comma = ",\n "
write( line + "\n};\n\n" ) write( line + "\n };\n\n\n" )
class StringNode: class StringNode:
def __init__(self,letter,value): def __init__( self, letter, value ):
self.letter = letter self.letter = letter
self.value = value self.value = value
self.children = {} self.children = {}
def __cmp__(self,other): def __cmp__( self, other ):
return ord(self.letter[0]) - ord(other.letter[0]) return ord( self.letter[0] ) - ord( other.letter[0] )
def add(self,word,value): def add( self, word, value ):
if len(word) == 0: if len( word ) == 0:
self.value = value self.value = value
return return
letter = word[0] letter = word[0]
word = word[1:] word = word[1:]
if self.children.has_key(letter):
if self.children.has_key( letter ):
child = self.children[letter] child = self.children[letter]
else: else:
child = StringNode(letter,0) child = StringNode( letter, 0 )
self.children[letter] = child self.children[letter] = child
child.add(word,value)
def optimize(self): child.add( word, value )
def optimize( self ):
# optimize all children first # optimize all children first
children = self.children.values() children = self.children.values()
self.children = {} self.children = {}
for child in children: for child in children:
self.children[child.letter[0]] = child.optimize() self.children[child.letter[0]] = child.optimize()
# don't optimize if there's a value, # don't optimize if there's a value,
# if we don't have any child or if we # if we don't have any child or if we
# have more than one child # have more than one child
if (self.value != 0) or (not children) or len(children) > 1: if ( self.value != 0 ) or ( not children ) or len( children ) > 1:
return self return self
child = children[0] child = children[0]
self.letter += child.letter
self.value = child.value self.letter += child.letter
self.value = child.value
self.children = child.children self.children = child.children
return self return self
def dump_debug(self,write,margin): def dump_debug( self, write, margin ):
# this is used during debugging # this is used during debugging
line = margin + "+-" line = margin + "+-"
if len(self.letter) == 0: if len( self.letter ) == 0:
line += "<NOLETTER>" line += "<NOLETTER>"
else: else:
line += self.letter line += self.letter
if self.value: if self.value:
line += " => " + repr(self.value) line += " => " + repr( self.value )
write( line + "\n" )
write( line+"\n" )
if self.children: if self.children:
margin += "| " margin += "| "
for child in self.children.values(): for child in self.children.values():
child.dump_debug(write,margin) child.dump_debug( write, margin )
def locate(self,index): def locate( self, index ):
self.index = index self.index = index
if len(self.letter) > 0: if len( self.letter ) > 0:
index += len(self.letter)+1 index += len( self.letter ) + 1
else: else:
index += 2 index += 2
@ -4832,30 +4835,33 @@ class StringNode:
children = self.children.values() children = self.children.values()
children.sort() children.sort()
index += 2*len(children)
index += 2 * len( children )
for child in children: for child in children:
index = child.locate(index) index = child.locate( index )
return index return index
def store(self,storage): def store( self, storage ):
# write the letters # write the letters
l = len(self.letter) l = len( self.letter )
if l == 0: if l == 0:
storage += struct.pack("B",0) storage += struct.pack( "B", 0 )
else: else:
for n in range(l): for n in range( l ):
val = ord(self.letter[n]) val = ord( self.letter[n] )
if n < l-1: if n < l - 1:
val += 128 val += 128
storage += struct.pack("B",val) storage += struct.pack( "B", val )
# write the count # write the count
children = self.children.values() children = self.children.values()
children.sort() children.sort()
count = len(children)
count = len( children )
if self.value != 0: if self.value != 0:
storage += struct.pack( "!BH", count+128, self.value ) storage += struct.pack( "!BH", count + 128, self.value )
else: else:
storage += struct.pack( "B", count ) storage += struct.pack( "B", count )
@ -4863,28 +4869,10 @@ class StringNode:
storage += struct.pack( "!H", child.index ) storage += struct.pack( "!H", child.index )
for child in children: for child in children:
storage = child.store(storage) storage = child.store( storage )
return storage return storage
t1_bias = 0
glyph_list = []
def adobe_glyph_names():
"""return the list of glyph names from the adobe list"""
lines = string.split( adobe_glyph_list, '\n' )
glyphs = []
for line in lines:
if line:
fields = string.split( line, ';' )
# print fields[1] + ' - ' + fields[0]
glyphs.append( fields[0] )
return glyphs
def adobe_glyph_values(): def adobe_glyph_values():
"""return the list of glyph names and their unicode values""" """return the list of glyph names and their unicode values"""
@ -4906,7 +4894,7 @@ def adobe_glyph_values():
def filter_glyph_names( alist, filter ): def filter_glyph_names( alist, filter ):
"""filter 'alist' by taking _out_ all glyph names that are in 'filter'""" """filter `alist' by taking _out_ all glyph names that are in `filter'"""
count = 0 count = 0
extras = [] extras = []
@ -4920,17 +4908,16 @@ def filter_glyph_names( alist, filter ):
return extras return extras
def dump_encoding( file, encoding_name, encoding_list ): def dump_encoding( file, encoding_name, encoding_list ):
"""dumps a given encoding""" """dump a given encoding"""
write = file.write write = file.write
write( "/* the following are indices into the SID name table */\n" ) write( " /* the following are indices into the SID name table */\n" )
write( "static const unsigned short " + encoding_name + "[" + \ write( " static const unsigned short " + encoding_name +
repr( len( encoding_list ) ) + "] =\n" ) "[" + repr( len( encoding_list ) ) + "] =\n" )
write( "{\n" ) write( " {\n" )
line = " " line = " "
comma = "" comma = ""
col = 0 col = 0
for value in encoding_list: for value in encoding_list:
@ -4940,35 +4927,37 @@ def dump_encoding( file, encoding_name, encoding_list ):
col += 1 col += 1
if col == 16: if col == 16:
col = 0 col = 0
comma = ",\n " comma = ",\n "
write( line + "\n};\n\n" ) write( line + "\n };\n\n\n" )
def dump_array( the_array, write, array_name ): def dump_array( the_array, write, array_name ):
"""dumps a given encoding""" """dumps a given encoding"""
write( "static const unsigned char " + array_name + "[" + \ write( " static const unsigned char " + array_name +
repr(len(the_array)) + "] =\n" ) "[" + repr( len( the_array ) ) + "] =\n" )
write( "{\n" ) write( " {\n" )
line = "" line = ""
comma = " " comma = " "
col = 0 col = 0
for value in the_array: for value in the_array:
line += comma line += comma
line += "%3d" % ord(value) line += "%3d" % ord( value )
comma = "," comma = ","
col += 1 col += 1
if col == 16:
col = 0
comma = ",\n "
if len(line) > 1024: if col == 16:
col = 0
comma = ",\n "
if len( line ) > 1024:
write( line ) write( line )
line = "" line = ""
write( line + "\n};\n\n" ) write( line + "\n };\n\n\n" )
def main(): def main():
@ -4983,23 +4972,22 @@ def main():
count_sid = len( sid_standard_names ) count_sid = len( sid_standard_names )
# 'mac_extras' contains the list of glyph names in the Macintosh standard # `mac_extras' contains the list of glyph names in the Macintosh standard
# encoding which are not in the SID Standard Names. # encoding which are not in the SID Standard Names.
# #
mac_extras = filter_glyph_names( mac_standard_names, sid_standard_names ) mac_extras = filter_glyph_names( mac_standard_names, sid_standard_names )
# 'base_list' contains the names of our final glyph names table. # `base_list' contains the names of our final glyph names table.
# It consists of the 'mac_extras' glyph names, followed by the SID # It consists of the `mac_extras' glyph names, followed by the SID
# Standard names. # standard names.
# #
mac_extras_count = len( mac_extras ) mac_extras_count = len( mac_extras )
t1_bias = mac_extras_count
base_list = mac_extras + sid_standard_names base_list = mac_extras + sid_standard_names
write( "/***************************************************************************/\n" ) write( "/***************************************************************************/\n" )
write( "/* */\n" ) write( "/* */\n" )
write( "/* %-71s*/\n" % sys.argv[1] ) write( "/* %-71s*/\n" % os.path.basename( sys.argv[1] ) )
write( "/* */\n" ) write( "/* */\n" )
write( "/* PostScript glyph names. */\n" ) write( "/* PostScript glyph names. */\n" )
@ -5016,17 +5004,19 @@ def main():
write( "/***************************************************************************/\n" ) write( "/***************************************************************************/\n" )
write( "\n" ) write( "\n" )
write( "\n" ) write( "\n" )
write( " /* ALL of this file has been generated automatically -- do not edit! */\n" ) write( " /* This file has been generated automatically -- do not edit! */\n" )
write( "\n" ) write( "\n" )
write( "\n" ) write( "\n" )
# dump final glyph list (mac extras + sid standard names) # dump final glyph list (mac extras + sid standard names)
# #
st = StringTable(base_list) st = StringTable( base_list, "ft_standard_glyph_names" )
st.dump(file,"ft_standard_glyph_names") st.dump( file )
st.dump_sublist(file,"ft_mac_names","FT_NUM_MAC_NAMES",mac_standard_names) st.dump_sublist( file, "ft_mac_names",
st.dump_sublist(file,"ft_sid_names","FT_NUM_SID_NAMES",sid_standard_names) "FT_NUM_MAC_NAMES", mac_standard_names )
st.dump_sublist( file, "ft_sid_names",
"FT_NUM_SID_NAMES", sid_standard_names )
dump_encoding( file, "t1_standard_encoding", t1_standard_encoding ) dump_encoding( file, "t1_standard_encoding", t1_standard_encoding )
dump_encoding( file, "t1_expert_encoding", t1_expert_encoding ) dump_encoding( file, "t1_expert_encoding", t1_expert_encoding )
@ -5035,32 +5025,33 @@ def main():
# #
agl_glyphs, agl_values = adobe_glyph_values() agl_glyphs, agl_values = adobe_glyph_values()
dict = StringNode( "", 0 ) dict = StringNode( "", 0 )
for g in range(len(agl_glyphs)):
dict.add(agl_glyphs[g],eval("0x"+agl_values[g]))
dict = dict.optimize() for g in range( len( agl_glyphs ) ):
dict_len = dict.locate(0) dict.add( agl_glyphs[g], eval( "0x" + agl_values[g] ) )
dict_array = dict.store("")
write( """ dict = dict.optimize()
/* this table is a compressed version of the Adobe Glyph List dict_len = dict.locate( 0 )
* which has been optimized for efficient searching. It has dict_array = dict.store( "" )
* been generated by the 'glnames.py' python script located
* in the 'src/tools' directory. write( """\
* /*
* the corresponding lookup function is defined just below * This table is a compressed version of the Adobe Glyph List (AGL),
* the table (several pages down this text :-) * optimized for efficient searching. It has been generated by the
*/ * `glnames.py' python script located in the `src/tools' directory.
*
* The lookup function to get the Unicode value for a given string
* is defined below the table.
*/
""" ) """ )
dump_array(dict_array,write,"ft_adobe_glyph_list") dump_array( dict_array, write, "ft_adobe_glyph_list" )
# write the lookup routine now # write the lookup routine now
# #
write( """ write( """\
/* this is the wicked routine used to search our compressed /*
* table efficiently * This function searches the compressed table efficiently.
*/ */
static unsigned long static unsigned long
ft_get_adobe_glyph_index( const char* name, ft_get_adobe_glyph_index( const char* name,
const char* limit ) const char* limit )
@ -5069,6 +5060,7 @@ def main():
int count, min, max; int count, min, max;
const unsigned char* p = ft_adobe_glyph_list; const unsigned char* p = ft_adobe_glyph_list;
if ( name == 0 || name >= limit ) if ( name == 0 || name >= limit )
goto NotFound; goto NotFound;
@ -5081,11 +5073,12 @@ def main():
while ( min < max ) while ( min < max )
{ {
int mid = (min+max) >> 1; int mid = ( min + max ) >> 1;
const unsigned char* q = p + mid*2; const unsigned char* q = p + mid * 2;
int c2; int c2;
q = ft_adobe_glyph_list + (((int)q[0] << 8) | q[1]);
q = ft_adobe_glyph_list + ( ( (int)q[0] << 8 ) | q[1] );
c2 = q[0] & 127; c2 = q[0] & 127;
if ( c2 == c ) if ( c2 == c )
@ -5094,7 +5087,7 @@ def main():
goto Found; goto Found;
} }
if ( c2 < c ) if ( c2 < c )
min = mid+1; min = mid + 1;
else else
max = mid; max = mid;
} }
@ -5109,7 +5102,7 @@ def main():
{ {
if ( (p[0] & 128) == 0 && if ( (p[0] & 128) == 0 &&
(p[1] & 128) != 0 ) (p[1] & 128) != 0 )
return (unsigned long)(((int)p[2] << 8) | p[3]); return (unsigned long)( ( (int)p[2] << 8 ) | p[3] );
goto NotFound; goto NotFound;
} }
@ -5132,10 +5125,10 @@ def main():
for ( ; count > 0; count--, p += 2 ) for ( ; count > 0; count--, p += 2 )
{ {
int offset = ((int)p[0] << 8) | p[1]; int offset = ( (int)p[0] << 8 ) | p[1];
const unsigned char* q = ft_adobe_glyph_list + offset; const unsigned char* q = ft_adobe_glyph_list + offset;
if ( c == (q[0] & 127) ) if ( c == ( q[0] & 127 ) )
{ {
p = q; p = q;
goto NextIter; goto NextIter;
@ -5159,33 +5152,36 @@ def main():
# #
write( "#ifdef TEST\n\n" ) write( "#ifdef TEST\n\n" )
write( "static const char* const the_names[] = {\n" ) write( "static const char* const the_names[] = {\n" )
for name in agl_glyphs: for name in agl_glyphs:
write( ' "'+name+'",\n' ) write( ' "' + name + '",\n' )
write( " 0\n};\n" ) write( " 0\n};\n" )
write( "static const unsigned long the_values[] = {\n" ) write( "static const unsigned long the_values[] = {\n" )
for val in agl_values: for val in agl_values:
write( ' 0x'+val+',\n' ) write( ' 0x' + val + ',\n' )
write( " 0\n};\n" ) write( " 0\n};\n" )
write( """ write( """
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
int main( void ) int
main( void )
{ {
int result = 0; int result = 0;
const char* const* names = the_names; const char* const* names = the_names;
const unsigned long* values = the_values; const unsigned long* values = the_values;
for ( ; *names; names++, values++ ) for ( ; *names; names++, values++ )
{ {
const char* name = *names; const char* name = *names;
unsigned long reference = *values; unsigned long reference = *values;
unsigned long value; unsigned long value;
value = ft_get_adobe_glyph_index( name, name + strlen(name) );
value = ft_get_adobe_glyph_index( name, name + strlen( name ) );
if ( value != reference ) if ( value != reference )
{ {
result = 1; result = 1;
@ -5197,9 +5193,10 @@ def main():
return result; return result;
} }
""" ) """ )
write( "#endif /* TEST */\n" ) write( "#endif /* TEST */\n" )
write("/* END */\n") write("\n/* END */\n")
# Now run the main routine # Now run the main routine