Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * t6.c
3
 * 
4
 * width functions, sizes and fonts
5
 */
6
 
7
#include "tdef.h"
8
#include "fns.h"
9
#include "ext.h"
10
 
11
int	fontlab[MAXFONTS+1];
12
int	cstab[MAXFONTS+1];
13
int	ccstab[MAXFONTS+1];
14
int	bdtab[MAXFONTS+1];
15
int	sbold = 0;
16
 
17
t_width(Tchar j)
18
{
19
	int i, k;
20
 
21
	if (iszbit(j))
22
		return 0;
23
	if (ismot(j)) {
24
		if (isvmot(j))
25
			return(0);
26
		k = absmot(j);
27
		if (isnmot(j))
28
			k = -k;
29
		return(k);
30
	}
31
	i = cbits(j);
32
	if (i < ' ') {
33
		if (i == '\b')
34
			return(-widthp);
35
		if (i == PRESC)
36
			i = eschar;
37
		else if (i == HX)
38
			return(0);
39
	}
40
	if (i == ohc)
41
		return(0);
42
	i = trtab[i];
43
	if (i < ' ')
44
		return(0);
45
	if (sfbits(j) == oldbits) {
46
		xfont = pfont;
47
		xpts = ppts;
48
	} else 
49
		xbits(j, 0);
50
	if (i < nchnames + ALPHABET && widcache[i].fontpts == (xfont<<8) + xpts && !setwdf)
51
		k = widcache[i].width;
52
	else {
53
		k = getcw(i);
54
		if (bd)
55
			k += (bd - 1) * HOR;
56
		if (cs)
57
			k = cs;
58
	}
59
	widthp = k;
60
	return(k);
61
}
62
 
63
/*
64
 * clear width cache-- s means just space
65
 */
66
void zapwcache(int s)
67
{
68
	int i;
69
 
70
	if (s) {
71
		widcache[' '].fontpts = 0;
72
		return;
73
	}
74
	for (i=0; i<NWIDCACHE; i++)
75
		widcache[i].fontpts = 0;
76
}
77
 
78
onfont(int n, int f)	/* is char n on font f? */
79
{
80
	int i;
81
	Font *fp = &fonts[f];
82
	Chwid *cp, *ep;
83
	char *np;
84
 
85
	if (n < ALPHABET) {
86
		if (fp->wp[n].num == n)	/* ascii at front */
87
			return n;
88
		else
89
			return -1;
90
	}
91
	cp = &fp->wp[ALPHABET];
92
	ep = &fp->wp[fp->nchars];
93
	for ( ; cp < ep; cp++)	/* search others */
94
		if (cp->num == n)
95
			return cp - &fp->wp[0];
96
	/* maybe it was a \N... */
97
	np = chname(n);
98
	if (*np == Number) {
99
		i = atoi(np+1);		/* sscanf(np+1, "%d", &i); */
100
		cp = &fp->wp[0];
101
		ep = &fp->wp[fp->nchars];
102
		for ( ; cp < ep; cp++) {	/* search others */
103
			if (cp->code == i)
104
				return cp - &fp->wp[0];
105
		}
106
		return -2;	/* a \N that doesn't have an entry */
107
	}
108
	return -1;	/* vanilla not found */
109
}
110
 
