|
|
1.1 ! root 1: /* Copyright (c) 1988 AT&T */ ! 2: /* All Rights Reserved */ ! 3: ! 4: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ ! 5: /* The copyright notice above does not evidence any */ ! 6: /* actual or intended publication of such source code. */ ! 7: ! 8: /* @(#)picasso:textgen.c 1.0 */ ! 9: ! 10: #include <string.h> ! 11: #include <ctype.h> ! 12: #include "picasso.h" ! 13: #include "y.tab.h" ! 14: ! 15: extern int pic_compat; ! 16: ! 17: obj *textgen() ! 18: { ! 19: static double prevh = 0; ! 20: static double prevw = 0; ! 21: ! 22: struct objattr obat; ! 23: int i, sub, at, with, saw_with = 0; ! 24: double *bnd, savGbox[4], xwith, ywith; ! 25: double savcurx, savcury; ! 26: obj *p, *ppos; ! 27: Attr *ap; ! 28: ! 29: if (pic_compat) { /* in pic, bounding box has size zero */ ! 30: savcurx = curx; ! 31: savcury = cury; ! 32: } ! 33: obat.a_weight = obat.a_pcolor = obat.a_lcolor = obat.a_tcolor = -1; ! 34: obat.a_ht = obat.a_wid = 0; ! 35: obat.a_dashpat.a = (float *)0; ! 36: obat.a_layer = (int)getfval("curlayer"); ! 37: sub = CENTER; ! 38: at = with = 0; ! 39: set_text(); ! 40: for (i = 0; i < nattr; i++) { ! 41: ap = &attr[i]; ! 42: switch (ap->a_type) { ! 43: default: ! 44: miscattrs(ap, &obat); ! 45: break; ! 46: case WITH: ! 47: with = ap->a_val.i; ! 48: saw_with++; ! 49: break; ! 50: case AT: ! 51: ppos = ap->a_val.o; ! 52: curx = Xformx(ppos, 1, ppos->o_x, ppos->o_y); ! 53: cury = Xformy(ppos, 0, ppos->o_x, ppos->o_y); ! 54: at++; ! 55: break; ! 56: } ! 57: } ! 58: p = makenode(TEXT, N_VAL, obat.a_layer); ! 59: /* NOTE: the three color attributes reduce to one here; their obj.val ! 60: * slots are used to record bounding box center. If outline fonts are ! 61: * implemented, o_fill will be needed, and some adjustments made below ! 62: */ ! 63: if (obat.a_tcolor == -1) ! 64: if ((obat.a_tcolor = obat.a_pcolor) == -1) ! 65: obat.a_tcolor = obat.a_lcolor; ! 66: p->o_text = obat.a_tcolor; ! 67: checktextcolor(p); ! 68: p->o_attr |= EDGED; ! 69: /* need to save and restore the global bounding box, since text_bounds ! 70: sets it based on o_x and o_y, which are not properly set yet! */ ! 71: for (i = 0; i < 4; i++) ! 72: savGbox[i] = Gbox[i]; ! 73: bnd = text_bounds(p); ! 74: for (i = 0; i < 4; i++) ! 75: Gbox[i] = savGbox[i]; ! 76: p->o_val[N_VAL-2].f = (bnd[0] + bnd[2]) / 2; ! 77: p->o_val[N_VAL-1].f = (bnd[1] + bnd[3]) / 2; ! 78: prevw = p->o_wid = (obat.a_wid > 0 ? obat.a_wid : bnd[2]-bnd[0]); ! 79: prevh = p->o_ht = (obat.a_ht > 0 ? obat.a_ht : bnd[3]-bnd[1]); ! 80: ! 81: if (pic_compat) { /* Here unchanged, or changed to at */ ! 82: if (!saw_with) { /* adjustment w.r.t. Here */ ! 83: p->o_x = curx; ! 84: p->o_y = cury; ! 85: } ! 86: else { /* forces text center to Here, since all corners ! 87: are at center (size is zero) */ ! 88: p->o_x = curx - p->o_val[N_VAL-2].f; ! 89: p->o_y = cury - p->o_val[N_VAL-1].f; ! 90: } ! 91: } ! 92: else { ! 93: if (at == 0 && saw_with == 0) ! 94: with = isright(hvmode) ? WEST : /* the default for with */ ! 95: isleft(hvmode) ? EAST : /* butts the text box a- */ ! 96: isup(hvmode) ? SOUTH :/* gainst the current point */ ! 97: NORTH; /* in the current direction */ ! 98: /* position of center relative to current point */ ! 99: xwith = ywith = 0.0; ! 100: switch (with) { ! 101: case NORTH: ywith = -prevh/2; break; ! 102: case SOUTH: ywith = prevh/2; break; ! 103: case EAST: xwith = -prevw/2; break; ! 104: case WEST: xwith = prevw/2; break; ! 105: case NE: xwith = -prevw/2; ywith = -prevh/2; break; ! 106: case SE: xwith = -prevw/2; ywith = prevh/2; break; ! 107: case NW: xwith = prevw/2; ywith = -prevh/2; break; ! 108: case SW: xwith = prevw/2; ywith = prevh/2; break; ! 109: } ! 110: curx += xwith; /* position of center, temporarily */ ! 111: cury += ywith; ! 112: /* calculate PLACE for this object based on center */ ! 113: p->o_x = curx - p->o_val[N_VAL-2].f; ! 114: p->o_y = cury - p->o_val[N_VAL-1].f; ! 115: ! 116: /* calculate new postion for Here */ ! 117: if (isright(hvmode)) ! 118: curx += prevw/2; ! 119: else if (isleft(hvmode)) ! 120: curx -= prevw/2; ! 121: else if (isup(hvmode)) ! 122: cury += prevh/2; ! 123: else ! 124: cury -= prevh/2; ! 125: } ! 126: ! 127: track_bounds (bnd[0]+p->o_x, bnd[1]+p->o_y, ! 128: bnd[2]+p->o_x, bnd[3]+p->o_y); ! 129: return(p); ! 130: } ! 131: ! 132: int def_font, def_size, def_space; ! 133: int cur_font, cur_size, cur_space; ! 134: ! 135: set_text() ! 136: { ! 137: cur_font = cur_size = cur_space = 0; ! 138: def_font = (int)getfval("textfont"); ! 139: def_size = (int)getfval("textsize"); ! 140: def_space = (int)getfval("textspace"); ! 141: } ! 142: ! 143: reset_font(val) /* user supplied font attribute on object */ ! 144: double val; /* (stored as negative, to distinguish it */ ! 145: { /* from troff escape embedded in a string) */ ! 146: cur_font = -val; ! 147: } ! 148: ! 149: reset_size (op, val) ! 150: int op; ! 151: double val; ! 152: { ! 153: if (cur_size == 0) ! 154: cur_size = -def_size; ! 155: switch (op) { ! 156: default: cur_size = -val; break; ! 157: case '+': cur_size -= val; break; ! 158: case '-': cur_size += val; break; ! 159: case '*': cur_size *= val; break; ! 160: case '/': if (val != 0) ! 161: cur_size /= val; ! 162: } ! 163: } ! 164: ! 165: reset_space (op, val) ! 166: int op; ! 167: double val; ! 168: { ! 169: if (cur_space == 0) ! 170: cur_space = -def_space; ! 171: switch (op) { ! 172: default: cur_space = -val; break; ! 173: case '+': cur_space -= val; break; ! 174: case '-': cur_space += val; break; ! 175: case '*': cur_space *= val; break; ! 176: case '/': if (val != 0) ! 177: cur_space /= val; ! 178: } ! 179: } ! 180: ! 181: fix_text(n1, n2) /* fill in default font/size/space values */ ! 182: int n1, n2; /* if space unspecified, set from size. */ ! 183: { ! 184: if (cur_font == 0) ! 185: cur_font = -def_font; ! 186: if (cur_size == 0) ! 187: cur_size = -def_size; ! 188: if (cur_space == 0) ! 189: cur_space = (cur_size==0 ? -def_space : (double)cur_size ! 190: * def_space/def_size); ! 191: while (n1 < n2) { ! 192: if (text[n1].t_font == 0) ! 193: text[n1].t_font = cur_font; ! 194: if (text[n1].t_size == 0) ! 195: text[n1].t_size = cur_size; ! 196: if (text[n1].t_space == 0) ! 197: text[n1].t_space = text[n1].t_size == 0 ? cur_space : ! 198: (short)(text[n1].t_size ! 199: * (double)def_space/def_size); ! 200: ++n1; ! 201: } ! 202: } ! 203: ! 204: int ntextlines = 0; ! 205: ! 206: savetext(type, s) /* record text elements for current object */ ! 207: int type; /* breaking up into homogeneous font/size. */ ! 208: char *s; ! 209: { ! 210: extern char eqn_delim; ! 211: extern int eqn_count; ! 212: int tmp_font = cur_font, ! 213: tmp_size = cur_size; ! 214: char *str; ! 215: ! 216: ++ntextlines; ! 217: if ((type & (CENTER|LJUST|RJUST)) == 0) ! 218: type |= CENTER; ! 219: if (*s == '\0') /* then save a blank (KLUDGE!!) */ ! 220: save_one(type, cur_font, cur_size, ntextlines, " "); ! 221: else while (str = parse_text(s, &cur_font, &cur_size)) ! 222: if (*str) ! 223: save_one(type, cur_font, cur_size, ntextlines, str); ! 224: free(s); ! 225: if (cur_font != tmp_font) ! 226: setfval("textfont",(double)cur_font); ! 227: if (cur_size != tmp_size) ! 228: setfval("textsize",(double)cur_size); ! 229: } ! 230: ! 231: save_one(type, font, size, n, str) ! 232: int type, font, n, size; ! 233: char *str; ! 234: { ! 235: if (ntext >= ntextlist) ! 236: text = (Text *) grow((char *) text, "text", ! 237: ntextlist += 200, sizeof(Text)); ! 238: text[ntext].t_type = type; ! 239: text[ntext].t_font = font; ! 240: text[ntext].t_size = size; ! 241: text[ntext].t_space = cur_space; ! 242: text[ntext].t_line = n; ! 243: text[ntext].t_val = tostring(str); ! 244: ntext++; ! 245: } ! 246: ! 247: int ! 248: copytext(start, end) ! 249: int start, end; ! 250: { ! 251: /* DBK--3/23/90: This is called from copyone(); if copyone is called during ! 252: the process of assembling a new obj, the calculation of o_nt2 could ! 253: possibly be upset (too many people updating ntext). However, I don't ! 254: believe this occurs. ! 255: */ ! 256: int i; ! 257: int linediff; ! 258: ! 259: linediff = ntextlines - text[start].t_line + 1; ! 260: for (i = start; i < end; i++, ntext++) { ! 261: if (ntext >= ntextlist) ! 262: text = (Text *) grow((char *) text, "text", ntextlist += 200, ! 263: sizeof(Text)); ! 264: text[ntext] = text[i]; ! 265: text[ntext].t_val = tostring(text[i].t_val); ! 266: text[ntext].t_line = ntextlines = text[i].t_line + linediff; ! 267: } ! 268: return ntext1 = ntext; ! 269: } ! 270: ! 271: double *text_bounds(p) /* returns relative bounding box */ ! 272: obj *p; /* if possible, EQN type text should be sized */ ! 273: { /* by looking for bounding box in dpost file. */ ! 274: static double bnd[4]; ! 275: double ext[4]; ! 276: double w0, w1, dely; ! 277: double ox, oy; ! 278: int n1, n2, seq, type; ! 279: ! 280: if ((n1=p->o_nt1) >= (n2=p->o_nt2)) ! 281: return bnd; ! 282: fix_text(n1, n2); ! 283: dely = abs(text[n1].t_space)/144.; ! 284: bnd[1] = dely - abs(text[n1].t_size)/144.; ! 285: switch (text[n1].t_type & (ABOVE | BELOW)) { ! 286: case ABOVE: bnd[1] += dely; break; ! 287: case BELOW: bnd[1] -= dely; break; ! 288: } ! 289: bnd[3] = bnd[1]; ! 290: bnd[0] = bnd[2] = 0; ! 291: while (n1 < n2) { /* assumes all text same spacing!!--DBK */ ! 292: seq = text[n1].t_line; ! 293: bnd[1] -= dely; bnd[3] += dely; ! 294: type = text[n1].t_type; ! 295: for (w0 = w1 = 0; n1 < n2 && text[n1].t_line == seq; ++n1) { ! 296: w1 += (text[n1].t_width = getstringwidth(text[n1].t_val, ! 297: text[n1].t_font,text[n1].t_size)); ! 298: } ! 299: switch (type & (CENTER | LJUST | RJUST)) { ! 300: case CENTER: w1 /= 2; w0 = -w1; break; ! 301: case RJUST: w0 = -w1; w1 = 0; break; ! 302: } ! 303: if (w0 < bnd[0]) ! 304: bnd[0] = w0; ! 305: if (w1 > bnd[2]) ! 306: bnd[2] = w1; ! 307: } ! 308: for (n1 = 0; n1 < 4; n1++) ! 309: ext[n1] = bnd[n1]; ! 310: if (p->o_type != TEXT) /* text is horizontally centered on o_x,o_y */ ! 311: ext[0] = - (ext[2] = (bnd[2] - bnd[0]) / 2); ! 312: ! 313: ox = Xformx(p, 1, p->o_x, p->o_y); ! 314: oy = Xformy(p, 0, p->o_x, p->o_y); ! 315: track_bounds(ox + ext[0], oy + ext[1], ox + ext[2], oy + ext[3]); ! 316: return bnd; ! 317: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.