shithub: neatroff

Download patch

ref: eae83eb62670272ecb37ba2ed1b3bfa5bbee64e0
parent: d1259f4af92f110f5025b0071872ff0e135f2513
author: Ali Gholami Rudi <ali@rudi.ir>
date: Wed Jul 24 17:44:01 EDT 2013

out: add .cs and .bd

--- a/dev.c
+++ b/dev.c
@@ -174,3 +174,23 @@
 {
 	return pos >= 0 && pos < fn_n ? fn_font[pos] : NULL;
 }
+
+int dev_getcs(int fn)
+{
+	return dev_font(fn)->cs;
+}
+
+void dev_setcs(int fn, int cs)
+{
+	dev_font(fn)->cs = cs;
+}
+
+int dev_getbd(int fn)
+{
+	return dev_font(fn)->bd;
+}
+
+void dev_setbd(int fn, int bd)
+{
+	dev_font(fn)->bd = bd;
+}
--- a/out.c
+++ b/out.c
@@ -210,9 +210,34 @@
 	return 0;
 }
 
+static void outg(char *c)
+{
+	if (utf8len((unsigned char) c[0]) == strlen(c))
+		outnn("c%s%s", c, c[1] ? "\n" : "");
+	else
+		out("C%s\n", c[0] == c_ec && c[1] == '(' ? c + 2 : c);
+}
+
+static void outc(char *c)
+{
+	struct glyph *g = dev_glyph(c, o_f);
+	int cwid = charwid(o_f, o_s, g ? g->wid : SC_DW);
+	int bwid = charwid_base(o_f, o_s, g ? g->wid : SC_DW);
+	if (dev_getcs(o_f))
+		outnn("h%d", (cwid - bwid) / 2);
+	outg(c);
+	if (dev_getbd(o_f)) {
+		outnn("h%d", dev_getbd(o_f) - 1);
+		outg(c);
+		outnn("h%d", -dev_getbd(o_f) + 1);
+	}
+	if (dev_getcs(o_f))
+		outnn("h%d", -(cwid - bwid) / 2);
+	outnn("h%d", cwid);
+}
+
 void out_line(char *s)
 {
-	struct glyph *g;
 	char c[ILNLEN + GNLEN * 4];
 	int t;
 	while ((t = out_readc(&s, c)) >= 0) {
@@ -223,12 +248,7 @@
 			}
 			if (c[0] == '\t' || c[0] == '' || !strcmp(c_hc, c))
 				continue;
-			g = dev_glyph(c, o_f);
-			if (utf8len((unsigned char) c[0]) == strlen(c))
-				outnn("c%s%s", c, c[1] ? "\n" : "");
-			else
-				out("C%s\n", c[0] == c_ec && c[1] == '(' ? c + 2 : c);
-			outnn("h%d", charwid(o_f, o_s, g ? g->wid : SC_DW));
+			outc(c);
 			continue;
 		}
 		switch (t) {
--- a/reg.c
+++ b/reg.c
@@ -66,6 +66,9 @@
 	static char numbuf[128];
 	numbuf[0] = '\0';
 	switch (id) {
+	case REG('.', 'b'):
+		sprintf(numbuf, "%d", dev_getbd(n_f));
+		break;
 	case REG('.', 'k'):
 		sprintf(numbuf, "%d", f_hpos());
 		break;
--- a/ren.c
+++ b/ren.c
@@ -85,10 +85,18 @@
 	}
 }
 
-int charwid(int fn, int sz, int wid)
+int charwid_base(int fn, int sz, int wid)
 {
 	/* the original troff rounds the widths up */
 	return (wid * sz + dev_uwid / 2) / dev_uwid;
+}
+
+int charwid(int fn, int sz, int wid)
+{
+	if (dev_getcs(fn))
+		return dev_getcs(n_f) * SC_EM / 36;
+	return charwid_base(fn, sz, wid) +
+		(dev_getbd(fn) ? dev_getbd(fn) - 1 : 0);
 }
 
 int spacewid(int fn, int sz)
--- a/roff.h
+++ b/roff.h
@@ -95,6 +95,7 @@
 	int nglyphs;
 	int spacewid;
 	int special;
+	int cs, bd;			/* for .cs and .bd requests */
 	char c[NGLYPHS][GNLEN];		/* character names in charset */
 	struct glyph *g[NGLYPHS];	/* character glyphs in charset */
 	int n;				/* number of characters in charset */
@@ -112,6 +113,10 @@
 int dev_mnt(int pos, char *id, char *name);
 int dev_pos(char *id);
 struct font *dev_font(int pos);
+void dev_setcs(int fn, int cs);
+int dev_getcs(int fn);
+void dev_setbd(int fn, int bd);
+int dev_getbd(int fn);
 
 /* font-related functions */
 struct font *font_open(char *path);
@@ -126,6 +131,7 @@
 struct glyph *dev_glyph_byid(char *id, int fn);
 int charwid(int fn, int sz, int wid);
 int spacewid(int fn, int sz);
+int charwid_base(int fn, int sz, int wid);
 
 /* different layers of neatroff */
 int in_next(void);		/* input layer */
@@ -247,6 +253,7 @@
 void ren_bracket(struct wb *wb, char *arg);	/* \b */
 void ren_over(struct wb *wb, char *arg);	/* \o */
 void ren_draw(struct wb *wb, char *arg);	/* \D */
+void ren_putc(struct wb *wb, char *c);		/* handling .cs and .bd */
 
 /* out.c */
 void out_line(char *s);				/* output rendered line */
--- a/tr.c
+++ b/tr.c
@@ -446,6 +446,20 @@
 		n_ss = eval_re(args[1], n_ss, 0);
 }
 
+static void tr_cs(char **args)
+{
+	if (!args[1])
+		return;
+	dev_setcs(dev_pos(args[1]), args[2] ? eval(args[2], 0) : 0);
+}
+
+static void tr_bd(char **args)
+{
+	if (!args[1] || !strcmp("S", args[1]))
+		return;
+	dev_setbd(dev_pos(args[1]), args[2] ? eval(args[2], 'u') : 0);
+}
+
 static char *arg_regname(char *s, int len)
 {
 	char *e = n_cp ? s + 2 : s + len;
@@ -621,6 +635,7 @@
 	{"af", tr_af},
 	{"am", tr_de, mkargs_reg1},
 	{"as", tr_as, mkargs_ds},
+	{"bd", tr_bd},
 	{"bp", tr_bp},
 	{"br", tr_br},
 	{"c2", tr_c2},
@@ -628,6 +643,7 @@
 	{"ce", tr_ce},
 	{"ch", tr_ch},
 	{"cp", tr_cp},
+	{"cs", tr_cs},
 	{"da", tr_di},
 	{"de", tr_de, mkargs_reg1},
 	{"di", tr_di},