|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Edward Wang at The University of California, Berkeley. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted provided ! 9: * that: (1) source distributions retain this entire copyright notice and ! 10: * comment, and (2) distributions including binaries display the following ! 11: * acknowledgement: ``This product includes software developed by the ! 12: * University of California, Berkeley and its contributors'' in the ! 13: * documentation or other materials provided with the distribution and in ! 14: * all advertising materials mentioning features or use of this software. ! 15: * Neither the name of the University nor the names of its contributors may ! 16: * be used to endorse or promote products derived from this software without ! 17: * specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: static char sccsid[] = "@(#)wwupdate.c 3.29 (Berkeley) 6/6/90"; ! 25: #endif /* not lint */ ! 26: ! 27: #include "ww.h" ! 28: #include "tt.h" ! 29: ! 30: wwupdate1(top, bot) ! 31: { ! 32: int i; ! 33: register j; ! 34: char *touched; ! 35: struct ww_update *upd; ! 36: char check_clreos = 0; ! 37: int scan_top, scan_bot; ! 38: ! 39: wwnupdate++; ! 40: { ! 41: register char *t1 = wwtouched + top, *t2 = wwtouched + bot; ! 42: register n; ! 43: ! 44: while (!*t1++) ! 45: if (t1 == t2) ! 46: return; ! 47: while (!*--t2) ! 48: ; ! 49: scan_top = top = t1 - wwtouched - 1; ! 50: scan_bot = bot = t2 - wwtouched + 1; ! 51: if (scan_bot - scan_top > 1 && ! 52: (tt.tt_clreos != 0 || tt.tt_clear != 0)) { ! 53: int st = tt.tt_clreos != 0 ? scan_top : 0; ! 54: ! 55: /* ! 56: * t1 is one past the first touched row, ! 57: * t2 is on the last touched row. ! 58: */ ! 59: for (t1--, n = 1; t1 < t2;) ! 60: if (*t1++) ! 61: n++; ! 62: /* ! 63: * If we can't clreos then we try for clearing ! 64: * the whole screen. ! 65: */ ! 66: if (check_clreos = n * 10 > (wwnrow - st) * 9) { ! 67: scan_top = st; ! 68: scan_bot = wwnrow; ! 69: } ! 70: } ! 71: } ! 72: if (tt.tt_clreol == 0 && !check_clreos) ! 73: goto simple; ! 74: for (i = scan_top, touched = &wwtouched[i], upd = &wwupd[i]; ! 75: i < scan_bot; ! 76: i++, touched++, upd++) { ! 77: register gain = 0; ! 78: register best_gain = 0; ! 79: register best_col; ! 80: register union ww_char *ns, *os; ! 81: ! 82: if (wwinterrupt()) ! 83: return; ! 84: if (!check_clreos && !*touched) ! 85: continue; ! 86: wwnupdscan++; ! 87: j = wwncol; ! 88: ns = &wwns[i][j]; ! 89: os = &wwos[i][j]; ! 90: while (--j >= 0) { ! 91: /* ! 92: * The cost of clearing is: ! 93: * ncol - nblank + X ! 94: * The cost of straight update is, more or less: ! 95: * ncol - nsame ! 96: * We clear if nblank - nsame > X ! 97: * X is the clreol overhead. ! 98: * So we make gain = nblank - nsame. ! 99: */ ! 100: if ((--ns)->c_w == (--os)->c_w) ! 101: gain--; ! 102: else ! 103: best_gain--; ! 104: if (ns->c_w == ' ') ! 105: gain++; ! 106: if (gain > best_gain) { ! 107: best_col = j; ! 108: best_gain = gain; ! 109: } ! 110: } ! 111: upd->best_gain = best_gain; ! 112: upd->best_col = best_col; ! 113: upd->gain = gain; ! 114: } ! 115: if (check_clreos) { ! 116: register struct ww_update *u; ! 117: register gain = 0; ! 118: register best_gain = 0; ! 119: int best_row; ! 120: register simple_gain = 0; ! 121: char didit = 0; ! 122: ! 123: /* ! 124: * gain is the advantage of clearing all the lines. ! 125: * best_gain is the advantage of clearing to eos ! 126: * at best_row and u->best_col. ! 127: * simple_gain is the advantage of using only clreol. ! 128: * We use g > best_gain because u->best_col can be ! 129: * undefined when u->best_gain is 0 so we can't use it. ! 130: */ ! 131: for (j = scan_bot - 1, u = wwupd + j; j >= top; j--, u--) { ! 132: register g = gain + u->best_gain; ! 133: ! 134: if (g > best_gain) { ! 135: best_gain = g; ! 136: best_row = j; ! 137: } ! 138: gain += u->gain; ! 139: if (tt.tt_clreol != 0 && u->best_gain > 4) ! 140: simple_gain += u->best_gain - 4; ! 141: } ! 142: if (tt.tt_clreos == 0) { ! 143: if (gain > simple_gain && gain > 4) { ! 144: xxclear(); ! 145: i = top = scan_top; ! 146: bot = scan_bot; ! 147: j = 0; ! 148: didit = 1; ! 149: } ! 150: } else ! 151: if (best_gain > simple_gain && best_gain > 4) { ! 152: i = best_row; ! 153: xxclreos(i, j = wwupd[i].best_col); ! 154: bot = scan_bot; ! 155: didit = 1; ! 156: } ! 157: if (didit) { ! 158: wwnupdclreos++; ! 159: wwnupdclreosline += wwnrow - i; ! 160: u = wwupd + i; ! 161: while (i < scan_bot) { ! 162: register union ww_char *os = &wwos[i][j]; ! 163: ! 164: for (j = wwncol - j; --j >= 0;) ! 165: os++->c_w = ' '; ! 166: wwtouched[i++] |= WWU_TOUCHED; ! 167: u++->best_gain = 0; ! 168: j = 0; ! 169: } ! 170: } else ! 171: wwnupdclreosmiss++; ! 172: } ! 173: simple: ! 174: for (i = top, touched = &wwtouched[i], upd = &wwupd[i]; i < bot; ! 175: i++, touched++, upd++) { ! 176: register union ww_char *os, *ns; ! 177: char didit; ! 178: ! 179: if (!*touched) ! 180: continue; ! 181: *touched = 0; ! 182: wwnupdline++; ! 183: didit = 0; ! 184: if (tt.tt_clreol != 0 && upd->best_gain > 4) { ! 185: wwnupdclreol++; ! 186: xxclreol(i, j = upd->best_col); ! 187: for (os = &wwos[i][j], j = wwncol - j; --j >= 0;) ! 188: os++->c_w = ' '; ! 189: didit = 1; ! 190: } ! 191: ns = wwns[i]; ! 192: os = wwos[i]; ! 193: for (j = 0; j < wwncol;) { ! 194: register char *p, *q; ! 195: char m; ! 196: int c; ! 197: register n; ! 198: char buf[512]; /* > wwncol */ ! 199: union ww_char lastc; ! 200: ! 201: for (; j++ < wwncol && ns++->c_w == os++->c_w;) ! 202: ; ! 203: if (j > wwncol) ! 204: break; ! 205: p = buf; ! 206: m = ns[-1].c_m; ! 207: c = j - 1; ! 208: os[-1] = ns[-1]; ! 209: *p++ = ns[-1].c_c; ! 210: n = 5; ! 211: q = p; ! 212: while (j < wwncol && ns->c_m == m) { ! 213: *p++ = ns->c_c; ! 214: if (ns->c_w == os->c_w) { ! 215: if (--n <= 0) ! 216: break; ! 217: os++; ! 218: ns++; ! 219: } else { ! 220: n = 5; ! 221: q = p; ! 222: lastc = *os; ! 223: *os++ = *ns++; ! 224: } ! 225: j++; ! 226: } ! 227: n = q - buf; ! 228: if (!wwwrap || i != wwnrow - 1 || c + n != wwncol) ! 229: xxwrite(i, c, buf, n, m); ! 230: else if (tt.tt_inschar || tt.tt_insspace) { ! 231: if (n > 1) { ! 232: q[-2] = q[-1]; ! 233: n--; ! 234: } else ! 235: c--; ! 236: xxwrite(i, c, buf, n, m); ! 237: c += n - 1; ! 238: if (tt.tt_inschar) ! 239: xxinschar(i, c, ns[-2].c_c, ! 240: ns[-2].c_m); ! 241: else { ! 242: xxinsspace(i, c); ! 243: xxwrite(i, c, &ns[-2].c_c, 1, ! 244: ns[-2].c_m); ! 245: } ! 246: } else { ! 247: if (--n) ! 248: xxwrite(i, c, buf, n, m); ! 249: os[-1] = lastc; ! 250: *touched = WWU_TOUCHED; ! 251: } ! 252: didit = 1; ! 253: } ! 254: if (!didit) ! 255: wwnupdmiss++; ! 256: } ! 257: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.