1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 /*
  31  * University Copyright- Copyright (c) 1982, 1986, 1988
  32  * The Regents of the University of California
  33  * All Rights Reserved
  34  *
  35  * University Acknowledgment- Portions of this document are derived from
  36  * software developed by the University of California, Berkeley, and its
  37  * contributors.
  38  */
  39 
  40 #pragma ident   "%Z%%M% %I%     %E% SMI"
  41 
  42 #include "tdef.h"
  43 #include "tw.h"
  44 #include "ext.h"
  45 #include <ctype.h>
  46 
  47 /*
  48  * n6.c -- width functions, sizes and fonts
  49 */
  50 
  51 int     bdtab[NFONT+1] ={ 0, 0, 0, 3, 3, 0, };
  52 int     sbold = 0;
  53 int     fontlab[NFONT+1] = { 0, 'R', 'I', 'B', PAIR('B','I'), 'S', 0 };
  54 
  55 extern  int     nchtab;
  56 
  57 int
  58 width(j)
  59 tchar j;
  60 {
  61         int     i, k;
  62 
  63         if (j & (ZBIT|MOT)) {
  64                 if (iszbit(j))
  65                         return(0);
  66                 if (isvmot(j))
  67                         return(0);
  68                 k = absmot(j);
  69                 if (isnmot(j))
  70                         k = -k;
  71                 return(k);
  72         }
  73         i = cbits(j);
  74         if (i < ' ') {
  75                 if (i == '\b')
  76                         return(-widthp);
  77                 if (i == PRESC)
  78                         i = eschar;
  79                 else if (iscontrol(i))
  80                         return(0);
  81         }
  82         if (i==ohc)
  83                 return(0);
  84 #ifdef EUC
  85 #ifdef NROFF
  86         if (multi_locale) {
  87                 if ((j & MBMASK) || (j & CSMASK)) {
  88                         switch(j & MBMASK) {
  89                                 case BYTE_CHR:
  90                                 case LASTOFMB:
  91                                         k = t.Char * csi_width[cs(j)];
  92                                         break;
  93                                 default:
  94                                         k = 0;
  95                                         break;
  96                         }
  97                         widthp = k;
  98                         return(k);
  99                 }
 100         }
 101         i &= 0x1ff;
 102 #endif /* NROFF */
 103 #endif /* EUC */
 104         i = trtab[i];
 105         if (i < 32)
 106                 return(0);
 107         k = t.width[i] * t.Char;
 108         widthp = k;
 109         return(k);
 110 }
 111 
 112 
 113 tchar setch()
 114 {
 115         int     j;
 116         char    temp[10];
 117         char    *s;
 118 
 119         s = temp;
 120         if ((*s++ = getach()) == 0 || (*s++ = getach()) == 0)
 121                 return(0);
 122         *s = '\0';
 123         if ((j = findch(temp)) > 0)
 124                 return j | chbits;
 125         else
 126                 return 0;
 127 }
 128 
 129 tchar setabs()          /* set absolute char from \C'...' */
 130 {                       /* for now, a no-op */
 131         int i, n, nf;
 132 
 133         getch();
 134         n = 0;
 135         n = inumb(&n);
 136         getch();
 137         if (nonumb)
 138                 return 0;
 139         return n + nchtab + _SPECCHAR_ST;
 140 }
 141 
 142 int
 143 findft(i)
 144 int     i;
 145 {
 146         int     k;
 147 
 148         if ((k = i - '0') >= 0 && k <= nfonts && k < smnt)
 149                 return(k);
 150         for (k = 0; fontlab[k] != i; k++)
 151                 if (k > nfonts)
 152                         return(-1);
 153         return(k);
 154 }
 155 
 156 int
 157 caseps()
 158 {
 159         return (0);
 160 }
 161 
 162 int
 163 mchbits()
 164 {
 165         chbits = 0;
 166         setfbits(chbits, font);
 167         sps = width(' ' | chbits);
 168 
 169         return (0);
 170 }
 171 
 172 
 173 int
 174 setps()
 175 {
 176         int     i, j;
 177 
 178         i = cbits(getch());
 179         if (ischar(i) && isdigit(i)) {          /* \sd or \sdd */
 180                 i -= '0';
 181                 if (i == 0)             /* \s0 */
 182                         ;
 183                 else if (i <= 3 && ischar(j = cbits(ch = getch())) &&
 184                     isdigit(j)) {       /* \sdd */
 185                         ch = 0;
 186                 }
 187         } else if (i == '(') {          /* \s(dd */
 188                 getch();
 189                 getch();
 190         } else if (i == '+' || i == '-') {      /* \s+, \s- */
 191                 j = cbits(getch());
 192                 if (ischar(j) && isdigit(j)) {          /* \s+d, \s-d */
 193                         ;
 194                 } else if (j == '(') {          /* \s+(dd, \s-(dd */
 195                         getch();
 196                         getch();
 197                 }
 198         }
 199 
 200         return (0);
 201 }
 202 
 203 
 204 tchar setht()           /* set character height from \H'...' */
 205 {
 206         int     n;
 207         tchar c;
 208 
 209         getch();
 210         n = inumb(&apts);
 211         getch();
 212         return(0);
 213 }
 214 
 215 
 216 tchar setslant()                /* set slant from \S'...' */
 217 {
 218         int     n;
 219         tchar c;
 220 
 221         getch();
 222         n = 0;
 223         n = inumb(&n);
 224         getch();
 225         return(0);
 226 }
 227 
 228 
 229 int
 230 caseft()
 231 {
 232         skip();
 233         setfont(1);
 234 
 235         return (0);
 236 }
 237 
 238 
 239 int
 240 setfont(a)
 241 int     a;
 242 {
 243         int     i, j;
 244 
 245         if (a)
 246                 i = getrq();
 247         else 
 248                 i = getsn();
 249         if (!i || i == 'P') {
 250                 j = font1;
 251                 goto s0;
 252         }
 253         if (i == 'S' || i == '0')
 254                 return (0);
 255         if ((j = findft(i, fontlab)) == -1)
 256                 return (0);
 257 s0:
 258         font1 = font;
 259         font = j;
 260         mchbits();
 261 
 262         return (0);
 263 }
 264 
 265 
 266 int
 267 setwd()
 268 {
 269         int     base, wid;
 270         tchar i;
 271         int     delim, emsz, k;
 272         int     savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1;
 273 
 274         base = numtab[ST].val = numtab[ST].val = wid = numtab[CT].val = 0;
 275         if (ismot(i = getch()))
 276                 return (0);
 277         delim = cbits(i);
 278         savhp = numtab[HP].val;
 279         numtab[HP].val = 0;
 280         savapts = apts;
 281         savapts1 = apts1;
 282         savfont = font;
 283         savfont1 = font1;
 284         savpts = pts;
 285         savpts1 = pts1;
 286         setwdf++;
 287         while (cbits(i = getch()) != delim && !nlflg) {
 288                 k = width(i);
 289                 wid += k;
 290                 numtab[HP].val += k;
 291                 if (!ismot(i)) {
 292                         emsz = (INCH * pts + 36) / 72;
 293                 } else if (isvmot(i)) {
 294                         k = absmot(i);
 295                         if (isnmot(i))
 296                                 k = -k;
 297                         base -= k;
 298                         emsz = 0;
 299                 } else 
 300                         continue;
 301                 if (base < numtab[SB].val)
 302                         numtab[SB].val = base;
 303                 if ((k = base + emsz) > numtab[ST].val)
 304                         numtab[ST].val = k;
 305         }
 306         setn1(wid, 0, (tchar) 0);
 307         numtab[HP].val = savhp;
 308         apts = savapts;
 309         apts1 = savapts1;
 310         font = savfont;
 311         font1 = savfont1;
 312         pts = savpts;
 313         pts1 = savpts1;
 314         mchbits();
 315         setwdf = 0;
 316 
 317         return (0);
 318 }
 319 
 320 
 321 tchar vmot()
 322 {
 323         dfact = lss;
 324         vflag++;
 325         return(mot());
 326 }
 327 
 328 
 329 tchar hmot()
 330 {
 331         dfact = EM;
 332         return(mot());
 333 }
 334 
 335 
 336 tchar mot()
 337 {
 338         int j, n;
 339         tchar i;
 340 
 341         j = HOR;
 342         getch(); /*eat delim*/
 343         if (n = atoi()) {
 344                 if (vflag)
 345                         j = VERT;
 346                 i = makem(quant(n, j));
 347         } else
 348                 i = 0;
 349         getch();
 350         vflag = 0;
 351         dfact = 1;
 352         return(i);
 353 }
 354 
 355 
 356 tchar sethl(k)
 357 int     k;
 358 {
 359         int     j;
 360         tchar i;
 361 
 362         j = t.Halfline;
 363         if (k == 'u')
 364                 j = -j;
 365         else if (k == 'r')
 366                 j = -2 * j;
 367         vflag++;
 368         i = makem(j);
 369         vflag = 0;
 370         return(i);
 371 }
 372 
 373 
 374 tchar makem(i)
 375 int     i;
 376 {
 377         tchar j;
 378 
 379         if ((j = i) < 0)
 380                 j = -j;
 381         j |= MOT;
 382         if (i < 0)
 383                 j |= NMOT;
 384         if (vflag)
 385                 j |= VMOT;
 386         return(j);
 387 }
 388 
 389 
 390 tchar getlg(i)
 391 tchar   i;
 392 {
 393         return(i);
 394 }
 395 
 396 
 397 int
 398 caselg()
 399 {
 400         return (0);
 401 }
 402 
 403 
 404 int
 405 casefp()
 406 {
 407         int     i, j;
 408 
 409         skip();
 410         if ((i = cbits(getch()) - '0') < 0 || i > nfonts)
 411                 return (0);
 412         if (skip() || !(j = getrq()))
 413                 return (0);
 414         fontlab[i] = j;
 415 
 416         return (0);
 417 }
 418 
 419 
 420 int
 421 casecs()
 422 {
 423         return (0);
 424 }
 425 
 426 
 427 int
 428 casebd()
 429 {
 430         int     i, j, k;
 431 
 432         k = 0;
 433 bd0:
 434         if (skip() || !(i = getrq()) || (j = findft(i)) == -1) {
 435                 if (k)
 436                         goto bd1;
 437                 else 
 438                         return (0);
 439         }
 440         if (j == smnt) {
 441                 k = smnt;
 442                 goto bd0;
 443         }
 444         if (k) {
 445                 sbold = j;
 446                 j = k;
 447         }
 448 bd1:
 449         skip();
 450         noscale++;
 451         bdtab[j] = atoi();
 452         noscale = 0;
 453 
 454         return (0);
 455 }
 456 
 457 
 458 int
 459 casevs()
 460 {
 461         int     i;
 462 
 463         skip();
 464         vflag++;
 465         dfact = INCH; /*default scaling is points!*/
 466         dfactd = 72;
 467         res = VERT;
 468         i = inumb(&lss);
 469         if (nonumb)
 470                 i = lss1;
 471         if (i < VERT)
 472                 i = VERT;       /* was VERT */
 473         lss1 = lss;
 474         lss = i;
 475 
 476         return (0);
 477 }
 478 
 479 
 480 
 481 int
 482 casess()
 483 {
 484         return (0);
 485 }
 486 
 487 
 488 tchar xlss()
 489 {
 490         /* stores \x'...' into
 491          * two successive tchars.
 492          * the first contains HX, the second the value,
 493          * encoded as a vertical motion.
 494          * decoding is done in n2.c by pchar().
 495          */
 496         int     i;
 497 
 498         getch();
 499         dfact = lss;
 500         i = quant(atoi(), VERT);
 501         dfact = 1;
 502         getch();
 503         if (i >= 0)
 504                 *pbp++ = MOT | VMOT | i;
 505         else
 506                 *pbp++ = MOT | VMOT | NMOT | -i;
 507         return(HX);
 508 }