ref: e59abf73546274ddadf77fed7eb9f9d452cdbb6a
parent: 284841844342e3be754905fa9eb6e05fd6d9f74c
author: Ali Gholami Rudi <[email protected]>
date: Sun Nov 24 13:50:20 EST 2013
tr: add .fmap to map character names to glyphs
--- a/font.c
+++ b/font.c
@@ -3,30 +3,40 @@
#include <string.h>
#include "roff.h"
-struct glyph *font_find(struct font *fn, char *name)
+/* look up a character in chead[]/cnext[] table */
+static int font_cidx(struct font *fn, char *name)
{
int i = fn->chead[(unsigned char) name[0]];
- while (i >= 0) {
- if (!strcmp(name, fn->c[i]))
- return fn->g[i];
+ while (i >= 0 && strcmp(name, fn->c[i]))
i = fn->cnext[i];
- }
- return NULL;
+ return i;
}
-struct glyph *font_glyph(struct font *fn, char *id)
+/* look up a character in ghead[]/gnext[] table */
+static int font_gidx(struct font *fn, char *id)
{
int i = fn->ghead[(unsigned char) id[0]];
- while (i >= 0) {
- if (!strcmp(fn->glyphs[i].id, id))
- return &fn->glyphs[i];
+ while (i >= 0 && strcmp(fn->glyphs[i].id, id))
i = fn->gnext[i];
- }
- return NULL;
+ return i;
}
-struct glyph *font_glyphput(struct font *fn, char *id, char *name, int wid, int type)
+struct glyph *font_find(struct font *fn, char *name)
{
+ int i = font_cidx(fn, name);
+ if (i < 0)
+ return NULL;
+ return fn->g_map[i] ? fn->g_map[i] : fn->g[i];
+}
+
+struct glyph *font_glyph(struct font *fn, char *id)
+{
+ int i = font_gidx(fn, id);
+ return i >= 0 ? &fn->glyphs[i] : NULL;
+}
+
+static struct glyph *font_glyphput(struct font *fn, char *id, char *name, int wid, int type)
+{
int i = fn->nglyphs++;
struct glyph *g;
g = &fn->glyphs[i];
@@ -40,6 +50,31 @@
return g;
}
+/* map character name to the given glyph */
+int font_map(struct font *fn, char *name, struct glyph *g)
+{
+ int i = font_cidx(fn, name);
+ if (g && g->font != fn)
+ return 1;
+ if (i < 0) {
+ if (fn->n >= NGLYPHS)
+ return 1;
+ i = fn->n++;
+ strcpy(fn->c[i], name);
+ fn->cnext[i] = fn->chead[(unsigned char) name[0]];
+ fn->chead[(unsigned char) name[0]] = i;
+ }
+ fn->g_map[i] = g;
+ return 0;
+}
+
+/* return nonzero if character name has been mapped with font_map() */
+int font_mapped(struct font *fn, char *name)
+{
+ int i = font_cidx(fn, name);
+ return i >= 0 && fn->g_map[i];
+}
+
/* glyph index in fn->glyphs[] */
static int font_idx(struct font *fn, struct glyph *g)
{
@@ -115,7 +150,9 @@
return 1;
if (!strcmp("---", name))
sprintf(name, "c%04d", fn->n);
- if (strcmp("\"", tok)) {
+ if (!strcmp("\"", tok)) {
+ glyph = fn->g[fn->n - 1];
+ } else {
wid = atoi(tok);
if (fscanf(fin, "%d %s", &type, id) != 2)
return 1;
@@ -122,8 +159,6 @@
glyph = font_glyph(fn, id);
if (!glyph)
glyph = font_glyphput(fn, id, name, wid, type);
- } else {
- glyph = fn->g[fn->n - 1];
}
strcpy(fn->c[fn->n], name);
fn->g[fn->n] = glyph;
--- a/out.c
+++ b/out.c
@@ -126,6 +126,8 @@
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 (g && font_mapped(g->font, c))
+ c = g->name;
if (dev_getcs(o_f))
outnn("h%d", (cwid - bwid) / 2);
outg(c, g ? dev_fontpos(g->font) : o_f);
--- a/roff.h
+++ b/roff.h
@@ -110,6 +110,7 @@
/* charset section characters */
char c[NGLYPHS][GNLEN]; /* character names in charset */
struct glyph *g[NGLYPHS]; /* character glyphs in charset */
+ struct glyph *g_map[NGLYPHS]; /* character remapped via font_map() */
int n; /* number of characters in charset */
/* glyph table based on the first character of their id fields in glyphs[] */
int ghead[256]; /* glyph list heads */
@@ -148,6 +149,8 @@
int font_lig(struct font *fn, char **c, int n);
int font_kern(struct font *fn, char *c1, char *c2);
int font_islig(struct font *fn, char *s);
+int font_map(struct font *fn, char *name, struct glyph *gl);
+int font_mapped(struct font *fn, char *name);
/* glyph handling functions */
struct glyph *dev_glyph(char *c, int fn);
--- a/tr.c
+++ b/tr.c
@@ -637,6 +637,16 @@
cdef_add(args[1], args[2], args[3]);
}
+static void tr_fmap(char **args)
+{
+ struct font *fn;
+ if (!args[2])
+ return;
+ fn = dev_font(dev_pos(args[1]));
+ if (fn)
+ font_map(fn, args[2], args[3] ? font_glyph(fn, args[3]) : NULL);
+}
+
static char *arg_regname(char *s, int len)
{
char *e = n_cp ? s + 2 : s + len;
@@ -838,6 +848,7 @@
{"ex", tr_ex},
{"fc", tr_fc},
{"fi", tr_fi},
+ {"fmap", tr_fmap},
{"fp", tr_fp},
{"fspecial", tr_fspecial},
{"ft", tr_ft},