ref: 3f23afabb528952a99b751ccc1ea7a7808b070df
dir: /wb.c/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "xroff.h"
#define R_F(wb) ((wb)->r_f >= 0 ? (wb)->r_f : n_f) /* current font */
#define R_S(wb) ((wb)->r_s >= 0 ? (wb)->r_s : n_s) /* current size */
void wb_init(struct wb *wb)
{
memset(wb, 0, sizeof(*wb));
sbuf_init(&wb->sbuf);
wb->f = -1;
wb->s = -1;
wb->r_f = -1;
wb->r_s = -1;
}
void wb_done(struct wb *wb)
{
sbuf_done(&wb->sbuf);
}
/* update wb->st and wb->sb */
static void wb_stsb(struct wb *wb)
{
wb->st = MIN(wb->st, wb->v - SC_HT);
wb->sb = MAX(wb->sb, wb->v);
}
/* append font and size to the buffer if needed */
static void wb_font(struct wb *wb)
{
if (wb->f != R_F(wb)) {
sbuf_printf(&wb->sbuf, "%cf(%02d", c_ec, R_F(wb));
wb->f = R_F(wb);
}
if (wb->s != R_S(wb)) {
sbuf_printf(&wb->sbuf, "%cs(%02d", c_ec, R_S(wb));
wb->s = R_S(wb);
}
wb_stsb(wb);
}
void wb_hmov(struct wb *wb, int n)
{
wb->h += n;
sbuf_printf(&wb->sbuf, "%ch'%du'", c_ec, n);
}
void wb_vmov(struct wb *wb, int n)
{
wb->v += n;
sbuf_printf(&wb->sbuf, "%cv'%du'", c_ec, n);
}
void wb_els(struct wb *wb, int els)
{
if (els > wb->els_pos)
wb->els_pos = els;
if (els < wb->els_neg)
wb->els_neg = els;
sbuf_printf(&wb->sbuf, "%cx'%du'", c_ec, els);
}
void wb_etc(struct wb *wb, char *x)
{
wb_font(wb);
sbuf_printf(&wb->sbuf, "%cX%s", c_ec, x);
}
void wb_put(struct wb *wb, char *c)
{
struct glyph *g;
if (c[0] == '\n') {
wb->part = 0;
return;
}
if (c[0] == ' ') {
wb_hmov(wb, charwid(dev_spacewid(), R_S(wb)));
return;
}
if (c[0] == '\t' || c[0] == '' ||
(c[0] == c_ni && (c[1] == '\t' || c[1] == ''))) {
sbuf_append(&wb->sbuf, c);
return;
}
g = dev_glyph(c, R_F(wb));
wb_font(wb);
sbuf_append(&wb->sbuf, c);
wb->h += charwid(g ? g->wid : SC_DW, R_S(wb));
wb->ct |= g ? g->type : 0;
wb_stsb(wb);
}
int wb_part(struct wb *wb)
{
return wb->part;
}
void wb_setpart(struct wb *wb)
{
wb->part = 1;
}
void wb_drawl(struct wb *wb, int h, int v)
{
wb_font(wb);
sbuf_printf(&wb->sbuf, "%cD'l %du %du'", c_ec, h, v);
wb->h += h;
wb->v += v;
wb_stsb(wb);
}
void wb_drawc(struct wb *wb, int r)
{
wb_font(wb);
sbuf_printf(&wb->sbuf, "%cD'c %du'", c_ec, r);
wb->h += r;
}
void wb_drawe(struct wb *wb, int h, int v)
{
wb_font(wb);
sbuf_printf(&wb->sbuf, "%cD'e %du %du'", c_ec, h, v);
wb->h += h;
}
void wb_drawa(struct wb *wb, int h1, int v1, int h2, int v2)
{
wb_font(wb);
sbuf_printf(&wb->sbuf, "%cD'a %du %du %du %du'", c_ec, h1, v1, h2, v2);
wb->h += h1 + h2;
wb->v += v1 + v2;
wb_stsb(wb);
}
void wb_drawxbeg(struct wb *wb, int c)
{
wb_font(wb);
sbuf_printf(&wb->sbuf, "%cD'%c", c_ec, c);
}
void wb_drawxdot(struct wb *wb, int h, int v)
{
sbuf_printf(&wb->sbuf, " %du %du", h, v);
wb->h += h;
wb->v += v;
wb_stsb(wb);
}
void wb_drawxend(struct wb *wb)
{
sbuf_printf(&wb->sbuf, "'");
}
static void wb_reset(struct wb *wb)
{
wb_done(wb);
wb_init(wb);
}
static void wb_putc(struct wb *wb, int t, char *s)
{
switch (t) {
case 0:
wb_put(wb, s);
break;
case 'D':
ren_draw(wb, s);
break;
case 'f':
wb->r_f = atoi(s);
break;
case 'h':
wb_hmov(wb, atoi(s));
break;
case 's':
wb->r_s = atoi(s);
break;
case 'v':
wb_vmov(wb, atoi(s));
break;
case 'x':
wb_els(wb, atoi(s));
break;
case 'X':
wb_etc(wb, s);
break;
}
}
void wb_cat(struct wb *wb, struct wb *src)
{
char *s = sbuf_buf(&src->sbuf);
char d[ILNLEN];
int c, part;
while ((c = out_readc(&s, d)) >= 0)
wb_putc(wb, c, d);
part = src->part;
wb->r_s = -1;
wb->r_f = -1;
wb_reset(src);
src->part = part;
}
int wb_wid(struct wb *wb)
{
return wb->h;
}
int wb_empty(struct wb *wb)
{
return sbuf_empty(&wb->sbuf);
}
void wb_wconf(struct wb *wb, int *ct, int *st, int *sb)
{
*ct = wb->ct;
*st = -wb->st;
*sb = -wb->sb;
}
/* hyphenate wb into w1 and w2; return zero on success */
int wb_hyph(struct wb *wb, int w, struct wb *w1, struct wb *w2)
{
return 1;
}