shithub: neatpost

Download patch

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, ...);