#define __NR_TYPE_PRIMITIVES_C__ /* * Typeface and script library * * Authors: * Lauris Kaplinski <lauris@kaplinski.com> * * This code is in public domain */ /* This should be enough for approximately 10000 fonts */ #define NR_DICTSIZE 2777 #include <stdlib.h> #include <string.h> #include <glib/gmem.h> #include <libnr/nr-macros.h> #include "nr-type-primitives.h" /** * An entry in a list of key->value pairs */ 00024 struct NRTDEntry { NRTDEntry *next; const gchar *key; void *val; }; /** * Type Dictionary, consisting of size number of key-value entries */ 00033 struct NRTypeDict { unsigned int size; NRTDEntry **entries; }; static NRTDEntry *nr_td_entry_new (void); /** * Calls the destructor for each item in list */ void nr_name_list_release (NRNameList *list) { if (list->destructor) { list->destructor (list); } } void nr_style_list_release (NRStyleList *list) { if (list->destructor) { list->destructor (list); } } /** * Creates a new typeface dictionary of size NR_DICTSIZE * and initalizes all the entries to NULL */ NRTypeDict * nr_type_dict_new (void) { NRTypeDict *td; int i; td = g_new (NRTypeDict, 1); td->size = NR_DICTSIZE; td->entries = g_new (NRTDEntry *, td->size); for (i = 0; i < NR_DICTSIZE; i++) { td->entries[i] = NULL; } return td; } /** * Hashes a string and returns the int */ static unsigned int nr_str_hash (const gchar *p) { unsigned int h; h = *p; if (h != 0) { for (p += 1; *p; p++) h = (h << 5) - h + *p; } return h; } /** * Inserts a key/value into a typeface dictionary */ void nr_type_dict_insert (NRTypeDict *td, const gchar *key, void *val) { if (key) { NRTDEntry *tde; unsigned int hval; hval = nr_str_hash (key) % td->size; for (tde = td->entries[hval]; tde; tde = tde->next) { if (!strcmp (key, tde->key)) { tde->val = val; return; } } tde = nr_td_entry_new (); tde->next = td->entries[hval]; tde->key = key; tde->val = val; td->entries[hval] = tde; } } /** * Looks up the given key from the typeface dictionary */ void * nr_type_dict_lookup (NRTypeDict *td, const gchar *key) { if (key) { NRTDEntry *tde; unsigned int hval; hval = nr_str_hash (key) % td->size; for (tde = td->entries[hval]; tde; tde = tde->next) { if (!strcmp (key, tde->key)) return tde->val; } } return NULL; } #define NR_TDE_BLOCK_SIZE 32 static NRTDEntry *nr_tde_free_list; /** * Creates a new TDEntry */ static NRTDEntry * nr_td_entry_new (void) { NRTDEntry *tde; if (!nr_tde_free_list) { int i; nr_tde_free_list = g_new (NRTDEntry, NR_TDE_BLOCK_SIZE); for (i = 0; i < (NR_TDE_BLOCK_SIZE - 1); i++) { nr_tde_free_list[i].next = nr_tde_free_list + i + 1; } nr_tde_free_list[i].next = NULL; } tde = nr_tde_free_list; nr_tde_free_list = tde->next; return tde; }