* 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:
parent
705620beeb
commit
56ef6bc4d6
33
ChangeLog
33
ChangeLog
@ -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>
|
||||
|
||||
* src/tools/glnames.py: rewrote the generator for the 'pstables.h'
|
||||
header, which contains various constant tables related to glyph
|
||||
names. It now uses a different storage scheme that saves about 20
|
||||
Kb and closes bug #12262
|
||||
* src/tools/glnames.py: Rewrite the generator for the `pstables.h'
|
||||
header file which contains various constant tables related to glyph
|
||||
names. It now uses a different, more compact storage scheme that
|
||||
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
|
||||
changes in 'pstables.h'
|
||||
* src/psnames/psmodule.c (ps_unicode_value): Use
|
||||
`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>
|
||||
|
||||
|
@ -2011,11 +2011,16 @@
|
||||
FT_UShort x_ppem = (FT_UShort)( ( dim_x + 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 ( x_ppem == metrics->x_ppem && y_ppem == metrics->y_ppem )
|
||||
return FT_Err_Ok;
|
||||
#endif
|
||||
|
||||
metrics->x_ppem = x_ppem;
|
||||
metrics->y_ppem = y_ppem;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* PSNames module implementation (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2005 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -32,9 +32,9 @@
|
||||
#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 */
|
||||
/* the name, as in `A.swash' or `e.final', etc. */
|
||||
/* the name, as in `A.swash' or `e.final'. */
|
||||
/* */
|
||||
static FT_UInt32
|
||||
ps_unicode_value( const char* glyph_name )
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@
|
||||
#
|
||||
|
||||
|
||||
# Copyright 1996-2000, 2003 by
|
||||
# Copyright 1996-2000, 2003, 2005 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
@ -20,20 +20,23 @@
|
||||
|
||||
usage: %s <output-file>
|
||||
|
||||
This very simple python script is used to generate the glyph names
|
||||
tables defined in the PSNames module.
|
||||
This python script generates the glyph names tables defined in the
|
||||
PSNames module.
|
||||
|
||||
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
|
||||
# specification. It is used by the TrueType Postscript names table.
|
||||
# This table lists the glyphs according to the Macintosh specification.
|
||||
# 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.
|
||||
#
|
||||
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
|
||||
# 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 = \
|
||||
[
|
||||
@ -4702,188 +4706,172 @@ zukatakana;30BA
|
||||
# string table management
|
||||
#
|
||||
class StringTable:
|
||||
def __init__(self,name_list):
|
||||
self.names = name_list
|
||||
self.indices = {}
|
||||
index = 0
|
||||
|
||||
def __init__( self, name_list, master_table_name ):
|
||||
self.names = name_list
|
||||
self.master_table = master_table_name
|
||||
self.indices = {}
|
||||
index = 0
|
||||
|
||||
for name in name_list:
|
||||
self.indices[name] = index
|
||||
index += len(name) + 1
|
||||
|
||||
self.total = index
|
||||
index += len( name ) + 1
|
||||
|
||||
def dump(self,file,table_name):
|
||||
self.total = index
|
||||
|
||||
def dump( self, file ):
|
||||
write = file.write
|
||||
write( "static const char " + table_name + "["+repr(self.total)+"] =\n" )
|
||||
write( "{\n" )
|
||||
column = 0
|
||||
line = " "
|
||||
comma = ""
|
||||
write( " static const char " + self.master_table +
|
||||
"[" + repr( self.total ) + "] =\n" )
|
||||
write( " {\n" )
|
||||
|
||||
line = ""
|
||||
for name in self.names:
|
||||
for n in range(len(name)):
|
||||
line += comma
|
||||
line += "'%c'" % name[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:
|
||||
line += "\n"
|
||||
|
||||
write( line + "};\n\n" )
|
||||
line += " '"
|
||||
line += string.join( ( re.findall( ".", name ) ), "','" )
|
||||
line += "', 0,\n"
|
||||
|
||||
def dump_sublist(self,file,table_name,macro_name,sublist):
|
||||
write = file.write
|
||||
write( "#define "+macro_name+" "+repr(len(sublist))+"\n\n" )
|
||||
write( "static const short " + table_name + "["+repr(len(sublist))+"] =\n" )
|
||||
write( "{\n" )
|
||||
line = " "
|
||||
comma = ""
|
||||
write( line + " };\n\n\n" )
|
||||
|
||||
def dump_sublist( self, file, table_name, macro_name, sublist ):
|
||||
write = file.write
|
||||
write( "#define " + macro_name + " " + repr( len( sublist ) ) + "\n\n" )
|
||||
|
||||
write( " /* Values are offsets into the `" +
|
||||
self.master_table + "' table */\n\n" )
|
||||
write( " static const short " + table_name +
|
||||
"[" + macro_name + "] =\n" )
|
||||
write( " {\n" )
|
||||
|
||||
line = " "
|
||||
comma = ""
|
||||
col = 0
|
||||
|
||||
for name in sublist:
|
||||
line += comma
|
||||
line += "%4d" % self.indices[name]
|
||||
col += 1
|
||||
comma = ","
|
||||
if col == 14:
|
||||
col = 0
|
||||
comma = ",\n "
|
||||
|
||||
write( line + "\n};\n\n" )
|
||||
|
||||
|
||||
class StringNode:
|
||||
def __init__(self,letter,value):
|
||||
self.letter = letter
|
||||
self.value = value
|
||||
self.children = {}
|
||||
|
||||
def __cmp__(self,other):
|
||||
return ord(self.letter[0]) - ord(other.letter[0])
|
||||
|
||||
def add(self,word,value):
|
||||
if len(word) == 0:
|
||||
self.value = value
|
||||
return
|
||||
letter = word[0]
|
||||
word = word[1:]
|
||||
if self.children.has_key(letter):
|
||||
child = self.children[letter]
|
||||
else:
|
||||
child = StringNode(letter,0)
|
||||
self.children[letter] = child
|
||||
child.add(word,value)
|
||||
|
||||
def optimize(self):
|
||||
# optimize all children first
|
||||
children = self.children.values()
|
||||
self.children = {}
|
||||
for child in children:
|
||||
self.children[child.letter[0]] = child.optimize()
|
||||
|
||||
# don't optimize if there's a value,
|
||||
# if we don't have any child or if we
|
||||
# have more than one child
|
||||
if (self.value != 0) or (not children) or len(children) > 1:
|
||||
return self
|
||||
|
||||
child = children[0]
|
||||
self.letter += child.letter
|
||||
self.value = child.value
|
||||
self.children = child.children
|
||||
return self
|
||||
|
||||
def dump_debug(self,write,margin):
|
||||
# this is used during debugging
|
||||
line = margin + "+-"
|
||||
if len(self.letter) == 0:
|
||||
line += "<NOLETTER>"
|
||||
else:
|
||||
line += self.letter
|
||||
|
||||
if self.value:
|
||||
line += " => " + repr(self.value)
|
||||
|
||||
write( line+"\n" )
|
||||
if self.children:
|
||||
margin += "| "
|
||||
for child in self.children.values():
|
||||
child.dump_debug(write,margin)
|
||||
|
||||
def locate(self,index):
|
||||
self.index = index
|
||||
if len(self.letter) > 0:
|
||||
index += len(self.letter)+1
|
||||
else:
|
||||
index += 2
|
||||
|
||||
if self.value != 0:
|
||||
index += 2
|
||||
|
||||
children = self.children.values()
|
||||
children.sort()
|
||||
index += 2*len(children)
|
||||
for child in children:
|
||||
index = child.locate(index)
|
||||
|
||||
return index
|
||||
|
||||
def store(self,storage):
|
||||
# write the letters
|
||||
l = len(self.letter)
|
||||
if l == 0:
|
||||
storage += struct.pack("B",0)
|
||||
else:
|
||||
for n in range(l):
|
||||
val = ord(self.letter[n])
|
||||
if n < l-1:
|
||||
val += 128
|
||||
storage += struct.pack("B",val)
|
||||
|
||||
# write the count
|
||||
children = self.children.values()
|
||||
children.sort()
|
||||
count = len(children)
|
||||
if self.value != 0:
|
||||
storage += struct.pack( "!BH", count+128, self.value )
|
||||
else:
|
||||
storage += struct.pack( "B", count )
|
||||
|
||||
for child in children:
|
||||
storage += struct.pack( "!H", child.index )
|
||||
|
||||
for child in children:
|
||||
storage = child.store(storage)
|
||||
|
||||
return storage
|
||||
line += comma
|
||||
line += "%4d" % self.indices[name]
|
||||
col += 1
|
||||
comma = ","
|
||||
if col == 14:
|
||||
col = 0
|
||||
comma = ",\n "
|
||||
|
||||
t1_bias = 0
|
||||
glyph_list = []
|
||||
write( line + "\n };\n\n\n" )
|
||||
|
||||
|
||||
def adobe_glyph_names():
|
||||
"""return the list of glyph names from the adobe list"""
|
||||
class StringNode:
|
||||
def __init__( self, letter, value ):
|
||||
self.letter = letter
|
||||
self.value = value
|
||||
self.children = {}
|
||||
|
||||
lines = string.split( adobe_glyph_list, '\n' )
|
||||
glyphs = []
|
||||
def __cmp__( self, other ):
|
||||
return ord( self.letter[0] ) - ord( other.letter[0] )
|
||||
|
||||
for line in lines:
|
||||
if line:
|
||||
fields = string.split( line, ';' )
|
||||
# print fields[1] + ' - ' + fields[0]
|
||||
glyphs.append( fields[0] )
|
||||
def add( self, word, value ):
|
||||
if len( word ) == 0:
|
||||
self.value = value
|
||||
return
|
||||
|
||||
return glyphs
|
||||
letter = word[0]
|
||||
word = word[1:]
|
||||
|
||||
if self.children.has_key( letter ):
|
||||
child = self.children[letter]
|
||||
else:
|
||||
child = StringNode( letter, 0 )
|
||||
self.children[letter] = child
|
||||
|
||||
child.add( word, value )
|
||||
|
||||
def optimize( self ):
|
||||
# optimize all children first
|
||||
children = self.children.values()
|
||||
self.children = {}
|
||||
|
||||
for child in children:
|
||||
self.children[child.letter[0]] = child.optimize()
|
||||
|
||||
# don't optimize if there's a value,
|
||||
# if we don't have any child or if we
|
||||
# have more than one child
|
||||
if ( self.value != 0 ) or ( not children ) or len( children ) > 1:
|
||||
return self
|
||||
|
||||
child = children[0]
|
||||
|
||||
self.letter += child.letter
|
||||
self.value = child.value
|
||||
self.children = child.children
|
||||
|
||||
return self
|
||||
|
||||
def dump_debug( self, write, margin ):
|
||||
# this is used during debugging
|
||||
line = margin + "+-"
|
||||
if len( self.letter ) == 0:
|
||||
line += "<NOLETTER>"
|
||||
else:
|
||||
line += self.letter
|
||||
|
||||
if self.value:
|
||||
line += " => " + repr( self.value )
|
||||
|
||||
write( line + "\n" )
|
||||
|
||||
if self.children:
|
||||
margin += "| "
|
||||
for child in self.children.values():
|
||||
child.dump_debug( write, margin )
|
||||
|
||||
def locate( self, index ):
|
||||
self.index = index
|
||||
if len( self.letter ) > 0:
|
||||
index += len( self.letter ) + 1
|
||||
else:
|
||||
index += 2
|
||||
|
||||
if self.value != 0:
|
||||
index += 2
|
||||
|
||||
children = self.children.values()
|
||||
children.sort()
|
||||
|
||||
index += 2 * len( children )
|
||||
for child in children:
|
||||
index = child.locate( index )
|
||||
|
||||
return index
|
||||
|
||||
def store( self, storage ):
|
||||
# write the letters
|
||||
l = len( self.letter )
|
||||
if l == 0:
|
||||
storage += struct.pack( "B", 0 )
|
||||
else:
|
||||
for n in range( l ):
|
||||
val = ord( self.letter[n] )
|
||||
if n < l - 1:
|
||||
val += 128
|
||||
storage += struct.pack( "B", val )
|
||||
|
||||
# write the count
|
||||
children = self.children.values()
|
||||
children.sort()
|
||||
|
||||
count = len( children )
|
||||
|
||||
if self.value != 0:
|
||||
storage += struct.pack( "!BH", count + 128, self.value )
|
||||
else:
|
||||
storage += struct.pack( "B", count )
|
||||
|
||||
for child in children:
|
||||
storage += struct.pack( "!H", child.index )
|
||||
|
||||
for child in children:
|
||||
storage = child.store( storage )
|
||||
|
||||
return storage
|
||||
|
||||
|
||||
def adobe_glyph_values():
|
||||
@ -4906,7 +4894,7 @@ def adobe_glyph_values():
|
||||
|
||||
|
||||
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
|
||||
extras = []
|
||||
@ -4920,56 +4908,57 @@ def filter_glyph_names( alist, filter ):
|
||||
return extras
|
||||
|
||||
|
||||
|
||||
def dump_encoding( file, encoding_name, encoding_list ):
|
||||
"""dumps a given encoding"""
|
||||
"""dump a given encoding"""
|
||||
|
||||
write = file.write
|
||||
write( "/* the following are indices into the SID name table */\n" )
|
||||
write( "static const unsigned short " + encoding_name + "[" + \
|
||||
repr( len( encoding_list ) ) + "] =\n" )
|
||||
write( "{\n" )
|
||||
|
||||
line = " "
|
||||
comma = ""
|
||||
write( " /* the following are indices into the SID name table */\n" )
|
||||
write( " static const unsigned short " + encoding_name +
|
||||
"[" + repr( len( encoding_list ) ) + "] =\n" )
|
||||
write( " {\n" )
|
||||
|
||||
line = " "
|
||||
comma = ""
|
||||
col = 0
|
||||
for value in encoding_list:
|
||||
line += comma
|
||||
line += "%3d" % value
|
||||
comma = ","
|
||||
col += 1
|
||||
if col == 16:
|
||||
col = 0
|
||||
comma = ",\n "
|
||||
|
||||
write( line + "\n};\n\n" )
|
||||
|
||||
|
||||
for value in encoding_list:
|
||||
line += comma
|
||||
line += "%3d" % value
|
||||
comma = ","
|
||||
col += 1
|
||||
if col == 16:
|
||||
col = 0
|
||||
comma = ",\n "
|
||||
|
||||
write( line + "\n };\n\n\n" )
|
||||
|
||||
|
||||
def dump_array( the_array, write, array_name ):
|
||||
"""dumps a given encoding"""
|
||||
|
||||
write( "static const unsigned char " + array_name + "[" + \
|
||||
repr(len(the_array)) + "] =\n" )
|
||||
write( "{\n" )
|
||||
line = ""
|
||||
comma = " "
|
||||
write( " static const unsigned char " + array_name +
|
||||
"[" + repr( len( the_array ) ) + "] =\n" )
|
||||
write( " {\n" )
|
||||
|
||||
line = ""
|
||||
comma = " "
|
||||
col = 0
|
||||
for value in the_array:
|
||||
line += comma
|
||||
line += "%3d" % ord(value)
|
||||
comma = ","
|
||||
col += 1
|
||||
if col == 16:
|
||||
col = 0
|
||||
comma = ",\n "
|
||||
|
||||
if len(line) > 1024:
|
||||
write( line )
|
||||
line = ""
|
||||
|
||||
write( line + "\n};\n\n" )
|
||||
|
||||
|
||||
|
||||
for value in the_array:
|
||||
line += comma
|
||||
line += "%3d" % ord( value )
|
||||
comma = ","
|
||||
col += 1
|
||||
|
||||
if col == 16:
|
||||
col = 0
|
||||
comma = ",\n "
|
||||
|
||||
if len( line ) > 1024:
|
||||
write( line )
|
||||
line = ""
|
||||
|
||||
write( line + "\n };\n\n\n" )
|
||||
|
||||
|
||||
def main():
|
||||
"""main program body"""
|
||||
@ -4983,23 +4972,22 @@ def main():
|
||||
|
||||
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.
|
||||
#
|
||||
mac_extras = filter_glyph_names( mac_standard_names, sid_standard_names )
|
||||
|
||||
# 'base_list' contains the names of our final glyph names table.
|
||||
# It consists of the 'mac_extras' glyph names, followed by the SID
|
||||
# Standard names.
|
||||
# `base_list' contains the names of our final glyph names table.
|
||||
# It consists of the `mac_extras' glyph names, followed by the SID
|
||||
# standard names.
|
||||
#
|
||||
mac_extras_count = len( mac_extras )
|
||||
t1_bias = mac_extras_count
|
||||
base_list = mac_extras + sid_standard_names
|
||||
|
||||
write( "/***************************************************************************/\n" )
|
||||
write( "/* */\n" )
|
||||
|
||||
write( "/* %-71s*/\n" % sys.argv[1] )
|
||||
write( "/* %-71s*/\n" % os.path.basename( sys.argv[1] ) )
|
||||
|
||||
write( "/* */\n" )
|
||||
write( "/* PostScript glyph names. */\n" )
|
||||
@ -5016,190 +5004,199 @@ def main():
|
||||
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" )
|
||||
|
||||
# dump final glyph list (mac extras + sid standard names)
|
||||
#
|
||||
st = StringTable(base_list)
|
||||
|
||||
st.dump(file,"ft_standard_glyph_names")
|
||||
st.dump_sublist(file,"ft_mac_names","FT_NUM_MAC_NAMES",mac_standard_names)
|
||||
st.dump_sublist(file,"ft_sid_names","FT_NUM_SID_NAMES",sid_standard_names)
|
||||
st = StringTable( base_list, "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_sid_names",
|
||||
"FT_NUM_SID_NAMES", sid_standard_names )
|
||||
|
||||
dump_encoding( file, "t1_standard_encoding", t1_standard_encoding )
|
||||
dump_encoding( file, "t1_expert_encoding", t1_expert_encoding )
|
||||
|
||||
# dump the AGL in its compressed form
|
||||
#
|
||||
agl_glyphs, agl_values = adobe_glyph_values()
|
||||
dict = StringNode( "", 0 )
|
||||
for g in range(len(agl_glyphs)):
|
||||
dict.add(agl_glyphs[g],eval("0x"+agl_values[g]))
|
||||
|
||||
dict = dict.optimize()
|
||||
dict_len = dict.locate(0)
|
||||
dict_array = dict.store("")
|
||||
|
||||
write( """
|
||||
/* this table is a compressed version of the Adobe Glyph List
|
||||
* which has been optimized for efficient searching. It has
|
||||
* been generated by the 'glnames.py' python script located
|
||||
* in the 'src/tools' directory.
|
||||
*
|
||||
* the corresponding lookup function is defined just below
|
||||
* the table (several pages down this text :-)
|
||||
*/
|
||||
""" )
|
||||
|
||||
dump_array(dict_array,write,"ft_adobe_glyph_list")
|
||||
|
||||
# write the lookup routine now
|
||||
#
|
||||
write( """
|
||||
/* this is the wicked routine used to search our compressed
|
||||
* table efficiently
|
||||
*/
|
||||
static unsigned long
|
||||
ft_get_adobe_glyph_index( const char* name,
|
||||
const char* limit )
|
||||
{
|
||||
int c = 0;
|
||||
int count, min, max;
|
||||
const unsigned char* p = ft_adobe_glyph_list;
|
||||
|
||||
if ( name == 0 || name >= limit )
|
||||
goto NotFound;
|
||||
|
||||
c = *name++;
|
||||
count = p[1];
|
||||
p += 2;
|
||||
|
||||
min = 0;
|
||||
max = count;
|
||||
|
||||
while ( min < max )
|
||||
{
|
||||
int mid = (min+max) >> 1;
|
||||
const unsigned char* q = p + mid*2;
|
||||
int c2;
|
||||
|
||||
q = ft_adobe_glyph_list + (((int)q[0] << 8) | q[1]);
|
||||
|
||||
c2 = q[0] & 127;
|
||||
if ( c2 == c )
|
||||
{
|
||||
p = q;
|
||||
goto Found;
|
||||
}
|
||||
if ( c2 < c )
|
||||
min = mid+1;
|
||||
else
|
||||
max = mid;
|
||||
}
|
||||
goto NotFound;
|
||||
|
||||
Found:
|
||||
for (;;)
|
||||
{
|
||||
/* assert (*p & 127) == c */
|
||||
|
||||
if ( name >= limit )
|
||||
{
|
||||
if ( (p[0] & 128) == 0 &&
|
||||
(p[1] & 128) != 0 )
|
||||
return (unsigned long)(((int)p[2] << 8) | p[3]);
|
||||
|
||||
goto NotFound;
|
||||
}
|
||||
c = *name++;
|
||||
if ( p[0] & 128 )
|
||||
{
|
||||
p++;
|
||||
if ( c != (p[0] & 127) )
|
||||
goto NotFound;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
p++;
|
||||
count = p[0] & 127;
|
||||
if ( p[0] & 128 )
|
||||
p += 2;
|
||||
|
||||
p++;
|
||||
|
||||
for ( ; count > 0; count--, p += 2 )
|
||||
{
|
||||
int offset = ((int)p[0] << 8) | p[1];
|
||||
const unsigned char* q = ft_adobe_glyph_list + offset;
|
||||
|
||||
if ( c == (q[0] & 127) )
|
||||
{
|
||||
p = q;
|
||||
goto NextIter;
|
||||
}
|
||||
}
|
||||
goto NotFound;
|
||||
|
||||
NextIter:
|
||||
;
|
||||
}
|
||||
|
||||
NotFound:
|
||||
return 0;
|
||||
}
|
||||
|
||||
""" )
|
||||
|
||||
if 0: # generate unit test, or don't
|
||||
#
|
||||
# now write the unit test to check that everything works OK
|
||||
#
|
||||
write( "#ifdef TEST\n\n" )
|
||||
|
||||
write( "static const char* const the_names[] = {\n" )
|
||||
for name in agl_glyphs:
|
||||
write( ' "'+name+'",\n' )
|
||||
write( " 0\n};\n" )
|
||||
|
||||
write( "static const unsigned long the_values[] = {\n" )
|
||||
for val in agl_values:
|
||||
write( ' 0x'+val+',\n' )
|
||||
write( " 0\n};\n" )
|
||||
|
||||
write( """
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
int result = 0;
|
||||
const char* const* names = the_names;
|
||||
const unsigned long* values = the_values;
|
||||
|
||||
for ( ; *names; names++, values++ )
|
||||
{
|
||||
const char* name = *names;
|
||||
unsigned long reference = *values;
|
||||
unsigned long value;
|
||||
|
||||
value = ft_get_adobe_glyph_index( name, name + strlen(name) );
|
||||
if ( value != reference )
|
||||
{
|
||||
result = 1;
|
||||
fprintf( stderr, "name '%s' => %04x instead of %04x\\n",
|
||||
name, value, reference );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
""" )
|
||||
write( "#endif /* TEST */\n" )
|
||||
|
||||
write("/* END */\n")
|
||||
|
||||
# dump the AGL in its compressed form
|
||||
#
|
||||
agl_glyphs, agl_values = adobe_glyph_values()
|
||||
dict = StringNode( "", 0 )
|
||||
|
||||
for g in range( len( agl_glyphs ) ):
|
||||
dict.add( agl_glyphs[g], eval( "0x" + agl_values[g] ) )
|
||||
|
||||
dict = dict.optimize()
|
||||
dict_len = dict.locate( 0 )
|
||||
dict_array = dict.store( "" )
|
||||
|
||||
write( """\
|
||||
/*
|
||||
* This table is a compressed version of the Adobe Glyph List (AGL),
|
||||
* 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" )
|
||||
|
||||
# write the lookup routine now
|
||||
#
|
||||
write( """\
|
||||
/*
|
||||
* This function searches the compressed table efficiently.
|
||||
*/
|
||||
static unsigned long
|
||||
ft_get_adobe_glyph_index( const char* name,
|
||||
const char* limit )
|
||||
{
|
||||
int c = 0;
|
||||
int count, min, max;
|
||||
const unsigned char* p = ft_adobe_glyph_list;
|
||||
|
||||
|
||||
if ( name == 0 || name >= limit )
|
||||
goto NotFound;
|
||||
|
||||
c = *name++;
|
||||
count = p[1];
|
||||
p += 2;
|
||||
|
||||
min = 0;
|
||||
max = count;
|
||||
|
||||
while ( min < max )
|
||||
{
|
||||
int mid = ( min + max ) >> 1;
|
||||
const unsigned char* q = p + mid * 2;
|
||||
int c2;
|
||||
|
||||
|
||||
q = ft_adobe_glyph_list + ( ( (int)q[0] << 8 ) | q[1] );
|
||||
|
||||
c2 = q[0] & 127;
|
||||
if ( c2 == c )
|
||||
{
|
||||
p = q;
|
||||
goto Found;
|
||||
}
|
||||
if ( c2 < c )
|
||||
min = mid + 1;
|
||||
else
|
||||
max = mid;
|
||||
}
|
||||
goto NotFound;
|
||||
|
||||
Found:
|
||||
for (;;)
|
||||
{
|
||||
/* assert (*p & 127) == c */
|
||||
|
||||
if ( name >= limit )
|
||||
{
|
||||
if ( (p[0] & 128) == 0 &&
|
||||
(p[1] & 128) != 0 )
|
||||
return (unsigned long)( ( (int)p[2] << 8 ) | p[3] );
|
||||
|
||||
goto NotFound;
|
||||
}
|
||||
c = *name++;
|
||||
if ( p[0] & 128 )
|
||||
{
|
||||
p++;
|
||||
if ( c != (p[0] & 127) )
|
||||
goto NotFound;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
p++;
|
||||
count = p[0] & 127;
|
||||
if ( p[0] & 128 )
|
||||
p += 2;
|
||||
|
||||
p++;
|
||||
|
||||
for ( ; count > 0; count--, p += 2 )
|
||||
{
|
||||
int offset = ( (int)p[0] << 8 ) | p[1];
|
||||
const unsigned char* q = ft_adobe_glyph_list + offset;
|
||||
|
||||
if ( c == ( q[0] & 127 ) )
|
||||
{
|
||||
p = q;
|
||||
goto NextIter;
|
||||
}
|
||||
}
|
||||
goto NotFound;
|
||||
|
||||
NextIter:
|
||||
;
|
||||
}
|
||||
|
||||
NotFound:
|
||||
return 0;
|
||||
}
|
||||
|
||||
""" )
|
||||
|
||||
if 0: # generate unit test, or don't
|
||||
#
|
||||
# now write the unit test to check that everything works OK
|
||||
#
|
||||
write( "#ifdef TEST\n\n" )
|
||||
|
||||
write( "static const char* const the_names[] = {\n" )
|
||||
for name in agl_glyphs:
|
||||
write( ' "' + name + '",\n' )
|
||||
write( " 0\n};\n" )
|
||||
|
||||
write( "static const unsigned long the_values[] = {\n" )
|
||||
for val in agl_values:
|
||||
write( ' 0x' + val + ',\n' )
|
||||
write( " 0\n};\n" )
|
||||
|
||||
write( """
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main( void )
|
||||
{
|
||||
int result = 0;
|
||||
const char* const* names = the_names;
|
||||
const unsigned long* values = the_values;
|
||||
|
||||
|
||||
for ( ; *names; names++, values++ )
|
||||
{
|
||||
const char* name = *names;
|
||||
unsigned long reference = *values;
|
||||
unsigned long value;
|
||||
|
||||
|
||||
value = ft_get_adobe_glyph_index( name, name + strlen( name ) );
|
||||
if ( value != reference )
|
||||
{
|
||||
result = 1;
|
||||
fprintf( stderr, "name '%s' => %04x instead of %04x\\n",
|
||||
name, value, reference );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
""" )
|
||||
|
||||
write( "#endif /* TEST */\n" )
|
||||
|
||||
write("\n/* END */\n")
|
||||
|
||||
|
||||
# Now run the main routine
|
||||
|
Loading…
Reference in New Issue
Block a user