shithub: neatroff

Download patch

ref: 66e510c36551eaa35584ec0213411d475bdb51f9
parent: 5bbd5fb88a804ccbf9d642d5f68be4acd74e9eaa
author: Ali Gholami Rudi <ali@rudi.ir>
date: Tue Aug 5 13:36:27 EDT 2014

font: enable or disable ligatures and kerning in font_layout()

--- a/font.c
+++ b/font.c
@@ -106,6 +106,23 @@
 	return i >= 0 && fn->g_map[i];
 }
 
+/* enable/disable ligatures; first bit for liga and the second bit for rlig */
+static int font_featlg(struct font *fn, int val)
+{
+	int ret = 0;
+	if (val & 1)
+		ret |= font_feat(fn, "liga", val);
+	if (val & 2)
+		ret |= font_feat(fn, "rlig", val) << 1;
+	return ret;
+}
+
+/* enable/disable pairwise kerning */
+static int font_featkn(struct font *fn, int val)
+{
+	return font_feat(fn, "kern", n_kn);
+}
+
 /* glyph index in fn->glyphs[] */
 static int font_idx(struct font *fn, struct glyph *g)
 {
@@ -216,14 +233,17 @@
 
 int font_layout(struct font *fn, struct glyph **gsrc, int nsrc, int sz,
 		struct glyph **gdst, int *dmap,
-		int *x, int *y, int *xadv, int *yadv)
+		int *x, int *y, int *xadv, int *yadv, int lg, int kn)
 {
 	int src[WORDLEN], dst[WORDLEN];
 	int ndst = 0;
 	int didx = 0;
 	int i, j;
+	int featlg, featkn;
 	for (i = 0; i < nsrc; i++)
 		src[i] = font_idx(fn, gsrc[i]);
+	if (lg)
+		featlg = font_featlg(fn, 3);
 	for (i = 0; i < nsrc; i++) {
 		struct grule *rule = font_findrule(fn, fn->gsub, fn->gsub_n,
 				src + i, nsrc - i, dst + ndst, ndst);
@@ -240,6 +260,8 @@
 			dst[ndst++] = src[i];
 		}
 	}
+	if (lg)
+		font_featlg(fn, featlg);
 	memset(x, 0, ndst * sizeof(x[0]));
 	memset(y, 0, ndst * sizeof(y[0]));
 	memset(xadv, 0, ndst * sizeof(xadv[0]));
@@ -246,6 +268,8 @@
 	memset(yadv, 0, ndst * sizeof(yadv[0]));
 	for (i = 0; i < ndst; i++)
 		gdst[i] = fn->glyphs + dst[i];
+	if (kn)
+		font_featkn(fn, 1);
 	for (i = 0; i < ndst; i++) {
 		struct grule *rule = font_findrule(fn, fn->gpos, fn->gpos_n,
 				dst + i, ndst - i, dst + i, i);
@@ -263,6 +287,8 @@
 			}
 		}
 	}
+	if (kn)
+		font_featkn(fn, featkn);
 	return ndst;
 }
 
@@ -568,6 +594,6 @@
 	int idx = font_findfeat(fn, name, 0);
 	int old = idx >= 0 ? fn->feat_set[idx] : 0;
 	if (idx >= 0)
-		fn->feat_set[idx] = val;
+		fn->feat_set[idx] = val != 0;
 	return old;
 }
--- a/roff.h
+++ b/roff.h
@@ -176,7 +176,7 @@
 int font_feat(struct font *fn, char *name, int val);
 int font_layout(struct font *fn, struct glyph **src, int nsrc, int sz,
 		struct glyph **dst, int *dmap,
-		int *x, int *y, int *xadv, int *yadv);
+		int *x, int *y, int *xadv, int *yadv, int lg, int kn);
 
 /* glyph handling functions */
 struct glyph *dev_glyph(char *c, int fn);
--- a/wb.c
+++ b/wb.c
@@ -213,7 +213,6 @@
 	char src_hyph[WORDLEN];
 	char hc[GNLEN];
 	int dst_n, i;
-	int feat_kern, feat_liga;
 	if (!wb->sub_n || !wb->sub_collect)
 		return;
 	wb->sub_collect = 0;
@@ -222,12 +221,8 @@
 		memset(src_hyph, 0, sizeof(src_hyph));
 	for (i = 0; i < wb->sub_n; i++)
 		gsrc[i] = font_find(fn, wb->sub_c[i]);
-	feat_kern = font_feat(fn, "kern", n_kn);
-	feat_liga = font_feat(fn, "liga", n_lg);
 	dst_n = font_layout(fn, gsrc, wb->sub_n, wb->s,
-			gdst, dmap, x, y, xadv, yadv);
-	font_feat(fn, "kern", feat_kern);
-	font_feat(fn, "liga", feat_liga);
+			gdst, dmap, x, y, xadv, yadv, n_lg, n_kn);
 	charnext_str(hc, c_hc);
 	for (i = 0; i < dst_n; i++) {
 		if (x[i])