|
|
1.1 ! root 1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ ! 2: static char rcsid[] = "$Header: eval.c,v 2.3 84/07/19 11:47:18 guido Exp $"; ! 3: ! 4: /* ! 5: * B editor -- Width attribute evaluation. ! 6: */ ! 7: ! 8: #include "b.h" ! 9: #include "node.h" ! 10: #include "gram.h" ! 11: #include "eval.h" ! 12: ! 13: ! 14: /* ! 15: * The following convention is used throughout the editor to indicate ! 16: * the sizes of objects. ! 17: * - A zero or positive `width' value means the object contains no ! 18: * linefeeds. The width is counted in characters. ! 19: * - A negative `width' means the object (or its children) contains ! 20: * at leasty one linefeed (return is treated as a linefeed here). ! 21: * The number of linefeeds is -width. ! 22: * There is no indication whether the object fits on that number of ! 23: * physical lines, as logical lines may have arbitrary length. ! 24: * ! 25: * For coordinates the following convention is used. ! 26: * (Note that, in accordance to the convention in curses(3), the ! 27: * `y' coordinate always precedes the `x' coorxdinate.) ! 28: * - `Y' is the line number, counted from the beginning of the unit. ! 29: * These are logical lines rather than physical lines. ! 30: * The first line has line number 0. ! 31: * - `X' is the column number. The first column is 0. For x < 0, ! 32: * see the important notice below. ! 33: * - `Level' is the indentation level, indicating where a new line ! 34: * would start if inserted at the current position. ! 35: * The initial `x' position of such a line is `level*TABS'. ! 36: * ! 37: * ***** IMPORTANT NOTICE ***** ! 38: * A special case is x = -1. This means that the current x position is ! 39: * unknown. Further output on the same line is suppressed, until a ! 40: * linefeed is encountered. This feature is necessary because while ! 41: * calculating coordinates, when an object has width < 0, only the y ! 42: * coordinate of the end of that object is known. In this case, the ! 43: * next non-empty object MUST START WITH A LINEFEED, or it will not ! 44: * be visible on the screen (in practice, a space is sometimes present ! 45: * in the parse tree which is not shown then). ! 46: */ ! 47: ! 48: ! 49: /* ! 50: * Compute the (y, x) coordinates and indent level just before ! 51: * the beginning of the j'th child, if the current node starts ! 52: * at the initial values of (y, x) and level. ! 53: */ ! 54: ! 55: Visible Procedure ! 56: evalcoord(n, jch, py, px, plevel) ! 57: register node n; ! 58: register int jch; ! 59: int *py; ! 60: int *px; ! 61: int *plevel; ! 62: { ! 63: node nn; ! 64: register int i; ! 65: register string *rp = noderepr(n); ! 66: register int k; ! 67: register int y = 0; ! 68: int x = *px; ! 69: int level = *plevel; ! 70: int nch = Type(n) == Tex ? 0 : nchildren(n); ! 71: ! 72: if (jch > nch) ! 73: jch = nch+1; ! 74: for (i = 0; i < jch; ++i) { ! 75: if (i) { ! 76: nn = child(n, i); ! 77: k = width(nn); ! 78: if (k < 0) { ! 79: y += -k; ! 80: x = k; ! 81: } ! 82: else if (x >= 0) ! 83: x += k; ! 84: } ! 85: k = Fwidth(rp[i]); ! 86: if (k < 0) { ! 87: y += -k; ! 88: x = rp[i][0] == '\r' ? 0 : TABS*level; ! 89: x += strlen(rp[i]) - 1; ! 90: } ! 91: else { ! 92: if (x >= 0) ! 93: x += k; ! 94: if (rp[i]) { ! 95: if (rp[i][k] == '\t') ! 96: ++level; ! 97: else if (rp[i][k] == '\b') ! 98: --level; ! 99: } ! 100: } ! 101: } ! 102: ! 103: *py += y; ! 104: *px = x; ! 105: *plevel = level; ! 106: } ! 107: ! 108: ! 109: /* ! 110: * Yield the width of a piece of fixed text as found in a node's repr, ! 111: * excluding \b or \t. If \n or \r is found, -1 is returned. ! 112: * It assumes that \n or \r only occur as first ! 113: * character, and \b or \t only as last. ! 114: */ ! 115: ! 116: Visible int ! 117: fwidth(str) ! 118: register string str; ! 119: { ! 120: register int c; ! 121: register int n = 0; ! 122: ! 123: if (!str) ! 124: return 0; ! 125: c = str[0]; ! 126: if (c == '\r' || c == '\n') ! 127: return -1; ! 128: for (; c; c = *++str) ! 129: ++n; ! 130: if (n > 0) { ! 131: c = str[-1]; ! 132: if (c == '\t' || c == '\b') ! 133: --n; ! 134: } ! 135: return n; ! 136: } ! 137: ! 138: ! 139: /* ! 140: * Evaluate the width of node n, assuming the widths of its children ! 141: * have correctly been calculated. ! 142: */ ! 143: ! 144: Visible int ! 145: evalwidth(n) ! 146: register node n; ! 147: { ! 148: register int w; ! 149: register int i; ! 150: register string *rp; ! 151: register int y = 0; ! 152: register int x = 0; ! 153: register int nch; ! 154: register node nn; ! 155: ! 156: rp = noderepr(n); ! 157: nch = Type(n) == Tex ? 0 : nchildren(n); ! 158: for (i = 0; i <= nch; ++i) { ! 159: if (i) { ! 160: nn = child(n, i); ! 161: w = width(nn); ! 162: if (w < 0) { ! 163: y += -w; ! 164: x = w; ! 165: } ! 166: else ! 167: x += w; ! 168: } ! 169: w = Fwidth(rp[i]); ! 170: if (w < 0) { ! 171: y += -w; ! 172: x = 0; ! 173: } ! 174: else ! 175: x += w; ! 176: } ! 177: if (y > 0) ! 178: return -y; ! 179: return x; ! 180: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.