1 /* converting scales */
2 #define SC_IN (dev_res) /* inch in units */
3 #define SC_PT (SC_IN / 72) /* point in units */
4 #define SC_EM (n_s * SC_IN / 72)
5 #define SC_DW (SC_EM / 3) /* default width */
6 #define SC_HT (n_s * SC_PT) /* character height */
8 /* predefined array limits */
9 #define PATHLEN 1024 /* path length */
10 #define NFILES 16 /* number of input files */
11 #define NFONTS 32 /* number of fonts */
12 #define NLIGS 32 /* number of font ligatures */
13 #define NKERNS 128 /* number of font pairwise kerning pairs */
14 #define FNLEN 32 /* font name length */
15 #define NGLYPHS 512 /* glyphs in fonts */
16 #define NMLEN 32 /* macro/register/environment/glyph name length */
17 #define GNLEN NMLEN /* glyph name length */
18 #define RNLEN NMLEN /* register/macro name */
19 #define ILNLEN 1000 /* line limit of input files */
20 #define LNLEN 4000 /* line buffer length (ren.c/out.c) */
21 #define NWORDS 256 /* number of words in line buffer */
22 #define NARGS 9 /* number of macro arguments */
23 #define NPREV 16 /* environment stack depth */
24 #define NTRAPS 1024 /* number of traps per page */
25 #define NIES 128 /* number of nested .ie commands */
26 #define NTABS 16 /* number of tab stops */
27 #define NFIELDS 32 /* number of fields */
28 #define MAXFRAC 100000 /* maximum value of the fractional part */
30 /* escape sequences */
31 #define ESC_Q "bCDhHlLNoSvwxX" /* quoted escape sequences */
32 #define ESC_P "*fgkmns" /* 1 or 2-char escape sequences */
34 #define MIN(a, b) ((a) < (b) ? (a) : (b))
35 #define MAX(a, b) ((a) < (b) ? (b) : (a))
36 #define LEN(a) (sizeof(a) / sizeof((a)[0]))
38 /* special characters */
39 extern int c_ec
; /* escape character (\) */
40 extern int c_cc
; /* basic control character (.) */
41 extern int c_c2
; /* no-break control character (') */
42 #define c_ni 4 /* non-interpreted copy mode escape */
43 #define c_hc env_hc()/* hyphenation character */
45 /* number registers */
46 int num_get(int id
, int inc
);
47 void num_set(int id
, int val
);
48 void num_inc(int id
, int val
);
50 char *num_str(int id
);
51 char *num_getfmt(int id
);
52 void num_setfmt(int id
, char *fmt
);
54 int eval(char *s
, int unit
);
55 int eval_up(char **s
, int unit
);
56 int eval_re(char *s
, int orig
, int unit
);
58 /* mapping register, macro and environment names to numbers */
60 char *map_name(int id
);
62 /* string registers */
63 void str_set(int id
, char *s
);
64 void str_dset(int id
, void *d
);
65 char *str_get(int id
);
66 void *str_dget(int id
);
68 void str_rn(int src
, int dst
);
70 /* saving and restoring registers before and after printing diverted lines */
77 struct adj
*env_adj(void);
79 int tab_next(int pos
);
81 /* device related variables */
88 char name
[GNLEN
]; /* name of the glyph */
89 char id
[GNLEN
]; /* device-dependent glyph identifier */
90 struct font
*font
; /* glyph font */
91 int wid
; /* character width */
92 int type
; /* character type; ascender/descender */
98 struct glyph glyphs
[NGLYPHS
];
102 char c
[NGLYPHS
][GNLEN
]; /* character names in charset */
103 struct glyph
*g
[NGLYPHS
]; /* character glyphs in charset */
104 int n
; /* number of characters in charset */
105 char lig
[NLIGS
][GNLEN
* 4]; /* font ligatures */
107 int kern
[NKERNS
]; /* font pairwise kerning */
108 char kern_c1
[NKERNS
][GNLEN
];
109 char kern_c2
[NKERNS
][GNLEN
];
113 /* output device functions */
114 int dev_open(char *path
);
115 void dev_close(void);
116 int dev_mnt(int pos
, char *id
, char *name
);
117 int dev_pos(char *id
);
118 struct font
*dev_font(int pos
);
119 int charwid(int wid
, int sz
);
121 /* font-related functions */
122 struct font
*font_open(char *path
);
123 void font_close(struct font
*fn
);
124 struct glyph
*font_glyph(struct font
*fn
, char *id
);
125 struct glyph
*font_find(struct font
*fn
, char *name
);
126 int font_lig(struct font
*fn
, char *c
);
127 int font_kern(struct font
*fn
, char *c1
, char *c2
);
129 /* glyph handling functions */
130 struct glyph
*dev_glyph(char *c
, int fn
);
131 struct glyph
*dev_glyph_byid(char *id
, int fn
);
132 int dev_spacewid(void);
134 /* different layers of neatroff */
135 int in_next(void); /* input layer */
136 int cp_next(void); /* copy-mode layer */
137 int tr_next(void); /* troff layer */
139 void in_push(char *s
, char **args
);
140 void in_pushnl(char *s
, char **args
);
141 void in_so(char *path
); /* .so request */
142 void in_nx(char *path
); /* .nx request */
143 void in_ex(void); /* .nx request */
144 void in_queue(char *path
); /* .ex request */
145 char *in_arg(int i
); /* look up argument */
146 int in_nargs(void); /* number of arguments */
147 void in_back(int c
); /* push back input character */
148 int in_top(void); /* the first pushed-back character */
149 char *in_filename(void); /* current filename */
151 void cp_blk(int skip
); /* skip or read the next line or block */
152 void cp_wid(int enable
); /* control inlining \w requests */
153 #define cp_back in_back /* cp.c is stateless */
154 void tr_first(void); /* read until the first non-command line */
156 /* variable length string buffer */
158 char *s
; /* allocated buffer */
159 int sz
; /* buffer size */
160 int n
; /* length of the string stored in s */
161 int prev_n
; /* n before the last sbuf_append() */
164 void sbuf_init(struct sbuf
*sbuf
);
165 void sbuf_done(struct sbuf
*sbuf
);
166 char *sbuf_buf(struct sbuf
*sbuf
);
167 void sbuf_add(struct sbuf
*sbuf
, int c
);
168 void sbuf_append(struct sbuf
*sbuf
, char *s
);
169 void sbuf_printf(struct sbuf
*sbuf
, char *s
, ...);
170 void sbuf_putnl(struct sbuf
*sbuf
);
171 void sbuf_pop(struct sbuf
*sbuf
);
172 int sbuf_len(struct sbuf
*sbuf
);
173 int sbuf_empty(struct sbuf
*sbuf
);
178 int f
, s
, m
; /* the last output font and size */
179 int r_f
, r_s
, r_m
; /* current font and size; use n_f and n_s if -1 */
180 int part
; /* partial input (\c) */
181 int els_neg
, els_pos
; /* extra line spacing */
182 int h
, v
; /* buffer vertical and horizontal positions */
183 int ct
, sb
, st
; /* \w registers */
184 char prev_c
[GNLEN
]; /* previous character added via wb_put() */
185 int prev_h
; /* wb->h after wb_put() calls */
186 int prev_l
; /* sbuf_len(&wb->sbuf) after wb_put() calls */
189 void wb_init(struct wb
*wb
);
190 void wb_done(struct wb
*wb
);
191 void wb_hmov(struct wb
*wb
, int n
);
192 void wb_vmov(struct wb
*wb
, int n
);
193 void wb_els(struct wb
*wb
, int els
);
194 void wb_etc(struct wb
*wb
, char *x
);
195 void wb_put(struct wb
*wb
, char *c
);
196 int wb_part(struct wb
*wb
);
197 void wb_setpart(struct wb
*wb
);
198 void wb_drawl(struct wb
*wb
, int h
, int v
);
199 void wb_drawc(struct wb
*wb
, int r
);
200 void wb_drawe(struct wb
*wb
, int h
, int v
);
201 void wb_drawa(struct wb
*wb
, int h1
, int v1
, int h2
, int v2
);
202 void wb_drawxbeg(struct wb
*wb
, int c
);
203 void wb_drawxdot(struct wb
*wb
, int h
, int v
);
204 void wb_drawxend(struct wb
*wb
);
205 void wb_cat(struct wb
*wb
, struct wb
*src
);
206 int wb_hyph(struct wb
*wb
, int w
, struct wb
*w1
, struct wb
*w2
, int flg
);
207 int wb_wid(struct wb
*wb
);
208 int wb_empty(struct wb
*wb
);
209 void wb_wconf(struct wb
*wb
, int *ct
, int *st
, int *sb
);
210 int wb_lig(struct wb
*wb
, char *c
);
211 int wb_kern(struct wb
*wb
, char *c
);
213 /* hyphenation flags */
214 #define HY_MASK 0x0f /* enable hyphenation */
215 #define HY_LAST 0x02 /* do not hyphenate last lines */
216 #define HY_FINAL 0x04 /* do not hyphenate the final character */
217 #define HY_FIRSTTWO 0x08 /* do not hyphenate the first two characters */
218 #define HY_ANY 0x10 /* break at any possible position */
220 void hyphenate(char *hyphs
, char *word
);
228 struct adj
*adj_alloc(void);
229 void adj_free(struct adj
*adj
);
230 int adj_fill(struct adj
*adj
, int ad_b
, int fill
, int hyph
, struct sbuf
*dst
,
231 int *ll
, int *in
, int *ti
, int *els_neg
, int *els_pos
);
232 int adj_full(struct adj
*adj
, int fill
);
233 int adj_empty(struct adj
*adj
, int fill
);
234 int adj_wid(struct adj
*adj
);
235 void adj_swid(struct adj
*adj
, int swid
);
236 void adj_ll(struct adj
*adj
, int ll
);
237 void adj_in(struct adj
*adj
, int in
);
238 void adj_ti(struct adj
*adj
, int ti
);
239 void adj_wb(struct adj
*adj
, struct wb
*wb
);
240 void adj_nl(struct adj
*adj
);
241 void adj_sp(struct adj
*adj
);
242 void adj_nonl(struct adj
*adj
);
245 void render(void); /* the main loop */
246 void ren_char(struct wb
*wb
, int (*next
)(void), void (*back
)(int));
247 int ren_wid(int (*next
)(void), void (*back
)(int));
248 void ren_tl(int (*next
)(void), void (*back
)(int));
249 void out_line(char *s
); /* output rendered line */
250 int out_readc(char **s
, char *d
); /* read request or glyph */
251 void out(char *s
, ...); /* output troff cmd */
252 void ren_hline(struct wb
*wb
, char *arg
); /* horizontal line */
253 void ren_vline(struct wb
*wb
, char *arg
); /* vertical line */
254 void ren_bracket(struct wb
*wb
, char *arg
); /* \b */
255 void ren_over(struct wb
*wb
, char *arg
); /* \o */
256 void ren_draw(struct wb
*wb
, char *arg
); /* \D */
259 void tr_bp(char **args
);
260 void tr_br(char **args
);
261 void tr_ce(char **args
);
262 void tr_ch(char **args
);
263 void tr_di(char **args
);
264 void tr_divbeg(char **args
);
265 void tr_divend(char **args
);
266 void tr_dt(char **args
);
267 void tr_em(char **args
);
268 void tr_ev(char **args
);
269 void tr_fc(char **args
);
270 void tr_fi(char **args
);
271 void tr_fp(char **args
);
272 void tr_ft(char **args
);
273 void tr_hw(char **args
);
274 void tr_in(char **args
);
275 void tr_ll(char **args
);
276 void tr_mk(char **args
);
277 void tr_ne(char **args
);
278 void tr_nf(char **args
);
279 void tr_ns(char **args
);
280 void tr_os(char **args
);
281 void tr_pn(char **args
);
282 void tr_ps(char **args
);
283 void tr_rs(char **args
);
284 void tr_rt(char **args
);
285 void tr_sp(char **args
);
286 void tr_sv(char **args
);
287 void tr_ta(char **args
);
288 void tr_ti(char **args
);
289 void tr_wh(char **args
);
290 void tr_eject(char **args
);
295 void errmsg(char *msg
, ...);
297 int utf8read(char **s
, char *d
);
298 void schar_read(char *d
, int (*next
)(void));
299 int schar_jump(char *d
, int (*next
)(void), void (*back
)(int));
301 /* internal commands */
302 #define TR_DIVBEG "\07<" /* diversion begins */
303 #define TR_DIVEND "\07>" /* diversion ends */
304 #define TR_EJECT "\07P" /* page eject */
306 /* register mapping */
307 #define NREGS (1 << 16)
308 #define NREGS2 (NREGS * 2)
309 #define REG(c1, c2) ((c1) * 256 + (c2))
312 #define CLR_R(c) (((c) >> 16) & 0xff)
313 #define CLR_G(c) (((c) >> 8) & 0xff)
314 #define CLR_B(c) ((c) & 0xff)
315 #define CLR_RGB(r, g, b) (((r) << 16) | ((g) << 8) | (b))
317 char *clr_str(int c
);
318 int clr_get(char *s
);
320 /* builtin number registers; n_X for .X register */
321 #define n_a (*nreg(REG('.', 'a')))
322 #define n_cp (*nreg(REG('.', 'C')))
323 #define n_d (*nreg(REG('.', 'd')))
324 #define n_f (*nreg(REG('.', 'f')))
325 #define n_h (*nreg(REG('.', 'h')))
326 #define n_i (*nreg(REG('.', 'i')))
327 #define n_j (*nreg(REG('.', 'j')))
328 #define n_l (*nreg(REG('.', 'l')))
329 #define n_L (*nreg(REG('.', 'L')))
330 #define n_n (*nreg(REG('.', 'n')))
331 #define n_m (*nreg(REG('.', 'm')))
332 #define n_o (*nreg(REG('.', 'o')))
333 #define n_p (*nreg(REG('.', 'p')))
334 #define n_s (*nreg(REG('.', 's')))
335 #define n_u (*nreg(REG('.', 'u')))
336 #define n_v (*nreg(REG('.', 'v')))
337 #define n_ct (*nreg(REG('c', 't')))
338 #define n_dl (*nreg(REG('d', 'l')))
339 #define n_dn (*nreg(REG('d', 'n')))
340 #define n_nl (*nreg(REG('n', 'l')))
341 #define n_sb (*nreg(REG('s', 'b')))
342 #define n_st (*nreg(REG('s', 't')))
343 #define n_pg (*nreg(REG('%', '\0'))) /* % */
344 #define n_lb (*nreg(REG(0, 'b'))) /* input line beg */
345 #define n_ce (*nreg(REG(0, 'c'))) /* .ce remaining */
346 #define n_f0 (*nreg(REG(0, 'f'))) /* last .f */
347 #define n_lg (*nreg(REG(0, 'g'))) /* .lg mode */
348 #define n_hy (*nreg(REG(0, 'h'))) /* .hy mode */
349 #define n_i0 (*nreg(REG(0, 'i'))) /* last .i */
350 #define n_kn (*nreg(REG(0, 'k'))) /* .kn mode */
351 #define n_l0 (*nreg(REG(0, 'l'))) /* last .l */
352 #define n_L0 (*nreg(REG(0, 'L'))) /* last .L */
353 #define n_m0 (*nreg(REG(0, 'm'))) /* last .m */
354 #define n_mk (*nreg(REG(0, 'M'))) /* .mk internal register */
355 #define n_na (*nreg(REG(0, 'n'))) /* .na mode */
356 #define n_ns (*nreg(REG(0, 'N'))) /* .ns mode */
357 #define n_o0 (*nreg(REG(0, 'o'))) /* last .o */
358 #define n_s0 (*nreg(REG(0, 's'))) /* last .s */
359 #define n_sv (*nreg(REG(0, 'S'))) /* .sv value */
360 #define n_lt (*nreg(REG(0, 't'))) /* .lt value */
361 #define n_t0 (*nreg(REG(0, 'T'))) /* previous .lt value */
362 #define n_v0 (*nreg(REG(0, 'v'))) /* last .v */
364 /* functions for implementing read-only registers */
365 int f_nexttrap(void); /* .t */
366 int f_divreg(void); /* .z */
367 int f_hpos(void); /* .k */