111
getcw(int i)
112
{
113
	int k, n, x;
114
	Font *fp;
115
	int nocache = 0;
116
	if (i < ' ')
117
		return 0;
118
	bd = 0;
119
	fp = &fonts[xfont];
120
	if (i == ' ') {	/* a blank */
121
		k = (fp->spacewidth * spacesz + 6) / 12;
122
		/* this nonsense because .ss cmd uses 1/36 em as its units */
123
		/* 	and default is 12 */
124
	} else if ((n = onfont(i, xfont)) >= 0) {	/* on this font at n */
125
		k = fp->wp[n].wid;
126
		if (setwdf)
127
			numtabp[CT].val |= fp->wp[n].kern;
128
	} else if (n == -2) {		/* \N with default width */
129
 
130
		k = fp->defaultwidth;
131
	} else {			/* not on current font */
132
		nocache = 1;
133
		k = fp->defaultwidth;	/* default-size space */
134
		if (smnt) {
135
			int ii, jj;
136
			for (ii=smnt, jj=0; jj < nfonts; jj++, ii=ii % nfonts + 1) {
137
				if ((n = onfont(i, ii)) >= 0) {
138
					k = fonts[ii].wp[n].wid;
139
					if (xfont == sbold)
140
						bd = bdtab[ii];
141
					if (setwdf)
142
						numtabp[CT].val |= fonts[ii].wp[n].kern;
143
					break;
144
				}
145
			}
146
		}
147
	}
148
	if (!bd)
149
		bd = bdtab[xfont];
150
	if (cs = cstab[xfont]) {
151
		nocache = 1;
152
		if (ccs = ccstab[xfont])
153
			x = ccs; 
154
		else 
155
			x = xpts;
156
		cs = (cs * EMPTS(x)) / 36;
157
	}
158
	/* was (k & BYTEMASK);  since .wid is unsigned, should never happen */
159
	if (k < 0)
160
		ERROR "can't happen: negative width %d in getcw %d\n", k, i WARN;
161
	k = (k * xpts + (Unitwidth / 2)) / Unitwidth;
162
	if (nocache|bd)
163
		widcache[i].fontpts = 0;
164
	else {
165
		widcache[i].fontpts = (xfont<<8) + xpts;
166
		widcache[i].width = k;
167
	}
168
	return(k);
169
	/* Unitwidth is Units/Point, where
170
	/* Units is the fundamental digitization
171
	/* of the character set widths, and
172
	/* Point is the number of goobies in a point
173
	/* e.g., for cat, Units=36, Point=6, so Unitwidth=36/6=6
174
	/* In effect, it's the size at which the widths
175
	/* translate directly into units.
176
	*/
177
}
178
 
179
void xbits(Tchar i, int bitf)
180
{
181
	int k;
182
 
183
	if(TROFF) {
184
		xfont = fbits(i);
185
		k = sbits(i);
186
		if(k) {
187
			xpts = pstab[k-1];
188
			oldbits = sfbits(i);
189
			pfont = xfont;
190
			ppts = xpts;
191
			return;
192
		}
193
		switch(bitf) {
194
		case 0:
195
			xfont = font;
196
			xpts = pts;
197
			break;
198
		case 1:
199
			xfont = pfont;
200
			xpts = ppts;
201
			break;
202
		case 2:
203
			xfont = mfont;
204
			xpts = mpts;
205
		}
206
	}
207
}
208
 
209
 
210
/* these next two functions ought to be the same in troff and nroff, */
211
/* but the data structures they search are different. */
212
/* silly historical problem. */
213
 
214
 
215
Tchar t_setch(int c)
216
{
217
	char temp[50];
218
	char *s;
219
 
220
	s = temp;
221
	if (c == '(') {	/* \(xx */
222
		if ((*s++ = getach()) == 0 || (*s++ = getach()) == 0)
223
			return(0);
224
	} else {	/* \C'...' */
225
		c = getach();
226
		while ((*s = getach()) != c && *s != 0 && s < temp + sizeof(temp) - 1)
227
			s++;
228
	}
229
	*s = '\0';
230
#ifdef UNICODE
231
	return chadd(temp, Troffchar, Install) | chbits; /* add name even if haven't seen it */
232
#else
233
	if (NROFF) {
234
		int j;
235
 
236
		j = chadd(temp, Troffchar, Lookup);
237
		if ( j == -1)
238
			return 0;
239
		else
240
			return j | chbits;
241
	} else
242
		return chadd(temp, Troffchar, Install) | chbits; /* add name even if haven't seen it */
243
 
244
#endif /*UNICODE*/
245
}
246
 
247
Tchar t_setabs(void)		/* set absolute char from \N'...' */
248
{
249
	int n;
250
	char temp[10];
251
 
252
	getch();	/* delim */
253
	n = 0;
254
	n = inumb(&n);
255
	getch();	/* delim */
256
	if (nonumb)
257
		return 0;
258
	sprintf(temp, "%d", n);	/* convert into "#n" */
259
	n = chadd(temp, Number, Install);
260
	return n | chbits;
261
}
262
 
263
 
