ref: 0645b041fc978afa94f089c122c6745abfeffea6
parent: 5dce7fb843ac8985602e83074f64382ba36440d3
author: Ali Gholami Rudi <ali@rudi.ir>
date: Fri Aug 15 15:29:08 EDT 2014
font: .fzoom request
--- a/fmt.c
+++ b/fmt.c
@@ -200,7 +200,7 @@
void fmt_space(struct fmt *fmt)
{
- fmt->gap += N_SS(n_f, n_s);
+ fmt->gap += font_swid(dev_font(n_f), n_s, n_ss);
}
int fmt_newline(struct fmt *f)
@@ -301,10 +301,11 @@
static int fmt_wordgap(struct fmt *f)
{
int nls = f->nls || f->nls_sup;
+ int swid = font_swid(dev_font(n_f), n_s, n_ss);
if (f->eos && f->nwords)
- if ((nls && !f->gap) || (!nls && f->gap == 2 * N_SS(n_f, n_s)))
- return N_SS(n_f, n_s) + N_SSS(n_f, n_s);
- return (nls && !f->gap && f->nwords) ? N_SS(n_f, n_s) : f->gap;
+ if ((nls && !f->gap) || (!nls && f->gap == 2 * swid))
+ return swid + font_swid(dev_font(n_f), n_s, n_sss);
+ return (nls && !f->gap && f->nwords) ? swid : f->gap;
}
/* insert wb into fmt */
--- a/font.c
+++ b/font.c
@@ -4,6 +4,8 @@
#include <string.h>
#include "roff.h"
+/* convert wid in device unitwidth size to size sz */
+#define DEVWID(sz, wid) (((wid) * (sz) + (dev_uwid / 2)) / dev_uwid)
#define GHASH(g1, g2) ((((g2) + 1) << 16) | ((g1) + 1))
#define GF_PAT 1 /* gsub/gpos pattern glyph */
@@ -32,7 +34,7 @@
char fontname[FNLEN];
int spacewid;
int special;
- int cs, bd; /* for .cs and .bd requests */
+ int cs, bd, zoom; /* for .cs, .bd, .fzoom requests */
struct glyph gl[NGLYPHS]; /* glyphs present in the font */
int gl_n; /* number of glyphs in the font */
struct dict gl_dict; /* mapping from gl[i].id to i */
@@ -648,11 +650,27 @@
return fn->special;
}
-int font_spacewid(struct font *fn)
+/* return width w for the given font and size */
+int font_wid(struct font *fn, int sz, int w)
{
- return fn->spacewid;
+ sz = font_zoom(fn, sz);
+ return w >= 0 ? DEVWID(sz, w) : -DEVWID(sz, -w);
}
+/* glyph width, where cfn is the current font and fn is glyph's font */
+int font_gwid(struct font *fn, struct font *cfn, int sz, int w)
+{
+ if (cfn->cs)
+ return cfn->cs * (font_zoom(fn, sz) * SC_IN / 72) / 36;
+ return font_wid(fn, sz, w) + (font_getbd(cfn) ? font_getbd(cfn) - 1 : 0);
+}
+
+/* space width for the give word space or sentence space */
+int font_swid(struct font *fn, int sz, int ss)
+{
+ return font_gwid(fn, fn, sz, (fn->spacewid * ss + 6) / 12);
+}
+
int font_getcs(struct font *fn)
{
return fn->cs;
@@ -671,6 +689,16 @@
void font_setbd(struct font *fn, int bd)
{
fn->bd = bd;
+}
+
+int font_zoom(struct font *fn, int sz)
+{
+ return fn->zoom ? (sz * fn->zoom + 500) / 1000 : sz;
+}
+
+void font_setzoom(struct font *fn, int zoom)
+{
+ fn->zoom = zoom;
}
/* enable/disable font features; returns the previous value */
--- a/out.c
+++ b/out.c
@@ -111,15 +111,18 @@
outnn("\n");
}
-static void outg(char *c, int fn)
+static void outg(char *c, int fn, int sz)
{
int ofn = o_f;
+ int osz = o_s;
out_ft(fn);
+ out_ps(sz);
if (utf8one(c))
outnn("c%s%s", c, c[1] ? "\n" : "");
else
out("C%s\n", c[0] == c_ec && c[1] == '(' ? c + 2 : c);
out_ft(ofn);
+ out_ps(osz);
}
static void outc(char *c)
@@ -129,16 +132,16 @@
int cwid, bwid;
if (!g)
return;
- cwid = charwid(o_f, o_s, g->wid);
- bwid = DEVWID(o_s, g->wid);
+ cwid = font_gwid(g->font, dev_font(o_f), o_s, g->wid);
+ bwid = font_wid(g->font, o_s, g->wid);
if (font_mapped(g->font, c))
c = g->name;
if (font_getcs(fn))
outnn("h%d", (cwid - bwid) / 2);
- outg(c, dev_fontpos(g->font));
+ outg(c, dev_fontpos(g->font), font_zoom(g->font, o_s));
if (font_getbd(fn)) {
outnn("h%d", font_getbd(fn) - 1);
- outg(c, dev_fontpos(g->font));
+ outg(c, dev_fontpos(g->font), font_zoom(g->font, o_s));
outnn("h%d", -font_getbd(fn) + 1);
}
if (font_getcs(fn))
@@ -177,7 +180,7 @@
out_clr(clr_get(c));
break;
case 's':
- out_ps(eval_re(c, o_s, '\0'));
+ out_ps(eval(c, 0));
break;
case 'v':
outnn("v%d", eval(c, 'v'));
--- a/ren.c
+++ b/ren.c
@@ -85,14 +85,6 @@
}
}
-int charwid(int fn, int sz, int wid)
-{
- struct font *f = dev_font(fn);
- if (font_getcs(f))
- return font_getcs(f) * SC_EM / 36;
- return DEVWID(sz, wid) + (font_getbd(f) ? font_getbd(f) - 1 : 0);
-}
-
int f_divreg(void)
{
return cdiv ? cdiv->reg : -1;
@@ -270,7 +262,7 @@
static int zwid(void)
{
struct glyph *g = dev_glyph("0", n_f);
- return charwid(n_f, n_s, g ? g->wid : 0);
+ return g ? font_gwid(g->font, dev_font(n_f), n_s, g->wid) : 0;
}
/* append the line number to the output line */
@@ -609,7 +601,7 @@
{
switch (c) {
case ' ':
- wb_hmov(wb, N_SS(n_f, n_s));
+ wb_hmov(wb, font_swid(dev_font(n_f), n_s, n_ss));
break;
case 'b':
ren_bcmd(wb, arg);
--- a/roff.h
+++ b/roff.h
@@ -160,6 +160,7 @@
int dev_pos(char *id);
struct font *dev_font(int pos);
int dev_fontpos(struct font *fn);
+struct glyph *dev_glyph(char *c, int fn);
/* font-related functions */
struct font *font_open(char *path);
@@ -169,25 +170,19 @@
int font_map(struct font *fn, char *name, struct glyph *gl);
int font_mapped(struct font *fn, char *name);
int font_special(struct font *fn);
-int font_spacewid(struct font *fn);
+int font_wid(struct font *fn, int sz, int w);
+int font_gwid(struct font *fn, struct font *cfn, int sz, int w);
+int font_swid(struct font *fn, int sz, int ss);
void font_setcs(struct font *fn, int cs);
int font_getcs(struct font *fn);
void font_setbd(struct font *fn, int bd);
int font_getbd(struct font *fn);
+void font_setzoom(struct font *fn, int zoom);
+int font_zoom(struct font *fn, int sz);
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 lg, int kn);
-
-/* glyph handling functions */
-struct glyph *dev_glyph(char *c, int fn);
-int charwid(int fn, int sz, int wid);
-
-/* convert wid in device unitwidth size to size sz */
-#define DEVWID(sz, wid) (((wid) * (sz) + (dev_uwid / 2)) / dev_uwid)
-/* the amount of word and sentence space for the given font and size */
-#define N_SS(fn, sz) (charwid((fn), (sz), (font_spacewid(dev_font(fn)) * n_ss + 6) / 12))
-#define N_SSS(fn, sz) (charwid((fn), (sz), (font_spacewid(dev_font(fn)) * n_sss + 6) / 12))
/* different layers of neatroff */
int in_next(void); /* input layer */
--- a/tr.c
+++ b/tr.c
@@ -450,18 +450,22 @@
static void tr_cs(char **args)
{
- if (!args[1])
- return;
- font_setcs(dev_font(dev_pos(args[1])), args[2] ? eval(args[2], 0) : 0);
+ struct font *fn = args[1] ? dev_font(dev_pos(args[1])) : NULL;
+ if (fn)
+ font_setcs(fn, args[2] ? eval(args[2], 0) : 0);
}
+static void tr_fzoom(char **args)
+{
+ struct font *fn = args[1] ? dev_font(dev_pos(args[1])) : NULL;
+ if (fn)
+ font_setzoom(fn, args[2] ? eval(args[2], 0) : 0);
+}
+
static void tr_ff(char **args)
{
- struct font *fn;
+ struct font *fn = args[1] ? dev_font(dev_pos(args[1])) : NULL;
int i;
- if (!args[2])
- return;
- fn = dev_font(dev_pos(args[1]));
for (i = 2; i <= NARGS; i++)
if (fn && args[i] && args[i][0] && args[i][1])
font_feat(fn, args[i] + 1, args[i][0] == '+');
@@ -888,6 +892,7 @@
{"fp", tr_fp},
{"fspecial", tr_fspecial},
{"ft", tr_ft},
+ {"fzoom", tr_fzoom},
{"hc", tr_hc},
{"hcode", tr_hcode},
{"hpf", tr_hpf},
--- a/wb.c
+++ b/wb.c
@@ -12,8 +12,6 @@
/* italic correction */
#define glyph_ic(g) (MAX(0, (g)->urx - (g)->wid))
#define glyph_icleft(g) (MAX(0, -(g)->llx))
-/* like DEVWID() but handles negative w */
-#define SDEVWID(sz, w) ((w) >= 0 ? DEVWID((sz), (w)) : -DEVWID((sz), -(w)))
/* the maximum and minimum values of bounding box coordinates */
#define BBMAX (1 << 29)
#define BBMIN -BBMAX
@@ -136,7 +134,7 @@
g = dev_glyph(c, wb->f);
}
if (g && !zerowidth && wb->icleft && glyph_icleft(g))
- wb_hmov(wb, SDEVWID(wb->s, glyph_icleft(g)));
+ wb_hmov(wb, font_wid(g->font, wb->s, glyph_icleft(g)));
wb->icleft = 0;
if (!c[1] || c[0] == c_ec || c[0] == c_ni || utf8one(c)) {
if (c[0] == c_ni && c[1] == c_ec)
@@ -151,11 +149,11 @@
}
if (!zerowidth) {
if (!n_cp && g)
- wb_bbox(wb, SDEVWID(wb->s, g->llx),
- SDEVWID(wb->s, g->lly),
- SDEVWID(wb->s, g->urx),
- SDEVWID(wb->s, g->ury));
- wb->h += charwid(wb->f, wb->s, g ? g->wid : 0);
+ wb_bbox(wb, font_wid(g->font, wb->s, g->llx),
+ font_wid(g->font, wb->s, g->lly),
+ font_wid(g->font, wb->s, g->urx),
+ font_wid(g->font, wb->s, g->ury));
+ wb->h += g ? font_gwid(g->font, dev_font(wb->f), wb->s, g->wid) : 0;
wb->ct |= g ? g->type : 0;
wb_stsb(wb);
}
@@ -224,9 +222,9 @@
gdst, dmap, x, y, xadv, yadv, n_lg, n_kn);
for (i = 0; i < dst_n; i++) {
if (x[i])
- wb_hmov(wb, SDEVWID(wb->s, x[i]));
+ wb_hmov(wb, font_wid(fn, wb->s, x[i]));
if (y[i])
- wb_vmov(wb, SDEVWID(wb->s, y[i]));
+ wb_vmov(wb, font_wid(fn, wb->s, y[i]));
if (src_hyph[dmap[i]])
wb_putbuf(wb, c_hc);
if (gdst[i] == gsrc[dmap[i]])
@@ -234,9 +232,9 @@
else
wb_putbuf(wb, gdst[i]->name);
if (x[i] || xadv[i])
- wb_hmov(wb, SDEVWID(wb->s, xadv[i] - x[i]));
+ wb_hmov(wb, font_wid(fn, wb->s, xadv[i] - x[i]));
if (y[i] || yadv[i])
- wb_vmov(wb, SDEVWID(wb->s, yadv[i] - y[i]));
+ wb_vmov(wb, font_wid(fn, wb->s, yadv[i] - y[i]));
}
wb->sub_n = 0;
wb->icleft = 0;
@@ -251,7 +249,7 @@
}
if (c[0] == ' ') {
wb_flushsub(wb);
- wb_hmov(wb, N_SS(R_F(wb), R_S(wb)));
+ wb_hmov(wb, font_swid(dev_font(R_F(wb)), R_S(wb), n_ss));
return;
}
if (wb_pendingfont(wb) || wb->sub_n == LEN(wb->sub_c))
@@ -468,7 +466,7 @@
{
struct glyph *g = wb_prevglyph(wb);
if (g && glyph_ic(g))
- wb_hmov(wb, SDEVWID(wb->s, glyph_ic(g)));
+ wb_hmov(wb, font_wid(g->font, wb->s, glyph_ic(g)));
}
void wb_italiccorrectionleft(struct wb *wb)
@@ -507,5 +505,5 @@
int wb_dashwid(struct wb *wb)
{
struct glyph *g = dev_glyph("hy", wb->f);
- return charwid(wb->f, wb->s, g ? g->wid : 0);
+ return g ? font_gwid(g->font, dev_font(wb->f), wb->s, g->wid) : 0;
}