void PseudoSpace(struct XYspace *S, /* coordinate space structure to fill out */ double M[2][2]) /* matrix that will become 'tofract.normal' */ { S->type = SPACETYPE; S->flag = ISPERMANENT(ON) + ISIMMORTAL(ON); S->references = 2; /* 3-26-91 added PNM */ S->tofract.normal[0][0] = M[0][0]; S->tofract.normal[1][0] = M[1][0]; S->tofract.normal[0][1] = M[0][1]; S->tofract.normal[1][1] = M[1][1]; FillOutFcns(S); }
/* :h3.KillPath() - Destroying a Path Destroying a path is simply a matter of freeing each segment in the linked list. Again, we let the experts handle text. */ void KillPath(struct segment *p) /* path to destroy */ { register struct segment *linkp; /* temp register holding next segment*/ /* return conditional based on reference count 3-26-91 PNM */ if ( (--(p->references) > 1) || ( (p->references == 1) && !ISPERMANENT(p->flag) ) ) return; while (p != NULL) { if (!ISPATHTYPE(p->type)) { ArgErr("KillPath: bad segment", p, NULL); return; } linkp = p->link; if (p->type == TEXTTYPE) KillText(p); else Free(p); p = linkp; } }
/* The following macro forces a space to have an inverse: */ #define CoerceInverse(S) if (!HASINVERSE((S)->flag)) { \ MatrixInvert((S)->tofract.normal, (S)->tofract.inverse); (S)->flag |= HASINVERSE(ON); } /* :h3.IDENTITY Space IDENTITY space is (logically) the space corresponding to the identity transformation matrix. However, since all our transformation matrices have a common FRACTFLOAT scale factor to convert to 'fractpel's, that is actually what we store in 'tofract' matrix of IDENTITY: */ static struct XYspace identity = { SPACETYPE, ISPERMANENT(ON) + ISIMMORTAL(ON) + HASINVERSE(ON), 2, /* added 3-26-91 PNM */ NULL, NULL, NULL, NULL, NULL, NULL, INVALIDID + 1, 0, {{{FRACTFLOAT, 0.0}, {0.0, FRACTFLOAT}}, {{1.0/FRACTFLOAT, 0.0}, {0.0, 1.0/FRACTFLOAT}}}, {{0, 0}, {0, 0}}}; struct XYspace *IDENTITY = &identity; /* */ #define MAXCONTEXTS 16 static struct doublematrix contexts[MAXCONTEXTS];