#ifndef lint static char sccsid[] = "@(#)shape.c 9.2 88/01/19 Copyright 1985 Sun Micro"; #endif /* * Copyright (c) 1985 by Sun Microsystems, Inc. */ /*- General utilities for dealing with shapes shape.c, Thu Oct 17 10:38:47 1985 */ #include #ifdef REF #include #include #endif #include "qalloc.h" #include "shape.h" struct shape InfiniteShape = { 0, 0, 0x7fff, 0x7fff, STATIC_OBJ, 1, }; struct shape InvalidShape = { 0, 0, 0, 0, STATIC_OBJ, 1, }; /* Free the trapezons associated with a shape */ sh_freeshape(sh) register struct shape *sh; { if (!sh->is_rect) { register struct shape_trapezon *p, *next; next = sh->trapset; while (p = next) { if (--p->refcnt > 0) break; next = p->next; QFREE(p); } sh->trapset = 0; } if (sh->refcnt == STATIC_OBJ - 1) sh_incref(sh); else { assert(sh->refcnt == 0); qtfree(sh); } } /* Copy a set of trapezons */ struct shape * sh_copy(sh) register struct shape *sh; { register struct shape_trapezon *ret, *tail; register struct shape_trapezon *t = sh->trapset; register struct shape *p; ret = 0; if (!sh->is_rect) while (t) { register size; register struct shape_trapezon *new; size = sizeof(struct shape_trapezon) + sizeof(struct shape_trapseg) * t->used; QALLOC(new, size, (struct shape_trapezon *)); bcopy(t, new, size); new->size = new->used; new->next = 0; new->refcnt = 1; if (ret) tail->next = new; else ret = new; tail = new; t = t->next; } qtalloc(p, (struct shape *)); *p = *sh; p->refcnt = 1; p->trapset = ret; sh_decref(sh); return p; } /* * Translate a shape by (dx,dy). Believe it or not, this apparently brute * force technique really does win over passing offsets around. Think * about counting the number of additions, and about how often the offsets * would be 0 */ struct shape * sh_translate(sh, dx, dy) register struct shape *sh; register short dx, dy; { if (sh == 0 || dx == 0 && dy == 0) return sh; if (sh->refcnt>1 || (!sh->is_rect && sh->trapset->refcnt>1)) sh = sh_copy(sh); sh->pos.x += dx; sh->pos.y += dy; if (!sh->is_rect) { register struct shape_trapezon *t; for (t = sh->trapset; t; t = t->next) { register struct shape_trapseg *p; t->top += dy; t->bottom += dy; t->left += dx; t->right += dx; for (p = &t->segs[t->used]; p >= &t->segs[0]; --p) { p->y += dy; p->x1 += dx; p->x2 += dx; } } } return sh; }