264
/*
265
 * fontlab[] is a cache that contains font information
266
 * for each font.
267
 * fontlab[] contains the 1- or 2-character name of the
268
 * font current associated with that font.
269
 * fonts 1..nfonts correspond to the mounted fonts;
270
 * the last of these are the special fonts.
271
 * If we don't use the (named) font in one of the
272
 * standard positions, we install the name in the next
273
 * free slot of fontlab[] and font[].
274
 * Whenever we need info about the font, we
275
 * read in the data into the next free slot with getfont.
276
 * The ptfont() (t10.c) routine will tell
277
 * the device filter to put the font always at position
278
 * zero if xfont > nfonts, so no need to change these filters.
279
 * Yes, this is a bit kludgy.
280
 *
281
 * This gives the new specs of findft:
282
 * 	find the font name i, where i also can be a number.
283
 * 	Installs the font(name) i when not present
284
 * 	returns -1 on error
285
 */
286
 
287
 
288
t_findft(int i)
289
{
290
	int k;
291
	Uchar *p;
292
 
293
	p = unpair(i);
294
 
295
	if (isdigit(p[0])) {		/* first look for numbers */
296
		k = p[0] - '0';
297
		if (p[1] > 0 && isdigit(p[1]))
298
			k = 10 * k + p[1] - '0';
299
		if (k > 0 && k <= nfonts && k < smnt)
300
			return(k);	/* mounted font:  .ft 3 */
301
		if (fontlab[k] && k <= MAXFONTS) {	/* translate */
302
			return(k);			/*number to a name */
303
		} else {
304
			fprintf(stderr, "troff: no font at position %d\n", k);
305
			return(-1);	/* wild number */
306
		}
307
	}
308
 
309
	/*
310
	 * Now we look for font names
311
	 */
312
	for (k = 1; fontlab[k] != i; k++) {
313
		if (k > MAXFONTS)
314
			return(-1);	/* running out of fontlab space */
315
		if (fontlab[k] == 0) {	/* passed all existing names */
316
			if (setfp(k, i, (char *) 0, 1) == -1)
317
				return(-1);
318
			else {
319
				fontlab[k] = i;	/* install the name */
320
				return(k);
321
			}
322
		}
323
	}
324
	return(k);			/* was one of the existing names */
325
}
326
 
327
 
328
void caseps(void)
329
{
330
	int i;
331
 
332
	if (TROFF) {
333
		if(skip())
334
			i = apts1;
335
		else {
336
			noscale++;
337
			i = inumb(&apts);	/* this is a disaster for fractional point sizes */
338
			noscale = 0;
339
			if(nonumb)
340
				i = apts1;
341
		}
342
		casps1(i);
343
	}
344
}
345
 
346
 
347
void casps1(int i)
348
{
349
 
350
/*
351
 * in olden times, it used to ignore changes to 0 or negative.
352
 * this is meant to allow the requested size to be anything,
353
 * in particular so eqn can generate lots of \s-3's and still
354
 * get back by matching \s+3's.
355
 
356
	if (i <= 0)
357
		return;
358
*/
359
	apts1 = apts;
360
	apts = i;
361
	pts1 = pts;
362
	pts = findps(i);
363
	mchbits();
364
}
365
 
366
 
367
findps(int i)
368
{
369
	int j, k;
370
 
371
	for (j=k=0 ; pstab[j] != 0 ; j++)
372
		if (abs(pstab[j]-i) < abs(pstab[k]-i))
373
			k = j;
374
 
375
	return(pstab[k]);
376
}
377
 
378
 
379
void t_mchbits(void)
380
{
381
	int i, j, k;
382
 
383
	i = pts;
384
	for (j = 0; i > (k = pstab[j]); j++)
385
		if (!k) {
386
			j--;
387
			break;
388
		}
389
	chbits = 0;
390
	setsbits(chbits, ++j);
391
	setfbits(chbits, font);
392
	sps = width(' ' | chbits);
393
	zapwcache(1);
394
}
395
 
396
void t_setps(void)
397
{
398
	int i, j;
399
 
400
	i = cbits(getch());
401
	j = i;				/* make compiler happy */
402
	if (isdigit(i)) {		/* \sd or \sdd */
403
		i -= '0';
404
		if (i == 0)		/* \s0 */
405
			j = apts1;
406
		else if (i <= 3 && (ch=getch()) && isdigit(j = cbits(ch))) {	/* \sdd */
407
			j = 10 * i + j - '0';
408
			ch = 0;
409
		} else		/* \sd */
410
			j = i;
411
	} else if (i == '(') {		/* \s(dd */
412
		j = cbits(getch()) - '0';
413
		j = 10 * j + cbits(getch()) - '0';
414
		if (j == 0)		/* \s(00 */
415
			j = apts1;
416
	} else if (i == '+' || i == '-') {	/* \s+, \s- */
417
		j = cbits(getch());
418
		if (isdigit(j)) {		/* \s+d, \s-d */
419
			j -= '0';
420
		} else if (j == '(') {		/* \s+(dd, \s-(dd */
421
			j = cbits(getch()) - '0';
422
			j = 10 * j + cbits(getch()) - '0';
423
		}
424
		if (i == '-')
425
			j = -j;
426
		j += apts;
427
	}
428
	casps1(j);
429
}
430
 
