Code

616134383d15eeaacc0eae0d95b8afcdf20d76bd
[inkscape.git] / src / libnrtype / nr-type-primitives.cpp
1 #define __NR_TYPE_PRIMITIVES_C__
3 /*
4  * Typeface and script library
5  *
6  * Authors:
7  *   Lauris Kaplinski <lauris@kaplinski.com>
8  *
9  * This code is in public domain
10  */
12 /* This should be enough for approximately 10000 fonts */
13 #define NR_DICTSIZE 2777
15 #include <stdlib.h>
16 #include <string.h>
17 #include <libnr/nr-macros.h>
18 #include "nr-type-primitives.h"
20 /**
21  * An entry in a list of key->value pairs
22  */
23 struct NRTDEntry {
24         NRTDEntry *next;
25         const gchar *key;
26         void *val;
27 };
29 /**
30  * Type Dictionary, consisting of size number of key-value entries
31  */
32 struct NRTypeDict {
33         unsigned int size;
34         NRTDEntry **entries;
35 };
37 static NRTDEntry *nr_td_entry_new (void);
39 /**
40  * Calls the destructor for each item in list
41  */
42 void
43 nr_name_list_release (NRNameList *list)
44 {
45         if (list->destructor) {
46                 list->destructor (list);
47         }
48 }
50 void
51 nr_style_list_release (NRStyleList *list)
52 {
53         if (list->destructor) {
54                 list->destructor (list);
55         }
56 }
58 /**
59  * Creates a new typeface dictionary of size NR_DICTSIZE
60  * and initalizes all the entries to NULL
61  */
62 NRTypeDict *
63 nr_type_dict_new (void)
64 {
65         NRTypeDict *td;
66         int i;
68         td = nr_new (NRTypeDict, 1);
70         td->size = NR_DICTSIZE;
71         td->entries = nr_new (NRTDEntry *, td->size);
72         for (i = 0; i < NR_DICTSIZE; i++) {
73                 td->entries[i] = NULL;
74         }
76         return td;
77 }
79 /**
80  * Hashes a string and returns the int
81  */
82 static unsigned int
83 nr_str_hash (const gchar *p)
84 {
85         unsigned int h;
87         h = *p;
89         if (h != 0) {
90                 for (p += 1; *p; p++) h = (h << 5) - h + *p;
91         }
93         return h;
94 }
96 /**
97  * Inserts a key/value into a typeface dictionary
98  */
99 void
100 nr_type_dict_insert (NRTypeDict *td, const gchar *key, void *val)
102         if (key) {
103                 NRTDEntry *tde;
104                 unsigned int hval;
106                 hval = nr_str_hash (key) % td->size;
108                 for (tde = td->entries[hval]; tde; tde = tde->next) {
109                         if (!strcmp (key, tde->key)) {
110                                 tde->val = val;
111                                 return;
112                         }
113                 }
115                 tde = nr_td_entry_new ();
116                 tde->next = td->entries[hval];
117                 tde->key = key;
118                 tde->val = val;
119                 td->entries[hval] = tde;
120         }
123 /**
124  * Looks up the given key from the typeface dictionary
125  */
126 void *
127 nr_type_dict_lookup (NRTypeDict *td, const gchar *key)
129         if (key) {
130                 NRTDEntry *tde;
131                 unsigned int hval;
132                 hval = nr_str_hash (key) % td->size;
133                 for (tde = td->entries[hval]; tde; tde = tde->next) {
134                         if (!strcmp (key, tde->key)) return tde->val;
135                 }
136         }
138         return NULL;
141 #define NR_TDE_BLOCK_SIZE 32
143 static NRTDEntry *nr_tde_free_list;
145 /**
146  * Creates a new TDEntry
147  */
148 static NRTDEntry *
149 nr_td_entry_new (void)
151         NRTDEntry *tde;
153         if (!nr_tde_free_list) {
154                 int i;
155                 nr_tde_free_list = nr_new (NRTDEntry, NR_TDE_BLOCK_SIZE);
156                 for (i = 0; i < (NR_TDE_BLOCK_SIZE - 1); i++) {
157                         nr_tde_free_list[i].next = nr_tde_free_list + i + 1;
158                 }
159                 nr_tde_free_list[i].next = NULL;
160         }
162         tde = nr_tde_free_list;
163         nr_tde_free_list = tde->next;
165         return tde;