Annotation of researchv10no/cmd/picasso/textgen.c, revision 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.