ref: 002e41a3c07346a8c1ebd805d65f1437c98443c6
parent: 28949d2e5934be77d5b8ed1e401ea214e3f52c20
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sun Jun 23 18:06:42 EDT 2013
font: read kernpairs section
--- a/dev.c
+++ b/dev.c
@@ -43,8 +43,8 @@
{
char path[PATHLEN];
char tok[ILNLEN];
- FILE *desc;
int i;
+ FILE *desc;
strcpy(dev_dir, dir);
sprintf(path, "%s/DESC", dir);
desc = fopen(path, "r");
@@ -119,15 +119,21 @@
return font_glyph(fn_font[fn], id);
}
-int charwid(int wid, int sz)
+int dev_kernpair(char *c1, char *c2)
{
- /* the original troff rounds the widths up */
- return (wid * sz + dev_uwid / 2) / dev_uwid;
+ return 0;
}
-struct font *dev_font(int fn)
+/* return the font struct at pos */
+struct font *dev_font(int pos)
{
- return fn < fn_n ? fn_font[fn] : NULL;
+ return pos >= 0 && pos < fn_n ? fn_font[pos] : NULL;
+}
+
+int charwid(int wid, int sz)
+{
+ /* the original troff rounds the widths up */
+ return (wid * sz + dev_uwid / 2) / dev_uwid;
}
int dev_fontid(struct font *fn)
--- a/font.c
+++ b/font.c
@@ -29,6 +29,8 @@
return NULL;
}
+static int font_section(struct font *fn, FILE *fin, char *name);
+
static void font_charset(struct font *fn, FILE *fin)
{
char tok[ILNLEN];
@@ -37,9 +39,13 @@
struct glyph *glyph = NULL;
struct glyph *prev = NULL;
int wid, type;
- while (fn->n < NGLYPHS) {
- if (fscanf(fin, "%s", name) != 1)
+ while (fscanf(fin, "%s", name) == 1) {
+ if (!font_section(fn, fin, name))
break;
+ if (fn->n >= NGLYPHS) {
+ skipline(fin);
+ continue;
+ }
fscanf(fin, "%s", tok);
glyph = prev;
if (strcmp("\"", tok)) {
@@ -60,6 +66,57 @@
}
}
+static void font_kernpairs(struct font *fn, FILE *fin)
+{
+ char c1[ILNLEN], c2[ILNLEN];
+ int 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++;
+ }
+ }
+}
+
+static int font_section(struct font *fn, FILE *fin, char *name)
+{
+ if (!strcmp("charset", name)) {
+ font_charset(fn, fin);
+ return 0;
+ }
+ if (!strcmp("kernpairs", name)) {
+ font_kernpairs(fn, fin);
+ return 0;
+ }
+ return 1;
+}
+
+/* return 1 if lig is a ligature */
+int font_lig(struct font *fn, char *lig)
+{
+ int i;
+ for (i = 0; i < fn->nlig; i++)
+ if (!strcmp(lig, fn->lig[i]))
+ return font_find(fn, lig) != NULL;
+ return 0;
+}
+
+/* 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];
+ return 0;
+}
+
struct font *font_open(char *path)
{
struct font *fn = malloc(sizeof(*fn));
@@ -85,7 +142,7 @@
continue;
}
if (!strcmp("fontname", tok)) {
- fscanf(fin, "%s", fn->psname);
+ fscanf(fin, "%s", fn->fontname);
continue;
}
if (!strcmp("named", tok)) {
@@ -93,16 +150,17 @@
continue;
}
if (!strcmp("ligatures", tok)) {
- while (fscanf(fin, "%s", tok) == 1)
+ while (fscanf(fin, "%s", tok) == 1) {
if (!strcmp("0", tok))
break;
+ if (fn->nlig < NLIGS)
+ strcpy(fn->lig[fn->nlig++], tok);
+ }
skipline(fin);
continue;
}
- if (!strcmp("charset", tok)) {
- font_charset(fn, fin);
+ if (!font_section(fn, fin, tok))
break;
- }
}
fclose(fin);
return fn;
--- a/out.c
+++ b/out.c
@@ -111,12 +111,12 @@
struct font *fn;
if (fid != p_f || o_s != p_s) {
fn = dev_font(fid);
- out("%d /%s f\n", o_s, fn->psname);
+ out("%d /%s f\n", o_s, fn->fontname);
p_f = fid;
p_s = o_s;
- sprintf(fnname, " %s ", fn->psname);
+ sprintf(fnname, " %s ", fn->fontname);
if (!strstr(o_fonts, fnname))
- sprintf(strchr(o_fonts, '\0'), "%s ", fn->psname);
+ sprintf(strchr(o_fonts, '\0'), "%s ", fn->fontname);
}
}
--- a/post.h
+++ b/post.h
@@ -1,7 +1,9 @@
/* predefined array limits */
#define PATHLEN 1024 /* path length */
#define NFONTS 32 /* number of fonts */
-#define FNLEN 32 /* font name length */
+#define NLIGS 32 /* number of font ligatures */
+#define NKERNS 128 /* number of font pairwise kerning pairs */
+#define FNLEN 64 /* font name length */
#define NGLYPHS 512 /* glyphs in fonts */
#define GNLEN 32 /* glyph name length */
#define ILNLEN 1000 /* line limit of input files */
@@ -18,8 +20,8 @@
extern int dev_ver;
struct glyph {
- char name[FNLEN]; /* name of the glyph */
- char id[FNLEN]; /* device-dependent glyph identifier */
+ char name[GNLEN]; /* name of the glyph */
+ char id[GNLEN]; /* device-dependent glyph identifier */
struct font *font; /* glyph font */
int wid; /* character width */
int type; /* character type; ascender/descender */
@@ -27,7 +29,7 @@
struct font {
char name[FNLEN];
- char psname[FNLEN];
+ char fontname[FNLEN];
struct glyph glyphs[NGLYPHS];
int nglyphs;
int spacewid;
@@ -35,6 +37,12 @@
char c[NGLYPHS][FNLEN]; /* 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 */
+ int nlig;
+ int kern[NKERNS]; /* font pairwise kerning */
+ char kern_c1[NKERNS][GNLEN];
+ char kern_c2[NKERNS][GNLEN];
+ int nkern;
};
/* output device functions */
@@ -52,6 +60,8 @@
void font_close(struct font *fn);
struct glyph *font_glyph(struct font *fn, char *id);
struct glyph *font_find(struct font *fn, char *name);
+int font_lig(struct font *fn, char *c);
+int font_kern(struct font *fn, char *c1, char *c2);
/* output functions */
void out(char *s, ...);