t2.c (4071B)
1 #include "a.h" 2 3 /* 4 * Section 2 - Font and character size control. 5 */ 6 7 /* 2.1 - Character set */ 8 /* XXX 9 * 10 * \C'name' - character named name 11 * \N'n' - character number 12 * \(xx - two-letter character 13 * \- 14 * \` 15 * \' 16 * ` 17 * ' 18 * - 19 */ 20 21 Rune* 22 getqarg(void) 23 { 24 static Rune buf[MaxLine]; 25 int c; 26 Rune *p, *e; 27 28 p = buf; 29 e = p + nelem(buf) - 1; 30 31 if(getrune() != '\'') 32 return nil; 33 while(p < e){ 34 c = getrune(); 35 if(c < 0) 36 return nil; 37 if(c == '\'') 38 break; 39 *p++ = c; 40 } 41 *p = 0; 42 return buf; 43 } 44 45 int 46 e_N(void) 47 { 48 Rune *a; 49 if((a = getqarg()) == nil) 50 goto error; 51 return eval(a); 52 53 error: 54 warn("malformed %CN'...'", backslash); 55 return 0; 56 } 57 58 int 59 e_paren(void) 60 { 61 int c, cc; 62 Rune buf[2], r; 63 64 if((c = getrune()) < 0 || c == '\n') 65 goto error; 66 if((cc = getrune()) < 0 || cc == '\n') 67 goto error; 68 buf[0] = c; 69 buf[1] = cc; 70 r = troff2rune(buf); 71 if(r == Runeerror) 72 warn("unknown char %C(%C%C", backslash, c, cc); 73 return r; 74 75 error: 76 warn("malformed %C(xx", backslash); 77 return 0; 78 } 79 80 /* 2.2 - Fonts */ 81 Rune fonttab[10][100]; 82 83 /* 84 * \fx \f(xx \fN - font change 85 * number register .f - current font 86 * \f0 previous font (undocumented?) 87 */ 88 /* change to font f. also \fx, \f(xx, \fN */ 89 /* .ft LongName is okay - temporarily at fp 0 */ 90 void 91 ft(Rune *f) 92 { 93 int i; 94 int fn; 95 96 if(f && runestrcmp(f, L("P")) == 0) 97 f = nil; 98 if(f == nil) 99 fn = 0; 100 else if(isdigit(f[0])) 101 fn = eval(f); 102 else{ 103 for(i=0; i<nelem(fonttab); i++){ 104 if(runestrcmp(fonttab[i], f) == 0){ 105 fn = i; 106 goto have; 107 } 108 } 109 warn("unknown font %S", f); 110 fn = 1; 111 } 112 have: 113 if(fn < 0 || fn >= nelem(fonttab)){ 114 warn("unknown font %d", fn); 115 fn = 1; 116 } 117 if(fn == 0) 118 fn = getnr(L(".f0")); 119 nr(L(".f0"), getnr(L(".f"))); 120 nr(L(".f"), fn); 121 runmacro1(L("font")); 122 } 123 124 /* mount font named f on physical position N */ 125 void 126 fp(int i, Rune *f) 127 { 128 if(i <= 0 || i >= nelem(fonttab)){ 129 warn("bad font position %d", i); 130 return; 131 } 132 runestrecpy(fonttab[i], fonttab[i]+sizeof fonttab[i], f); 133 } 134 135 int 136 e_f(void) 137 { 138 ft(getname()); 139 return 0; 140 } 141 142 void 143 r_ft(int argc, Rune **argv) 144 { 145 if(argc == 1) 146 ft(nil); 147 else 148 ft(argv[1]); 149 } 150 151 void 152 r_fp(int argc, Rune **argv) 153 { 154 if(argc < 3){ 155 warn("missing arguments to %Cfp", dot); 156 return; 157 } 158 fp(eval(argv[1]), argv[2]); 159 } 160 161 /* 2.3 - Character size */ 162 163 /* \H'±N' sets height */ 164 165 void 166 ps(int s) 167 { 168 if(s == 0) 169 s = getnr(L(".s0")); 170 nr(L(".s0"), getnr(L(".s"))); 171 nr(L(".s"), s); 172 runmacro1(L("font")); 173 } 174 175 /* set point size */ 176 void 177 r_ps(int argc, Rune **argv) 178 { 179 Rune *p; 180 181 if(argc == 1 || argv[1][0] == 0) 182 ps(0); 183 else{ 184 p = argv[1]; 185 if(p[0] == '-') 186 ps(getnr(L(".s"))-eval(p+1)); 187 else if(p[0] == '+') 188 ps(getnr(L(".s"))+eval(p+1)); 189 else 190 ps(eval(p)); 191 } 192 } 193 194 int 195 e_s(void) 196 { 197 int c, cc, ccc, n, twodigit; 198 199 c = getnext(); 200 if(c < 0) 201 return 0; 202 if(c == '+' || c == '-'){ 203 cc = getnext(); 204 if(cc == '('){ 205 cc = getnext(); 206 ccc = getnext(); 207 if(cc < '0' || cc > '9' || ccc < '0' || ccc > '9'){ 208 warn("bad size %Cs%C(%C%C", backslash, c, cc, ccc); 209 return 0; 210 } 211 n = (cc-'0')*10+ccc-'0'; 212 }else{ 213 if(cc < '0' || cc > '9'){ 214 warn("bad size %Cs%C%C", backslash, c, cc); 215 return 0; 216 } 217 n = cc-'0'; 218 } 219 if(c == '+') 220 ps(getnr(L(".s"))+n); 221 else 222 ps(getnr(L(".s"))-n); 223 return 0; 224 } 225 twodigit = 0; 226 if(c == '('){ 227 twodigit = 1; 228 c = getnext(); 229 if(c < 0) 230 return 0; 231 } 232 if(c < '0' || c > '9'){ 233 warn("bad size %Cs%C", backslash, c); 234 ungetnext(c); 235 return 0; 236 } 237 if(twodigit || (c < '4' && c != '0')){ 238 cc = getnext(); 239 if(c < 0) 240 return 0; 241 n = (c-'0')*10+cc-'0'; 242 }else 243 n = c-'0'; 244 ps(n); 245 return 0; 246 } 247 248 void 249 t2init(void) 250 { 251 fp(1, L("R")); 252 fp(2, L("I")); 253 fp(3, L("B")); 254 fp(4, L("BI")); 255 fp(5, L("CW")); 256 257 nr(L(".s"), 10); 258 nr(L(".s0"), 10); 259 260 addreq(L("ft"), r_ft, -1); 261 addreq(L("fp"), r_fp, -1); 262 addreq(L("ps"), r_ps, -1); 263 addreq(L("ss"), r_warn, -1); 264 addreq(L("cs"), r_warn, -1); 265 addreq(L("bd"), r_warn, -1); 266 267 addesc('f', e_f, 0); 268 addesc('s', e_s, 0); 269 addesc('(', e_paren, 0); /* ) */ 270 addesc('C', e_warn, 0); 271 addesc('N', e_N, 0); 272 /* \- \' \` are handled in html.c */ 273 }