// polygon.c // // by John D. de Boer #include "common.h" #include "cstring.h" #include "cyber.h" #include "disk.h" #include "floating.h" #include "frame.h" #include "gui.h" #include "tapedeck.h" #include "vector.h" #include "view.h" #include "polygon.h" // Writing text polygon resources void writetextpoly(const polygon **P) { int NUM,i; const polypoint *L; if (!P || !*P) return; NUM=(*P)->num; if (NUM<1) return; writetext("// ",' '); writetext((*P)->name,13); writechar(13); if ((*P)->open) { writefig(NUM,' '); writetext("open",13); } else writefig(NUM,13); writechar(13); for (i=0;ipt + i; if (i % 20) { writefig(L->v - L[-1].v,' '); writefig(L->h - L[-1].h,13); } else { writetext(i>0 ? "d" : "m",' '); writefig(L->v,' '); writefig(L->h,13); } } writechar(13); writechar(13); } void writetextpolys(const polygons **Py) { int i; if (!Py || !*Py) return; writetext("Text Polygon Resource #",13); writechar(13); writefig((*Py)->num,13); writechar(13); for (i=0;i<(*Py)->num;i++) writetextpoly((const polygon **)((*Py)->poly[i])); } // Reading text polygon resources polygon **parsetextpoly(char **T) { char *S,*Temp,*S2; polygon **P,*MP; long i,NUM,RH,RV; if (!T || !*T) return NULL; S=firstocc('/',*T); if (!S) return NULL; S2=firstoccoflist("\n\r",S); nextword(&S); if (!S) return NULL; Temp=S; S=firstoccoflist("\n\r",S); if (!S) return NULL; if (Tempname=Temp; MP->num=NUM; nextword(&S); if (!S) return NULL; MP->open=begins(S,"open"); if (MP->open) { nextword(&S); if (!S) return NULL; } if (*S!='m') return NULL; RH=0; RV=0; for (i=0;ipt + i; L->h=HORZ; L->v=VERT; } *T=S; unlock(P); return P; } bool parsetextpolys(const char *S, polygons **Py) { char *T; int i; long NUM; polygon **P; if (!S || !*S || !Py || !*Py) return 0; T=firstocc('#',S); if (!T) return 0; while (!numeral(*T)) { nextline(&T); if (!T) return 0; } if (!parseinteger(T,&NUM) || NUM<1) return 0; resizehandle(Py,sizeof(polygons) + (NUM * sizeof(polygon))); // sizeof(polygon **) ? (*Py)->num=NUM; for (i=0;ipoly[i]=P; } (*Py)->changed=0; return 1; } bool readrespolys(polygons **Py, const char *Name) { string S; bool R; if (!Py || !*Py || !Name || !*Name) return 0; S=gettext(Name); if (!S) return 0; R=parsetextpolys(S,Py); old(S); (*Py)->changed=0; return R; } // Allocating polygons polygon **newpoly(const polypoint *L) { polygon **P; P=(polygon **)handle(sizeof(polygon) + sizeof(polypoint)); (*P)->num=1; (*P)->open=1; (*P)->name=NULL; (*P)->pt[0]=*L; return P; } void oldpoly(polygon **P) { if (!P || !*P) return; if ((*P)->name) old((*P)->name); release(P); } polygons **newpolys(void) { polygons **Py; Py=(polygons **)handle(sizeof(polygons)); (*Py)->num=0; (*Py)->changed=0; return Py; } void oldpolys(polygons **Py) { int i; if (!Py || !*Py) return; for (i=0;i<(*Py)->num;i++) oldpoly((*Py)->poly[i]); release(Py); } // Modifying polygons void movecorner(polygons **Py, int POLY, int PT, const polypoint *L) { polygon **P; if (!Py || !*Py || !range(POLY,(*Py)->num) || !L) return; P=(*Py)->poly[POLY]; if (!P || !*P || !range(PT,(*P)->num)) return; (*P)->pt[PT]=*L; (*Py)->changed=1; } void insertcorner(polygons **Py, int POLY, int PREV, const polypoint *L) { polygon **P; int i; if (!Py || !*Py || !range(POLY,(*Py)->num) || !L) return; P=(*Py)->poly[POLY]; if (!P || !*P || !range(PREV,(*P)->num)) return; resizehandle(P,sizeof(polygon) + (++(*P)->num * sizeof(polypoint))); for (i= (*P)->num - 1;i > PREV + 1;i--) (*P)->pt[i]=(*P)->pt[i - 1]; (*P)->pt[PREV + 1]=*L; (*Py)->changed=1; } void removecorner(polygons **Py, int POLY, int PT) { polygon **P; int i; if (!Py || !*Py || !range(POLY,(*Py)->num)) return; P=(*Py)->poly[POLY]; if (!P || !*P || !range(PT,(*P)->num)) return; if ((*P)->num<=2) { removepoly(Py,POLY); return; } for (i=PT;i < (*P)->num - 1;i++) (*P)->pt[i]=(*P)->pt[i + 1]; resizehandle(P,sizeof(polygon) + (--(*P)->num * sizeof(polypoint))); (*Py)->changed=1; } void addpoly(polygons **Py, const polypoint *L, long DLAT) { polypoint K; if (!Py || !*Py || !L) return; resizehandle(Py,sizeof(polygons) + (++(*Py)->num * sizeof(polygon))); (*Py)->poly[(*Py)->num - 1]=newpoly(L); K=*L; K.v-=DLAT; insertcorner(Py,(*Py)->num - 1,0,&K); (*Py)->changed=1; } void removepoly(polygons **Py, int POLY) { int i; if (!Py || !*Py || !range(POLY,(*Py)->num)) return; oldpoly((*Py)->poly[POLY]); for (i=POLY;i < (*Py)->num - 1;i++) (*Py)->poly[i]=(*Py)->poly[i + 1]; resizehandle(Py,sizeof(polygons) + (--(*Py)->num * sizeof(polygon))); (*Py)->changed=1; } void insertpoly(polygons **Py, polygon **P) { if (!Py || !*Py || !P || !*P) return; resizehandle(Py,sizeof(polygons) + (++(*Py)->num * sizeof(polygon))); (*Py)->poly[(*Py)->num - 1]=P; (*Py)->changed=1; } void namepolygon(polygons **Py, int POLY, const char *S) { polygon **P; if (!Py || !*Py || !range(POLY,(*Py)->num)) return; P=(*Py)->poly[POLY]; old((*P)->name); (*P)->name=copyof(S); (*Py)->changed=1; } bool polyisopen(const polygons **Py, int POLY) { polygon **P; if (!Py || !*Py || !range(POLY,(*Py)->num)) return 0; P=(*Py)->poly[POLY]; return (*P)->open; } void changepolyopenness(polygons **Py, int POLY) { polygon **P; if (!Py || !*Py || !range(POLY,(*Py)->num)) return; P=(*Py)->poly[POLY]; (*P)->open=!(*P)->open; (*Py)->changed=1; } void reversepoly(polygons **Py, int POLY, short *SEL) { polygon **P; polypoint *L,TEMP; int i,HALF,LAST; if (!Py || !*Py || !range(POLY,(*Py)->num)) return; P=(*Py)->poly[POLY]; if (!P || !*P) return; HALF= (*P)->num / 2; LAST= (*P)->num - 1; L=(*P)->pt; for (i=0;ichanged=1; }