ref: e071b935a6af5f98c9d1fd17e0ab36e7bf9c5335
parent: bd6b4b8bf37c00319dbc17b898c1426594169809
author: Ali Gholami Rudi <ali@rudi.ir>
date: Tue Jul 30 10:52:02 EDT 2013
font: store kerning pairs in per-glyph lists
--- a/font.c
+++ b/font.c
@@ -31,6 +31,11 @@
return NULL;
}
+static int font_idx(struct font *fn, struct glyph *g)
+{
+ return g ? g - fn->glyphs : -1;
+}
+
static int font_section(struct font *fn, FILE *fin, char *name);
static void font_charset(struct font *fn, FILE *fin)
@@ -75,17 +80,22 @@
static void font_kernpairs(struct font *fn, FILE *fin)
{
char c1[ILNLEN], c2[ILNLEN];
- int val;
+ int i1, i2, val;
while (fscanf(fin, "%s", c1) == 1) {
if (!font_section(fn, fin, c1))
break;
if (fscanf(fin, "%s %d", c2, &val) != 2)
break;
- if (fn->nkern < NKERNS) {
- strcpy(fn->kern_c1[fn->nkern], c1);
- strcpy(fn->kern_c2[fn->nkern], c2);
- fn->kern[fn->nkern] = val;
- fn->nkern++;
+ if (fn->knn < NKERNS) {
+ i1 = font_idx(fn, font_find(fn, c1));
+ i2 = font_idx(fn, font_find(fn, c2));
+ if (i1 >= 0 && i2 >= 0) {
+ fn->knnext[fn->knn] = fn->knhead[i1];
+ fn->knhead[i1] = fn->knn;
+ fn->knval[fn->knn] = val;
+ fn->knpair[fn->knn] = i2;
+ fn->knn++;
+ }
}
}
}
@@ -135,10 +145,17 @@
/* return pairwise kerning value between c1 and c2 */
int font_kern(struct font *fn, char *c1, char *c2)
{
- int i;
- for (i = 0; i < fn->nkern; i++)
- if (!strcmp(fn->kern_c1[i], c1) && !strcmp(fn->kern_c2[i], c2))
- return fn->kern[i];
+ int i1, i2, i;
+ i1 = font_idx(fn, font_find(fn, c1));
+ i2 = font_idx(fn, font_find(fn, c2));
+ if (i1 < 0 || i2 < 0)
+ return 0;
+ i = fn->knhead[i1];
+ while (i >= 0) {
+ if (fn->knpair[i] == i2)
+ return fn->knval[i];
+ i = fn->knnext[i];
+ }
return 0;
}
@@ -152,6 +169,8 @@
memset(fn, 0, sizeof(*fn));
for (i = 0; i < LEN(fn->head); i++)
fn->head[i] = -1;
+ for (i = 0; i < LEN(fn->knhead); i++)
+ fn->knhead[i] = -1;
while (fscanf(fin, "%s", tok) == 1) {
if (tok[0] == '#') {
skipline(fin);
--- a/roff.h
+++ b/roff.h
@@ -9,10 +9,10 @@
#define PATHLEN 1024 /* path length */
#define NFILES 16 /* number of input files */
#define NFONTS 32 /* number of fonts */
+#define NGLYPHS 1024 /* glyphs in fonts */
#define NLIGS 32 /* number of font ligatures */
-#define NKERNS 128 /* number of font pairwise kerning pairs */
+#define NKERNS 512 /* number of font pairwise kerning pairs */
#define FNLEN 32 /* font name length */
-#define NGLYPHS 512 /* glyphs in fonts */
#define NMLEN 32 /* macro/register/environment/glyph name length */
#define GNLEN NMLEN /* glyph name length */
#define RNLEN NMLEN /* register/macro name */
@@ -107,15 +107,18 @@
char c[NGLYPHS][GNLEN]; /* character names in charset */
struct glyph *g[NGLYPHS]; /* character glyphs in charset */
int n; /* number of characters in charset */
- char lig[NLIGS][GNLEN * 4]; /* font ligatures */
+ /* font ligatures */
+ char lig[NLIGS][LIGLEN * GNLEN];
int nlig;
- int kern[NKERNS]; /* font pairwise kerning */
- char kern_c1[NKERNS][GNLEN];
- char kern_c2[NKERNS][GNLEN];
- int nkern;
/* glyph list based on the first character of glyph names */
int head[256]; /* glyph list head */
int next[NGLYPHS]; /* next item in glyph list */
+ /* kerning pair list per glyph */
+ int knhead[NGLYPHS]; /* kerning pairs of glyphs[] */
+ int knnext[NKERNS]; /* next item in knhead[] list */
+ int knpair[NKERNS]; /* kerning pair 2nd glyphs */
+ int knval[NKERNS]; /* font pairwise kerning value */
+ int knn; /* number of kerning pairs */
};
/* output device functions */