431
 
432
Tchar t_setht(void)		/* set character height from \H'...' */
433
{
434
	int n;
435
	Tchar c;
436
 
437
	getch();
438
	n = inumb(&apts);
439
	getch();
440
	if (n == 0 || nonumb)
441
		n = apts;	/* does this work? */
442
	c = CHARHT;
443
	c |= ZBIT;
444
	setsbits(c, n);
445
	setfbits(c, pts);	/* sneaky, CHARHT font bits are size bits */
446
	return(c);
447
}
448
 
449
Tchar t_setslant(void)		/* set slant from \S'...' */
450
{
451
	int n;
452
	Tchar c;
453
 
454
	getch();
455
	n = 0;
456
	n = inumb(&n);
457
	getch();
458
	if (nonumb)
459
		n = 0;
460
	c = SLANT;
461
	c |= ZBIT;
462
	setsfbits(c, n+180);
463
	return(c);
464
}
465
 
466
 
467
void caseft(void)
468
{
469
	if (!TROFF) {
470
		n_caseft();
471
		return;
472
	}
473
	skip();
474
	setfont(1);
475
}
476
 
477
 
478
void t_setfont(int a)
479
{
480
	int i, j;
481
 
482
	if (a)
483
		i = getrq();
484
	else 
485
		i = getsn();
486
	if (!i || i == 'P') {
487
		j = font1;
488
		goto s0;
489
	}
490
	if (/* i == 'S' || */ i == '0')	/* an experiment -- why can't we change to it? */
491
		return;
492
	if ((j = findft(i)) == -1)
493
		if ((j = setfp(0, i, (char*) 0, 1)) == -1)	/* try to put it in position 0 */
494
			return;
495
s0:
496
	font1 = font;
497
	font = j;
498
	mchbits();
499
}
500
 
501
 
502
void t_setwd(void)
503
{
504
	int base, wid;
505
	Tchar i;
506
	int delim, emsz, k;
507
	int savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1;
508
 
509
	base = numtabp[ST].val = numtabp[SB].val = wid = numtabp[CT].val = 0;
510
	if (ismot(i = getch()))
511
		return;
512
	delim = cbits(i);
513
	savhp = numtabp[HP].val;
514
	numtabp[HP].val = 0;
515
	savapts = apts;
516
	savapts1 = apts1;
517
	savfont = font;
518
	savfont1 = font1;
519
	savpts = pts;
520
	savpts1 = pts1;
521
	setwdf++;
522
	while (cbits(i = getch()) != delim && !nlflg) {
523
		k = width(i);
524
		wid += k;
525
		numtabp[HP].val += k;
526
		if (!ismot(i)) {
527
			emsz = (INCH/72) * xpts;
528
		} else if (isvmot(i)) {
529
			k = absmot(i);
530
			if (isnmot(i))
531
				k = -k;
532
			base -= k;
533
			emsz = 0;
534
		} else 
535
			continue;
536
		if (base < numtabp[SB].val)
537
			numtabp[SB].val = base;
538
		if ((k = base + emsz) > numtabp[ST].val)
539
			numtabp[ST].val = k;
540
	}
541
	setn1(wid, 0, (Tchar) 0);
542
	numtabp[HP].val = savhp;
543
	apts = savapts;
544
	apts1 = savapts1;
545
	font = savfont;
546
	font1 = savfont1;
547
	pts = savpts;
548
	pts1 = savpts1;
549
	mchbits();
550
	setwdf = 0;
551
}
552
 
553
 
554
Tchar t_vmot(void)
555
{
556
	dfact = lss;
557
	vflag++;
558
	return t_mot();
559
}
560
 
561
 
562
Tchar t_hmot(void)
563
{
564
	dfact = EM;
565
	return t_mot();
566
}
567
 
568
 
