You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
#include <config.h>
-#include <assert.h>
+#include "font.h"
+#include "error.h"
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include "alloc.h"
#include "error.h"
#include "filename.h"
-#include "font.h"
#include "hash.h"
#include "pool.h"
#include "str.h"
int space_index;
static int font_msg (int, const char *,...)
- __attribute__ ((format (printf, 2, 3)));
+ PRINTF_FORMAT (2, 3);
static void scan_badchars (char *, int);
static void dup_char_metric (struct font_desc * font, int dest, int src);
static void add_char_metric (struct font_desc * font, struct char_metrics *metrics,
/* Typical whitespace characters for tokenizing. */
static const char whitespace[] = " \t\n\r\v";
-void
-groff_init (void)
-{
- space_index = font_char_name_to_index ("space");
-}
-
-/* Some notes on the groff_font(8) manpage:
+/* Some notes on the groff_font manpage:
DESC file format: A typical PostScript `res' would be 72000, with
`hor' and `vert' set to 1 to indicate that all those positions are
/* Reads a Groff font description file and converts it to a usable
binary format in memory. Installs the binary format in the global
- font table. See groff_font(8) for a description of the font
+ font table. See groff_font for a description of the font
description format supported. Returns nonzero on success. */
struct font_desc *
groff_read_font (const char *fn)
char *key;
/* 0=kernpairs section, 1=charset section. */
- int charset;
+ int charset = 0;
/* Index for previous line. */
int prev_index = -1;
/* Current location in file, used for error reporting. */
struct file_locator where;
-#if unix
+#ifdef unix
fn = fn_tilde_expand (fn);
#endif
font->metric_size = 0;
font->metric_used = 0;
font->kern = NULL;
- font->kern_size = 0;
- font->kern_size_p = hsh_next_prime (64);
+ font->kern_size = 8;
font->kern_used = 0;
font->kern_max_used = 0;
goto file_lossage;
}
free (line);
-#if unix
+#ifdef unix
free ((char *) fn);
#endif
/* Come here on any error. */
lose:
- fclose (f);
+ if (f != NULL)
+ fclose (f);
pool_destroy (font_pool);
-#if unix
+#ifdef unix
free ((char *) fn);
#endif
err_pop_file_locator (&where);
/* Character index hash table. */
static struct
{
- int size; /* Size of table. */
- int *size_p; /* Next larger table size. */
+ int size; /* Size of table (must be power of 2). */
int used; /* Number of full entries. */
- int max_used; /* # used entries where we enlarge & rehash. */
int next_index; /* Next index to allocate. */
struct index_hash *tab; /* Hash table proper. */
struct pool *ar; /* Pool for names. */
}
hash;
+void
+groff_init (void)
+{
+ space_index = font_char_name_to_index ("space");
+}
+
+void
+groff_done (void)
+{
+ free (hash.tab) ;
+ pool_destroy(hash.ar);
+}
+
+
/* Searches for NAME in the global character code table, returns the
index if found; otherwise inserts NAME and returns the new
index. */
if (!hash.tab)
{
- hash.size_p = hsh_next_prime (128);
- hash.size = *hash.size_p++;
+ hash.size = 128;
hash.used = 0;
- hash.max_used = hash.size / 2;
hash.next_index = 256;
hash.tab = xmalloc (sizeof *hash.tab * hash.size);
hash.ar = pool_create ();
hash.tab[i].name = NULL;
}
- for (i = hashpjw (name) % hash.size; hash.tab[i].name;)
+ for (i = hsh_hash_string (name) & (hash.size - 1); hash.tab[i].name; )
{
if (!strcmp (hash.tab[i].name, name))
return hash.tab[i].index;
}
hash.used++;
- if (hash.used >= hash.max_used)
+ if (hash.used >= hash.size / 2)
{
struct index_hash *old_tab = hash.tab;
int old_size = hash.size;
int i, j;
- hash.size = *hash.size_p++;
- hash.max_used = hash.size / 2;
+ hash.size *= 2;
hash.tab = xmalloc (sizeof *hash.tab * hash.size);
for (i = 0; i < hash.size; i++)
hash.tab[i].name = NULL;
for (i = 0; i < old_size; i++)
if (old_tab[i].name)
{
- for (j = hashpjw (old_tab[i].name) % hash.size; hash.tab[j].name;)
+ for (j = hsh_hash_string (old_tab[i].name) & (hash.size - 1);
+ hash.tab[j].name;)
if (++j >= hash.size)
j = 0;
hash.tab[j] = old_tab[i];
int old_kern_size = font->kern_size;
int j;
- font->kern_size = *font->kern_size_p++;
+ font->kern_size *= 2;
font->kern_max_used = font->kern_size / 2;
font->kern = pool_malloc (font->owner,
sizeof *font->kern * font->kern_size);
for (i = 0; i < font->kern_size; i++)
font->kern[i].ch1 = -1;
- for (i = 0; i < old_kern_size; i++)
- {
- if (old_kern[i].ch1 == -1)
- continue;
-
- j = hash_kern (old_kern[i].ch1, old_kern[i].ch2) % font->kern_size;
- while (font->kern[j].ch1 != -1)
- if (0 == j--)
- j = font->kern_size - 1;
- font->kern[j] = old_kern[i];
- }
if (old_kern)
- pool_free (font->owner, old_kern);
+ {
+ for (i = 0; i < old_kern_size; i++)
+ {
+ if (old_kern[i].ch1 == -1)
+ continue;
+
+ j = (hash_kern (old_kern[i].ch1, old_kern[i].ch2)
+ & (font->kern_size - 1));
+ while (font->kern[j].ch1 != -1)
+ if (0 == j--)
+ j = font->kern_size - 1;
+ font->kern[j] = old_kern[i];
+ }
+ pool_free (font->owner, old_kern);
+ }
}
- for (i = hash_kern (ch1, ch2) % font->kern_size; font->kern[i].ch1 != -1;)
+ for (i = hash_kern (ch1, ch2) & (font->kern_size - 1);
+ font->kern[i].ch1 != -1; )
if (0 == i--)
i = font->kern_size - 1;
font->kern[i].ch1 = ch1;
if (!font->kern)
return 0;
- for (i = hash_kern (ch1, ch2) % font->kern_size; font->kern[i].ch1 != -1;)
+ for (i = hash_kern (ch1, ch2) & (font->kern_size - 1);
+ font->kern[i].ch1 != -1;)
{
if (font->kern[i].ch1 == ch1 && font->kern[i].ch2 == ch2)
return font->kern[i].adjust;
font->metric_size = 0;
font->metric_used = 0;
font->kern = NULL;
- font->kern_size = 0;
- font->kern_size_p = hsh_next_prime (64);
+ font->kern_size = 8;
font->kern_used = 0;
font->kern_max_used = 0;
return font;