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 <glib/gmem.h>
18 #include <libnr/nr-macros.h>
19 #include "nr-type-primitives.h"
21 /**
22 * An entry in a list of key->value pairs
23 */
24 struct NRTDEntry {
25 NRTDEntry *next;
26 const gchar *key;
27 void *val;
28 };
30 /**
31 * Type Dictionary, consisting of size number of key-value entries
32 */
33 struct NRTypeDict {
34 unsigned int size;
35 NRTDEntry **entries;
36 };
38 static NRTDEntry *nr_td_entry_new (void);
40 /**
41 * Calls the destructor for each item in list
42 */
43 void
44 nr_name_list_release (NRNameList *list)
45 {
46 if (list->destructor) {
47 list->destructor (list);
48 }
49 }
51 void
52 nr_style_list_release (NRStyleList *list)
53 {
54 if (list->destructor) {
55 list->destructor (list);
56 }
57 }
59 /**
60 * Creates a new typeface dictionary of size NR_DICTSIZE
61 * and initalizes all the entries to NULL
62 */
63 NRTypeDict *
64 nr_type_dict_new (void)
65 {
66 NRTypeDict *td;
67 int i;
69 td = g_new (NRTypeDict, 1);
71 td->size = NR_DICTSIZE;
72 td->entries = g_new (NRTDEntry *, td->size);
73 for (i = 0; i < NR_DICTSIZE; i++) {
74 td->entries[i] = NULL;
75 }
77 return td;
78 }
80 /**
81 * Hashes a string and returns the int
82 */
83 static unsigned int
84 nr_str_hash (const gchar *p)
85 {
86 unsigned int h;
88 h = *p;
90 if (h != 0) {
91 for (p += 1; *p; p++) h = (h << 5) - h + *p;
92 }
94 return h;
95 }
97 /**
98 * Inserts a key/value into a typeface dictionary
99 */
100 void
101 nr_type_dict_insert (NRTypeDict *td, const gchar *key, void *val)
102 {
103 if (key) {
104 NRTDEntry *tde;
105 unsigned int hval;
107 hval = nr_str_hash (key) % td->size;
109 for (tde = td->entries[hval]; tde; tde = tde->next) {
110 if (!strcmp (key, tde->key)) {
111 tde->val = val;
112 return;
113 }
114 }
116 tde = nr_td_entry_new ();
117 tde->next = td->entries[hval];
118 tde->key = key;
119 tde->val = val;
120 td->entries[hval] = tde;
121 }
122 }
124 /**
125 * Looks up the given key from the typeface dictionary
126 */
127 void *
128 nr_type_dict_lookup (NRTypeDict *td, const gchar *key)
129 {
130 if (key) {
131 NRTDEntry *tde;
132 unsigned int hval;
133 hval = nr_str_hash (key) % td->size;
134 for (tde = td->entries[hval]; tde; tde = tde->next) {
135 if (!strcmp (key, tde->key)) return tde->val;
136 }
137 }
139 return NULL;
140 }
142 #define NR_TDE_BLOCK_SIZE 32
144 static NRTDEntry *nr_tde_free_list;
146 /**
147 * Creates a new TDEntry
148 */
149 static NRTDEntry *
150 nr_td_entry_new (void)
151 {
152 NRTDEntry *tde;
154 if (!nr_tde_free_list) {
155 int i;
156 nr_tde_free_list = g_new (NRTDEntry, NR_TDE_BLOCK_SIZE);
157 for (i = 0; i < (NR_TDE_BLOCK_SIZE - 1); i++) {
158 nr_tde_free_list[i].next = nr_tde_free_list + i + 1;
159 }
160 nr_tde_free_list[i].next = NULL;
161 }
163 tde = nr_tde_free_list;
164 nr_tde_free_list = tde->next;
166 return tde;
167 }