569
Tchar t_mot(void)
570
{
571
	int j, n;
572
	Tchar i;
573
 
574
	j = HOR;
575
	getch(); /*eat delim*/
576
	if (n = atoi0()) {
577
		if (vflag)
578
			j = VERT;
579
		i = makem(quant(n, j));
580
	} else
581
		i = 0;
582
	getch();
583
	vflag = 0;
584
	dfact = 1;
585
	return(i);
586
}
587
 
588
 
589
Tchar t_sethl(int k)
590
{
591
	int j;
592
	Tchar i;
593
 
594
	j = EM / 2;
595
	if (k == 'u')
596
		j = -j;
597
	else if (k == 'r')
598
		j = -2 * j;
599
	vflag++;
600
	i = makem(j);
601
	vflag = 0;
602
	return(i);
603
}
604
 
605
 
606
Tchar t_makem(int i)
607
{
608
	Tchar j;
609
 
610
	if (i >= 0)
611
		j = i;
612
	else
613
		j = -i;
614
	if (Hor > 1 && !vflag)
615
		j = (j + Hor/2)/Hor * Hor;
616
	j |= MOT;
617
	if (i < 0)
618
		j |= NMOT;
619
	if (vflag)
620
		j |= VMOT;
621
	return(j);
622
}
623
 
624
 
625
Tchar getlg(Tchar i)
626
{
627
	Tchar j, k;
628
	int lf;
629
 
630
	if (!TROFF)
631
		return i;
632
	if ((lf = fonts[fbits(i)].ligfont) == 0) /* font lacks ligatures */
633
		return(i);
634
	j = getch0();
635
	if (cbits(j) == 'i' && (lf & LFI))
636
		j = LIG_FI;
637
	else if (cbits(j) == 'l' && (lf & LFL))
638
		j = LIG_FL;
639
	else if (cbits(j) == 'f' && (lf & LFF)) {
640
		if ((lf & (LFFI|LFFL)) && lg != 2) {
641
			k = getch0();
642
			if (cbits(k)=='i' && (lf&LFFI))
643
				j = LIG_FFI;
644
			else if (cbits(k)=='l' && (lf&LFFL))
645
				j = LIG_FFL;
646
			else {
647
				*pbp++ = k;
648
				j = LIG_FF;
649
			}
650
		} else 
651
			j = LIG_FF;
652
	} else {
653
		*pbp++ = j;
654
		j = i;
655
	}
656
	return(i & SFMASK | j);
657
}
658
 
659
 
660
void caselg(void)
661
{
662
 
663
	if(TROFF) {
664
		skip();
665
		lg = atoi0();
666
		if (nonumb)
667
			lg = 1;
668
	}
669
}
670
 
671
void casefp(void)
672
{
673
	int i, j;
674
 
675
	if (!TROFF) {
676
		n_casefp();
677
		return;
678
	}
679
	skip();
680
	i = cbits(getch());
681
	if (isdigit(i)) {
682
		i -= '0';
683
		j = cbits(getch());
684
		if (isdigit(j))
685
			i = 10 * i + j - '0';
686
	}
687
	if (i <= 0 || i > nfonts)
688
		ERROR "fp: bad font position %d", i WARN;
689
	else if (skip() || !(j = getrq()))
690
		ERROR "fp: no font name" WARN; 
691
	else if (skip() || !getname())
692
		setfp(i, j, (char*) 0, 1);
693
	else		/* 3rd argument = filename */
694
		setfp(i, j, nextf, 1);
695
}
696
 
697
char *strdupl(const char *s)	/* make a copy of s */
698
{
699
	char *t;
700
 
701
	t = (char *) malloc(strlen(s) + 1);
702
	if (t == NULL)
703
		ERROR "out of space in strdupl(%s)", s FATAL;
704
	strcpy(t, s);
705
	return t;
706
}
707
 
