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])