Commit ad306eaa5e0675c623f823230b7962f401109c43

Werner Lemberg 2015-12-20T08:33:21

[base, bdf] Add number hashing. * src/base/fthash.c (hash_num_lookup, hash_num_compare): New functions. (ft_hash_init): Add argument to select between number and string hashing. (ft_hash_num_insert, ft_hash_num_lookup): New functions. * include/freetype/internal/fthash.h: Updated. * src/bdf/bdflib.c (_bdf_parse_start): Updated.

diff --git a/ChangeLog b/ChangeLog
index 154a2ec..251da08 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2015-12-20  Werner Lemberg  <wl@gnu.org>
 
+	[base, bdf] Add number hashing.
+
+	* src/base/fthash.c (hash_num_lookup, hash_num_compare): New
+	functions.
+	(ft_hash_init): Add argument to select between number and string
+	hashing.
+	(ft_hash_num_insert, ft_hash_num_lookup): New functions.
+
+	* include/freetype/internal/fthash.h: Updated.
+
+	* src/bdf/bdflib.c (_bdf_parse_start): Updated.
+
+2015-12-20  Werner Lemberg  <wl@gnu.org>
+
 	[base] Introduce hash lookup, compare, and free function pointers.
 
 	* include/freetype/internal/fthash.c (FT_Hash_LookupFunc,
diff --git a/include/freetype/internal/fthash.h b/include/freetype/internal/fthash.h
index 80c4b9b..84563cb 100644
--- a/include/freetype/internal/fthash.h
+++ b/include/freetype/internal/fthash.h
@@ -99,6 +99,7 @@ FT_BEGIN_HEADER
 
   FT_Error
   ft_hash_init( FT_Hash    hash,
+                FT_Bool    is_num,
                 FT_Memory  memory );
 
   void
@@ -111,10 +112,21 @@ FT_BEGIN_HEADER
                       FT_Hash      hash,
                       FT_Memory    memory );
 
+  FT_Error
+  ft_hash_num_insert( FT_Int     num,
+                      size_t     data,
+                      FT_Hash    hash,
+                      FT_Memory  memory );
+
   FT_Hashnode
   ft_hash_str_lookup( const char*  key,
                       FT_Hash      hash );
 
+  FT_Hashnode
+  ft_hash_num_lookup( FT_Int   num,
+                      FT_Hash  hash );
+
+
 FT_END_HEADER
 
 
diff --git a/src/base/fthash.c b/src/base/fthash.c
index d73c5df..942e650 100644
--- a/src/base/fthash.c
+++ b/src/base/fthash.c
@@ -61,6 +61,23 @@
   }
 
 
+  static FT_ULong
+  hash_num_lookup( FT_Hashkey*  key )
+  {
+    FT_ULong  num = key->num;
+    FT_ULong  res;
+
+
+    /* Mocklisp hash function. */
+    res = num & 0xFF;
+    res = ( res << 5 ) - res + ( ( num >>  8 ) & 0xFF );
+    res = ( res << 5 ) - res + ( ( num >> 16 ) & 0xFF );
+    res = ( res << 5 ) - res + ( ( num >> 24 ) & 0xFF );
+
+    return res;
+  }
+
+
   static FT_Bool
   hash_str_compare( FT_Hashkey*  a,
                     FT_Hashkey*  b )
@@ -69,7 +86,18 @@
          ft_strcmp( a->str, b->str ) == 0 )
       return 1;
 
-   return 0;
+    return 0;
+  }
+
+
+  static FT_Bool
+  hash_num_compare( FT_Hashkey*  a,
+                    FT_Hashkey*  b )
+  {
+    if ( a->num == b->num )
+      return 1;
+
+    return 0;
   }
 
 
@@ -143,6 +171,7 @@
 
   FT_Error
   ft_hash_init( FT_Hash    hash,
+                FT_Bool    is_num,
                 FT_Memory  memory )
   {
     FT_UInt   sz = INITIAL_HT_SIZE;
@@ -153,9 +182,18 @@
     hash->limit = sz / 3;
     hash->used  = 0;
 
-    hash->lookup  = hash_str_lookup;
-    hash->compare = hash_str_compare;
-    hash->free    = hash_str_free;
+    if ( is_num )
+    {
+      hash->lookup  = hash_num_lookup;
+      hash->compare = hash_num_compare;
+      hash->free    = NULL;
+    }
+    else
+    {
+      hash->lookup  = hash_str_lookup;
+      hash->compare = hash_str_compare;
+      hash->free    = hash_str_free;
+    }
 
     FT_MEM_NEW_ARRAY( hash->table, sz );
 
@@ -238,6 +276,21 @@
   }
 
 
+  FT_Error
+  ft_hash_num_insert( FT_Int     num,
+                      size_t     data,
+                      FT_Hash    hash,
+                      FT_Memory  memory )
+  {
+    FT_Hashkey  hk;
+
+
+    hk.num = num;
+
+    return hash_insert( hk, data, hash, memory );
+  }
+
+
   static FT_Hashnode
   hash_lookup( FT_Hashkey  key,
                FT_Hash     hash )
@@ -262,4 +315,17 @@
   }
 
 
+  FT_Hashnode
+  ft_hash_num_lookup( FT_Int   num,
+                      FT_Hash  hash )
+  {
+    FT_Hashkey  hk;
+
+
+    hk.num = num;
+
+    return hash_lookup( hk, hash );
+  }
+
+
 /* END */
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 34410a2..6944467 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1941,7 +1941,7 @@
         bdf_property_t*  prop;
 
 
-        error = ft_hash_init( &(font->proptbl), memory );
+        error = ft_hash_init( &(font->proptbl), 0, memory );
         if ( error )
           goto Exit;
         for ( i = 0, prop = (bdf_property_t*)_bdf_properties;
@@ -1956,7 +1956,7 @@
 
       if ( FT_ALLOC( p->font->internal, sizeof ( FT_HashRec ) ) )
         goto Exit;
-      error = ft_hash_init( (FT_Hash)p->font->internal, memory );
+      error = ft_hash_init( (FT_Hash)p->font->internal, 0, memory );
       if ( error )
         goto Exit;
       p->font->spacing      = p->opts->font_spacing;