4758 |
write( line + "\n };\n\n\n" ) |
write( line + "\n };\n\n\n" ) |
4759 |
|
|
4760 |
|
|
4761 |
|
# We now store the Adobe Glyph List in compressed form. The list is put |
4762 |
|
# into a data structure called `trie' (because it has a tree-like |
4763 |
|
# appearance). Consider, for example, that you want to store the |
4764 |
|
# following name mapping: |
4765 |
|
# |
4766 |
|
# A => 1 |
4767 |
|
# Aacute => 6 |
4768 |
|
# Abalon => 2 |
4769 |
|
# Abstract => 4 |
4770 |
|
# |
4771 |
|
# It is possible to store the entries as follows. |
4772 |
|
# |
4773 |
|
# A => 1 |
4774 |
|
# | |
4775 |
|
# +-acute => 6 |
4776 |
|
# | |
4777 |
|
# +-b |
4778 |
|
# | |
4779 |
|
# +-alon => 2 |
4780 |
|
# | |
4781 |
|
# +-stract => 4 |
4782 |
# |
# |
4783 |
# here's an explanation about the way we now store the Adobe Glyph List. |
# We see that each node in the trie has: |
|
# First of all, we store the list as a tree. Consider for example that |
|
|
# you want to store the following name mapping: |
|
|
# |
|
|
# A => 1 |
|
|
# Aacute => 6 |
|
|
# Abalon => 2 |
|
|
# Abstract => 4 |
|
|
# |
|
|
# it's possible to store them in a tree, as in: |
|
|
# |
|
|
# A => 1 |
|
|
# | |
|
|
# +-acute => 6 |
|
|
# | |
|
|
# +-b |
|
|
# | |
|
|
# +-alone => 2 |
|
|
# | |
|
|
# +-stract => 4 |
|
4784 |
# |
# |
4785 |
# we see that each node in the tree has: |
# - one or more `letters' |
|
# |
|
|
# - one or more 'letters' |
|
4786 |
# - an optional value |
# - an optional value |
4787 |
# - zero or more child nodes |
# - zero or more child nodes |
4788 |
# |
# |
4789 |
# you can build such a tree with: |
# The first step is to call |
4790 |
# |
# |
4791 |
# root = StringNode( "",0 ) |
# root = StringNode( "", 0 ) |
4792 |
# for word in map.values(): |
# for word in map.values(): |
4793 |
# root.add(word,map[word]) |
# root.add( word, map[word] ) |
|
# |
|
|
# this will create a large tree where each node has only one letter |
|
|
# then call: |
|
|
# |
|
|
# root = root.optimize() |
|
|
# |
|
|
# which will optimize the tree by mergin the letters of successive |
|
|
# nodes whenever possible |
|
4794 |
# |
# |
4795 |
# now, each node of the tree is stored as follows in the table: |
# which creates a large trie where each node has only one children. |
4796 |
# |
# |
4797 |
# - first the node's letters, according to the following scheme: |
# Executing |
4798 |
# |
# |
4799 |
|
# root = root.optimize() |
4800 |
# |
# |
4801 |
# name bitsize description |
# optimizes the trie by merging the letters of successive nodes whenever |
4802 |
# ----------------------------------------- |
# possible. |
|
# notlast 1 set to 1 if this is not the last letter |
|
|
# in the word |
|
|
# ascii 7 the letter's ASCII value |
|
4803 |
# |
# |
4804 |
# - then, the children count and optional value: |
# Each node of the trie is stored as follows. |
4805 |
# |
# |
4806 |
# name bitsize description |
# - First the node's letter, according to the following scheme. We |
4807 |
# ----------------------------------------- |
# use the fact that in the AGL no name contains character codes > 127. |
|
# hasvalue 1 set to 1 if a 16-bit Unicode value follows |
|
|
# num_children 7 number of childrens. can be 0 only if |
|
|
# 'hasvalue' is set to 1 |
|
|
# if (hasvalue) |
|
|
# value 16 optional Unicode value |
|
4808 |
# |
# |
4809 |
# - followed by the list of 16-bit absolute offsets to the children. |
# name bitsize description |
4810 |
# Children must be sorted in increasing order of their first letter. |
# ---------------------------------------------------------------- |
4811 |
|
# notlast 1 Set to 1 if this is not the last letter |
4812 |
|
# in the word. |
4813 |
|
# ascii 7 The letter's ASCII value. |
4814 |
|
# |
4815 |
|
# - The letter is followed by a children count and the value of the |
4816 |
|
# current key (if any). Again we can do some optimization because all |
4817 |
|
# AGL entries are from the BMP; this means that 16 bits are sufficient |
4818 |
|
# to store its Unicode values. Additionally, no node has more than |
4819 |
|
# 127 children. |
4820 |
|
# |
4821 |
|
# name bitsize description |
4822 |
|
# ----------------------------------------- |
4823 |
|
# hasvalue 1 Set to 1 if a 16-bit Unicode value follows. |
4824 |
|
# num_children 7 Number of childrens. Can be 0 only if |
4825 |
|
# `hasvalue' is set to 1. |
4826 |
|
# value 16 Optional Unicode value. |
4827 |
|
# |
4828 |
|
# - A node is finished by a list of 16bit absolute offsets to the |
4829 |
|
# children, which must be sorted in increasing order of their first |
4830 |
|
# letter. |
4831 |
# |
# |
4832 |
# All 16-bit quantities are stored in big-endian. If you don't know why, |
# For simplicity, all 16bit quantities are stored in big-endian order. |
|
# you've never debugged this kind of code ;-) |
|
4833 |
# |
# |
4834 |
# Finally, the root node has first letter = 0, and no value. |
# The root node has first letter = 0, and no value. |
4835 |
# |
# |
4836 |
class StringNode: |
class StringNode: |
4837 |
def __init__( self, letter, value ): |
def __init__( self, letter, value ): |