708
setfp(int pos, int f, char *truename, int print)	/* mount font f at position pos[0...nfonts] */
709
{
710
	char pathname[NS], shortname[NS];
711
 
712
	zapwcache(0);
713
	if (truename)
714
		strcpy(shortname, truename);
715
	else
716
		strcpy(shortname, (char *) unpair(f));
717
	if (truename && strrchr(truename, '/')) {	/* .fp 1 R dir/file: use verbatim */
718
		sprintf(pathname, "%s", truename);
719
		if (fonts[pos].truename)
720
			free(fonts[pos].truename);
721
		fonts[pos].truename = strdupl(truename);
722
	} else if (truename) {			/* synonym: .fp 1 R Avant */
723
		sprintf(pathname, "%s/dev%s/%s", fontdir, devname, truename);
724
		truename = 0;	/* so doesn't get repeated by ptfpcmd */
725
	} else					/* vanilla: .fp 5 XX */
726
		sprintf(pathname, "%s/dev%s/%s", fontdir, devname, shortname);
727
	if (truename == 0 && fonts[pos].truename != 0) {
728
		free(fonts[pos].truename);
729
		fonts[pos].truename = 0;
730
	}
731
	if (getfont(pathname, pos) < 0) {
732
		ERROR "Can't open font file %s", pathname WARN;
733
		return -1;
734
	}
735
	if (print && !ascii) {
736
		ptfpcmd(pos, fonts[pos].longname, truename);
737
		ptfont();
738
	}
739
	if (pos == smnt) {
740
		smnt = 0; 
741
		sbold = 0; 
742
	}
743
	fontlab[pos] = f;
744
	if (smnt == 0 && fonts[pos].specfont)
745
		smnt = pos;
746
	bdtab[pos] = cstab[pos] = ccstab[pos] = 0;
747
	return pos;
748
}
749
 
750
/*
751
 * .cs request; don't check legality of optional arguments
752
 */
753
void casecs(void)
754
{
755
	int i, j;
756
 
757
	if (TROFF) {
758
		int savtr = trace;
759
 
760
		trace = 0;
761
		noscale++;
762
		skip();
763
		if (!(i = getrq()) || (i = findft(i)) < 0)
764
			goto rtn;
765
		skip();
766
		cstab[i] = atoi0();
767
		skip();
768
		j = atoi0();
769
		if(nonumb)
770
			ccstab[i] = 0;
771
		else
772
			ccstab[i] = findps(j);
773
	rtn:
774
		zapwcache(0);
775
		noscale = 0;
776
		trace = savtr;
777
	}
778
}
779
 
780
 
781
void casebd(void)
782
{
783
	int i, j, k;
784
 
785
	if (!TROFF) {
786
		n_casebd();
787
		return;
788
	}
789
	zapwcache(0);
790
	j = k = 0;
791
bd0:
792
	if (skip() || !(i = getrq()) || (j = findft(i)) == -1) {
793
		if (k)
794
			goto bd1;
795
		else 
796
			return;
797
	}
798
	if (j == smnt) {
799
		k = smnt;
800
		goto bd0;
801
	}
802
	if (k) {
803
		sbold = j;
804
		j = k;
805
	}
806
bd1:
807
	skip();
808
	noscale++;
809
	bdtab[j] = atoi0();
810
	noscale = 0;
811
}
812
 
813
 
814
void casevs(void)
815
{
816
	int i;
817
 
818
	if (!TROFF) {
819
		n_casevs();
820
		return;
821
	}
822
	skip();
823
	vflag++;
824
	dfact = INCH; /* default scaling is points! */
825
	dfactd = 72;
826
	res = VERT;
827
	i = inumb(&lss);
828
	if (nonumb)
829
		i = lss1;
830
	if (i < VERT) 
831
		i = VERT;
832
	lss1 = lss;
833
	lss = i;
834
}
835
 
836
 
837
void casess(void)
838
{
839
	int i;
840
 
841
	if(TROFF) {
842
		noscale++;
843
		skip();
844
		if(i = atoi0()) {
845
			spacesz = i & 0177;
846
			zapwcache(0);
847
			sps = width(' ' | chbits);
848
		}
849
		noscale = 0;
850
	}
851
}
852
 
853
 
854
Tchar t_xlss(void)
855
{
856
	/* stores \x'...' into two successive Tchars.
857
	/* the first contains HX, the second the value,
858
	/* encoded as a vertical motion.
859
	/* decoding is done in n2.c by pchar().
860
	*/
861
	int i;
862
 
863
	getch();
864
	dfact = lss;
865
	i = quant(atoi0(), VERT);
866
	dfact = 1;
867
	getch();
868
	if (i >= 0)
869
		*pbp++ = MOT | VMOT | i;
870
	else
871
		*pbp++ = MOT | VMOT | NMOT | -i;
872
	return(HX);
873
}
874
 
875
Uchar *unpair(int i)
876
{
877
	static Uchar name[3];
878
 
879
	name[0] = i & SHORTMASK;
880
	name[1] = (i >> SHORT) & SHORTMASK;
881
	name[2] = 0;
882
	return name;
883
}