Annotation of researchv10no/cmd/picasso/textgen.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.