diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/latexdraw/latexdraw.c |
Initial commit
Diffstat (limited to 'support/latexdraw/latexdraw.c')
-rw-r--r-- | support/latexdraw/latexdraw.c | 10677 |
1 files changed, 10677 insertions, 0 deletions
diff --git a/support/latexdraw/latexdraw.c b/support/latexdraw/latexdraw.c new file mode 100644 index 0000000000..66451f0aba --- /dev/null +++ b/support/latexdraw/latexdraw.c @@ -0,0 +1,10677 @@ + +/* Das Programm erlaubt das Erstellen von Zeichnungen */ +/* fuer LaTeX. Notwendig ist hierzu latexdraw.sty mit */ +/* den darin aufgerufenen sty-Dateien */ +/* interner Koordinatenursprung fuer Zeichnung und Menue */ +/* links unten am Schirm. */ +/* Weiteres in der Beschreibung latexdraw.tex */ +/* Stand 09.05.1999, copyright: H.-J. Siegert, TUM */ +/* nichtkommerzielle Nutzung F&L Hochschulen erlaubt */ +/* gegen Stand v. 19.03.1999 undelete ->UnDelete */ +/* gegen Stand v. 23.08.1998 STDIN ueber thread */ +/* gegen Stand v. 22.08.1998 Dateiname im Window-Namen */ +/* gegen Stand v. 12.04.1998 eigene cmap, wenn noetig */ +/* gegen Stand v. 28.10.1997 cast bei wi in rotate */ +/* gegen Stand v. 02.08.1997 erweitert fuer read von stdin */ +/* gegen Stand v. 17.06.1997 dgrenz Faktor 0.3 statt 0.5 */ +/* gegen Stand v. 19.03.1997 groessere Differenz beim */ +/* Ausrichten vertikale, horizontale Linien */ +/* gegen Stand v. 03.02.1997 kein snap bei fill */ +/* neue Abstandsberechnungen */ +/* gegen Stand v. 11.01.1997 bei Kuerzung wg Pfeilen wird */ +/* nicht mehr TeX-Definition der Winkel verwendet */ +/* gegen Stand v. 24.12.1996 alle Elemente gezeichnet bei */ +/* blinken, Abstandsmodifikation unterschiedlich bei */ +/* Selektion gefuellter und nichtgefuellter Elemente */ +/* gegen Stand v. 20.10.1996 Fehler bei Ausgabe Rechteck */ +/* gegen Stand v. 17.09.1996 Fehler in Pfeilen bei Boegen */ +/* gegen Stand v. 16.09.1996 Abfrage der Attribute m"oglich */ +/* gegen Stand v. 17.08.1996 Fehler in LaTeX-Datei bei */ +/* Pieslice (Klammer zu viel) */ +/* gegen Stand v. 27.07.1996 ^k bei Zeicheneingabe */ +/* gegen Stand v. 22.07.1996 ifdef XK_KP_... */ +/* autom. Erzeugung LaTeX-Datei ohne Oeffnung Fenster */ +/* (Parameter -io beim Aufruf) */ +/* gegen Stand v. 16.05.1996 Ausgabe Linien gepunktet, */ +/* strichpunktiert neue Form; LdpArc, LdpEllarc und */ +/* LdpBezier mit verkuerzten Boegen wegen Pfeilen! */ +/* gegen Stand v. 25.12.1995 auch Cursortasten v. Keypad */ +/* gegen Stand v. 19.06.1995 Menuefont ist Option */ +/* gegen Stand v. 12.06.1995 bessere Pfeilspitzen */ +/* gegen Stand v. 02.06.1995 usleep wg. Linux umbenannt */ +/* gegen Stand v. 13.05.1995 Fehler in Darstellung Bezier */ +/* gegen Stand v. 27.04.1995 weitere Farben, Bezier gefuellt*/ +/* Entkopplung Farbnummer und Anordnung Farbe im Menue */ +/* autom. Anordnung Farben im Menue */ +/* gegen Stand v. 26.04.1995 Fehler bei Texteingabe */ +/* gegen Stand v. 15.04.1995 Korrektur Auswahlrechteck cut, */ +/* statt ires,fres static, Fehler in trim und connect */ +/* bei Verschieben dazwischen */ +/* gegen Stand v. 07.04.1995 Korrektur chatt bei Text */ +/* gegen Stand v. 05.04.1995 Digitalisiertablett */ +/* gegen Stand v. 02.04.1995 auch Anklickpunkt bei connect */ +/* gegen Stand v. 22.03.1995 rot, CapProjecting */ +/* gegen Stand v. 19.03.1995 Lesen Versionen < 4.0 */ +/* gegen Stand v. 02.03.1995 Laenge Text unabhaengig von */ +/* der Fensterbreite */ +/* gegen Stand v. 26.02.1995 Fehler bei Abbruch Text */ +/* korrigiert, Textposition in chatt aufgenommen */ +/* gegen Stand v. 31.01.1995 laengerer Eingabestring */ +/* gegen Stand v. 29.01.1995 Fehler in selekt. chatt behoben*/ +/* gegen Stand v. 04.01.1995 Selektives chatt,Aufruf-Param. */ +/* gegen Stand v. 31.12.1994 Grauwerte bei Monochromschirm */ +/* gegen Stand v. 30.09.1994 Andere Berechnung Bezier */ +/* gegen Stand v. 21.09.1994 Anordnung Menue */ +/* gegen Stand v. 17.09.1994 trim fuer Recht-,Drei-,Viereck */ +/* gegen Stand v. 12.09.1994 Auswahlrechteck bei newgroup */ +/* gegen Stand v. 20.08.1994 andere Blinkzeiten */ +/* gegen Stand v. 17.08.1994 connect mit allen Elementen */ +/* gegen Stand v. 28.07.1994 Realisierung von Gruppen */ +/* gegen Stand v. 24.07.1994 undo bei loeschen d. backspace */ +/* blinken ausgewaehlter Elemente bei mcopy mmove */ +/* gegen Stand v. 02.07.1994 Ausrichten Punkte in x oder y */ +/* gegen Stand v. 18.06.1994 XSetInputFocus und ^a,^e */ +/* gegen Stand v. 06.06.1994 fuellen vorhandener Elemente */ +/* gegen Stand v. 02.05.1994 neben up auch down */ +/* gegen Stand v. 15.04.1994 Gerade mit Pfeilen st"arker */ +/* eingekuerzt */ +/* gegen Stand v. 08.04.1994 gespeicherte Ausgabeoptionen */ +/* und neue Makros aLdPfeil,eLdPfeil und LdpLine */ +/* gegen Stand v. 22.3.1994 uralte Versionsnummern mit CV */ +/* werden richtig erkannt */ +/* gegen Stand v. 18.03.94 Darstellung Text, der editiert */ +/* wird, an alter Position vermeiden */ +/* gegen Stand v. 11.03.94 Rundung korrigiert */ +/* gegen Stand v. 28.01.94 Gitterwerte werden ausgegeben */ +/* gegen Stand v. 22.01.94 parallele Linie kippt nicht */ +/* gegen Stand v. 20.01.94 Cursortasten bewegen Bild, */ +/* gegen Stand v. 27.11.93 Erweiterung extend auf Boegen, */ +/* redraw, */ +/* gegen Stand v. 01.11.93 Verbesserung minmax-Berechnung */ +/* gegen Stand v. 23.9.93 Definition documentstyle moeglich */ +/* gegen Stand v. 23.08.1993 Farben neu definiert */ +/* gegen Stand v. 10.8.93 bezier Linientyp variabel */ +/* gegen Stand v. 3.7.93 gefuellte Segmente */ +/* gegen Stand v. 18.5.92 Aenderung bei pbezabstand */ +/* gegen Stand v. 20.12.1992 vorwaerts/rueckwaerts Taste 3, */ +/* xend, yend fuer umgebendes Rechteck andersartig bestimmt */ +/* farbige Zeichnungelemente */ +/* email: siegert@informatik.tu-muenchen.dbp.de */ + + +#include <Xlib.h> +#include <Xutil.h> +#include <Xos.h> +#include <X.h> +#include <keysym.h> +#include <keysymdef.h> +#include <Xresource.h> +#include <cursorfont.h> + +#include <stdio.h> +#include <bitmaps/icon> +#include <ctype.h> +#include <math.h> +#include <setjmp.h> +#include <assert.h> +#include <string.h> +/*#include <strings.h>*/ +/*# include <sys/types.h>*/ + +#ifdef THREAD +#include <pthread.h> +#endif + +#ifdef TABLETT +#include "digitizer.h" +#endif + +#define Char char /* Characters (not bytes) */ +#define Static static /* Private global funcs and vars */ +#define Void void +#define siintround(a) (long) (a) /* Rundung bei double nach long */ + +#define boolean long +#define cboolean char +#define true 1L +#define false 0L +#define unbekannt -1 +#ifdef TABLETT +#define window_name "LaTeXdraw (Siegert, TUM, C15.29)Digi" +#endif +#ifndef TABLETT +#define window_name "LaTeXdraw (Siegert, TUM, C15.29)" +#endif +#define icon_name "latexdraw" +#define intfiletext "LaTeXdraw output file:" +#define extfiletext "LaTeX output file:" +#define zel 5000 /*Anzahl Zeichnungselemente*/ +#define zstr 300 /*Anzahl Stringelemente*/ +#define maxldicke 20 /*Liniendicke 1..20 vorhanden */ + +#define xzmax00 552.0 /*Window-Zeichenbereichbreite x*/ +#define yzmax00 760.0 ; /*Window-Hoehe, Zeichenbereichhoehe y*/ +#define xfont "8x13bold" /* Windowfont Menue, Prompt*/ +#define ersatzfont "8x13" /* Ersatz, falls Textfont fehlt*/ +#define ztextfonts 19 /* Zahl Fonts fuer Text in Zeichnung */ + /* Fonts in inittextfonts definiert */ +#define dminein 3.0 /*minimale Laengen bei der Eingabe*/ + +#define pi 3.141592653 +#define einrueck " " /*einruecken in TEX*/ +#define kom "," +#define blank " " + +#define verlline 30.0 +#define texfaktorv 0.3 /*1 pixel = texfaktor mm, Voreinstellung!*/ + +#define maxpunkte 1000 +#define maxstrl 123 /* maximale Stringlaenge */ +#define maxgruppen 500 /* maximale Anzahl Gruppen */ + +#define zrequw 5 /* Zahl der gleichzeitigen Requestwindows */ +#define prxachse " end point x axis?" +#define pryachse " end point y axis?" +#define pranfwi " beginning of arc?" +#define prendwi " end of arc?" +#define prendwisektor " end of arc for next sector?" +#define prpoint3 " point 3?" +#define prpoint4 " point 4?" +#define docstylestd "\\documentstyle[latexdraw]{article}" +#define docstyle2e "\\documentclass{article}\\input{latexdraw.sty}" + +#define wg 3600.0 +#define wh 1800.0 +#define wv 900.0 +#define wdv 2700.0 +#define initabstand 300000.0 +#define maxabstand 10.0 +/* Umrechnung Linienstaerke in pts */ +#define lw2pt 0.57 + + +/* Definitionen fuer Suchen von ausgewaehlten Elementen */ +/* Wird auch in array suchtypok[][] verwendet */ +#define alleelem 0 +#define nurtrimel 1 +#define nurboundel 2 +#define nurgerade 3 +#define nurmpel 4 +#define nurextendel 5 +#define nurfillel 6 + + +#define schwarz 0L +#define weiss 1L +#define maxzahlfarben 100L +#define paint 1L +#define erase 0L +#define maxlenmenfarbe 9L +#define maxlenfarbe 20L +#define somenspalten 3L + +#define tastatur_erwartet 1 +#define click_erwartet 2 +#define phase2 10 + +#ifndef XK_KP_Left +#define XK_KP_Left XK_Left +#define XK_KP_Right XK_Right +#define XK_KP_Up XK_Up +#define XK_KP_Down XK_Down +#endif + +#define tastecursleft1 XK_Left +#define tastecursright1 XK_Right +#define tastecursup1 XK_Up +#define tastecursdown1 XK_Down + +#define tastecursleft2 XK_KP_Left +#define tastecursright2 XK_KP_Right +#define tastecursup2 XK_KP_Up +#define tastecursdown2 XK_KP_Down + +#define tastea XK_a +#define tasted XK_d +#define tastee XK_e +#define tastek XK_k +#define tasteplus1 XK_plus +#define tasteplus2 XK_KP_Add +#define tasteminus1 XK_minus +#define tasteminus2 XK_KP_Subtract +#define tastedelete XK_Delete +#define tastebackspace XK_BackSpace +#define tastereturn XK_Return +#define tastecontroll XK_Control_L +#define tastecontrolr XK_Control_R +#define tasteundo XK_Undo +#define button1 1 +#define button2 2 +#define button3 3 +#define ttext 2 /*elementtypen*/ +#define tgerade 3 +#define tkreis 5 +#define tkreisgef 6 +#define tkreisbogen 7 +#define tell 8 +#define tellgef 9 +#define tellbogen 10 +#define trechteckgef 11 +#define tbezier 12 +#define tdreieckgef 13 +#define tviereckgef 14 +#define tkreissektorgef 15 +#define tellsektorgef 16 +#define tbeziergef 17 + +#define mende 1 /*menue_nummern*/ +#define mtext 2 +#define mgerade 3 +#define mkreis 4 +#define mell 5 +#define mrechteck 6 +#define mbezier 7 +#define mpolygon 8 +#define mspiegeln 9 +#define mkopieren 10 +#define mbewegen 11 +#define mergaenzen 12 +#define mausdehnen 13 +#define mbrechen 14 +#define mloeschen 15 +#define meinrasten 16 +#define mgefuellt 17 +#define mverbunden 17 +#define mbogen 18 +#define mparallel 19 +#define mlot 20 +#define mmittelpunkt 21 +#define mpfeilanf 22 +#define mpfeilende 23 +#define mdick 24 +#define mgestrichelt 25 +#define mgepunktet 26 +#define mlschieben 27 +#define moschieben 28 +#define muschieben 29 +#define mrschieben 30 +#define mgitter 31 +#define mcenter 32 +#define mgross 33 +#define mklein 34 +#define mxytastatur 35 +#define msave 36 +#define mkopbewmaus 37 +#define mredraw 38 +#define mltext 39 +#define mrtext 40 +#define mbtext 41 +#define mttext 42 +#define mladen 43 +#define mfont 44 +#define mcut 45 +#define mpaste 46 +#define mdreieck 47 +#define mcolor 48 +#define mviereck 49 +#define mup 50 +#define mchangelineattr 51 +#define mdegrees 52 +#define mdown 53 +#define mfill 54 +#define mgroupmode 55 +#define mnewgroup 56 +#define mungroup 57 +#define mshowgroup 58 +#define mgroupok 59 +#define mconnect 60 +#define mconnxy 61 +#define mconnyx 62 +#define mrot 63 +#define mwinkelrot 64 +#define mcapprojecting 65 +#define mconnpoint 66 +#define mqueryattr 67 +#define mread 68 +#define mreadzeit 69 +#define zmenue 69 + + +typedef Char tmenue[zmenue+1][maxstrl+1]; +typedef double telr[zel+1]; +typedef long teli[zel+1]; +typedef cboolean telb[zel+1]; +typedef Char tstr[zstr+1][maxstrl+1]; +typedef double tpunkte[6]; + +typedef struct tbezierkoeff { + double ax, bx, cx, dx, dreiax, zweibx, ay, by, cy, dy, dreiay, zweiby; +} tbezierkoeff; + +typedef double terg[5]; + + +Static long zelmax; +Static double xanf,yanf,xend,yend,xsnap,ysnap,xprompt,yprompt; +Static double xlast,ylast; +Static int irootx, irooty, iwinx, iwiny, ixzmax,iyzmax; +unsigned int keysbuttons; +Static double xzmax0,yzmax0,xzmax,yzmax,xgr,xgrf, + kaestchenbreite,kaestchenhoehe; + +Static double curs_x,curs_y; +Static double fgradbo, fbograd, texfaktor,version; +Static boolean zeichnen; +Static double texdashl, texdotg, texinterd, gridw, gridw0, gridx0, gridy0, + gridwx1, gridwy1, gridwx2, gridwy2, xmittelzei, ymittelzei; +Static long ltype, lwidth, lends; +Static Char dateiname[maxstrl+1],texdateiname[maxstrl+1]; +Static FILE *datdeskr; +Static double xmarker[5], ymarker[5]; +Static boolean bmarker[5]; +Static Char pr1[maxstrl+1], pr2[maxstrl+1], pr3[maxstrl+1], + pr4[maxstrl+1], pr5[maxstrl+1], pr6[maxstrl+1]; +Static Char tpr1res[maxstrl+1], tpr2res[maxstrl+1], + tpr3res[maxstrl+1], tpr4res[maxstrl+1]; +Static Char EinText[maxstrl+1]; +Static Char nullstr[maxstrl+1]; +Static Char docstyle[maxstrl+1]; + +Static tmenue menue, pr2menue, pr3menue; +Static double xam[zmenue + 1], yam[zmenue + 1], xem[zmenue + 1], + yem[zmenue + 1]; +Static boolean selmenue[zmenue + 1]; +Static long radiogroup[zmenue + 1]; +Static double rpxarray[maxpunkte], rpyarray[maxpunkte]; +Static long vater[maxgruppen+1], umbenennung[maxgruppen+1]; +long grumax; /*Maximalzahl aktueller Gruppen*/ +Static cboolean gruppentag[maxgruppen+1]; +Static boolean aenderunggruppen; +Static teli typ, sequenz, group; +Static telb blink, blinkalt; +Static telr x1, y1_, x2, y2, xb1, yb1, xb2, yb2, wanf, wend; +Static telr elxmin, elxmax, elymin, elymax; +Static teli lineende, linedicke, linetype; +Static telr laenge1, laenge2, rotwi, crw, srw; +Static teli textno; +Static tstr texte; +Static long blinkend, blinkfarbe; /* blinkfarbe == paint oder erase */ +Static long blinkintervallzaehler; +struct timeval st_delay; +Static long winkelrotate; +Static boolean changelende, changelstyle, changelwidth, changecolor; +Static boolean changefont, changeposition; +Static Char textausrichtung[9][maxstrl+1]; +Static double wzeichenhoehe,wzeichenascent,wzeichendescent, wzeichenbreite; +Static double textzeichenhoehe[ztextfonts],textzeichenascent[ztextfonts], + textzeichenbreite[ztextfonts]; +Static Char textfont[ztextfonts][maxstrl+1], + textfontmakro[ztextfonts][maxstrl+1], + textfontlabel[ztextfonts][maxstrl+1], + menuefont[maxstrl+1]; +Static long fontnummer, stdfontnummer, + folgefont[ztextfonts], prevfont[ztextfonts]; +Static long aktldicke; +Static double breite, hoehe, nbreite, nhoehe; +Static boolean quer0format,querformat,mitvorspann,nmitvorspann,oldunitlength; +Static long phase=0;/* fuer mehrere verbundene Aktionen */ +Static long phasexyein; +Static long erwartet, winerwartet, koordinateneingegeben; +Static long texterase; +Static long controlan; +Static long tposres, export_kmark, export_relsel, import_zelsel; +Static long geoeffnet, dragbox; +Static XEvent report; +Static Char eingabezeile[maxstrl+1]; +Static long aktreadzeit, readphase = 0; +Static double readdxx,readdyy,readf; +#ifdef THREAD +Static pthread_t threadID; +#ifdef LINUX +#define pthread_attr_default NULL +#endif +#endif + +Static long threadausel=0, threadaktiv, threadrunning = 0; +Static Time requesttime, lasteventtime; +Static boolean wartendexport, requestbelegt[zrequw], requestaktiv[zrequw]; +Static boolean tablett; /*true falls Digitizer angeschlossen */ +Static boolean nur_texausgabe; +Static XSelectionEvent selnotify[zrequw]; +Static Atom latexdraw_object, latexdraw_text, latexdraw_selection; +Static long requestkakt[zrequw]; +Static Colormap cmap; +Static XColor rgbistdef[maxzahlfarben]; +Static char farbname[maxzahlfarben][maxlenfarbe+1]; +Static char menfarbname[maxzahlfarben][maxlenmenfarbe+1]; +Static long farbposfarbnr[maxzahlfarben],farbnrfarbpos[maxzahlfarben]; +Static long aktzahlfarben; +Static long aktcolor,letztesgrau,aktposcolor; +Static Pixmap graystipple[9]; +Static char graybits[10][2] ={{0x04,0x00},{0x04,0x10},{0x12,0x48},{0x52,0x58}, + {0x5a,0x52}, + {0xad,0xa7},{0xed,0xb7},{0xfb,0xe7},{0xfb,0xef}, + {0xff, 0xff}}; + +/*fuer Grauwerte der Farben */ +#define hcolorbits 16 /* Hoehe colorstipple in Pixels */ +#define bcolorbits 16 /* Breite colorstipple in Pixels */ +Static char colorbits[hcolorbits*bcolorbits/8+1]; +Static Pixmap colorstipple[maxzahlfarben]; /*fuer Grauwerte der Farben */ +Static boolean nocolors; + +Static double intensity[maxzahlfarben]; /* Helligkeit */ +Static GC gcinverse, gcxor,gcstd, somengctext[ztextfonts], + gctext[ztextfonts], gczeichnung; +Static Visual *visual; +Static char winname[maxstrl+1]; +Static border_width=4; +Static XSizeHints size_hints; +Static XFontStruct *font_info, *text_font_info[ztextfonts]; +Static char *display_name = NULL; +Static Display *display; +Static Cursor busycursor,textcursor,clickcursor; +Static long screen; +Static Window win, rootwin, childwin; +Static XComposeStatus compose; +Static KeySym keysym; +Static Pixmap pixmap; +Static long button1gedrueckt, button2gedrueckt, button3gedrueckt; + +Static char symstr[maxstrl+1]; + +/* Feld, das angibt, ob ein Zeichnungselemettyp (1. Parameter) bei */ +/* einem bestimmten Suchvorgang (z.B. nurtrimel, 2. Parameter) */ +/* beruecksichtigt werden soll. ja = 'y', nein = 'n' */ +/* alleelem,nurtrimel,nurboundel,nurgerade,nurmpel,nurextendel,nurfillel */ + +Static char suchtypok[18][7]={ + {'n', 'n', 'n', 'n', 'n', 'n', 'n'}, /*frei*/ + {'n', 'n', 'n', 'n', 'n', 'n', 'n'}, /*frei*/ + {'y', 'n', 'n', 'n', 'n', 'n', 'n'}, /*ttext*/ + {'y', 'y', 'y', 'y', 'y', 'y', 'y'}, /*tgerade*/ + {'n', 'n', 'n', 'n', 'n', 'n', 'n'}, /*frei*/ + {'y', 'y', 'y', 'n', 'y', 'n', 'y'}, /*tkreis*/ + {'y', 'y', 'y', 'n', 'y', 'n', 'n'}, /*tkreisgef*/ + {'y', 'y', 'y', 'n', 'y', 'y', 'y'}, /*tkreisbogen*/ + {'y', 'y', 'y', 'n', 'y', 'n', 'y'}, /*tell*/ + {'y', 'y', 'y', 'n', 'y', 'n', 'n'}, /*tellgef*/ + {'y', 'y', 'y', 'n', 'y', 'y', 'y'}, /*tellbogen*/ + {'y', 'n', 'y', 'n', 'y', 'n', 'n'}, /*trechteckgef*/ + {'y', 'n', 'n', 'n', 'n', 'n', 'y'}, /*tbezier*/ + {'y', 'n', 'y', 'n', 'y', 'n', 'n'}, /*tdreieckgef*/ + {'y', 'n', 'y', 'n', 'n', 'n', 'n'}, /*tviereckgef*/ + {'y', 'y', 'y', 'n', 'y', 'y', 'n'}, /*tkreissektorgef*/ + {'y', 'y', 'y', 'n', 'y', 'y', 'n'}, /*tellsektorgef*/ + {'y', 'n', 'n', 'n', 'n', 'n', 'n'}, /*tbeziergef*/ +}; + + + +Static void test(i) +{ +printf("******test#: %ld\n",i); +} + +Static Void konkat(s, s1, s2) +Char *s1, *s2, *s; +/* Konkatenation von strings s1 und s2 */ +{ + long i,n1,n2; + + n1 = strlen(s1); + n2 = strlen(s2); + for(i=0;i<=n1;i++) + s[i]=s1[i]; + for(i=0;i<=n2;i++) + s[n1+i]=s2[i]; +} + + +Static double frand() +{ /* einfacher Zufallszahlengenerator aus 0...1*/ + static long seed=314159267; + double xx; + + seed=69069*seed; + xx = seed; + xx = xx/4294967296.0+0.5; + if (xx<0.0) xx = 0.0; + if(xx>=1.0) xx = 0.99; + return xx; +} + + +Static Void strfirst(namestring,anz) + Char *namestring; + long anz; +/* anz=Anzahl Zeichen, die bleiben */ +{ + long ls; + ls=strlen(namestring); + if (ls==0) return; + if (anz >=ls) return; + if (anz <0) anz=0; + namestring[anz]='\0'; +} + +Static Void strlast(namestring,anz) + Char *namestring; + long anz; +/* anz=Anzahl Zeichen, die wegfallen*/ +{ + long i,ls; + ls=strlen(namestring); + if (anz>=ls) { + strcpy(namestring,nullstr); + return; + } + if (anz<=0) return; + for (i=anz;i<=ls;i++){ + namestring[i-anz]=namestring[i]; + } +} + +Static Void strinsert(c,nstring,pos) + Char *c, *nstring; + long pos; +/* fuege c als pos-tes Zeichen (Index: pos - 1) in nstring ein*/ +{ + long i,n,index; + + n=strlen(nstring); + index=pos-1; + if (index > n) index = n; + for (i=n;i>=index;i--) + nstring[i+1]=nstring[i]; + nstring[index] = *c; +} + +Static Void strdelete(nstring,pos) + Char *nstring; + long pos; +/*loesche pos-tes Zeichen (Index: pos - 1) in nstring*/ +{ + long i,n,index; + + n=strlen(nstring); + index=pos-1; + for (i=index;i<n;i++) + nstring[i]=nstring[i+1]; +} + +Static Void substringcpy(s,ss,anfpos,zahlzeichen) + Char *s, *ss; + long anfpos,zahlzeichen; + /* substring aus ss mit vorgegebener Anzahl von Zeichen ab der */ + /* Position anfpos (erste Position ist 0!) nach s uebertragen */ +{ + long apos, ls, i, n; + + apos = anfpos; + if (anfpos < 0) + apos = 0; + ls = strlen(ss)-apos; + if (ls > zahlzeichen) + ls = zahlzeichen; + for (i=0;i<ls;i++) + s[i] = ss[i+apos]; + s[ls] = '\0'; +} + + + +Static Void trenneextension(s) +Char *s; +/* Extension von Dateinamen trennen */ +{ + long i,n; + n=strlen(s)-1; + if (n<0) return; + for (i=n;i>0;i--) { /* i>0 wegen Punkt am Anfang */ + if (s[i] == '/') return; + if (s[i] == '.') { + s[i]='\0'; + return; + } + } +} + + +Static boolean strvergl(s1,s2) + Char *s1,*s2; +{ + long ls,i; + if ((ls=strlen(s1))!=strlen(s2)) return false; + for (i=0;i<ls;i++){ if (s1[i]!=s2[i]) return false;} + return true; +} + +Static boolean istnullstr(s1) + Char *s1; +{ + if (*s1==*nullstr) return true; + else return false; +} + +Static void protokoll(s1,s2) +Char *s1,*s2; +{ +printf("%s%s\n",s1,s2); +} + +Static long rgb2hsv2ordnung(r,g,b,skalierung) +long r,g,b,skalierung; /* 0..skalierung*/ +{ /* Berechnung der Reihenfolge der Farben im Menue nach dem */ + /* hsv-Modell mit vier Gruppierungen */ + + long ordnung,max,min,diff; + double h,s,v,rdist,gdist,bdist; + /* hsv = hue saturation value */ + max = r; + if (g > max) max = g; + if (b > max) max = b; + min = r; + if (g < min) min = g; + if (b < min) min = b; + diff = max - min; + v = 1.0*max/skalierung; + if ((max ==0)||(diff==0)) { /*Grauwerte */ + ordnung = 100.0*(1.0-v); + if (v==0.0) ordnung = 0L; /* schwarz */ + if (v==1.0) ordnung = 1L; /* weiss */ + return ordnung; + } + s = 1.0*diff/max; + rdist = 1.0*(max-r)/diff; + gdist = 1.0*(max-g)/diff; + bdist = 1.0*(max-b)/diff; + if (b==max) h = 4.0+gdist-rdist; + if (g==max) h = 2.0+rdist-bdist; + if (r==max) h = bdist-gdist; + h = h/6.0; + if (h < 0.0) h += 1.0; + ordnung = 4; /* light, hell*/ + if ((s>=0.3)&&(v>0.81)) ordnung = 3; /* pale,hell */ + if ((s>=0.7)&&(v>0.81)) ordnung = 1; /* gesaettigt, hell */ + if (v<=0.81) ordnung = 2; /* dunkle Farben */ + ordnung = 1000.0*(ordnung+h); + ordnung = 100.0*(ordnung+(1.0-v)); + ordnung = 100.0*(ordnung+(1.0-s)); + return ordnung; +/* Anmerkung: ordnung steht zunaechst in farbposfarbnr[nr] */ +} + +Static Void reihenfolgefarben() +{/* Anordnung der Farben gemaess Ordungskriterium in farbposfarbnr[nr]*/ + /* farbposfarbnr und farbnrfarbpos besetzen */ + + long i,j,nr,nrtmp,postmp; + + for (nr=0;nr<aktzahlfarben;nr++) farbnrfarbpos[nr]=nr; + /* jetzt nach ordnung aus rgb2hsv2ordnung sortieren */ + for (i=0;i<aktzahlfarben;i++) { + for (j=aktzahlfarben-1;j>i;j--) { + if (farbposfarbnr[j] < farbposfarbnr[i]) { + postmp = farbnrfarbpos[i]; + nrtmp = farbposfarbnr[i]; + farbnrfarbpos[i] = farbnrfarbpos[j]; + farbnrfarbpos[j] = postmp; + farbposfarbnr[i] = farbposfarbnr[j]; + farbposfarbnr[j] = nrtmp; + } + } + } + for (nr=0;nr<aktzahlfarben;nr++) + farbposfarbnr[farbnrfarbpos[nr]] = nr; +} + +Static long schreibenausdatei(); +Static Void berechneminmax(); + +Static Void fehler(i) +long i; +{ Char name[maxstrl+1]; long taste, phase, msel; + taste=1; phase=0; msel = mende; + strcpy(name, "?"); + switch (i) { + case 1: + strcpy(name, "too many objects"); + break; + case 2: + strcpy(name, "too many text objects"); + break; + case 3: + strcpy(name, "too many objects in input file"); + break; + case 4: + strcpy(name, "too many points for bezier object"); + break; + case 5: + strcpy(name, "negative sqrt"); + break; + case 6: + strcpy(name, "can't connect to X-Server"); + konkat(name,name, XDisplayName(display_name)); + break; + case 7: + strcpy(name,"can't load window font"); + break; + case 8: + strcpy(name,"can't load text font"); + break; + case 9: + strcpy(name,"mismatch in number of text fonts"); + break; + case 10: + strcpy(name,"sort, last element not free"); + break; + case 11: + strcpy(name,"definition groups in input file not ok, type == 0"); + break; + case 12: + strcpy(name,"definition groups in input file not ok, element# wrong"); + break; + case 13: + strcpy(name,"definition groups in input file not ok, group# wrong"); + break; + case 14: + strcpy(name,"definition groups in input file not ok, node# wrong"); + break; + case 15: + strcpy(name,"definition groups in input file not ok, fathernode# wrong"); + break; + case 16: + strcpy(name,"definition groups in input file not ok"); + break; + case 17: + strcpy(name,"not enough groups available"); + break; + case 18: + strcpy(name,"couldn't connect to digitizer"); + }/*case*/ + protokoll("******error******: ", name); + phase=schreibenausdatei(&msel,"error.epc",taste, phase); + exit(-1); +} + + +Static int myerrorhandler(display,error) +Display *display; +XErrorEvent *error; +{ + char msg[100]; + XGetErrorText(display, error->error_code,msg,100); + protokoll("warning XError: ",msg); + return 0; +} + +Static Void readzeitsymbol() +{ + Char sss[10]; + sprintf(sss,"d:%lds",aktreadzeit); + strcpy(menue[mreadzeit],sss); +} + + +Static Void strichsymbol() +{ + Char sss[10]; + sprintf(sss,"=%2ld",aktldicke); + strcpy(menue[mdick],sss); +} + +Static Void colorsymbol() +{ + Char sss[maxlenmenfarbe+5]; + sprintf(sss,"%2ld:%s",aktcolor,menfarbname[aktcolor]); + strcpy(menue[mcolor],sss); +} + +Static long tastegedrueckt() + { + unsigned long mask; + mask=KeyPressMask|KeyReleaseMask; + if(XCheckWindowEvent(display,win,mask,&report)==true) return 1; + else return 0; + } + + +Static Void welt_to_bildschirm(xx, yy, xpix, ypix) +double xx, yy; +long *xpix, *ypix; +/* Umrechnung Punkt (xx,yy) in Bildschirmkoordinaten */ +{ + + *xpix = siintround(xx); + *ypix = siintround(yzmax - yy); +} + +Static Void getweltkoord(xx, yy) +double *xx, *yy; + +/* Punkt in event report in weltkoord umrechnen */ +{ + long ix,iy; + +#ifdef TABLETT + if ( (tablett) && (report.xany.send_event)) + translate_x_to_ltd(report.xbutton.x, report.xbutton.y, xx, yy); + else +#endif + { + ix=report.xbutton.x; + *xx = ix; + iy=iyzmax - report.xbutton.y; + *yy= iy; + } +} + +Static Void getmotionweltkoord(ix, iy, xx, yy) +long ix, iy; +double *xx, *yy; + +/* Punkt ix, iy in weltkoord umrechnen */ +{ + *xx = ix; + *yy= (iyzmax - iy); +} + +Static long si_iabs(x) +long x; +/* Absolutwert ganze Zahl */ +{ if (x < 0) + return (-x); + else return x; +} + +Static Void rechteckbildschirmkoord(x1,y1,x2,y2,ix,iy,width,height) + double x1,y1,x2,y2; + long *ix,*iy,*width,*height; +/* Bestimmen Bildschirm-Koordinaten Rechteck */ +{ long ix2,iy2; + welt_to_bildschirm(x1,y1,ix,iy); + welt_to_bildschirm(x2,y2,&ix2,&iy2); + *width= si_iabs(ix2-*ix); + *height= si_iabs(iy2-*iy); + if (*ix > ix2) *ix=ix2; + if (*iy > iy2) *iy=iy2; +} + +Static Void setcolor(display,gc,zcolor) + Display *display; + GC gc; + long zcolor; +{ + XSetBackground(display,gc,rgbistdef[weiss].pixel); + if ((zcolor==weiss) || (zcolor==schwarz)) { + XSetFillStyle(display,gc,FillSolid); + XSetForeground(display,gc,rgbistdef[zcolor].pixel); + return; + } + if ((zcolor >= aktzahlfarben)||(zcolor <0)) { + XSetFillStyle(display,gc,FillSolid); + XSetForeground(display,gc,rgbistdef[schwarz].pixel); + return; + } + if (zcolor <= letztesgrau) {/* graustufen */ + XSetFillStyle(display,gc,FillOpaqueStippled); + XSetStipple(display,gc,graystipple[zcolor-2]); + XSetForeground(display,gc,rgbistdef[schwarz].pixel); + return; + } + if (nocolors == false) { + XSetFillStyle(display,gc,FillSolid); + XSetForeground(display,gc,rgbistdef[zcolor].pixel); + } + else { + XSetFillStyle(display,gc,FillOpaqueStippled); + XSetStipple(display,gc,colorstipple[zcolor]); + XSetForeground(display,gc,rgbistdef[zcolor].pixel); + } +} + +Static Void rechteckinverse(x1,y1,x2,y2) + double x1,y1,x2,y2; +{ + long ix,iy,width,height; + rechteckbildschirmkoord(x1,y1,x2,y2,&ix,&iy,&width,&height); + XFillRectangle(display,win,gcinverse,ix,iy,width,height); +} + + +Static Void xorrechteck(x1,y1,x2,y2) + double x1,y1,x2,y2; +{ + long ix,iy,width,height; + rechteckbildschirmkoord(x1,y1,x2,y2,&ix,&iy,&width,&height); + if ((width<5) && (height<5)) return; + if (width<5) width=1; + if (height<5) height=1; + if (x1 < xgr) return; + if (x2 < xgr) return; + XDrawRectangle(display,win,gcinverse,ix,iy,width,height); +} + +Static Void menuerechteck(x1,y1,x2,y2) + double x1,y1,x2,y2; +{ + long ix,iy,width,height; + rechteckbildschirmkoord(x1,y1,x2,y2,&ix,&iy,&width,&height); + setcolor(display,gcstd,schwarz); + XDrawRectangle(display,win,gcstd,ix,iy,width,height); +} + + +Static Void setvalues(display,gc,zcolor,line_type,lwidth,lende) + Display *display; + GC gc; + long zcolor,line_type,lwidth,lende; + +{long line_style,cap_style,lw; + double grunddash, grunddot; + long dashlist_length; + char dashlist[10]; + + + lw = 0.7*lwidth; + grunddash = 1.6*lw; + if (grunddash <= 3.0) + grunddash = 4.0; + grunddot = lw; + if (grunddot <= 3.0) + grunddot = 2.0; + else + grunddot = 1.0; + if (lende == 4) + cap_style = CapProjecting; + else + cap_style = CapButt; + if (line_type < 2) line_style=LineSolid; + else { + if (lw > 3) + cap_style = CapRound; + else + cap_style = CapButt; + line_style=LineOnOffDash; + dashlist_length = 2; + switch (line_type) { + case 3: /* gepunktet */ + dashlist_length = 2; + dashlist[0]=grunddot; + dashlist[1]=grunddash; + break; + case 5: /* gestrichelt */ + dashlist_length = 2; + dashlist[0]=2.0*grunddash; + dashlist[1]=grunddash; + break; + case 6: /* Textlinie */ + dashlist_length = 6; + dashlist[0]=4; + dashlist[1]=3; + dashlist[2]=2; + dashlist[3]=2; + dashlist[4]=2; + dashlist[5]=3; + break; + case 7: /* strichpunktiert */ + dashlist_length = 4; + dashlist[0]=2.0*grunddash; + dashlist[1]=grunddash; + dashlist[2]=grunddot; + dashlist[3]=grunddash; + break; + default: /*nicht definierte Faelle */ + dashlist_length = 6; + dashlist[0]=2; + dashlist[1]=2; + dashlist[2]=2; + dashlist[3]=2; + dashlist[4]=2; + dashlist[5]=5; + } + XSetDashes(display,gc,0,dashlist,dashlist_length); + } + XSetLineAttributes(display,gc,lw,line_style,cap_style,JoinBevel); + setcolor(display,gc,zcolor); +} + +Static Void ausfillpolygon(anzp,zcolor) + long anzp,zcolor; +{ + long ix,iy,k; + double xx,yy; + XPoint points[maxpunkte]; + for (k=0;k<anzp;k++) { + xx=rpxarray[k]; + yy=rpyarray[k]; + welt_to_bildschirm(xx,yy,&ix,&iy); + points[k].x = ix; + points[k].y = iy; + } + setvalues(display,gczeichnung,zcolor,0L,0L,0L); + XFillPolygon(display,win,gczeichnung,points,anzp, + Complex,CoordModeOrigin); +} + +Static Void setze_clip_bereiche(display) + Display *display; + +{long zcolor,line_type,ix,iy,width,height,lwidth,i; + XRectangle rectangles[1]; + + /* Clip-Bereich fuer Zeichnung*/ + rechteckbildschirmkoord(xgr,yzmax,xzmax,yprompt+wzeichenhoehe, + &ix,&iy,&width,&height); + rectangles[0].x=ix; + rectangles[0].y=iy; + rectangles[0].width=width; + rectangles[0].height=height; + XSetClipRectangles(display,gczeichnung,0,0,rectangles,1,Unsorted); + for (i=0; i<ztextfonts; i++) + { + XSetClipRectangles(display, gctext[i],0,0,rectangles,1,Unsorted); + } +} + + +Static Void setzefont(i,sqnr,fm,fl,fn) + long i, *sqnr; + char *fn, *fm, *fl; +{ + strcpy(textfont[i],fn); + strcpy(textfontmakro[i],fm); + strcpy(textfontlabel[i],fl); + prevfont[i]=*sqnr; + folgefont[*sqnr]=i; + *sqnr=i; + folgefont[i]=stdfontnummer; + prevfont[1]=i; +} + +Static Void inittextfonts() +{ + long sqnr; + /* Definition der Fonts fuer Schriften in der Zeichnung */ + /* vierte Pos fuer Menue, Texte gleich lang! */ + /* Param 1: Fontnummer */ + /* Param 2: Makroname, der vor Text kommt */ + /* Param 3: Anzeige im Menue */ + /* Param 4: Fontname */ + /* Reihenfolge Aufschreibung = Reihenfolge Anzeige */ + + if (ztextfonts != 19) fehler(9); + + sqnr = 0; + stdfontnummer= 1; + setzefont(1, &sqnr, nullstr, " ", "-*-times-medium-r-*-*-17-*"); + /* Standardfont und immer immer erster Font */ + setzefont(0, &sqnr, "\\FVIpt " , "6pt ", "-*-times-medium-r-*-*-8-*"); + setzefont(2, &sqnr, "\\FVIIIpt ", "8pt ", "-*-times-medium-r-*-*-10-*"); + setzefont(3, &sqnr, "\\FXpt " , "10pt ", "-*-times-medium-r-*-*-14-*"); + setzefont(4, &sqnr, "\\FXIIpt " , "12pt ", "-*-times-medium-r-*-*-17-*"); + setzefont(5, &sqnr, "\\FXIVpt ", "14pt ", "-*-times-medium-r-*-*-20-*"); + setzefont(6, &sqnr, "\\FXVIIIpt ","18pt ", "-*-times-medium-r-*-*-24-*"); + + setzefont(7, &sqnr, "\\FVIbpt " ,"6bpt ", "-*-times-bold-r-*-*-8-*"); + setzefont(8, &sqnr, "\\FVIIIbpt ","8bpt ", "-*-times-bold-r-*-*-10-*"); + setzefont(9, &sqnr, "\\FXbpt " ,"10bpt", "-*-times-bold-r-*-*-14-*"); + setzefont(10, &sqnr, "\\FXIIbpt ","12bpt", "-*-times-bold-r-*-*-17-*"); + setzefont(11, &sqnr, "\\FXIVbpt ","14bpt", "-*-times-bold-r-*-*-20-*"); + setzefont(12, &sqnr, "\\FXVIIIbpt ","18bpt", "-*-times-bold-r-*-*-24-*"); + + setzefont(13, &sqnr, "\\FVIipt " , "6ipt ", "-*-times-medium-i-*-*-8-*"); + setzefont(14, &sqnr, "\\FVIIIipt ", "8ipt ", "-*-times-medium-i-*-*-10-*"); + setzefont(15, &sqnr, "\\FXipt " , "10ipt", "-*-times-medium-i-*-*-14-*"); + setzefont(16, &sqnr, "\\FXIIipt " , "12ipt", "-*-times-medium-i-*-*-17-*"); + setzefont(17, &sqnr, "\\FXIVipt ", "14ipt", "-*-times-medium-i-*-*-20-*"); + setzefont(18, &sqnr, "\\FXVIIIipt ", "18ipt","-*-times-medium-i-*-*-24-*"); + +} + + +Static Void initgctext(display,win,valuemask,values) + Display *display; + Window win; + unsigned long valuemask; + XGCValues *values; +{ long i,hilf; + char fontname[maxstrl+1]; + + inittextfonts(); + for (i=0; i<ztextfonts; i++) { + strcpy(fontname,textfont[i]); + if ((text_font_info[i] = XLoadQueryFont(display,fontname)) == NULL) + {protokoll("can't load font: ", fontname); + strcpy(fontname,ersatzfont); + if ((text_font_info[i] = XLoadQueryFont(display,fontname)) == NULL) + fehler(8);} + values->font=text_font_info[i]->fid; + hilf=text_font_info[i]->ascent; + textzeichenascent[i]=hilf; + hilf=text_font_info[i]->descent; + textzeichenhoehe[i]=hilf + textzeichenascent[i]; + hilf=XTextWidth(text_font_info[i],"x",1); + textzeichenbreite[i]=hilf; + values->line_width=0; + values->line_style=LineSolid; + somengctext[i] = XCreateGC(display,win,valuemask,values); + gctext[i] = XCreateGC(display,win,valuemask,values); + } +} + + +Static Void init_window_font(display) + Display *display; +{ + long hilf,ls,lsmax; + char fontname[maxstrl+1]; + + strcpy(fontname,menuefont); + if ((font_info = XLoadQueryFont(display,fontname)) == NULL) + {protokoll("can't load font: ", fontname); + fehler(7);} + hilf=font_info->ascent; + wzeichenascent=hilf; + hilf=font_info->descent; + wzeichendescent = hilf; + wzeichenhoehe=wzeichendescent + wzeichenascent; + hilf=XTextWidth(font_info,"x",1); + wzeichenbreite=hilf; + lsmax=0; + for (hilf=1;hilf<=zmenue;hilf++) + { + ls=strlen(menue[hilf]); + if (ls>lsmax) lsmax=ls; + } + for (hilf=0;hilf<aktzahlfarben;hilf++) + { + ls=strlen(menfarbname[hilf])+1; + if (ls>lsmax) lsmax=ls; + } + kaestchenbreite = lsmax; + kaestchenbreite = (kaestchenbreite+3.0)*wzeichenbreite; + kaestchenhoehe=1.2*wzeichenhoehe; + xgrf= somenspalten*kaestchenhoehe+1.0*wzeichenbreite; + xgr=xgrf+kaestchenbreite +3.0*wzeichenbreite; + xzmax=xzmax0+xgr; + yzmax=yzmax0; + if (quer0format==true){ + xzmax=yzmax0+xgr; + yzmax=xzmax0+1.5*wzeichenhoehe; + } + xprompt=wzeichenbreite; + yprompt=0.5*wzeichenhoehe; + ixzmax=(long)floor(xzmax); + iyzmax=(long)floor(yzmax); +} + + +Static Void initGC(screen, display, win) + long screen; + Display *display; + Window win; +/* Erzeugen aller gc und des Fonts */ +{ + unsigned long valuemask = 0; + XGCValues values; + char fontname[maxstrl+1]; + + strcpy(fontname,menuefont); + valuemask=(GCForeground|GCBackground|GCFunction|GCLineWidth| + GCLineStyle|GCCapStyle|GCJoinStyle|GCFillStyle|GCFillRule| + GCFont|GCDashOffset|GCDashList|GCArcMode); + values.function=GXcopy; + values.cap_style=CapButt; + values.join_style=JoinBevel; + values.fill_style=FillSolid; + values.fill_rule=WindingRule; + values.arc_mode=ArcPieSlice; + values.dash_offset=0; + values.dashes=4; + if ((font_info = XLoadQueryFont(display,fontname)) == NULL) + {protokoll("can't load font: ", fontname); + fehler(7);} + values.font=font_info->fid; + values.line_width=2; + values.line_style=LineSolid; + values.foreground=BlackPixel(display,screen); + values.background=WhitePixel(display,screen); + gcinverse = XCreateGC(display,win,valuemask,&values); + XSetFunction(display,gcinverse,GXinvert); + XSetPlaneMask(display,gcinverse, + BlackPixel(display,screen)^WhitePixel(display,screen)); + gcxor = XCreateGC(display,win,valuemask,&values); + XSetFunction(display,gcxor,GXxor); + XSetPlaneMask(display,gcxor, + BlackPixel(display,screen)^WhitePixel(display,screen)); + values.line_width=1; + gcstd = XCreateGC(display,win,valuemask,&values); + gczeichnung= XCreateGC(display,win,valuemask,&values); + initgctext(display, win,valuemask,&values); +} + +Static Void systemstipple(display,win,nr,intensitaet) + Display *display; + Window win; + long nr; + double intensitaet; +{ /* erzeugen systematisches Stipple fuer Farben bei Monochrom */ + long i, bitnr, j, k, helligkeit, maxbits, maxbytes, offset; + double faktor; + + maxbits = hcolorbits*bcolorbits; + maxbytes = maxbits/8; + if (maxbits > 8*maxbytes) maxbytes++; + helligkeit = maxbits*intensitaet; + if ((helligkeit % 2)==0) helligkeit++; /* damit keine | _ Linien */ + offset = helligkeit % 8; + faktor = (double)maxbits/(double)helligkeit; + for (i=0;i<maxbytes;i++) + colorbits[i] = 255; /* ganz schwarz */ + for (i=0; i<=helligkeit;i++) {/* stipples loeschen */ + bitnr = faktor*i + offset; + if (frand()>0.95) /* etwas Zufall ! */ + bitnr++; + j = bitnr/8; j = j % maxbytes; + k = bitnr % 8; + colorbits[j] = colorbits[j] & (~ (1<<k)); /*k.Bit in j.Zeile*/ + } + colorstipple[nr] = XCreateBitmapFromData(display,win,colorbits, + bcolorbits,hcolorbits); +} + +Static Void initfarben(screen, display, win) + long screen; + Display *display; + Window win; +/* Erzeugen aller verfuegbaren Farben */ +{ + long i, nr, erg, ordnung, nvh; + double h,s,v; + Char colorname[maxlenfarbe+1]; + XColor rgbsolldef; + XWindowAttributes winattr; + + nvh = 0; + cmap=DefaultColormap(display,screen); + for (nr=0;nr<aktzahlfarben;nr++) { + strcpy(colorname, farbname[nr]); + erg=XAllocNamedColor(display,cmap,colorname,&(rgbistdef[nr]),&rgbsolldef); + if (erg!=1) { + printf("color %s not available\n",colorname); + nvh++; + } + if ((erg!=1)||((nr>=2)&& + (rgbistdef[nr].red ==rgbistdef[weiss].red)&& + (rgbistdef[nr].green==rgbistdef[weiss].green)&& + (rgbistdef[nr].blue ==rgbistdef[weiss].blue))){ + rgbistdef[nr].pixel=rgbistdef[schwarz].pixel; + rgbistdef[nr].red=rgbistdef[schwarz].red; + rgbistdef[nr].green=rgbistdef[schwarz].green; + rgbistdef[nr].blue=rgbistdef[schwarz].blue; + rgbistdef[nr].flags=rgbistdef[schwarz].flags; + } + /* Helligkeit 0..1 bestimmen */ + intensity[nr] = (0.299*rgbsolldef.red + 0.587*rgbsolldef.green + + 0.114*rgbsolldef.blue)/65535.0; + if (nr <= letztesgrau) + farbposfarbnr[nr]=nr; + else + farbposfarbnr[nr]=rgb2hsv2ordnung(rgbsolldef.red, + rgbsolldef.green,rgbsolldef.blue,65535); + + if (nocolors == true) { + systemstipple(display, win, nr,intensity[nr]); + } + } + if (nvh != 0) { + printf("we try to allocate own colormap\n"); + nvh = XGetWindowAttributes(display,win,&winattr); + if (nvh != 0) { + cmap = XCreateColormap(display,win,winattr.visual,AllocNone); + XSetWindowColormap(display,win,cmap); + for (nr=0;nr<aktzahlfarben;nr++) { + strcpy(colorname, farbname[nr]); + erg=XAllocNamedColor(display,cmap,colorname,&(rgbistdef[nr]),&rgbsolldef); + if (erg!=1) { + printf("color %s not available in own colormap\n",colorname); + } + if ((erg!=1)||((nr>=2)&& + (rgbistdef[nr].red ==rgbistdef[weiss].red)&& + (rgbistdef[nr].green==rgbistdef[weiss].green)&& + (rgbistdef[nr].blue ==rgbistdef[weiss].blue))){ + rgbistdef[nr].pixel=rgbistdef[schwarz].pixel; + rgbistdef[nr].red=rgbistdef[schwarz].red; + rgbistdef[nr].green=rgbistdef[schwarz].green; + rgbistdef[nr].blue=rgbistdef[schwarz].blue; + rgbistdef[nr].flags=rgbistdef[schwarz].flags; + } + /* Helligkeit 0..1 bestimmen */ + intensity[nr] = (0.299*rgbsolldef.red + 0.587*rgbsolldef.green + + 0.114*rgbsolldef.blue)/65535.0; + if (nr <= letztesgrau) + farbposfarbnr[nr]=nr; + else + farbposfarbnr[nr]=rgb2hsv2ordnung(rgbsolldef.red, + rgbsolldef.green,rgbsolldef.blue,65535); + + if (nocolors == true) { + systemstipple(display, win, nr,intensity[nr]); + } + } + } + } + + + for (i=0;i <= 8;i++) { + /* Bitmaps fuer grau erzeugen */ + graystipple[i]=XCreateBitmapFromData(display,win,graybits[i],4,4); + } +} + +Static Void eintragefarbname(nr, colorname) + long *nr; + Char *colorname; +/* Eintragen eines Farbnamens */ +/* nr ist Farbnummer, die auch in Farbmakros verwendet wird */ + +{ long i, m; + Char cc; + + if (*nr >= maxzahlfarben) return; /*ignorieren, zu viele Farben*/ + strcpy(farbname[*nr],colorname); + m=strlen(colorname); + /* verkuerzten Farbnamen fuer Menue erzeugen */ + if (m<=maxlenmenfarbe) strcpy(menfarbname[*nr],colorname); + else { + for (i=0; i<maxlenmenfarbe;i++) menfarbname[*nr][i]=colorname[i]; + cc=colorname[m-1]; + if ((cc>='0')&&(cc<='9')) menfarbname[*nr][maxlenmenfarbe-1]=cc; + menfarbname[*nr][maxlenmenfarbe]='\0'; + } + *nr = *nr+1; +} + +Static Void initfarbnamen() +/* Erzeugen aller verfuegbaren Farbnamen */ +/* Reihenfolge der Aufrufe bestimmt Farbnummer in Latex */ +/* deshalb darf Reihenfolge nicht mehr ver"andert werden !!! */ +/* die Positionsnummer im Farbmenue wird spaeter berechnet */ +{ long nr; + + nr=0; + eintragefarbname(&nr, "black"); + eintragefarbname(&nr, "white"); + eintragefarbname(&nr, "gray90"); + eintragefarbname(&nr, "gray80"); + eintragefarbname(&nr, "gray70"); + eintragefarbname(&nr, "gray60"); + eintragefarbname(&nr, "gray50"); + eintragefarbname(&nr, "gray40"); + eintragefarbname(&nr, "gray30"); + eintragefarbname(&nr, "gray20"); + eintragefarbname(&nr, "gray10"); + letztesgrau = nr-1; /*maximal 10*/ + if (letztesgrau > 10) {letztesgrau = 10; nr=11;} + eintragefarbname(&nr, "red1"); + eintragefarbname(&nr, "orange1"); + eintragefarbname(&nr, "sienna1"); + eintragefarbname(&nr, "gold1"); + eintragefarbname(&nr, "yellow"); + eintragefarbname(&nr, "chartreuse1"); + eintragefarbname(&nr, "green"); + eintragefarbname(&nr, "SpringGreen1"); + eintragefarbname(&nr, "cyan"); + eintragefarbname(&nr, "blue"); + eintragefarbname(&nr, "DarkOrchid1"); + eintragefarbname(&nr, "orchid1"); + eintragefarbname(&nr, "magenta"); + eintragefarbname(&nr, "red3"); + eintragefarbname(&nr, "orange3"); + eintragefarbname(&nr, "brown2"); + eintragefarbname(&nr, "orange2"); + eintragefarbname(&nr, "yellow3"); + eintragefarbname(&nr, "chartreuse3"); + eintragefarbname(&nr, "green3"); + eintragefarbname(&nr, "SpringGreen3"); + eintragefarbname(&nr, "cyan3"); + eintragefarbname(&nr, "blue3"); + eintragefarbname(&nr, "DarkOrchid3"); + eintragefarbname(&nr, "orchid3"); + eintragefarbname(&nr, "magenta3"); + eintragefarbname(&nr, "MistyRose1"); + eintragefarbname(&nr, "PeachPuff1"); + eintragefarbname(&nr, "RosyBrown1"); + eintragefarbname(&nr, "khaki1"); + eintragefarbname(&nr, "LightYellow1"); + eintragefarbname(&nr, "wheat1"); + eintragefarbname(&nr, "MintCream"); + eintragefarbname(&nr, "PaleGreen1"); + eintragefarbname(&nr, "LightCyan1"); + eintragefarbname(&nr, "LightBlue1"); + eintragefarbname(&nr, "thistle1"); + eintragefarbname(&nr, "plum1"); + eintragefarbname(&nr, "LavenderBlush1"); + eintragefarbname(&nr, "PaleTurquoise1"); + eintragefarbname(&nr, "DarkSeaGreen1"); + eintragefarbname(&nr, "aquamarine1"); + eintragefarbname(&nr, "DeepSkyBlue1"); + eintragefarbname(&nr, "SlateBlue1"); + eintragefarbname(&nr, "MediumOrchid1"); + eintragefarbname(&nr, "IndianRed1"); + eintragefarbname(&nr, "DeepPink1"); + eintragefarbname(&nr, "brown1"); + + if (nr > maxzahlfarben) aktzahlfarben=maxzahlfarben; + else aktzahlfarben = nr; +} + +Static Void schluss(i) +long i; +{ + XCloseDisplay(display); + if (datdeskr != NULL) + fclose(datdeskr); + exit(i); +} + + +Static double si_fabs(x) +double x; +/* Absolutwert GP-Zahl */ +{ + if (x < 0.0) + return (-x); + else return (x); +} + +Static double sisqrt(term, x) +double term, x; +/* Wurzel mit Ausgleich Rundungsfehler */ +/* Wurzel aus neg. Zahl gibt neg. Wert */ +{ + if (x > 0.0) + return sqrt(x); + else if (si_fabs(x) <= si_fabs(term) * 0.001) + return 0.0; + else + return (-sqrt(si_fabs(x))); +} + +Static double sifsqrt(term, x) +double term, x; +/* Wurzel mit Ausgleich Rundungsfehler */ +/* Wurzel aus neg. Zahl gibt Fehler */ +{ + double w; + w = sisqrt(term, x); + if (w < 0.0) + fehler(5L); + return w; +} + +Static double fsign(x) +double x; +/* Vorzeichen einer GP-Zahl */ +{ + if (x >= 0.0) + return 1.0; + else + return -1.0; +} + +Static Void glersterord(a, b, anz, erg) +double a, b; +long *anz; +double *erg; +/* Gl. ax+b=0 loesen */ +/* Anzahl anz der Loesungen in erg[1],... */ +{ + *anz = 0; + if (a != 0.0) { + *anz = 1; + erg[1] = -(b / a); + } +} + +Static Void glzweiterord(a, b, c, anz, erg) +double a, b, c; +long *anz; +double *erg; +/* Gl. ax*x+b*x+c=0 loesen */ +/* Anzahl anz der Loesungen in erg[1],... */ +{ + double w, n; + if (a == 0.0) { + glersterord(b, c, anz, erg); + return; + } + w = b * b - 4.0 * a * c; + n = 1.0 / (2.0 * a); + w = sisqrt(b * b, w); + if (w < 0.0) + *anz = 0; + if (w == 0.0) { + *anz = 1; + erg[1] = -b * n; + } + if (w <= 0.0) + return; + *anz = 2; + erg[1] = (w - b) * n; + erg[2] = (-b - w) * n; +} + + +Static double drittewurzel(x) +double x; +{ + return (-fsign(x) * exp(log(si_fabs(x)) / 3.0)); +} + + +Static double Cosh(x) +double x; +{ + return ((exp(x) + exp(-x)) / 2.0); +} + + +Static double Sinh(x) +double x; +{ + return ((exp(x) - exp(-x)) / 2.0); +} + + +Static double arcosh(x) +double x; +{ + /* x ist groesser 1 !*/ + return log(x + sifsqrt(1.0, x * x - 1.0)); +} + + +Static double arsinh(x) +double x; +{ + return log(x + sifsqrt(1.0, x * x + 1.0)); +} + + +Static Void nachkorr(a, b, c, d, e, x) +double a, b, c, d, e, *x; +/* Nachkorrektur einer Loesung x einer Gleichung */ +/* a*x*x*x*x+b*x*x*x+c*x*x+d*x+e=0 */ +/* durch Newton-Extrapolation */ +{ + double g, gstr, gzwstr, dx; + dx = 0.0; + g = (((a * *x + b) * *x + c) * *x + d) * *x + e; + gstr = ((4.0 * a * *x + 3.0 * b) * *x + 2.0 * c) * *x + d; + if (0.1 * si_fabs(*x * gstr) > si_fabs(g)) /*Korrektur sinnvoll*/ + dx = -(g / gstr); + else { /*Doppelnullstelle */ + gzwstr = (2.0 * a * *x + b) * 6.0 * *x + 2.0 * c; + if (0.1 * si_fabs(*x * gzwstr) > si_fabs(gstr)) + dx = -(gstr / gzwstr); + } + *x += dx; +} + + +Static Void gldritterord(a, b, c, d, anz, erg) +double a, b, c, d; +long *anz; +double *erg; +/* Gl. ax*x*x+b*x*x+c*x+d=0 loesen */ +/* Anzahl anz der Loesungen in erg[1],... */ +{ + double p, q, eda, det, r, cphi, sphi, phi, korr; + long i; + if (a == 0.0) { + glzweiterord(b, c, d, anz, erg); + goto _L1; + } + if (si_fabs(d) < 0.001) { + glzweiterord(a, b, c, anz, erg); + (*anz)++; + erg[*anz] = 0.0; + goto _L1; + } + eda = 1 / a; + korr = b * eda / -3.0; + p = (3.0 * a * c - b * b) * eda * eda / 9.0; + q = ((b * b * b * eda / 27.0 - b * c / 6.0) * eda + d / 2.0) * eda; + det = q * q + p * p * p; + r = fsign(q) * sifsqrt(1.0, si_fabs(p)); + if (p == 0.0 && q == 0.0) { + *anz = 1; + erg[1] = korr; + goto _L1; + } + if (p == 0.0) { + *anz = 1; + erg[1] = drittewurzel(-2.0 * q) + korr; + goto _L1; + } + if (p < 0.0 && det <= 0.0) { + cphi = q / (r * r * r); + if (cphi == 0.0) + phi = pi / 2.0; + else { + sphi = sifsqrt(1.0, 1.0 - cphi * cphi); + phi = atan(sphi / cphi); + } + *anz = 3; + erg[1] = korr - 2.0 * r * cos(phi / 3.0); + erg[2] = 2.0 * r * cos((pi - phi) / 3.0) + korr; + erg[3] = 2.0 * r * cos((pi + phi) / 3.0) + korr; + goto _L1; + } + if (p < 0.0 && det > 0.0) { + *anz = 1; + erg[1] = korr - 2.0 * r * Cosh(arcosh(q / (r * r * r)) / 3.0); + goto _L1; + } + *anz = 1; + erg[1] = korr - 2.0 * r * Sinh(arsinh(q / (r * r * r)) / 3.0); +_L1: + for (i = 1; i <= *anz; i++) + nachkorr(0.0, a, b, c, d, &erg[i]); +} + + +Static Void glvierterord(a, b, c, d, e, anz, erg) +double a, b, c, d, e; +long *anz; +double *erg; +/* Gl. a*x*x*x*x+b*x*x*x+c*x*x+d*x+e=0 loesen */ +/* Anzahl anz der Loesungen in erg[1],... */ +{ + double ga, eda, b1, c1, d1, e1, y, w; + terg erg1; + long anz1, i; + if (a == 0.0) { + gldritterord(b, c, d, e, anz, erg); + goto _L1; + } + if (si_fabs(e) < 0.001) { + gldritterord(a, b, c, d, anz, erg); + (*anz)++; + erg[*anz] = 0.0; + goto _L1; + } + if (b == 0.0 && d == 0.0) { + glzweiterord(a, c, e, &anz1, erg1); + *anz = 0; + for (i = 1; i <= anz1; i++) { + w = sisqrt(1.0, erg1[i]); + if (w >= 0.0) { + *anz += 2; + erg[*anz - 1] = w; + erg[*anz] = -w; + } + } + goto _L1; + } + eda = 1 / a; + b1 = b * eda; + c1 = c * eda; + d1 = d * eda; + e1 = e * eda; + gldritterord(8.0, -4.0 * c1, 2.0 * b1 * d1 - 8.0 * e1, + e1 * (4.0 * c1 - b1 * b1) - d1 * d1, anz, erg); + y = erg[1]; + ga = 8.0 * y + b1 * b1 - 4.0 * c1; + if (si_fabs(8.0 * y) > si_fabs(b1 * b1)) + w = 8.0 * y; + else + w = b1 * b1; + if (si_fabs(w) < si_fabs(4.0 * c1)) + w = 4.0 * c1; + ga = sisqrt(w, ga); + *anz = 0; + if (ga < 0.0) + goto _L1; + eda = b1 * y - d1; + if (ga == 0.0 && si_fabs(eda) > 0.001) + goto _L1; + if (ga == 0.0 && si_fabs(eda) <= 0.001) + eda = 0.0; + else + eda /= ga; + glzweiterord(1.0, (b1 + ga) / 2.0, y + eda, &anz1, erg1); + glzweiterord(1.0, (b1 - ga) / 2.0, y - eda, anz, erg); + for (i = 1; i <= anz1; i++) + erg[*anz + i] = erg1[i]; + *anz += anz1; +_L1: + for (i = 1; i <= *anz; i++) + nachkorr(a, b, c, d, e, &erg[i]); +} + + +Static Void initgrid() +{ + gridw0 = 5.0 / texfaktorv; + gridw = gridw0; + gridx0 = xmittelzei; + gridy0 = ymittelzei; + gridwx1 = 1.0; + gridwy1 = 0.0; + gridwx2 = 0.0; + gridwy2 = 1.0; +} + +Static Void ftausch(x, y) +double *x, *y; +{ + double c; + + c = *x; + *x = *y; + *y = c; +} + +Static Void initgruppentag(tag) +long tag; +{ + long i; + + for (i=0; i<=grumax; i++) + gruppentag[i] = tag; +} + +Static long sohn(i, gruppe) +long gruppe, i; +{ /*i. Sohn der Gruppe im Baum */ + /* Null falls keiner vorhanden */ + long j, k; + + if ((gruppe < 1)||(gruppe >grumax)) return 0; + k = 0; + for (j=1;j<=grumax;j++) { + if (vater[j]==gruppe) { + k++; + if (k==i) return j; + } + } + return 0; +} + +Static long gruppenwurzel(elsel) +long elsel; +{ /* oberste Gruppe, zu der die angegebene Gruppe gehoert */ + /* Null es gibt keine */ + long i, gruppe; + + gruppe = group[elsel]; + if ((gruppe < 1)||(gruppe >grumax)) return 0; + i = gruppe; + while (vater[i] != 0) + i = vater[i]; + return i; +} + +Static Void markteilbaum(gruppe,tag) +long gruppe,tag; +{ + long j,g; + + j = 1; + while ( (g=sohn(j,gruppe)) != 0) {/* j. Sohn von gruppe untersuchen */ + j++; + markteilbaum(g,tag); + } + gruppentag[gruppe] = tag; +} + +Static Void blinkgruppe(elsel) +long elsel; +{/* bei allen Elementen, die zur Gruppe des angegebenen Elements und */ + /* den darueberliegenden Gruppen gehoeren wird blink gesetzt */ + /* blink wird vorher nicht geloescht ! */ + long i,gw; + + if ((elsel<1)||(typ[elsel]<=0)||(elsel >zelmax)) return; + blink[elsel]=true; + gw=gruppenwurzel(elsel); + if (gw==0) return; + markteilbaum(gw,true); + for (i=1;i<=zelmax;i++) { + if ((typ[i] >0) && (group[i] != 0) && + (gruppentag[group[i]] == true)) { + /* Element gehoert zu der Gruppe */ + blink[i]=true; + } + } + /* alle Elemente der Gruppe sind markiert */ +} + + +Static long freiegruppe() +{ + long i; + + for (i=1;i<=maxgruppen;i++) + if (vater[i]==-1){/*freies Element*/ + vater[i]=0; + gruppentag[i] = false; + if (i>grumax) + grumax = i; + return i; + } + fehler(17); +} + +Static Void gruppieren(elsel,wurzel) +long elsel, wurzel; +{ /* neue Gruppe bilden */ + + long g; + + g = gruppenwurzel(elsel); + if (g==wurzel) return; + if (g==0) /* Element direkt in Gruppe */ + group[elsel] = wurzel; + else + vater[g]=wurzel; +} + +Static Void grumaxbestimmen() +{ + long i; + + for (i=grumax;i>0;i--) { + if (vater[i] != -1) + break; + } + grumax = i; +} + +Static Void loeschegruppe(elsel) +long elsel; +{ + long i, vorh, wurzel; + + vorh=false; + wurzel = gruppenwurzel(elsel); + if (wurzel == 0) {/* nur ein Element */ + group[elsel] = 0; + return; + } + for (i=1;i<=grumax;i++) { + if (vater[i]==wurzel) { + vater[i]=0; + } + } + vater[wurzel]=-1; /*Gruppennummer wieder frei */ + grumaxbestimmen(); + /* Direkt an Wurzel haengende Eelemente vereinzeln */ + for (i=1;i<=zelmax;i++) { + if (group[i]==wurzel) + group[i]=0; + } +} + +Static Void unbenutztegruppenfreigeben() +{ + long elsel, g, gw; + + if (aenderunggruppen == false) + return; + aenderunggruppen = false; + initgruppentag(false); + for (elsel=1;elsel <= zelmax; elsel++) { + if (typ[elsel] > 0) { + g = group[elsel]; + if (g != 0) + gruppentag[g] = true; + } + } + LL: ; + for (g=1;g<=grumax;g++) { + if (gruppentag[g] == true){ + if (vater[g] == -1) + vater[g] =0; + if ((vater[g] > 0)&&(gruppentag[vater[g]] ==false)) { + gruppentag[vater[g]] = true; + goto LL; + } + } + } + /* nicht benoetigte Gruppen freigeben ! */ + for (g=1;g<=grumax;g++) { + if (gruppentag[g] == false) + vater[g] = -1; + } + grumaxbestimmen(); +} + +Static Void gruppenumbenennen() +{ +/* es werden die Gruppen zur Umbenennung vorgesehen, deren Gruppentag */ +/* true ist */ + long i,imax,ineu,v,vneu,g; + + for (i=1;i<=grumax;i++) + umbenennung[i] = i; + if (selmenue[mgroupmode] == false) return; + imax = grumax; + for (i=1;i<=imax;i++) { + if (gruppentag[i] == true) { + g = freiegruppe(); + gruppentag[g] = false; + umbenennung[i] = g; + aenderunggruppen = true; + } + } + for (i=1;i<=imax;i++) { + if (gruppentag[i] == true) { + v = vater[i]; + if (v != 0) + vneu = umbenennung[v]; + else + vneu = 0; + ineu = umbenennung[i]; + vater[ineu] = vneu; + } + } +} + + +Static Void bestimmeneuegruppe(elsel) +long elsel; +{ + if (group[elsel] == 0) return; + if (selmenue[mgroupmode] == true) + group[elsel] = umbenennung[group[elsel]]; + else + group[elsel] = 0; +} + +Static double ppabstand(x1, y1, x2, y2) +double x1, y1, x2, y2; +/* Abstand zweier Punkte */ +{ + double dx, dy; + + dx = (x2 - x1); + dy = (y2 - y1); + return (sifsqrt(1.0, dx * dx + dy * dy)); +} + + +Static Void cursan(x, y) +double x, y; +/* Text-Cursor anschalten */ +{ + double yrel; + curs_x=x; + curs_y=y; + yrel=y-wzeichendescent; + rechteckinverse(x,yrel,x+wzeichenbreite,yrel+wzeichenhoehe); +} + + +Static boolean nglw(a, b) + double a, b; + /* true, falls naeherungsweise gleiche Winkel */ +{ + if (si_fabs(a - b) < 2.0) + return true; + else + return false; +} + + +Static boolean nglx(a, b) + double a, b; + /* true, falls naeherungsweise gleiche Koordinaten */ +{ + if (si_fabs(a - b) < 0.1) + return true; + else + return false; +} + + +Static Void pskalieren(x, y, dx, dy, f) +double *x, *y, dx, dy, f; +/* Translation Punkt x,y um dx,dy, Skalierungsfaktor f*/ +/* Ergebnis wieder in x,y */ +{ + *x = (*x - xmittelzei) * f + xmittelzei + dx; + *y = (*y - ymittelzei) * f + ymittelzei + dy; +} + +Static Void ausmenueelement(); + +Static Void somenfontwahl(i) + long i; +{ + fontnummer = i; + strcpy(menue[mfont],textfontlabel[fontnummer]); + ausmenueelement(mfont); +} + + +Static Void setzeakttextfont(elsel) +long elsel; +{ + long fontart; + + fontart = linetype[elsel]; + if (fontart < 0) fontart = 0; + if (fontart >= ztextfonts) fontart = ztextfonts -1; + somenfontwahl(fontart); +} + +Static Void textparam(elsel) +long elsel; +/* Berechenbare Parameter fuer Texte bestimmen */ +{ + double th, thh, tl, tlh, ll, rl, dy; + long lage, fontart, lstr; + fontart = linetype[elsel]; + if (fontart < 0) fontart = 0; + if (fontart >= ztextfonts) fontart = ztextfonts -1; + laenge1[elsel] = strlen(texte[textno[elsel]]); + lstr = siintround(laenge1[elsel]); + tl = XTextWidth(text_font_info[fontart],texte[textno[elsel]],lstr); + /*textbreite*/ + tlh = 0.5 * tl; + th = textzeichenascent[fontart]; /*texthoehe*/ + thh = 0.5 * th; + lage = (long)floor(si_fabs(laenge2[elsel]) + 0.2); + if (lage > 8) {/*eigentlich Fehlerfall*/ + lage = 0; + laenge2[elsel] = 0.0; + } + switch (lage) { /*case*/ + case 0: /*bl*/ + ll = 0.0; + dy = 0.0; + break; + case 1: /*cc*/ + ll = tlh; + dy = thh; + break; + case 2: /*rb*/ + ll = tl; + dy = 0.0; + break; + case 3: /*cb*/ + ll = tlh; + dy = 0.0; + break; + case 4: /*lt*/ + ll = 0.0; + dy = th; + break; + case 5: /*rt*/ + ll = tl; + dy = th; + break; + case 6: /*ct*/ + ll = tlh; + dy = th; + break; + case 7: /*lc*/ + ll = 0.0; + dy = thh; + break; + case 8: /*rc*/ + ll = tl; + dy = thh; + break; + } + rl = tl - ll; + x2[elsel] = x1[elsel] - ll; + y2[elsel] = y1_[elsel] - dy; + xb2[elsel] = x1[elsel] + rl * crw[elsel]; + yb2[elsel] = y1_[elsel] + rl * srw[elsel]; + xb1[elsel] = x1[elsel] - ll * crw[elsel]; + yb1[elsel] = y1_[elsel] - ll * srw[elsel]; +} + + +Static Void skalieren(i, dx, dy, f) +long i; +double dx, dy, f; +/* Skalieren Zeichnungselement i */ +{ + pskalieren(&x1[i], &y1_[i], dx, dy, f); + pskalieren(&x2[i], &y2[i], dx, dy, f); + pskalieren(&xb1[i], &yb1[i], dx, dy, f); + pskalieren(&xb2[i], &yb2[i], dx, dy, f); + if (si_iabs(typ[i]) != ttext) { + laenge1[i] *= f; + laenge2[i] *= f; + } + else + textparam(i); + berechneminmax(i); +} + + +Static Void addtheorem(ca, sa, cb, sb, cab, sab) +double ca, sa, cb, sb, *cab, *sab; +{ + *cab = ca * cb - sa * sb; + *sab = ca * sb + sa * cb; +} + + +Static Void ellpar(elsel, xm, ym, lx, ly, cr, sr) +long elsel; +double *xm, *ym, *lx, *ly, *cr, *sr; +/* Parameter einer Ellipse zurueckgeben */ +{ + *xm = x1[elsel]; + *ym = y1_[elsel]; + *lx = laenge1[elsel]; + *ly = laenge2[elsel]; + *cr = crw[elsel]; + *sr = srw[elsel]; +} + + +Static Void translation(dx, dy, xp, yp, xpr_, ypr_) + double dx, dy, xp, yp, *xpr_, *ypr_; + /* Koord. von p in neuem Koord.system, das um dx,dy translatiert*/ +{ *xpr_ = xp - dx; + *ypr_ = yp - dy; +} + + +Static Void rotation(cw, sw, xp, yp) + double cw, sw, *xp, *yp; + /*Koord. von p in neuem Koord.system, das positiv rotiert*/ +{ + double hx, hy; + hx = cw * *xp + sw * *yp; + hy = cw * *yp - sw * *xp; + *xp = hx; + *yp = hy; +} + + +Static double winkel0(dx, dy, a, b) +double dx, dy, a, b; +/* Winkel von x_Achse zu Strecke von (0,0) zu (dx,dy) fuer Ellipse */ +/* mit Hauptachsen a und b und Mittelpunkt (0,0) */ +{ + double at, rm; + if (dy == 0.0) { + if (dx >= 0.0) + at = 0.0; + else + at = wh; + goto _L1; + } + if (dx == 0.0) { + if (dy >= 0.0) + at = wv; + else + at = wdv; + goto _L1; + } + if (si_fabs(dy) > 10000.0 * si_fabs(dx)) { /*fast senkrecht*/ + if (dy >= 0.0) + at = wv; + else + at = wdv; + goto _L1; + } + rm = si_fabs(a / b * (dy / dx)); + at = fbograd * atan(rm); + /*spezielle Winkelrichtung gemaess Quadrant*/ + if (dx < 0.0 && dy > 0.0) + at = wh - at; + if (dx < 0.0 && dy < 0.0) + at += wh; + if (dx > 0.0 && dy < 0.0) + at = wg - at; + if (si_fabs(at) < 0.01) + at = 0.0; + if (si_fabs(at - wg) < 0.01) + at = wg; +_L1: + return at; +} + + +Static double winkelk(xm, ym, xp, yp) + double xm, ym, xp, yp; + /* Winkel von x_Achse zu Strecke von (xm,ym) zu (xp,yp)*/ + /*xm,ym Mittelpunkt Kreis*/ + /* xp,yp Koordinaten eines Punktes */ +{ + double dx, dy; + translation(xm, ym, xp, yp, &dx, &dy); + return (winkel0(dx, dy, 1.0, 1.0)); +} + + +Static Void setzewinkel(elsel, xm, ym, xp, yp) +long elsel; +double xm, ym, xp, yp; +/* Berechne Drehwinkel des Zeichnungselementes elsel */ +{ + rotwi[elsel] = winkelk(xm, ym, xp, yp); + crw[elsel] = cos(fgradbo * rotwi[elsel]); + srw[elsel] = sin(fgradbo * rotwi[elsel]); +} + + +Static Void ell_xy(xm, ym, a, b, cr, sr, xpr_, ypr_, xp, yp) + double xm, ym, a, b, cr, sr, xpr_, ypr_, *xp, *yp; + /* Umrechnung Punkt (xpr,ypr) im Ellipsenkoordinatensystem */ + /* in das Weltkoordinatensystem, dort (xp,yp) */ +{ + *xp = xpr_; + *yp = ypr_; + rotation(cr, -sr, xp, yp); /*Rotation um neg. Winkel*/ + translation(-xm, -ym, *xp, *yp, xp, yp); +} + + +Static Void ellw_xy(xm, ym, a, b, cr, sr, w, xp, yp) + double xm, ym, a, b, cr, sr, w, *xp, *yp; + /* Punkt auf Ellipse durch Winkel w in Grad bei Ellipse definiert */ + /* in Punkt (xp,yp) des Weltkoordinatensystems umrechnen */ +{ + ell_xy(xm, ym, a, b, cr, sr, a * cos(w * fgradbo), + b * sin(w * fgradbo), xp, yp); +} + + +Static Void xy_ell(xm, ym, cr, sr, xp, yp, xpr_, ypr_) + double xm, ym, cr, sr, xp, yp, *xpr_, *ypr_; + /*Transformation Punkt (xp,yp) in Weltkoordinaten in */ + /*Koordinatensystem der Ellipse, dort (xpr,ypr)*/ +{ + translation(xm, ym, xp, yp, xpr_, ypr_); + rotation(cr, sr, xpr_, ypr_); /*Rotation um pos. Winkel*/ +} + + +Static double winkelell(xm, ym, a, b, cr, sr, xp, yp) + double xm, ym, a, b, cr, sr, xp, yp; + /* xm,ym,a,b,cr,sr definieren Ellipse*/ + /* xp,yp Punkt in Zeichenebene */ + /* Winkel gesucht im Bezugskoordinatensystem der Ellipse*/ +{ + double dx, dy; + xy_ell(xm, ym, cr, sr, xp, yp, &dx, &dy); + return (winkel0(dx, dy, a, b)); +} + + +Static Void stdimagetextaus(twin, x, y, t, zcolor) +Window twin; +long zcolor; +double x, y; +Char *t; +/* Ausgabe string t an Stelle x,y */ +{ + long ix,iy,length; + length=strlen(t); + welt_to_bildschirm(x, y, &ix, &iy); + setcolor(display,gcstd,zcolor); + XDrawImageString(display,twin,gcstd,ix,iy,t,length); +} + +Static Void stdtextaus(twin, x, y, t, zcolor) +Window twin; +long zcolor; +double x, y; +Char *t; +/* Ausgabe string t an Stelle x,y */ +{ + long ix,iy,length; + length=strlen(t); + welt_to_bildschirm(x, y, &ix, &iy); + setcolor(display,gcstd,zcolor); + XDrawString(display,twin,gcstd,ix,iy,t,length); +} + + +Static Void ztextaus(twin, elsel, x, y, t, zcolor, fontart) +Window twin; +long zcolor,fontart, elsel; +double x, y; +Char *t; +/* Ausgabe string t an Stelle x,y in der Zeichnung */ +{ long ix,iy,length; + + length=strlen(t); + welt_to_bildschirm(x, y, &ix, &iy); + setcolor(display,gctext[fontart],zcolor); + XDrawString(display,twin,gctext[fontart],ix,iy,t,length); +} + + +Static Void somentextaus(x, y, t, fontart) +long fontart; +double x, y; +Char *t; +/* Ausgabe string t an Stelle x,y in der Zeichnung */ +{ + long ix,iy,lstr; + double dx; + + lstr=strlen(t); + dx = XTextWidth(text_font_info[fontart],t,lstr); + welt_to_bildschirm(x-dx/2.0, y, &ix, &iy); + XDrawString(display,win,somengctext[fontart],ix,iy,t,lstr); +} + +Static Void ausfarbkaestchen(xa,ye,xe,ya,zcolor) + double xa,ye,xe,ya; + long zcolor; +{ long ix,iy,width,height; + + rechteckbildschirmkoord(xa,ye,xe,ya,&ix,&iy,&width,&height); + setcolor(display,gcstd,zcolor); + XFillRectangle(display,win,gcstd,ix,iy,width,height); +} + +Static Void faerbekaestchen(i, zcolor) + long i, zcolor; +{ + ausfarbkaestchen(xam[i],yem[i],xem[i],yam[i],zcolor); +} + +Static Void somenbestxy(i, xa,ya,xe,ye,xt,yt) + long i; + double *xa,*ya,*xe,*ye,*xt,*yt; +{ long reihe,spalte; + + reihe= i/somenspalten; + spalte=i % somenspalten; + *xa=spalte*kaestchenhoehe+1.0*wzeichenbreite; + *ya=reihe*kaestchenhoehe+yprompt+1.5*wzeichenhoehe; + *xe=*xa+kaestchenhoehe; + *ye=*ya+kaestchenhoehe; + *xt=*xa+kaestchenhoehe/2.0; + *yt=*ya+kaestchenhoehe*0.1; +} + +Static long somenbesti(x,y) + double x,y; +{ long reihe,spalte; + double xa,ya; + + xa=x-1.0*wzeichenbreite; + ya=y-yprompt-1.5*wzeichenhoehe; + if ((xa<0.0)||(ya<0.0)) return -1L; + spalte=xa/kaestchenhoehe; + reihe=ya/kaestchenhoehe; + return (reihe*somenspalten+spalte); +} + +Static Void aussomenue() +{ long i; + double xa,ya,xe,ye,xt,yt; + + for (i=0;i<ztextfonts;i++) { + somenbestxy(i, &xa,&ya,&xe,&ye,&xt,&yt); + if (i!=1) somentextaus(xt,yt,"T",i); + } + for (i=0; i < aktzahlfarben; i++) { + somenbestxy(i+ztextfonts, &xa,&ya,&xe,&ye,&xt,&yt); + ausfarbkaestchen(xa,ye,xe,ya,farbnrfarbpos[i]); + } +} + +Static Void prompt() +/* Ausgabe Prompttext ab Stelle xprompt,yprompt */ +{ + Char promptzeile[maxstrl+maxstrl+2]; + long ls; + konkat(promptzeile,pr1,pr2); /*select/ menue[msel]*/ + konkat(promptzeile,promptzeile,pr3); /*Hinweise*/ + konkat(promptzeile,promptzeile,pr4); /*pr2menue[msel]*/ + konkat(promptzeile,promptzeile,pr5); /*Text fuer Texteingabe*/ + konkat(promptzeile,promptzeile,pr6); /*Eingabetext*/ + ls = (long) floor((xzmax-xprompt)/wzeichenbreite); + if (ls >= maxstrl) ls=maxstrl; + ls = ls - strlen(promptzeile); + while (ls > 0) { + konkat(promptzeile,promptzeile,blank); + ls--; + } + stdimagetextaus(win,xprompt, yprompt, promptzeile,schwarz); +} + +Static Void gridpunkt(mstrich, nstrich, x, y) + double mstrich,nstrich; + double *x, *y; +{ + *x = gridx0 + (mstrich * gridwx1 + nstrich * gridwx2) * gridw; + *y = gridy0 + (mstrich * gridwy1 + nstrich * gridwy2) * gridw; +} + + +Static Void textpositionieren() +/* Positionieren des Textes im Fensterausschnitt */ +{ long lsa, ls, lsmax, tposoffset, ogrenzeoffset; + + lsa = strlen(pr1)+strlen(pr2)+strlen(pr3)+strlen(pr4)+strlen(pr5); + ls = strlen(EinText); + lsmax = (long) floor((xzmax-xprompt)/wzeichenbreite)-3-lsa; + ogrenzeoffset = ls - lsmax; + if (ls <= lsmax) + tposoffset = 0; + else { + tposoffset = tposres - lsmax/2; + if (tposoffset < 0) + tposoffset = 0; + if (tposoffset > ogrenzeoffset) + tposoffset = ogrenzeoffset; + } + substringcpy(pr6,EinText,tposoffset,lsmax); + curs_x=xprompt+(tposres-tposoffset+lsa-1)*wzeichenbreite; + curs_y=yprompt; + if (geoeffnet==0) return; + cursan(curs_x, curs_y); +} + + +Static Void inittastaturtext(s,prtext, voll) +Char *s,*prtext; +long voll; +/* Eingabe Tastaturtext */ +/* s ist Ergebnisstring, erst am Ende verfuegbar */ +/* s muss initialisiert sein */ +{ + long ls,dphase; + Char csw[maxstrl+1]; + + erwartet=tastatur_erwartet; + strcpy(tpr1res,pr1); + strcpy(tpr2res,pr2); + strcpy(tpr3res,pr3); + strcpy(tpr4res,pr4); + if (voll==0) { + strcpy(pr1,nullstr); + strcpy(pr2,nullstr); + strcpy(pr3,nullstr); + strcpy(pr4,nullstr); + } + strcpy(pr5,prtext); + strcpy(EinText,s); + ls = strlen(EinText); + tposres = ls + 1; + textpositionieren(); +} + + +Static long tastaturtext(taste) +long taste; +/* Eingabe Tastaturtext */ +/* Ergebnis ==0: String fertig eingegeben */ +/* Ergebnis !=0: String noch nicht mit Return abgeschlossen */ +{ + long ls,lsa; + Char csw[maxstrl+1]; + + lsa = strlen(pr1)+strlen(pr2)+strlen(pr3)+strlen(pr4)+strlen(pr5); + ls = strlen(EinText); + if ((taste == tastecursright1)|| (taste == tastecursright2)) { + if (tposres <= ls) (tposres)++; + goto L0A; + } + if ((taste == tastecursleft1)||(taste == tastecursleft2)) { + if (tposres > 1) (tposres)--; + goto L0A; + } + if ((taste==tasted)&&(controlan==1L)) {/*delete */ + if (ls >= tposres) strdelete(EinText, (int)tposres); + goto L0A; + } + if ((taste==tastea)&&(controlan==1L)) {/*an Anfang Zeile */ + tposres = 1; + goto L0A; + } + if ((taste==tastee)&&(controlan==1L)) {/*an Ende Zeile */ + tposres = ls+1; + goto L0A; + } + if ((taste==tastek)&&(controlan==1L)) {/*loeschen bis Ende Zeile */ + EinText[tposres-1] = 0; + goto L0A; + } + if (taste == tastebackspace || taste == tastedelete) { + if (tposres > 1) { + (tposres)--; + strdelete(EinText, (int)tposres); + } + goto L0A; + } + if (taste == tastereturn) /*Return*/ + goto LE; + if (taste == 13) /*cr*/ + goto LE; + if (taste == 10) /*lf*/ + goto LE; + if (taste < 32) /*illegale Zeichen*/ + goto L0A; + if (taste >255) /*illegale Zeichen */ + goto L0A; + if (ls >= maxstrl) /*max stringlaenge erreicht*/ + goto LE; + sprintf(csw, "%c", (Char)taste); + if (tposres <= ls) + strinsert(csw, EinText, (int)tposres); + else + konkat(EinText, EinText,csw); + (tposres)++; + goto L0A; + LE: + strcpy(pr1,tpr1res); + strcpy(pr2,tpr2res); + strcpy(pr3,tpr3res); + strcpy(pr4,tpr4res); + strcpy(pr5,nullstr); + strcpy(pr6,nullstr); + erwartet=click_erwartet; + return 0; + + L0A: + textpositionieren(); + return 1; +} + +Static Void ausmenuetext(i,zcolor) +/* Ausdruck eines Textes im Element i des Menues */ +long i,zcolor; +{ + double dx,dy; + Char s[maxstrl+1]; + + dx=0.5*wzeichenbreite; + dy=(si_fabs(yem[i]-yam[i])-wzeichenhoehe)/2.0; + dy=0.8*dy + wzeichendescent; + strcpy(s, menue[i]); + stdtextaus(win,xam[i] + dx, yam[i] + dy,s,zcolor); +} + +Static Void ausmenueelement(i) + long i; +{ + if ((selmenue[i]==true)&&(i!=mcolor)){ + faerbekaestchen(i,schwarz); + ausmenuetext(i, weiss); + menuerechteck(xam[i],yam[i],xem[i],yem[i]); + return; + } + if (i!=mcolor){ + faerbekaestchen(i,weiss); + ausmenuetext(i, schwarz); + menuerechteck(xam[i],yam[i],xem[i],yem[i]); + return; + } + faerbekaestchen(i,aktcolor); + if (aktcolor==weiss) {ausmenuetext(i, schwarz); goto LW;} + if (aktcolor==schwarz) {ausmenuetext(i, weiss); goto LW;} + if (aktcolor <= (long) (letztesgrau/2)) {ausmenuetext(i, schwarz); goto LW;} + if (aktcolor <= letztesgrau) {ausmenuetext(i, weiss); goto LW;} +/* if (((rgbistdef[aktcolor].red & 0377) >100)|| + ((rgbistdef[aktcolor].green & 0377)>100)|| + ((rgbistdef[aktcolor].blue & 0377)>100)) +*/ + if (intensity[aktcolor] > 0.5) + ausmenuetext(i, schwarz); + else + ausmenuetext(i, weiss); + LW: + menuerechteck(xam[i],yam[i],xem[i],yem[i]); +} + +Static long xyein(x, y, taste, phase) + long phase,taste; + double *x, *y; +{ + long anz; + double lgx, lgy; + switch (phase){ + case 0: goto L0; + default: goto L1; + } + L0: + inittastaturtext(nullstr,pr2menue[mxytastatur],1L); + return 1; + L1: + anz=sscanf(EinText,"%lf%lf",&lgx,&lgy); + if (anz!=2) {lgx=0; lgy=0;} + /* lgx,lgy im Grid-Koordinatensystem, also umrechnen */ + gridpunkt(lgx, lgy, x, y); + selmenue[mxytastatur] = false; + ausmenueelement((long)mxytastatur); + return 0; +} + + +Static Void koeff_bezier(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, bk) +double p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y; +tbezierkoeff *bk; +{ + bk->dx = p0x; + bk->cx = (p1x - p0x) * 3.0; + bk->bx = (p2x - p1x) * 3.0 - bk->cx; + bk->ax = p3x - p0x - bk->cx - bk->bx; + bk->dreiax = 3.0 * bk->ax; + bk->zweibx = 2.0 * bk->bx; + bk->dy = p0y; + bk->cy = (p1y - p0y) * 3.0; + bk->by = (p2y - p1y) * 3.0 - bk->cy; + bk->ay = p3y - p0y - bk->cy - bk->by; + bk->dreiay = 3.0 * bk->ay; + bk->zweiby = 2.0 * bk->by; +} + + +Static Void punkt_bezier(elsel, t, prx, pry) +long elsel; +double t, *prx, *pry; +{ double J0,J1,J2,J3,emt; + + emt = 1.0-t; + J0=emt*emt*emt; + J1=3.0*t*emt*emt; + J2=3.0*t*t*emt; + J3=t*t*t; + *prx=x1[elsel]*J0+xb1[elsel]*J1+xb2[elsel]*J2+x2[elsel]*J3; + *pry=y1_[elsel]*J0+yb1[elsel]*J1+yb2[elsel]*J2+y2[elsel]*J3; +} + +Static Void ableitung_bezier(elsel, t, dxdt, dydt) +long elsel; +double t, *dxdt,*dydt; +{ double dJ0,dJ1,dJ2,dJ3,emt; + + emt = 1.0-t; + dJ0=-3.0*emt*emt; + dJ1=3.0*emt*emt-6.0*t*emt; + dJ2=6.0*t*emt-3.0*t*t; + dJ3=3.0*t*t; + *dxdt= x1[elsel]*dJ0+xb1[elsel]*dJ1+xb2[elsel]*dJ2+x2[elsel]*dJ3; + *dydt=y1_[elsel]*dJ0+yb1[elsel]*dJ1+yb2[elsel]*dJ2+y2[elsel]*dJ3; +} + +Static double pbezabstand(elsel, xp, yp) +long elsel; +double xp, yp; +{ + terg erg; + tbezierkoeff bk; + long i, anzt; + double p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, d, dmin, xb, yb; + + p0x = x1[elsel]; + p0y = y1_[elsel]; + p1x = xb1[elsel]; + p1y = yb1[elsel]; + p2x = xb2[elsel]; + p2y = yb2[elsel]; + p3x = x2[elsel]; + p3y = y2[elsel]; + dmin = ppabstand(p0x, p0y, xp, yp); + d = ppabstand(p3x, p3y, xp, yp); + if (d < dmin) + dmin = d; + koeff_bezier(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, &bk); + gldritterord(bk.ax, bk.bx, bk.cx, bk.dx - xp, &anzt, erg); + for (i = 1; i <= anzt; i++) { + if ((erg[i] >= 0.0)&&(erg[i] <= 1.0)) { /*Aenderung 19.12.92.*/ + punkt_bezier(elsel, erg[i], &xb, &yb); + d = ppabstand(xb, yb, xp, yp); + if (d < dmin) dmin = d; + } + } + gldritterord(bk.ay, bk.by, bk.cy, bk.dy - yp, &anzt, erg); + for (i = 1; i <= anzt; i++) { + if ((erg[i] >= 0.0)&&(erg[i] <= 1.0)) { /*Aenderung 19.12.92.*/ + punkt_bezier(elsel, erg[i], &xb, &yb); + d = ppabstand(xb, yb, xp, yp); + if (d < dmin) dmin = d; + } + } + return dmin; +} + +Static long getlinedicke(i) +long i; +{long ldicke; + + ldicke=linedicke[i]; + ldicke=ldicke % 100; + if (ldicke > maxldicke) ldicke=maxldicke; + return ldicke; +} + + +Static long getmenuecolor() +{ + return aktcolor; +} + +Static long getlinecolor(i) +long i; +{long lcolor; + + lcolor=schwarz; /*linecolor*/ + if (linedicke[i] >=100) lcolor = linedicke[i]/100; + return lcolor; +} + + +Static long getzcolor(i, painterase) + long i, painterase; +{ long lcolor, zcolor; + + lcolor = getlinecolor(i); /*Farbe der Linie*/ + zcolor = weiss; /*Farbe, die zu zeichnen*/ + if (painterase==paint) zcolor=lcolor; + return zcolor; +} + + +Static Void getlineattribute(i, elemtyp, ltyp, ldicke, lende, lcolor) +long i, elemtyp, *ltyp, *ldicke, *lende, *lcolor; +{ + if (i == 0) { + *lende = 0; /*kein Pfeil*/ + if (selmenue[mpfeilende]==true) /*Pfeil am Ende*/ + *lende = 2; + if (selmenue[mpfeilanf]==true) /*Pfeil am Anfang*/ + *lende = 1; + if ((selmenue[mpfeilanf]==true) && (selmenue[mpfeilende]==true)) + *lende = 3; + *ldicke = aktldicke; /*eingestellte Linienstaerke*/ + *ltyp = 1; /*solid*/ + if (selmenue[mgestrichelt]==true) /*_ _ */ + *ltyp = 5; + if (selmenue[mgepunktet]==true) /*....*/ + *ltyp = 3; + if ((selmenue[mgestrichelt]==true) && (selmenue[mgepunktet]==true)) + /*_._*/ + *ltyp = 7; + if ((selmenue[mcapprojecting] == true)&&(elemtyp == tgerade)&& + (*lende == 0)&&(*ltyp == 1)) + *lende = 4; /*cap projecting */ + *lcolor = getmenuecolor(); + return; + } + *ltyp = linetype[i]; + *ldicke = getlinedicke(i); + *lende = lineende[i]; + *lcolor = getlinecolor(i); +} + +Static Void setlineattribute(i, elsel) + long i, elsel; +{long ltyp, ldicke, lende, lcolor; + + getlineattribute(i, typ[elsel], <yp, &ldicke, &lende, &lcolor); + if (typ[elsel] != ttext) linetype[elsel] = ltyp; + linedicke[elsel] = 100*lcolor+ldicke; + lineende[elsel] = lende; +} + +Static Void winpfeilaus(i, ende, xp, yp, x2, y2,zcolor) + long i, ende,zcolor; + double xp, yp, x2, y2; +/* Pfeilspitze an xp,yp */ +/* Pfeilende in Richtung Punkt x2,y2 */ +/* ende=1 fuer Anfang, ende=2 fuer Ende */ +{ + double d,lpf,bpf,sg,cg; + XPoint points[maxpunkte]; + switch (lineende[i]){ + case 0: return; + case 1: if (ende!=1) return; break; + case 2: if (ende!=2) return; break; + case 3: break; + case 4: return; + } + lpf=6.0+0.8*getlinedicke(i);/*Laenge Pfeil*/ + bpf=(4.0+1.2*getlinedicke(i))*0.5;/*halbe Breite Pfeil*/ + d=ppabstand(xp,yp,x2,y2); + if (d==0) return; + sg=(y2-yp)/d; + cg=(x2-xp)/d; + rpxarray[0] = xp; + rpyarray[0] = yp; + rpxarray[1] = xp+(cg*lpf-sg*bpf); + rpyarray[1] = yp+(sg*lpf+cg*bpf); + rpxarray[2] = xp+(cg*lpf+sg*bpf); + rpyarray[2] = yp+(sg*lpf-cg*bpf); + rpxarray[3] = xp; + rpyarray[3] = yp; + ausfillpolygon(4L,zcolor); +} + + +Static Void winpfeile(i,zcolor) +long i, zcolor; +{ + double xm, ym, lx, ly, cr, sr,xp1,xp2,yp1,yp2; + + switch (typ[i]) { + case tgerade: + winpfeilaus(i, 1L,x1[i],y1_[i],x2[i],y2[i],zcolor); + winpfeilaus(i, 2L,x2[i],y2[i],x1[i],y1_[i],zcolor); + break; + case tkreisbogen: + case tellbogen: + ellpar(i,&xm,&ym,&lx,&ly,&cr,&sr); + ellw_xy(xm,ym,lx,ly,cr,sr,wanf[i],&xp1,&yp1); + ellw_xy(xm,ym,lx,ly,cr,sr,wanf[i]+50,&xp2,&yp2); + winpfeilaus(i,1L,xp1,yp1,xp2,yp2,zcolor); + ellw_xy(xm,ym,lx,ly,cr,sr,wend[i],&xp1,&yp1); + ellw_xy(xm,ym,lx,ly,cr,sr,wend[i]-50,&xp2,&yp2); + winpfeilaus(i,2L,xp1,yp1,xp2,yp2,zcolor); + break; + case tbezier: + winpfeilaus(i, 1L, x1[i],y1_[i],xb1[i],yb1[i],zcolor); + winpfeilaus(i, 2L, x2[i],y2[i],xb2[i],yb2[i],zcolor); + break; + }/*case*/ +} + + +Static Void auspolyline(zcolor,elsel,anzp) + long zcolor,elsel,anzp; + /* Koordinaten 1..anzp in rpxarray und rpyarray*/ + /* elsel fuer Liniendefinition */ + /* falls elsel = 0 dann Standardattribute verwenden */ +{ + long ldicke,lende,ltyp,lcolor,ix,iy,k; + double xx,yy; + XPoint points[maxpunkte]; + for (k=0;k<anzp;k++) { + xx=rpxarray[k]; + yy=rpyarray[k]; + welt_to_bildschirm(xx,yy,&ix,&iy); + points[k].x = ix; + points[k].y = iy; + } + if (elsel==0){ + setvalues(display,gczeichnung,zcolor,0L,0L,0L); + XDrawLines(display,win,gczeichnung, + points,anzp,CoordModeOrigin);} + else { + getlineattribute(elsel, typ[elsel], <yp, &ldicke, &lende, &lcolor); + setvalues(display,gczeichnung,zcolor,ltyp,ldicke,lende); + XDrawLines(display,win,gczeichnung,points,anzp,CoordModeOrigin); + winpfeile(elsel,zcolor); + } +} + +Static double pgxyabstand(); + +Static Void bezierpunkte(x1,y1,x2,y2,x3,y3,x4,y4,anzp) + double x1,y1,x2,y2,x3,y3,x4,y4; + long *anzp; +{ double x12,y12,x23,y23,x34,y34,x1223,y1223,x2334,y2334; + double x12232334, y12232334; + + x23 = (x2+x3)*0.5; + y23 = (y2+y3)*0.5; + /*liegen Punkte ungefaehr auf einer Geraden? */ + if ( (pgxyabstand(x1, y1, x4, y4, x2, y2)< 3.0)&& + (pgxyabstand(x1, y1, x4, y4, x3, y3)< 3.0)) { + rpxarray[*anzp] = x1; + rpyarray[*anzp] = y1; + rpxarray[*anzp+1] = x23; + rpyarray[*anzp+1] = y23; + *anzp += 2; + if (*anzp >= maxpunkte-2) + fehler(4L); + return; + } + x12 = (x1+x2)*0.5; + y12 = (y1+y2)*0.5; + x34 = (x3+x4)*0.5; + y34 = (y3+y4)*0.5; + x1223 = (x12+x23)*0.5; + y1223 = (y12+y23)*0.5; + x2334 = (x23+x34)*0.5; + y2334 = (y23+y34)*0.5; + x12232334 = (x1223+x2334)*0.5; + y12232334 = (y1223+y2334)*0.5; + bezierpunkte(x1,y1,x12,y12,x1223,y1223,x12232334,y12232334,anzp); + bezierpunkte(x12232334,y12232334,x2334,y2334,x34,y34,x4,y4,anzp); +} + +Static Void minmaxbezier(elsel,anzp) + long elsel, anzp; +{ long i; + + elxmin[elsel]=rpxarray[0]; + elxmax[elsel]=rpxarray[0]; + elymin[elsel]=rpyarray[0]; + elymax[elsel]=rpyarray[0]; + + for (i=1;i<anzp;i++) { + if (rpxarray[i] < elxmin[elsel]) + elxmin[elsel]=rpxarray[i]; + if (rpyarray[i] < elymin[elsel]) + elymin[elsel]=rpyarray[i]; + if (rpxarray[i] > elxmax[elsel]) + elxmax[elsel]=rpxarray[i]; + if (rpyarray[i] > elymax[elsel]) + elymax[elsel]=rpyarray[i]; + } +} + + +Static Void ausbezier(elsel,zcolor) +long elsel,zcolor; +{ + long anzp; + + anzp = 0; + bezierpunkte(x1[elsel],y1_[elsel],xb1[elsel],yb1[elsel], + xb2[elsel],yb2[elsel],x2[elsel],y2[elsel],&anzp); + rpxarray[anzp] = x2[elsel]; + rpyarray[anzp] = y2[elsel]; + anzp++; + minmaxbezier(elsel,anzp); + auspolyline(zcolor,elsel,anzp); +} + + +Static Void ausbeziergef(elsel,zcolor) +long elsel,zcolor; +{ + long anzp; + + anzp = 0; + bezierpunkte(x1[elsel],y1_[elsel],xb1[elsel],yb1[elsel], + xb2[elsel],yb2[elsel],x2[elsel],y2[elsel],&anzp); + rpxarray[anzp] = x2[elsel]; + rpyarray[anzp] = y2[elsel]; + anzp++; + minmaxbezier(elsel,anzp); + ausfillpolygon(anzp, zcolor); +} + +Static Void kaestchen(i, anteil, teilung, pos) +long i, anteil, teilung, *pos; +{ + long zeile, platz; + double dx, dy; + + if (*pos == 0) + *pos = 11; + zeile = (long)(*pos / 10.0); + platz = *pos - zeile * 10; + dx = (xem[0] - xam[0]) / teilung; + dy = si_fabs(yem[0] - yam[0]); + xam[i] = xam[0] + (platz - 1) * dx; + xem[i] = xam[i] + anteil * dx; + if (si_fabs(xem[i]-xem[0]) < 1.0) xem[i]=xem[0]; + yem[i] = yem[0] - zeile * dy; + yam[i] = yam[0] - zeile * dy; + platz += anteil; + if (platz > teilung) { + zeile++; + platz = 1; + } + *pos = zeile * 10 + platz; +} + + +Static Void init_tmenue() +{ + long i; + + for (i = 1; i <= zmenue; i++) + strcpy(pr2menue[i], blank); + for (i = 1; i <= zmenue; i++) + strcpy(pr3menue[i], blank); + strcpy(menue[mende], "quit"); + strcpy(pr2menue[mende],intfiletext); + strcpy(pr3menue[mende],extfiletext); + radiogroup[mende] = 1; + strcpy(menue[mladen], "load"); + strcpy(pr2menue[mladen],"input file:"); + radiogroup[mladen] = 1; + strcpy(menue[msave], "save"); + strcpy(pr2menue[msave],intfiletext); + strcpy(pr3menue[msave],extfiletext); + radiogroup[msave] = 1; + strcpy(menue[mtext], "text"); + strcpy(pr2menue[mtext], " position?"); + strcpy(pr3menue[mtext], "?:"); + radiogroup[mtext] = 1; + strcpy(menue[mgerade], "line"); + strcpy(pr2menue[mgerade], " point 1?"); + strcpy(pr3menue[mgerade], " point 2?"); + radiogroup[mgerade] = 1; + strcpy(menue[mkreis], "circle"); + strcpy(pr2menue[mkreis], " center point?"); + strcpy(pr3menue[mkreis], " point on circle?"); + radiogroup[mkreis] = 1; + strcpy(menue[mell], "ellipse"); + strcpy(pr2menue[mell], " center point?"); + strcpy(pr3menue[mell], prxachse); + radiogroup[mell] = 1; + strcpy(menue[mrechteck], "rectangle"); + strcpy(pr2menue[mrechteck], " corner 1?"); + strcpy(pr3menue[mrechteck], " corner 2?"); + radiogroup[mrechteck] = 1; + strcpy(menue[mdreieck], "triangle"); + strcpy(pr2menue[mdreieck], " point 1?"); + strcpy(pr3menue[mdreieck], " point 2?"); + radiogroup[mdreieck] = 1; + strcpy(menue[mviereck], "quadrangle"); + strcpy(pr2menue[mviereck], " point 1?"); + strcpy(pr3menue[mviereck], " point 2?"); + radiogroup[mviereck] = 1; + strcpy(menue[mbezier], "Bezier"); + strcpy(pr2menue[mbezier], " starting point?"); + strcpy(pr3menue[mbezier], " end point?"); + radiogroup[mbezier] = 1; + strcpy(menue[mpolygon], "polygon"); + strcpy(pr2menue[mpolygon], " center point?"); + strcpy(pr3menue[mpolygon], " point on circle?"); + radiogroup[mpolygon] = 1; + strcpy(menue[mspiegeln], "mirror"); + strcpy(pr2menue[mspiegeln], " mirror line?"); + strcpy(pr3menue[mspiegeln], " object(s)?"); + radiogroup[mspiegeln] = 1; + strcpy(menue[mkopieren], "copy"); + strcpy(pr2menue[mkopieren], " reference line?"); + strcpy(pr3menue[mkopieren], " destination line?"); + radiogroup[mkopieren] = 1; + strcpy(menue[mkopbewmaus], "m"); + strcpy(pr2menue[mkopbewmaus], " reference point?"); + strcpy(pr3menue[mkopbewmaus], " destination point?"); + radiogroup[mkopbewmaus] = 0; + strcpy(menue[mbewegen], "move"); + strcpy(pr2menue[mbewegen], " reference line?"); + strcpy(pr3menue[mbewegen], " destination line?"); + radiogroup[mbewegen] = 1; + strcpy(menue[mergaenzen], "complete"); + strcpy(pr2menue[mergaenzen], " line 1?"); + strcpy(pr3menue[mergaenzen], " line 2?"); + radiogroup[mergaenzen] = 1; + strcpy(menue[mausdehnen], "extend"); + strcpy(pr2menue[mausdehnen], " line/arc?"); + radiogroup[mausdehnen] = 1; + strcpy(menue[mbrechen], "trim"); + strcpy(pr2menue[mbrechen], " remove part?"); + radiogroup[mbrechen] = 1; + strcpy(menue[mloeschen], "delete"); + strcpy(pr2menue[mloeschen], " object(s)?"); + radiogroup[mloeschen] = 1; + strcpy(menue[mup], "up"); + strcpy(pr2menue[mup], "/reverse print order, object(s)?"); + radiogroup[mup] = 1; + strcpy(menue[mdown], "down"); + strcpy(pr2menue[mdown], "/put in background, object(s) ?"); + radiogroup[mdown] = 1; + strcpy(menue[meinrasten], "snap"); + radiogroup[meinrasten] = 0; + strcpy(menue[mgefuellt], "*"); + radiogroup[mgefuellt] = 0; + strcpy(menue[mbogen], "C"); + radiogroup[mbogen] = 0; + strcpy(menue[mparallel], "||"); + strcpy(pr2menue[mparallel], " direction of end point?"); + strcpy(pr3menue[mparallel], " parallel line?"); + radiogroup[mparallel] = 2; + strcpy(menue[mlot], "-|"); + strcpy(pr3menue[mlot], " line for normal?"); + radiogroup[mlot] = 2; + strcpy(menue[mmittelpunkt], "mp"); + strcpy(pr2menue[mmittelpunkt], " (mp for center of object)"); + radiogroup[mmittelpunkt] = 0; + strcpy(menue[mpfeilanf], "b>"); + radiogroup[mpfeilanf] = 0; + strcpy(menue[mpfeilende], "e>"); + radiogroup[mpfeilende] = 0; + strcpy(menue[mdick], "=="); + radiogroup[mdick] = 0; + strcpy(menue[mgestrichelt], " _"); + radiogroup[mgestrichelt] = 0; + strcpy(menue[mgepunktet], " ."); + radiogroup[mgepunktet] = 0; + strcpy(menue[mlschieben], "<"); + strcpy(pr2menue[mlschieben], " picture moves left"); + radiogroup[mlschieben] = 0; + strcpy(menue[moschieben], "^"); + strcpy(pr2menue[moschieben], " picture moves up"); + radiogroup[moschieben] = 0; + strcpy(menue[muschieben], "v"); + strcpy(pr2menue[muschieben], " picture moves down"); + radiogroup[muschieben] = 0; + strcpy(menue[mrschieben], ">"); + strcpy(pr2menue[mrschieben], " picture moves right"); + radiogroup[mrschieben] = 0; + strcpy(menue[mredraw], "[]"); + strcpy(pr2menue[mredraw], " redraw"); + radiogroup[mredraw] = 0; + strcpy(menue[mgitter], "G"); + strcpy(pr2menue[mgitter], " grid origin?"); + radiogroup[mgitter] = 1; + strcpy(menue[mcenter], "o"); + strcpy(pr2menue[mcenter], " picture to center"); + radiogroup[mcenter] = 0; + strcpy(menue[mgross], "+"); + strcpy(pr2menue[mgross], " zooming in"); + radiogroup[mgross] = 0; + strcpy(menue[mklein], "-"); + strcpy(pr2menue[mklein], " zooming out"); + radiogroup[mklein] = 0; + strcpy(menue[mxytastatur], " xy"); + strcpy(pr2menue[mxytastatur], + " key input of point in grid coordinates:"); + radiogroup[mxytastatur] = 0; + strcpy(menue[mltext], "l"); + radiogroup[mltext] = 4; + strcpy(menue[mrtext], "r"); + radiogroup[mrtext] = 4; + strcpy(menue[mbtext], "b"); + radiogroup[mbtext] = 5; + strcpy(menue[mttext], "t"); + radiogroup[mttext] = 5; + strcpy(menue[mfont], nullstr); + radiogroup[mfont] = 0; + strcpy(menue[mcut], "cut"); + strcpy(pr2menue[mcut]," reference point?"); + radiogroup[mcut] = 1; + strcpy(menue[mpaste], "paste"); + strcpy(pr2menue[mpaste]," destination point?"); + radiogroup[mpaste] = 1; + strcpy(menue[mcolor], "color"); + radiogroup[mcolor] = 0; + strcpy(menue[mchangelineattr], "chatt"); + strcpy(pr2menue[mchangelineattr], " set attributes to change (= _ . b> e> |] font color l r b t) then select object(s)?"); + radiogroup[mchangelineattr] = 1; + strcpy(menue[mdegrees], "deg"); + strcpy(pr2menue[mdegrees], " input angle in degrees:"); + radiogroup[mdegrees] = 0; + strcpy(menue[mfill], "fill"); + strcpy(pr2menue[mfill], " circle, ellipse, arc or first line (to define triangle or quadrangle)?"); + strcpy(pr3menue[mfill], " second line (to define triangle or quadrangle)?"); + radiogroup[mfill] = 1; + strcpy(menue[mgroupmode], "groupmode"); + radiogroup[mgroupmode] = 0; + strcpy(menue[mnewgroup], "newgroup"); + strcpy(pr2menue[mnewgroup], " first(next) group to combine defined by object(s)?"); + radiogroup[mnewgroup] = 1; + strcpy(menue[mungroup], "ungroup"); + strcpy(pr2menue[mungroup], " group defined by object?, OK to ungroup"); + radiogroup[mungroup] = 1; + strcpy(menue[mshowgroup], "showgroup"); + strcpy(pr2menue[mshowgroup], " group defined by object?"); + radiogroup[mshowgroup] = 1; + strcpy(menue[mgroupok], "OK"); + strcpy(pr2menue[mgroupok], " group ok"); + radiogroup[mgroupok] = 0; + + strcpy(menue[mconnect], "connect"); + strcpy(pr2menue[mconnect], " (not all object types allowed) object1?"); + strcpy(pr3menue[mconnect], " (not all object types allowed) object2 or point?"); + radiogroup[mconnect] = 1; + strcpy(menue[mconnxy], "X"); + radiogroup[mconnxy] = 6; + strcpy(menue[mconnyx], "Y"); + radiogroup[mconnyx] = 6; + strcpy(menue[mconnpoint], "p"); + strcpy(menue[mqueryattr], "attr?"); + strcpy(pr2menue[mqueryattr], " (color, font, linewidth) object?"); + radiogroup[mqueryattr] = 1; + radiogroup[mconnpoint] = 0; + strcpy(menue[mrot], "rotate"); + strcpy(pr2menue[mrot], " degrees, object(s)?"); + strcpy(pr3menue[mrot], " degrees, pivot point?"); + radiogroup[mrot] = 1; + strcpy(menue[mcapprojecting], "|]"); + radiogroup[mcapprojecting] = 0; + strcpy(menue[mwinkelrot], ""); + radiogroup[mwinkelrot] = 0; + strcpy(menue[mread], "stdin"); + strcpy(pr2menue[mread]," "); + radiogroup[mread] = 1; + strcpy(menue[mreadzeit], ""); + radiogroup[mreadzeit] = 0; +/* maximale Nr. bei radiogroup ist 6 */ +/* 1 fuer normale Menueeintraege */ +/* 0 fuer Voreinstellungen */ +} + +Static Void init_kmenue() +{ + long pos,i; double dy; + + xam[0] = xgrf+1.0*wzeichenbreite; + xem[0] = xam[0]+kaestchenbreite; + yam[0] = yzmax - 0.5*kaestchenhoehe; + yem[0] = yam[0]+ kaestchenhoehe; + /* Reihenfolge des Aufrufs gibt Reihenfolge der Anordnung */ + /* 2. und 3. Parameter bei kaestchen: anteil, teilung */ + pos = 0; + kaestchen((long)mtext, 1L, 2L, &pos); + kaestchen((long)mfont, 1L, 2L, &pos); + kaestchen((long)mgerade, 1L, 2L, &pos); + kaestchen((long)mkreis, 1L, 2L, &pos); + kaestchen((long)mell, 1L, 1L, &pos); + kaestchen((long)mrechteck, 1L, 1L, &pos); + kaestchen((long)mdreieck, 1L, 1L, &pos); + kaestchen((long)mviereck, 1L, 1L, &pos); + kaestchen((long)mbezier, 1L, 1L, &pos); + kaestchen((long)mpolygon, 1L, 1L, &pos); + kaestchen((long)mconnect, 5L, 8L, &pos); + kaestchen((long)mconnpoint, 1L, 8L, &pos); + kaestchen((long)mconnxy, 1L, 8L, &pos); + kaestchen((long)mconnyx, 1L, 8L, &pos); + kaestchen((long)mspiegeln, 1L, 2L, &pos); + kaestchen((long)mqueryattr, 1L, 2L, &pos); + kaestchen((long)mrot, 2L, 3L, &pos); + kaestchen((long)mwinkelrot, 1L, 3L, &pos); + kaestchen((long)mkopbewmaus, 1L, 8L, &pos); + kaestchen((long)mkopieren, 3L, 8L, &pos); + kaestchen((long)mbewegen, 4L, 8L, &pos); + kaestchen((long)mergaenzen, 1L, 1L, &pos); + kaestchen((long)mausdehnen, 1L, 2L, &pos); + kaestchen((long)mbrechen, 1L, 2L, &pos); + kaestchen((long)mloeschen, 1L, 2L, &pos); + kaestchen((long)mfill, 1L, 2L, &pos); + kaestchen((long)mup, 1L, 2L, &pos); + kaestchen((long)mdown, 1L, 2L, &pos); + kaestchen((long)mcut, 1L, 2L, &pos); + kaestchen((long)mpaste, 1L, 2L, &pos); + kaestchen((long)mltext, 1L, 4L, &pos); + kaestchen((long)mrtext, 1L, 4L, &pos); + kaestchen((long)mbtext, 1L, 4L, &pos); + kaestchen((long)mttext, 1L, 4L, &pos); + kaestchen((long)mgefuellt, 1L, 4L, &pos); + kaestchen((long)mbogen, 1L, 4L, &pos); + kaestchen((long)mparallel, 1L, 4L, &pos); + kaestchen((long)mlot, 1L, 4L, &pos); + kaestchen((long)mmittelpunkt, 1L, 4L, &pos); + kaestchen((long)mpfeilanf, 1L, 4L, &pos); + kaestchen((long)mpfeilende, 1L, 4L, &pos); + kaestchen((long)mcapprojecting, 1L, 4L, &pos); + kaestchen((long)mdick, 1L, 3L, &pos); + kaestchen((long)mgestrichelt, 1L, 3L, &pos); + kaestchen((long)mgepunktet, 1L, 3L, &pos); + kaestchen((long)mgroupmode, 1L, 1L, &pos); + kaestchen((long)mnewgroup, 1L, 1L, &pos); + kaestchen((long)mungroup, 3L, 4L, &pos); + kaestchen((long)mgroupok, 1L, 4L, &pos); + kaestchen((long)mshowgroup, 1L, 1L, &pos); + kaestchen((long)mlschieben, 1L, 5L, &pos); + kaestchen((long)moschieben, 1L, 5L, &pos); + kaestchen((long)mredraw, 1L, 5L, &pos); + kaestchen((long)muschieben, 1L, 5L, &pos); + kaestchen((long)mrschieben, 1L, 5L, &pos); + kaestchen((long)mgitter, 1L, 4L, &pos); + kaestchen((long)mcenter, 1L, 4L, &pos); + kaestchen((long)mgross, 1L, 4L, &pos); + kaestchen((long)mklein, 1L, 4L, &pos); + kaestchen((long)meinrasten, 1L, 3L, &pos); + kaestchen((long)mxytastatur, 1L, 3L, &pos); + kaestchen((long)mdegrees, 1L,3L, &pos); + kaestchen((long)mcolor, 1L, 1L, &pos); + kaestchen((long)mread, 1L, 2L, &pos); + kaestchen((long)mreadzeit, 1L, 2L, &pos); + kaestchen((long)mchangelineattr, 1L,2L, &pos); + kaestchen((long)mladen, 1L, 2L, &pos); + kaestchen((long)msave, 1L, 2L, &pos); + kaestchen((long)mende, 1L, 2L, &pos); + + dy=yprompt+1.5*wzeichenhoehe-yam[mende]; + for (i=1;i<=zmenue;i++) {yam[i] += dy; yem[i] += dy;} +} + +Static Void ausmenue() +/* Ausdruck des Menues */ +{ + long i; + for (i = 1; i <= zmenue; i++) + ausmenueelement(i); + aussomenue(); +} + +Static Void mstrnstr(x, y, mstr, nstr) +double x, y; +long *mstr, *nstr; +{ + double dx, dy, f; + + dx = x - gridx0; + dy = y - gridy0; + f = 1 / ((gridwx1 * gridwy2 - gridwx2 * gridwy1) * gridw); + *mstr = (long)floor((dx * gridwy2 - dy * gridwx2) * f + 0.5); + *nstr = (long)floor((dy * gridwx1 - dx * gridwy1) * f + 0.5); +} + + +Static Void gridsnap(x, y) +double *x, *y; +{ + long mstrich, nstrich; + double xx,yy; + mstrnstr(*x, *y, &mstrich, &nstrich); + gridpunkt((double)mstrich, (double)nstrich, &xx, &yy); + *x=xx; + *y=yy; +} + + +Static Void naehe(x1, y1, x2, y2, xmin, ymin, min) +double x1, y1, x2, y2, *xmin, *ymin, *min; +{ + double d, dx, dy; + + dx = si_fabs(x2 - x1); + if (dx >= *min) + return; + dy = si_fabs(y2 - y1); + if (dy >= *min) + return; + d = ppabstand(x1, y1, x2, y2); + if (d >= *min) + return; + *min = d; + *xmin = x1; + *ymin = y1; +} + + +Static Void elsnap(x, y) +double *x, *y; +{ + long i; + double xg, yg, xmin, ymin, min; + Static boolean relevant(); + + min = 5.0; + xmin = *x; + ymin = *y; + xg = *x; + yg = *y; + gridsnap(&xg, &yg); + naehe(xg, yg, *x, *y, &xmin, &ymin, &min); + for (i = 1; i <= zelmax; i++) { + if (typ[i] > 0) { + if (relevant(i, *x, *y)==true) { + naehe(x1[i], y1_[i], *x, *y, &xmin, &ymin, &min); + switch (typ[i]) { + + case tgerade: /*Gerade*/ + naehe(x2[i], y2[i], *x, *y, &xmin, &ymin, &min); + break; + + case trechteckgef: + case tviereckgef: + naehe(x2[i], y2[i], *x, *y, &xmin, &ymin, &min); + naehe(xb1[i], yb1[i], *x, *y, &xmin, &ymin, &min); + naehe(xb2[i], yb2[i], *x, *y, &xmin, &ymin, &min); + break; + + case tdreieckgef: + naehe(x2[i], y2[i], *x, *y, &xmin, &ymin, &min); + naehe(xb1[i], yb1[i], *x, *y, &xmin, &ymin, &min); + break; + + case tkreisbogen: + case tellbogen: /*Bogen*/ + case tkreissektorgef: + case tellsektorgef: + naehe(xb1[i], yb1[i], *x, *y, &xmin, &ymin, &min); + naehe(xb2[i], yb2[i], *x, *y, &xmin, &ymin, &min); + break; + + case tbezier: /*Bezier*/ + case tbeziergef: + naehe(x2[i], y2[i], *x, *y, &xmin, &ymin, &min); + break; + }/*case*/ + }/*if relevant */ + } /*if,for*/ + } + *x = xmin; + *y = ymin; +} + +Static Void marklinie(ix,iy,idx,idy,zcolor) + long zcolor,ix,iy,idx,idy; +{ + setvalues(display,gczeichnung,zcolor,0L,0L,0L); + XDrawLine(display,win,gczeichnung,ix-idx,iy-idy,ix+idx,iy+idy); +} + + +Static Void ausmarken(anzp, mtyp, mhoehe, zcolor) +long anzp, mtyp, zcolor; +double mhoehe; +/* Koordinaten in rpxarray,rpyarray */ +{ + long i,ix,iy,imhoehe; + double xx,yy; + XPoint points[maxpunkte],tpoints[10]; + imhoehe = siintround(mhoehe); + if (anzp==0) return; + for (i=0;i<anzp;i++){ + xx=rpxarray[i]; + yy=rpyarray[i]; + welt_to_bildschirm(xx,yy,&ix,&iy); + points[i].x=ix; + points[i].y=iy; + } + if (mtyp==1) {/* Punkte */ + setvalues(display,gczeichnung,zcolor,0L,0L,0L); + XDrawPoints(display,win,gczeichnung,points,anzp,CoordModeOrigin); + return; + } + for (i=0;i<anzp;i++){/*Jede Marke einzeln zeichnen*/ + xx=rpxarray[i]; + yy=rpyarray[i]; + ix=points[i].x; + iy=points[i].y; + switch (mtyp) + { + case 2: /*fuer click (45 Grad Kreuz liegend)*/ + marklinie(ix,iy,imhoehe,imhoehe,zcolor); + marklinie(ix,iy,-imhoehe,imhoehe,zcolor); + break; + case 3: /*fuer Mittelpunkt Zeichnung (Stern)*/ + marklinie(ix,iy,imhoehe,imhoehe,zcolor); + marklinie(ix,iy,-imhoehe,imhoehe,zcolor); + marklinie(ix,iy,0,imhoehe,zcolor); + marklinie(ix,iy,imhoehe,0,zcolor); + break; + case 4: /*fuer Textposition (Dreieck) */ + tpoints[0].x=ix; + tpoints[0].y=iy; + tpoints[3].x=ix; + tpoints[3].y=iy; + welt_to_bildschirm(xx + .3*mhoehe,yy-mhoehe,&ix,&iy); + tpoints[1].x=ix; + tpoints[1].y=iy; + welt_to_bildschirm(xx - .3*mhoehe,yy-mhoehe,&ix,&iy); + tpoints[2].x=ix; + tpoints[2].y=iy; + setvalues(display,gczeichnung,zcolor,0L,0L,0L); + XDrawLines(display,win,gczeichnung,tpoints,4,CoordModeOrigin); + break; + }/* switch */ + } +}/*ausmarken*/ + + +Static Void einemarkeaus(x,y,mtyp,mhoehe,zcolor) + double x,y, mhoehe; + long mtyp,zcolor; +{ + rpxarray[0]=x; + rpyarray[0]=y; + ausmarken(1L,mtyp,mhoehe,zcolor); +} + + +Static Void setzetextmarke(x, y, zcolor) +double x, y; +long zcolor; +{ + long typmarke,i; + double hoehemarke; + typmarke = 4; + hoehemarke = wzeichenbreite; + einemarkeaus(x,y, typmarke, hoehemarke,zcolor); +} + +Static Void setzeclickmarke(x, y, zcolor) +double x, y; +long zcolor; +{ + long typmarke,i; + double hoehemarke; + typmarke = 2; + hoehemarke = 6.0; + einemarkeaus(x,y, typmarke, hoehemarke,zcolor); +} + + +Static Void ausalleclickmarken() +/* Markierung der Click-Punkte */ +{ + long i; + + for (i = 1; i <= 4; i++) { + if (bmarker[i]==true) + setzeclickmarke(xmarker[i], ymarker[i],schwarz); + } +} + + +Static Void neueclickmarke(x, y) +double x, y; +{ + long i; + + if (bmarker[1]==true) + setzeclickmarke(xmarker[1], ymarker[1],weiss); + for (i = 1; i <= 3; i++) { + xmarker[i] = xmarker[i + 1]; + ymarker[i] = ymarker[i + 1]; + bmarker[i] = bmarker[i + 1]; + } + bmarker[4] = true; + xmarker[4] = x; + ymarker[4] = y; + setzeclickmarke(x, y, schwarz); +} + + +Static Void ijminmax(x, y, imin, imax, jmin, jmax) +double x, y; +long *imin, *imax, *jmin, *jmax; +{ + long i,j; + + mstrnstr(x, y, &i, &j); + if (i < *imin) + *imin = i; + if (i > *imax) + *imax = i; + if (j < *jmin) + *jmin = j; + if (j > *jmax) + *jmax = j; +} + + +Static Void ausgrid(zcolor) +long zcolor; +{ + long i, j, imin, jmin, imax, jmax, nn; + double x, y, hoehemarke; + nn = 0; + hoehemarke = 2.0; + einemarkeaus(gridx0, gridy0, 3L,hoehemarke, zcolor); + /*fuer Zentrum */ + mstrnstr(xgr, yprompt, &i, &j); + imin = i; + imax = i; + jmin = j; + jmax = j; + ijminmax(xgr, yzmax, &imin, &imax, &jmin, &jmax); + ijminmax(xzmax, yprompt, &imin, &imax, &jmin, &jmax); + ijminmax(xzmax, yzmax, &imin, &imax, &jmin, &jmax); + hoehemarke = 1.0; + for (j = jmin; j <= jmax; j++) { + for (i = imin; i <= imax; i++) { + gridpunkt((double)i, (double)j, &x, &y); + rpxarray[nn]=x; + rpyarray[nn]=y; + nn++; + if (nn >= maxpunkte) { + ausmarken(nn,1L,hoehemarke,zcolor); + nn = 0; + } + } + } + if (nn > 0) + ausmarken(nn,1L,hoehemarke,zcolor); +} /*ausgrid*/ + + + +Static Void elskalieren(gridw, dxx, dyy, f) +double *gridw, dxx, dyy, f; +{ + long i; + double dx, dy; + + if (f != 1.0) { + *gridw = f * *gridw; + while (*gridw > 1.5 * gridw0) + *gridw /= 2.0; + while (*gridw < 0.6 * gridw0) + *gridw = 2.0 * *gridw; + } + i = (long)floor(dxx / *gridw + 0.5); + dx = i * *gridw; + i = (long)floor(dyy / *gridw + 0.5); + dy = i * *gridw; + + /* fuer readstdin vermerken, welche Skalierungen durchgef"uhrt wurden */ + readdxx = readdxx*f +dx; + readdyy = readdyy*f +dy; + readf = readf*f; + + /* jetzt eigentliche Skalierung */ + + for (i = 1; i <= zelmax; i++) { + if (typ[i] != 0) + skalieren(i, dx, dy, f); + } + for (i = 1; i <= 4; i++) { + if (bmarker[i]==true) + pskalieren(&xmarker[i], &ymarker[i], dx, dy, f); + } + pskalieren(&xlast, &ylast, dx, dy, f); + pskalieren(&gridx0, &gridy0, dx, dy, f); +} + + +Static Void minmax(xmin, xmax, ymin, ymax) +double *xmin, *xmax, *ymin, *ymax; +{ + long i; + boolean erstes; + + *xmax = 0.0; + *ymax = 0.0; + *xmin = 0.0; + *ymin = 0.0; + erstes = true; + for (i = 1; i <= zelmax; i++) { + if (typ[i] > 0) { /*i*/ + if (erstes==true) { + *xmax = elxmax[i]; + *ymax = elymax[i]; + *xmin = elxmin[i]; + *ymin = elymin[i]; + erstes = false; + } + if (elxmax[i] > *xmax) *xmax = elxmax[i]; + if (elymax[i] > *ymax) *ymax = elymax[i]; + if (elxmin[i] < *xmin) *xmin = elxmin[i]; + if (elymin[i] < *ymin) *ymin = elymin[i]; + } + } +} + +Static boolean inwinkel(elsel, w) +long elsel; +double w; +{ + boolean erg; + double wa, we; + + erg = false; + wa = wanf[elsel]; + we = wend[elsel]; + if (si_fabs(wa - w) < 5.0) + erg = true; + if (si_fabs(we - w) < 5.0) + erg = true; + if (we > wa) { + if (w >= wa && w <= we) + erg = true; + } + if (we <= wa) { + if (w <= we || w >= wa) + erg = true; + } + return erg; +} + +Static Void initgrenzen(xp,yp,xxmax,xxmin,yymax,yymin) + double xp,yp,*xxmax,*xxmin,*yymax,*yymin; +{ + *xxmax = xp; + *xxmin = xp; + *yymax = yp; + *yymin = yp; +} + +Void grenzen(xp,yp,xxmax,xxmin,yymax,yymin) + double xp, yp, *xxmax,*xxmin,*yymax,*yymin; +{ + if (xp > *xxmax) *xxmax = xp; + if (xp < *xxmin) *xxmin = xp; + if (yp > *yymax) *yymax = yp; + if (yp < *yymin) *yymin = yp; +} + +Static Void ellgrenzpunkte(i,xxmax,xxmin,yymax,yymin) + long i; + double *xxmax,*xxmin,*yymax,*yymin; +{ + double xm,ym,lx,ly,cr,sr; + double xg1,yg1,w1,xg2,yg2,w2,xg3,yg3,w3,xg4,yg4,w4; + double h1,h2,h3,h4,h5; + + ellpar(i,&xm,&ym,&lx,&ly,&cr,&sr); + h1 = lx*lx*cr*cr+ly*ly*sr*sr; + h2 = ly*ly*cr*cr+lx*lx*sr*sr; + h3 = cr*sr*(lx*lx-ly*ly); + h4 = sqrt(h1); + h5 = sqrt(h2); + xg1 = xm + h4; + xg2 = xm - h4; + yg1 = ym + h4*h3/h1; + yg2 = ym - h4*h3/h1; + w1 = winkelell(xm, ym, lx, ly, cr, sr, xg1, yg1); + w2 = winkelell(xm, ym, lx, ly, cr, sr, xg2, yg2); + yg3 = ym + h5; + yg4 = ym - h5; + xg3 = xm + h5*h3/h2; + xg4 = xm - h5*h3/h2; + w3 = winkelell(xm, ym, lx, ly, cr, sr, xg3, yg3); + w4 = winkelell(xm, ym, lx, ly, cr, sr, xg4, yg4); + if (inwinkel(i,w1)==true) grenzen(xg1,yg1,xxmax,xxmin,yymax,yymin); + if (inwinkel(i,w2)==true) grenzen(xg2,yg2,xxmax,xxmin,yymax,yymin); + if (inwinkel(i,w3)==true) grenzen(xg3,yg3,xxmax,xxmin,yymax,yymin); + if (inwinkel(i,w4)==true) grenzen(xg4,yg4,xxmax,xxmin,yymax,yymin); +} + + +Static Void berechneminmax(i) + long i; +{ + double xxmin,yymin,xxmax,yymax; + double xm,ym,lx,ly,cr,sr; + + if (typ[i] <= 0) return; + switch (typ[i]) { + + case ttext: + initgrenzen(x1[i], y1_[i],&xxmax,&xxmin,&yymax,&yymin); + grenzen(xb1[i], yb1[i],&xxmax,&xxmin,&yymax,&yymin); + grenzen(xb2[i], yb2[i],&xxmax,&xxmin,&yymax,&yymin); + break; + + case tgerade: + initgrenzen(x1[i], y1_[i],&xxmax,&xxmin,&yymax,&yymin); + grenzen(x2[i], y2[i],&xxmax,&xxmin,&yymax,&yymin); + break; + + case trechteckgef: + case tviereckgef: + initgrenzen(x1[i], y1_[i],&xxmax,&xxmin,&yymax,&yymin); + grenzen(x2[i], y2[i],&xxmax,&xxmin,&yymax,&yymin); + grenzen(xb1[i], yb1[i],&xxmax,&xxmin,&yymax,&yymin); + grenzen(xb2[i], yb2[i],&xxmax,&xxmin,&yymax,&yymin); + break; + + case tdreieckgef: + initgrenzen(x1[i], y1_[i],&xxmax,&xxmin,&yymax,&yymin); + grenzen(x2[i], y2[i],&xxmax,&xxmin,&yymax,&yymin); + grenzen(xb1[i], yb1[i],&xxmax,&xxmin,&yymax,&yymin); + break; + + case tkreis: + case tkreisgef: + ellpar(i,&xm,&ym,&lx,&ly,&cr,&sr); + initgrenzen(xm+lx, ym+ly,&xxmax,&xxmin,&yymax,&yymin); + grenzen(xm-lx, ym-ly,&xxmax,&xxmin,&yymax,&yymin); + break; + + case tell: + case tellgef: + initgrenzen(x1[i],y1_[i],&xxmax,&xxmin,&yymax,&yymin); + ellgrenzpunkte(i,&xxmax,&xxmin,&yymax,&yymin); + break; + + case tkreisbogen: + case tellbogen: + initgrenzen(xb1[i], yb1[i],&xxmax,&xxmin,&yymax,&yymin); + grenzen(xb2[i],yb2[i],&xxmax,&xxmin,&yymax,&yymin); + ellgrenzpunkte(i,&xxmax,&xxmin,&yymax,&yymin); + break; + + case tellsektorgef: + case tkreissektorgef: + initgrenzen(x1[i],y1_[i],&xxmax,&xxmin,&yymax,&yymin); + grenzen(xb1[i], yb1[i],&xxmax,&xxmin,&yymax,&yymin); + grenzen(xb2[i],yb2[i],&xxmax,&xxmin,&yymax,&yymin); + ellgrenzpunkte(i,&xxmax,&xxmin,&yymax,&yymin); + break; + + case tbezier: + case tbeziergef: + /* keine minmax-Berechnung, da diese ueber ausel() erfolgt */ + return; + }/*case*/ + elxmin[i]=xxmin; + elxmax[i]=xxmax; + elymin[i]=yymin; + elymax[i]=yymax; +} + +Static Void ausfastalles() +{ + static void ausnurelemente(); + XClearWindow(display,win); + if (erwartet==tastatur_erwartet) + textpositionieren(); + prompt(); + ausmenue(); + ausnurelemente(); +} + + +Static Void ausalles() +{ + static void auselemente(); + XClearWindow(display,win); + if (erwartet==tastatur_erwartet) + textpositionieren(); + prompt(); + ausmenue(); + auselemente(); + ausalleclickmarken(); + if (erwartet==tastatur_erwartet) + cursan(curs_x,curs_y); +} + + +Static Void verschieben(art) +long art; +{ + double f, fminus, fplus, dxx, dyy, xmax, ymax, xmin, ymin; + Char s1[maxstrl+1], s2[maxstrl+1], s3[maxstrl+1], + s4[maxstrl+1], s5[maxstrl+1], s6[maxstrl+1]; + + fplus = 1.5; + fminus = 1.0 / fplus; + strcpy(s1, pr1); + strcpy(s2, pr2); + strcpy(s3, pr3); + strcpy(s4, pr4); + strcpy(s5, pr5); + strcpy(s6, pr6); + strcpy(pr1, pr2menue[art]); + strcpy(pr2, nullstr); + strcpy(pr3, nullstr); + strcpy(pr4, nullstr); + strcpy(pr5, nullstr); + strcpy(pr6, nullstr); + + prompt(); + f = 1.0; + dxx = (long)floor((xzmax - xgr) / 4.0 + 0.5); + dyy = (long)floor(yzmax / 4.0 + 0.5); + switch (art) { + + case mlschieben: + dyy = 0.0; + dxx = -dxx; + break; + + case mrschieben: + dyy = 0.0; + break; + + case moschieben: + dxx = 0.0; + break; + + case muschieben: + dxx = 0.0; + dyy = -dyy; + break; + + case mgross: + dxx = 0.0; + dyy = 0.0; + f = fplus; + break; + + case mklein: + dxx = 0.0; + dyy = 0.0; + f = fminus; + break; + + case mcenter: + minmax(&xmin, &xmax, &ymin, &ymax); + dxx = xmittelzei - (long)floor((xmax + xmin) * 0.5 + 0.5); + dyy = ymittelzei - (long)floor((ymax + ymin) * 0.5 + 0.5); + break; + }/*case*/ + elskalieren(&gridw, dxx, dyy, f); + XClearWindow(display,win); + selmenue[art] = false; + strcpy(pr1, s1); + strcpy(pr2, s2); + strcpy(pr3, s3); + strcpy(pr4, s4); + strcpy(pr5, s5); + strcpy(pr6, s6); + ausalles(); +} /*schieben*/ + +Static Void sondertaste (taste) +long taste; +{/* Behandlung von Tasten, die nicht bei */ + /* erwarteter Texteingabe gedrueckt wurden */ + if ((taste == tastecursleft1)||(taste == tastecursleft2)) + verschieben((long)mlschieben); + if ((taste == tastecursright1)||(taste == tastecursright2)) + verschieben((long)mrschieben); + if ((taste == tastecursup1)||(taste == tastecursup2)) + verschieben((long)moschieben); + if ((taste == tastecursdown1)||(taste == tastecursdown2)) + verschieben((long)muschieben); + if ((taste == tasteplus2)||(taste == tasteplus1)) + verschieben((long)mgross); + if ((taste == tasteminus2)||(taste == tasteminus1)) + verschieben((long)mklein); +} + +Static Void control (taste, press) +long taste, press; +{ + if ((taste == tastecontroll)||(taste == tastecontrolr)) + controlan = press; +} + +Static Void menueloc(x, y, i) +double x, y; +long *i; +{ + long j; + + *i = 0; + for (j = 1; j <= zmenue; j++) { + if (x < xam[j]) + goto _L1; + if (x > xem[j]) + goto _L1; + if (y < yam[j]) + goto _L1; + if (y > yem[j]) + goto _L1; + *i = j; + goto _L2; +_L1: ; + } + goto _L3; +_L2: + if (*i==mredraw) { + *i=0; + ausalles(); + return; + } + /* test ob Anklicken fuer changeattributs relevant */ + if (*i==mpfeilanf) changelende = true; + if (*i==mpfeilende) changelende = true; + if (*i==mcapprojecting) changelende = true; + if (*i==mdick) changelwidth = true; + if (*i==mgestrichelt) changelstyle = true; + if (*i==mgepunktet) changelstyle = true; + if (*i==mfont) changefont = true; + if (*i==mcolor) changecolor = true; + if (*i==mltext) changeposition = true; + if (*i==mrtext) changeposition = true; + if (*i==mbtext) changeposition = true; + if (*i==mttext) changeposition = true; + + if (!(radiogroup[*i] == 1 && selmenue[*i]==true)) { + if (selmenue[*i]==true) selmenue[*i] = false; + else selmenue[*i]=true; + ausmenueelement(*i); + } + if (radiogroup[*i] != 0 && selmenue[*i]==true) { /*if*/ + for (j = 1; j <= zmenue; j++) { + if (*i != j && selmenue[j]==true && radiogroup[j] == radiogroup[*i]) { + selmenue[j] = false; + ausmenueelement(j); + } + } /*j*/ + } +_L3: ; +} + + +Static boolean gschnittpunkt(x1, y1, dx1, dy1, x2, y2, dx2, dy2, xs, ys) +double x1, y1, dx1, dy1, x2, y2, dx2, dy2, *xs, *ys; +{ + boolean Result; + double xp, yp, m1, m2, dm, diffx12, diffy12; + + /*Schnittpunkt zweier Geraden*/ + Result = false; + diffx12 = x1 - x2; + diffy12 = y1 - y2; + xp = 0.0; + yp = 0.0; + if (dx1 == 0.0 && dx2 == 0.0) /*parallel*/ + goto _L2; + if (dx1 == 0.0) { + xp = x1; + yp = dy2 / dx2 * diffx12 + y2; + goto _L1; + } + if (dx2 == 0.0) { + xp = x2; + yp = y1 - dy1 / dx1 * diffx12; + goto _L1; + } + if (dy1 == 0.0 && dy2 == 0.0) /*parallel*/ + goto _L2; + if (dy1 == 0.0) { + xp = diffy12 * dx2 / dy2 + x2; + yp = y1; + goto _L1; + } + if (dy2 == 0.0) { + xp = x1 - diffy12 * dx1 / dy1; + yp = y2; + goto _L1; + } + m1 = dy1 / dx1; + m2 = dy2 / dx2; + if (si_fabs(m1 - m2) < 0.0001) /*parallel*/ + goto _L2; + dm = m2 - m1; + dm = 1 / dm; + xp = diffy12 * dm + m2 * dm * x2 - m1 * dm * x1; + yp = m2 * dm * y1 - m1 * dm * m2 * diffx12 - m1 * dm * y2; +_L1: + Result = true; +_L2: + *xs = xp; + *ys = yp; + return Result; +} + + +Static boolean lot(x1, y1, dx1, dy1, xp, yp, xs, ys) +double x1, y1, dx1, dy1, xp, yp, *xs, *ys; +{ + if (gschnittpunkt(x1, y1, dx1, dy1, xp, yp, -dy1, dx1, xs, ys)==true) + return true; + else + return false; +} + + +Static boolean inxystrecke(x1, y1, x2, y2, xs, ys) +double x1, y1, x2, y2, xs, ys; +{ + double d, d1, d2; + + d = ppabstand(x1, y1, x2, y2); + d1 = ppabstand(xs, ys, x1, y1); + d2 = ppabstand(xs, ys, x2, y2); + if ((d1 + d2) < (d + 3.0)) + return true; + else + return false; +} + + +Static double pgxyabstand(x1, y1, x2, y2, xp, yp) +double x1, y1, x2, y2, xp, yp; +{ + double xs,ys,d12,d1s,d2s,dmin; + + dmin = initabstand; + lot(x1, y1, x2-x1, y2-y1, xp, yp, &xs, &ys); + d12=ppabstand(x1,y1,x2,y2); + d1s=ppabstand(x1,y1,xs,ys); + d2s=ppabstand(x2,y2,xs,ys); + if (inxystrecke(x1, y1, x2, y2, xs, ys)==true) { + /* Fusspunkt Lot ist etwa in Strecke */ + /* nur dann wird Strecke als selektiert betrachtet! */ + dmin = ppabstand(xp,yp,xs,ys); + } + return dmin; +} + +Static double pgabstand(elsel, xp, yp) +long elsel; +double xp, yp; +{ double dmin; + + dmin = pgxyabstand(x1[elsel], y1_[elsel], x2[elsel], y2[elsel], xp, yp); + return dmin; +} + + + + +Static Void kopunvotext(elsel, i) +long elsel, i; +{ + typ[i] = typ[elsel]; + x1[i] = x1[elsel]; + y1_[i] = y1_[elsel]; + x2[i] = x2[elsel]; + y2[i] = y2[elsel]; + xb1[i] = xb1[elsel]; + yb1[i] = yb1[elsel]; + xb2[i] = xb2[elsel]; + yb2[i] = yb2[elsel]; + wanf[i] = wanf[elsel]; + wend[i] = wend[elsel]; + elxmin[i] =elxmin[elsel]; + elxmax[i] =elxmax[elsel]; + elymin[i] =elymin[elsel]; + elymax[i] =elymax[elsel]; + lineende[i] = lineende[elsel]; + linedicke[i] = linedicke[elsel]; + linetype[i] = linetype[elsel]; + laenge1[i] = laenge1[elsel]; + laenge2[i] = laenge2[elsel]; + rotwi[i] = rotwi[elsel]; + crw[i] = crw[elsel]; + srw[i] = srw[elsel]; + textno[i] = textno[elsel]; + sequenz[i] = sequenz[elsel]; + blink[i] = false; /* Beim Kopieren ist neues Element nicht */ + /* selektiert !!!!! */ + blinkalt[i] = false; + group[i] = group[elsel]; +} + +Static Void loescheelement(i) +long i; +{ + if ((typ[i] == ttext) || (typ[i] == -ttext)) + strcpy(texte[textno[i]],nullstr); + typ[i] = 0; +} + + +Static Void kompakt() +{ + /*belegte Elemente an Anfang der Liste*/ + /*ohne Aenderung der Reihenfolge */ + long i, delta; + + delta=0; + for (i = 1; i <= zelmax; i++) { + if (typ[i] <= 0) { + delta++; + loescheelement(i); + } + else { + if (delta != 0) {kopunvotext(i,i-delta); typ[i]=0;} + } + } + zelmax=zelmax-delta; +} + +Static Void freieselement(k) +long *k; +{ + long i; +_L0: + if (zelmax==zel) fehler(1L); + zelmax++; + i = zelmax; + *k = i; + typ[i] = -1; /*vorlaeufig belegt*/ + x1[i] = 0.0; + y1_[i] = 0.0; + x2[i] = 0.0; + y2[i] = 0.0; + xb1[i] = 0.0; + yb1[i] = 0.0; + xb2[i] = 0.0; + yb2[i] = 0.0; + wanf[i] = 0.0; + wend[i] = wg; + elxmin[i] = 0.0; + elxmax[i] = 0.0; + elymin[i] = 0.0; + elymax[i] = 0.0; + linedicke[i] = 1L; + lineende[i] = 0L; + linetype[i] = 1L; + laenge1[i] = 0.0; + laenge2[i] = 0.0; + rotwi[i] = 0.0; + crw[i] = 1.0; + srw[i] = 0.0; + textno[i] = 0; + sequenz[i] = 0; + blink[i] = false; + blinkalt[i] = false; + group[i] = 0; +} + +Static Void freiestextel(k) +long *k; +{ + long i; + + for (i = 1; i <= zstr; i++) { + if (istnullstr(texte[i])==true) + goto _L1; + } + fehler(2L); +_L1: + *k = i; +} + + +Static Void kopunv(elsel, i) +long elsel, i; +{ kopunvotext(elsel,i); + if (typ[i] != ttext) + return; + typ[i] = -ttext; + freiestextel(&textno[i]); + typ[i] = ttext; + strcpy(texte[textno[i]], texte[textno[elsel]]); +} + +Static Void ausline(k,zcolor) + long k,zcolor; +{ + rpxarray[0]=x1[k]; + rpyarray[0]=y1_[k]; + rpxarray[1]=x2[k]; + rpyarray[1]=y2[k]; + auspolyline(zcolor,k,2L); +} + + +Static Void ausgefviereck(k,zcolor) +long k,zcolor; +{ + rpxarray[0]=x1[k]; + rpyarray[0]=y1_[k]; + rpxarray[1]=xb1[k]; + rpyarray[1]=yb1[k]; + rpxarray[2]=x2[k]; + rpyarray[2]=y2[k]; + rpxarray[3]=xb2[k]; + rpyarray[3]=yb2[k]; + rpxarray[4]=x1[k]; + rpyarray[4]=y1_[k]; + ausfillpolygon(5L,zcolor); +} + +Static Void ausgefdreieck(k,zcolor) +long k,zcolor; +{ + rpxarray[0]=x1[k]; + rpyarray[0]=y1_[k]; + rpxarray[1]=x2[k]; + rpyarray[1]=y2[k]; + rpxarray[2]=xb1[k]; + rpyarray[2]=yb1[k]; + rpxarray[3]=x1[k]; + rpyarray[3]=y1_[k]; + ausfillpolygon(4L,zcolor); +} + +Static Void austextline(k,zcolor) +long k; +{ + long ix1,iy1,ix2,iy2; + + welt_to_bildschirm(xb1[k], yb1[k], &ix1, &iy1); + welt_to_bildschirm(xb2[k], yb2[k], &ix2, &iy2); + setvalues(display,gczeichnung,zcolor,6L,0L,0L); + XDrawLine(display,win,gczeichnung,ix1,iy1,ix2,iy2); +} + + +Static Void bogenauspar(elsel,ltyp,ldicke,lende,lcolor, + ixa,iya,ilx,ily,iwa,idw) +long elsel,*ltyp,*ldicke,*lcolor,*ixa,*iya,*ilx,*ily,*iwa,*idw; +{ + double xm,ym,lx,ly,cr,sr,wa,dw; + long ixm, iym; + ellpar(elsel, &xm, &ym, &lx, &ly, &cr, &sr); + getlineattribute(elsel, typ[elsel], ltyp, ldicke, lende, lcolor); + welt_to_bildschirm(xm-lx, ym+ly, ixa, iya); + *ilx = siintround(2.0*lx); + *ily = siintround(2.0*ly); + wa=wanf[elsel]; + dw=wend[elsel]-wa; + if (dw<=0.0) dw += wg; + /* Winkel in Grad*64 */ + *iwa=siintround(wa*6.4); + *idw=siintround(dw*6.4); +} + + +Static Void ausbogen(elsel,zcolor) + long elsel,zcolor; +{ + long ltyp,ldicke,lende,lcolor,ixa,iya,ilx,ily,iwa,idw; + + bogenauspar(elsel,<yp,&ldicke,&lende,&lcolor, + &ixa,&iya,&ilx,&ily,&iwa,&idw); + setvalues(display,gczeichnung,zcolor,ltyp,ldicke,lende); + XDrawArc(display,win,gczeichnung,ixa,iya,ilx,ily,iwa,idw); + winpfeile(elsel,zcolor); +} + +Static Void ausgefbogen(elsel,zcolor) + long elsel,zcolor; +{ + long ltyp,ldicke,lende,lcolor,ixa,iya,ilx,ily,iwa,idw; + bogenauspar(elsel,<yp,&ldicke,&lende,&lcolor, + &ixa,&iya,&ilx,&ily,&iwa,&idw); + setvalues(display,gczeichnung,zcolor,ltyp,ldicke,lende); + XFillArc(display,win,gczeichnung,ixa,iya,ilx,ily,iwa,idw); + winpfeile(elsel,zcolor); +} + +Static Void ellipse2polygon(i,kerg) +long i,*kerg; +{ + double umfang, lambda, lambdaq, xp, yp, dw, w, + xm, ym, lx, ly, lmax, cr, sr, wa, we; + long k, m; + + ellpar(i, &xm, &ym, &lx, &ly, &cr, &sr); + lambda = (lx-ly)/(lx+ly); + lambdaq = lambda*lambda; + umfang = pi*(lx+ly)*(64.0-3.0*lambdaq*lambdaq)/(64.0-16*lambdaq); + m = umfang/10.0; /* ungefaehre Zahl der Strecken mit je 5 Pixel */ + if (m < 10) m = 10; + if (m > maxpunkte) m = maxpunkte - 10; + if (m > 50) m = 50; + dw = wg/m; + wa = wanf[i]; + we = wend[i]; + w = wa; + if (we <= wa) we += wg; + + k = 0; + while (w < we){ + ellw_xy(xm, ym, lx, ly, cr, sr, w, &xp, &yp); + w += dw; + rpxarray[k]=xp; + rpyarray[k]=yp; + k++; + }; + ellw_xy(xm, ym, lx, ly, cr, sr, we, &xp, &yp); + rpxarray[k]=xp; + rpyarray[k]=yp; + k++; + if (typ[i] == tellsektorgef) { + rpxarray[k]=xm; + rpyarray[k]=ym; + k++; + rpxarray[k]=rpxarray[0]; + rpyarray[k]=rpyarray[0]; + k++; + } + *kerg = k; +} + +Static Void ausellgef(i,zcolor) +long i,zcolor; +{ long k; + + ellipse2polygon(i,&k); + ausfillpolygon(k,zcolor); +} + +Static Void ausellipse(i,zcolor) +long i,zcolor; +{ long k; + + ellipse2polygon(i,&k); + auspolyline(zcolor,i,k); +} + +Static Void ausel(i, painterase) +long i, painterase; +{ long fontart, zcolor; + + zcolor = getzcolor(i, painterase); + /* zcolor ist Farbe der Zeichnung */ + /* bestimmen aus Angabe color und Wert Farbe bei Element! */ + switch (typ[i]) { /*case*/ + + case ttext: + if (rotwi[i] != 0.0) austextline(i,zcolor); + fontart=linetype[i]; + if (i != texterase) + ztextaus(win, i, x2[i], y2[i], texte[textno[i]],zcolor,fontart); + setzetextmarke(x1[i], y1_[i], zcolor); + break; + + case tgerade: + ausline(i,zcolor); + break; + + case trechteckgef: + case tviereckgef: + ausgefviereck(i,zcolor); + break; + + case tdreieckgef: + ausgefdreieck(i,zcolor); + break; + + case tkreis: + ausbogen(i,zcolor); + break; + + case tkreisgef: + case tkreissektorgef: + ausgefbogen(i,zcolor); + break; + + case tkreisbogen: + ausbogen(i,zcolor); + break; + + case tellgef: + case tellsektorgef: + ausellgef(i,zcolor); + break; + + case tell: + case tellbogen: + ausellipse(i,zcolor); + break; + + case tbezier: + ausbezier(i,zcolor); + break; + + case tbeziergef: + ausbeziergef(i,zcolor); + break; + } +} + +Static Void ltd_usleep(s, mu) +long s, mu; +{ + st_delay.tv_usec = mu; + st_delay.tv_sec = s; + select(32, 0, 0, 0, &st_delay); +} + +Static Void Flush_ltd_usleep(s, mu) +long s, mu; +{ + XFlush(display); + /* ganz wichtig, damit vor sleep noch alles ausgegeben wird */ + ltd_usleep(s, mu); +} + +Static Void ausblinkelemente() +{ + long i,f; + f = 1; + if (tablett) + f = 10; + if (blinkintervallzaehler==0) { + /* blinkfarbe == paint oder erase ! */ + if (blinkfarbe == erase) { + for (i = 1; i <= zelmax; i++) + if ((typ[i] > 0)&&(blink[i]==true)) ausel(i, erase); + for (i = 1; i <= zelmax; i++) + if ((typ[i] > 0)&&(blink[i]==false)) ausel(i, paint); + } + else + for (i = 1; i <= zelmax; i++) { + if (typ[i] > 0) ausel(i, paint); + } + } + ausgrid(schwarz); + Flush_ltd_usleep(0L,(long)(100000/f)); + /* 100/f ms Grund-Wartezeit bzw. Reaktionszeit */ + if ((blinkfarbe==paint)&&(blinkintervallzaehler++ > 10*f)) { + blinkintervallzaehler = 0; + blinkfarbe=erase; + } + else { + if ((blinkfarbe==erase)&&(blinkintervallzaehler++ > 2*f)) { + blinkintervallzaehler = 0; + blinkfarbe=paint; + } + } +} + +Static Void ausnurelemente() +{ + long i; + + for (i = 1; i <= zelmax; i++) { + if (typ[i] > 0) + ausel(i, paint); + } /* end for */ + zeichnen = false; +} + +Static Void auselemente() +{ + ausnurelemente(); + ausalleclickmarken(); + ausgrid(schwarz); +} + +Static Void blinkenaus() +{ + blinkend = false; + auselemente(); +} + +Static Void blinkenan() +{ long i; + + for (i = 1; i <= zelmax; i++) { + blinkalt[i] = blink[i]; + blink[i] = false; + } + if (blinkend==true) + blinkenaus(); + blinkfarbe = erase; + blinkend = true; + blinkintervallzaehler = 0; +} +Static boolean duplikat(); + +Static long interncreateline(elselalt, xx1, yy1, xx2, yy2) +long elselalt; +double xx1, yy1, xx2, yy2; +{ + double d; + long elsel, ldicke, ltyp, lende; + + if (elselalt == 0) { + d = ppabstand(xx1, yy1, xx2, yy2); + if (d < dminein) + return 0; + } + freieselement(&elsel); + typ[elsel] = tgerade; + x1[elsel] = xx1; + y1_[elsel] = yy1; + x2[elsel] = xx2; + y2[elsel] = yy2; + setlineattribute(elselalt, elsel); + berechneminmax(elsel); + return elsel; +} + +Static Void createline(elselalt, xx1, yy1, xx2, yy2) +long elselalt; +double xx1, yy1, xx2, yy2; +{ + long elsel; + + elsel = interncreateline(elselalt, xx1, yy1, xx2, yy2); + if (elsel != 0) + ausel(elsel, paint); +} + +Static long einbezier(x,y,taste,msel,phase) +long *msel,phase,taste; +double x,y; +{ + static long elsel; + long elselalt, ltyp, ldicke, lende; + static boolean fortsetzung; + double d1,d2; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + case 3: goto L3; + case 4: goto L4; + } + L0: + fortsetzung = false; + return 1; + L1: + freieselement(&elsel); + x1[elsel] = x; + y1_[elsel] = y; + strcpy(pr4, " end point of tangent to starting point?"); + return 2; + L2: + xb1[elsel] = x; + yb1[elsel] = y; + if (si_fabs(x - x1[elsel]) < 3.0 && si_fabs(y - y1_[elsel]) < 3.0) + return 2; + strcpy(pr4, " first point of tangent to end point?"); + return 3; + L3: + xb2[elsel] = x; + yb2[elsel] = y; + if (fortsetzung == true) { + /* Steigung bei Anfangspunkt beibehalten, aber die Entfernung zum */ + /* Punkt 2 auf halben Abstand Punkt3 von Anfangspunkt setzen */ + d1 = ppabstand(x1[elsel],y1_[elsel], xb1[elsel],yb1[elsel]); + d2 = ppabstand(x1[elsel],y1_[elsel], x,y); + if (d2==0.0) + d2=4.0; + xb1[elsel] = x1[elsel] + d2/d1*0.4*(xb1[elsel]-x1[elsel]); + yb1[elsel] = y1_[elsel] + d2/d1*0.4*(yb1[elsel]-y1_[elsel]); + } + strcpy(pr4, pr3menue[*msel]); + return 4; + L4: + x2[elsel] = x; + y2[elsel] = y; + if (si_fabs(x - xb2[elsel]) < 3.0 && si_fabs(y - yb2[elsel]) < 3.0) + return 4; + if (selmenue[mgefuellt] == true) + typ[elsel] = tbeziergef; + else + typ[elsel] = tbezier; + setlineattribute(0L, elsel); + /* berechneminmax(elsel); */ + /* unnoetig, da bei ausel fuer bezier berechnet!! */ + ausel(elsel, paint); + /* ggf. weiterfuehren der Bezierkurve */ + elselalt=elsel; + freieselement(&elsel); + x1[elsel]=x2[elselalt]; + y1_[elsel]=y2[elselalt]; + xb1[elsel]=2*x1[elsel]-xb2[elselalt]; + yb1[elsel]=2*y1_[elsel]-yb2[elselalt]; + strcpy(pr4, " first point of tangent to end point?"); + fortsetzung = true; + return 3; +} + + +Static Void ellanfendpunkt(i) +long i; +{ + double lx, ly, xm, ym, cr, sr; + + ellpar(i, &xm, &ym, &lx, &ly, &cr, &sr); + while (wanf[i] >= wg) + wanf[i] -= wg; + while (wanf[i] < 0.0) + wanf[i] += wg; + while (wend[i] > wg) + wend[i] -= wg; + while (wend[i] < 0.0) + wend[i] += wg; + ellw_xy(xm, ym, lx, ly, cr, sr, wanf[i], &xb1[i], &yb1[i]); + ellw_xy(xm, ym, lx, ly, cr, sr, wend[i], &xb2[i], &yb2[i]); +} + + +Static Void kreisanfendpunkt(i) +long i; +{ + double xm, ym, rad; + + xm = x1[i]; + ym = y1_[i]; + rad = laenge1[i]; + while (wanf[i] >= wg) + wanf[i] -= wg; + while (wanf[i] < 0.0) + wanf[i] += wg; + while (wend[i] > wg) + wend[i] -= wg; + while (wend[i] < 0.0) + wend[i] += wg; + xb1[i] = xm + rad * cos(wanf[i] * fgradbo); + yb1[i] = ym + rad * sin(wanf[i] * fgradbo); + xb2[i] = xm + rad * cos(wend[i] * fgradbo); + yb2[i] = ym + rad * sin(wend[i] * fgradbo); +} + +Static long winkeleingabe(w) +double *w; +{ long i; double wi; + + if(istnullstr(EinText)==true) return 1; + i=sscanf(EinText,"%lf",&wi); + if (i!=1) return 2; + if ((wi > 4000)||(wi < -4000)) return 2; + while (wi > 360.0) wi -= 360.0; + while (wi < 0.0) wi += 360.0; + *w = wi*10; + return 0; +} + +Static long einarc(x,y,elsel,taste,phase) + long elsel, taste, phase; + double x,y; + /* Eingabe Kreisbogen */ +{ + long i, ltyp, ldicke, lende; + + phase -= phase2; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + } + L0: + strcpy(pr4, pranfwi); + if (selmenue[mdegrees]==true) + inittastaturtext(nullstr,pr2menue[mdegrees],1L); + winerwartet = 1; + return (phase2+1); + L1: + if (taste==0) {/* stringeingabe*/ + i = winkeleingabe(&wanf[elsel]); + if (i != 0) goto L0; + } + else + wanf[elsel] = winkelk(x1[elsel], y1_[elsel], x, y); + L1B: + winerwartet = 1; + strcpy(pr4, prendwi); + if (selmenue[mdegrees]==true) + inittastaturtext(nullstr,pr2menue[mdegrees],1L); + return (phase2+2); + L2: + if (taste==0) {/* stringeingabe*/ + i = winkeleingabe(&wend[elsel]); + if (i != 0) goto L1B; + } + else + wend[elsel] = winkelk(x1[elsel], y1_[elsel], x, y); + winerwartet = 0; + if (si_fabs(wanf[elsel]-wend[elsel])<10) goto L1B; + setlineattribute(0L, elsel); + kreisanfendpunkt(elsel); + if (selmenue[mgefuellt]==true) {typ[elsel] = tkreissektorgef;} + else typ[elsel] = tkreisbogen; + berechneminmax(elsel); + ausel(elsel, paint); + if (typ[elsel] != tkreissektorgef) return 0; + /* anschliessenden Sektor eingeben, nur Endwinkel */ + /* zunaechst bisherigen Sektor umspeichern */ + freieselement(&i); + kopunv(elsel,i); + typ[elsel] = -1; + wanf[elsel] = wend[elsel]; + strcpy(pr4, prendwisektor); + goto L1B; +} + + + +Static Void normgrid() +{ + double a, dx, dy; + + dx = gridwx1 + gridwx2; + dy = gridwy1 + gridwy2; + a = sifsqrt(1.0, dx * dx + dy * dy); + gridw0 = a; + gridw = a; + a = 1 / a; + gridwx1 *= a; + gridwy1 *= a; + gridwx2 *= a; + gridwy2 *= a; +} + +Static Void selmenloeschen(msel) +long *msel; +{ + selmenue[*msel]=false; + ausmenueelement(*msel); + *msel=0; +} + +Static long eingitter(x,y,msel,phase) + long *msel,phase; + double x,y; + /*eingitter*/ +{ + double dx, dy, a, c, aq, cq, cosa; + static double b, bq; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + case 3: goto L3; + } + L0: + strcpy(pr2, " grid"); + ausgrid(weiss); + initgrid(); + ausgrid(schwarz); + strcpy(pr4, pr2menue[*msel]); + return 1; + L1: + ausgrid(weiss); + gridx0 = x; + gridy0 = y; + ausgrid(schwarz); + strcpy(pr4, " first grid point to the right?"); + return 2; + L2: + x -= gridx0; + y -= gridy0; + bq = x * x + y * y; + b = sifsqrt(1.0, bq); + if (b < 5) return 2; + ausgrid(weiss); + gridwx1 = x; + gridwy1 = y; + gridwx2 = -y; + gridwy2 = x; + normgrid(); + ausgrid(schwarz); + strcpy(pr4, " first grid point up?"); + return 3; + L3: + x -= gridx0; + y -= gridy0; + cq = x * x + y * y; + c = sifsqrt(1.0, cq); + if (c < 5) return 3; + dx = gridwx1 * gridw - x; + dy = gridwy1 * gridw - y; + aq = dx * dx + dy * dy; + a = sifsqrt(1.0, aq); + if (a < 5) return 3; + /*Kosinussatz*/ + cosa = (aq - bq - cq) / (2 * b * c); + if (si_fabs(cosa) > 0.98) return 2; + ausgrid(weiss); + gridwx1 *= gridw; + gridwy1 *= gridw; + gridwx2 = x; + gridwy2 = y; + normgrid(); + ausgrid(schwarz); + selmenloeschen(msel); + return 0; +} + + +Static long eincircle(x,y,taste,msel,phase) + long *msel,taste,phase; + double x,y; + /* Eingabe Kreis oder Kreisbogen */ +{ + static long elsel; + long ltyp, ldicke, lende; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + default: goto L3; /* Fuer einarc */ + } + L0: + return 1; + L1: + freieselement(&elsel); + x1[elsel] = x; + y1_[elsel] = y; + strcpy(pr4, pr3menue[*msel]); + return 2; + L2: + laenge1[elsel] = ppabstand(x, y, x1[elsel], y1_[elsel]); + if (laenge1[elsel] < 2.0) laenge1[elsel] = 2.0; + laenge2[elsel] = laenge1[elsel]; + setlineattribute(0L, elsel); + lineende[elsel] = 0; + if ((selmenue[mbogen]!=true)&&(selmenue[mgefuellt]!=true)) { + typ[elsel] = tkreis; + berechneminmax(elsel); + ausel(elsel, paint); + return 0; + } + if ((selmenue[mbogen]!=true)&&(selmenue[mgefuellt]==true)) { + typ[elsel] = tkreisgef; + berechneminmax(elsel); + ausel(elsel, paint); + return 0; + } + phase=phase2; + L3: + phase =einarc(x,y,elsel,taste,phase); + return phase; +} + + +Static boolean relevant(i, xp, yp) +long i; +double xp, yp; +/* Pruefung, ob der Punkt relevant fuer */ +/* die Wahl des Elements i sein kann */ +{ + double xanf, yanf, xend, yend, rmax; + + if (typ[i] <=0) return false; + rmax = 1.05*maxabstand; + xanf=elxmin[i]-rmax; + xend=elxmax[i]+rmax; + yanf=elymin[i]-rmax; + yend=elymax[i]+rmax; + if ((xp >= xanf)&&(xp <= xend)&& + (yp >= yanf)&&(yp <= yend)) return true; + return false; +} + +Static double pkreisabstand(i, xp, yp) +long i; +double xp, yp; +{ double d, dmin; + + dmin= initabstand; + d = si_fabs(ppabstand(x1[i], y1_[i], xp, yp) - laenge1[i]); + if (d < dmin) + dmin = d; + return dmin; +} + +Static double pkreisboabstand(i, xp, yp) +long i; +double xp, yp; +{ + double d, w; + + d = pkreisabstand(i, xp, yp); + if (d>=initabstand) + return d; + w = winkelk(x1[i], y1_[i], xp, yp); + if (inwinkel(i, w)==false) + return initabstand; + return d; +} + +Static double pellabstand(i, xp, yp) +long i; +double xp, yp; +{ + double xell, yell, w, d, dmin; + + dmin= initabstand; + w = winkelell(x1[i], y1_[i], laenge1[i], laenge2[i], crw[i], srw[i], xp, yp); + ellw_xy(x1[i], y1_[i], laenge1[i], laenge2[i], crw[i], srw[i], w, &xell, + &yell); + d = ppabstand(xp, yp, xell, yell); + if (d < dmin) + dmin = d; + return dmin; +} + +Static double pellboabstand(i, xp, yp) +long i; +double xp, yp; +{ + double xell, yell, w, d, dmin; + + dmin= initabstand; + w = winkelell(x1[i], y1_[i], laenge1[i], laenge2[i], crw[i], srw[i], xp, yp); + ellw_xy(x1[i], y1_[i], laenge1[i], laenge2[i], crw[i], srw[i], w, &xell, + &yell); + d = ppabstand(xp, yp, xell, yell); + if (inwinkel(i, w)==false) + return dmin; + if (d < dmin) + dmin = d; + return dmin; +} + +Static double pviereckabstand(i, xp, yp) +long i; +double xp, yp; +{ double d, dmin; + + dmin = pgxyabstand(x1[i], y1_[i], x2[i], y2[i], xp, yp); + d = pgxyabstand(x1[i], y1_[i], xb1[i], yb1[i], xp, yp); + if (d < dmin) + dmin = d; + d = pgxyabstand(xb1[i], yb1[i], x2[i], y2[i], xp, yp); + if (d < dmin) + dmin = d; + d = pgxyabstand(x2[i], y2[i], xb2[i], yb2[i], xp, yp); + if (d < dmin) + dmin = d; + d = pgxyabstand(xb2[i], yb2[i], x1[i], y1_[i], xp, yp); + if (d < dmin) + dmin = d; + return dmin; +} + +Static double pdreieckabstand(i, xp, yp) +long i; +double xp, yp; +{ + double d, dmin; + dmin = pgxyabstand(x1[i], y1_[i], xb1[i], yb1[i], xp, yp); + d = pgxyabstand(xb1[i], yb1[i], x2[i], y2[i], xp, yp); + if (d < dmin) + dmin = d; + d = pgxyabstand(x2[i], y2[i], x1[i], y1_[i], xp, yp); + if (d < dmin) + dmin = d; + return dmin; +} + +Static double abstmod1(d) +double d; +{/* fuer nicht gefuellte Elemente */ + double x, dgrenz; + dgrenz = maxabstand*0.3; + if (d < dgrenz) return d; + x = (d-dgrenz)*2.0+dgrenz; + return x; +} + +Static double abstmod2(d) +double d; +{/* fuer gefuellte Elemente */ + double x, dgrenz; + dgrenz = maxabstand*0.3; + if (d < dgrenz) return (d+2.0); + x = (d-dgrenz)*0.5+dgrenz+2.0; + return x; +} + +Static double abstelement(i, xp, yp) +long i; +double xp, yp; +/* wird nur zur Selektion der Elemente benutzt, deshalb wird der */ +/* berechnete Abstand bei gefuellten Elementen und anderen Elementen */ +/* so modifiziert, dass bei gef. Elemeneten groessere Abstaende noch */ +/* zugelassen sind und kleinere Abstaende erhoeht werden */ +/* In der Naehe eines nichtgefuellten Element wird deshalb diese bevorzugt */ + +{ + double d, d2; + + d = initabstand; + if (typ[i] <= 0) + goto _L1; + if (relevant(i, xp, yp)==false) + goto _L1; + switch (typ[i]) { + + case ttext: + d = ppabstand(x1[i], y1_[i], xp, yp); + goto Lngef; + + case tgerade: + d = pgabstand(i, xp, yp); + goto Lngef; + + case trechteckgef: + case tviereckgef: + d = pviereckabstand(i, xp, yp); + goto Lgef; + + case tdreieckgef: + d = pdreieckabstand(i, xp, yp); + goto Lgef; + + case tkreis: + d = pkreisabstand(i, xp, yp); + goto Lngef; + + case tkreisgef: + d = pkreisabstand(i, xp, yp); + goto Lgef; + + + case tkreisbogen: + d = pkreisboabstand(i, xp, yp); + goto Lngef; + + case tkreissektorgef: + d = pkreisboabstand(i, xp, yp); + d2 = pgxyabstand(x1[i], y1_[i], xb2[i], yb2[i], xp, yp); + if (d2 < d) d = d2; + d2 = pgxyabstand(x1[i], y1_[i], xb1[i], yb1[i], xp, yp); + if (d2 < d) d = d2; + goto Lgef; + + case tell: + d = pellabstand(i, xp, yp); + goto Lngef; + + case tellgef: + d = pellabstand(i, xp, yp); + goto Lgef; + + case tellbogen: + d = pellboabstand(i, xp, yp); + goto Lngef; + + case tellsektorgef: + d = pellboabstand(i, xp, yp); + d2 = pgxyabstand(x1[i], y1_[i], xb2[i], yb2[i], xp, yp); + if (d2 < d) d = d2; + d2 = pgxyabstand(x1[i], y1_[i], xb1[i], yb1[i], xp, yp); + if (d2 < d) d = d2; + goto Lgef; + + case tbezier: + d = pbezabstand(i, xp, yp); + goto Lngef; + case tbeziergef: + d = pbezabstand(i, xp, yp); + d2 = pgxyabstand(x1[i], y1_[i], x2[i], y2[i], xp, yp); + if (d2 < d) d = d2; + goto Lgef; + }/*case*/ +Lgef: + d = abstmod2(d); + return d; +Lngef: + d= abstmod1(d); + return d; +_L1: + return d; +} + + +Static Void sucheelement(art, elsel, xp, yp) +long art, *elsel; +double xp, yp; +{ + double dmin, d; + long i; + + *elsel = 0; + dmin = 5.0*maxabstand; + for (i = 1; i <= zelmax; i++) { + if (typ[i] > 0) { + if (suchtypok[typ[i]][art]=='y') { + d = abstelement(i, xp, yp); + if (d < dmin) { + dmin = d; + *elsel = i; + } + } + } + } +} + +Static boolean blinkgruppeninre(); +Static boolean elementinre(); + +Static boolean blinkelemente(xanf, yanf, xend, yend, elselmin) +double xanf, yanf, xend, yend; +long elselmin; +{/* Alle Elemente/Gruppen im Bereich blink == true */ + /* return true, falls solche vorhanden */ + /* Falls Bereich: nur Elemente >= elselmin beruecksichtigt */ + /* Blinken ist aber noch nicht aktiviert !! */ + long elsel, erg; + + blinkenan(); + blinkend = false; + initgruppentag(false); + if (xanf == xend) { /*selecteinelement*/ + sucheelement((long)alleelem, &elsel, xanf, yanf); + if (elsel == 0) { + return false; + } + if (selmenue[mgroupmode] == false){ + blink[elsel] = true; + return true; + } + blinkgruppe(elsel); + return true; + } + if (selmenue[mgroupmode] == false){ + erg = false; + for (elsel = elselmin; elsel <= zelmax; elsel++) { + if (elementinre(xanf, yanf, xend, yend, elsel)==true) { + blink[elsel] = true; + erg = true; + } + } + return erg; + } + return blinkgruppeninre(xanf, yanf, xend, yend, elselmin); +} + +Static long einellarc(x,y,elsel,taste,phase) + long elsel,phase,taste; + double x,y; +/* Eingabe Ellipsenbogen */ +{ + long i, ltyp, ldicke, lende; + + phase -= phase2; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + } + L0: + strcpy(pr4, pranfwi); + if (selmenue[mdegrees]==true) + inittastaturtext(nullstr,pr2menue[mdegrees],1L); + winerwartet = 1; + return (phase2+1); + L1: + if (taste==0) {/* stringeingabe*/ + i = winkeleingabe(&wanf[elsel]); + if (i != 0) goto L0; + } + else + wanf[elsel] = winkelell(x1[elsel], y1_[elsel], laenge1[elsel], + laenge2[elsel], crw[elsel], srw[elsel], x, y); + L1B: + winerwartet = 1; + strcpy(pr4, prendwi); + if (selmenue[mdegrees]==true) + inittastaturtext(nullstr,pr2menue[mdegrees],1L); + return (phase2+2); + L2: + if (taste==0) {/* stringeingabe*/ + i = winkeleingabe(&wend[elsel]); + if (i != 0) goto L1B; + } + else + wend[elsel] = winkelell(x1[elsel], y1_[elsel], laenge1[elsel], + laenge2[elsel], crw[elsel], srw[elsel], x, y); + winerwartet = 0; + if (si_fabs(wanf[elsel]-wend[elsel])<10) goto L1B; + setlineattribute(0L, elsel); + ellanfendpunkt(elsel); + if (selmenue[mgefuellt]==true) {typ[elsel] = tellsektorgef;} + else typ[elsel] = tellbogen; + berechneminmax(elsel); + ausel(elsel, paint); + if (typ[elsel] != tellsektorgef) return 0; + /* anschliessenden Sektor eingeben, nur Endwinkel */ + /* zunaechst bisherigen Sektor umspeichern */ + freieselement(&i); + kopunv(elsel,i); + typ[elsel] = -1; + wanf[elsel] = wend[elsel]; + strcpy(pr4, prendwisektor); + goto L1B; +} + + +Static long einellipse(x,y,xa,ya,taste,msel,phase) +long *msel,taste,phase; +double x,y,xa,ya; +/* Eingabe Ellipse */ +{ + double xpr_, ypr_; + static long elsel, elselg; + long ltyp, ldicke, lende; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + case 3: goto L3; + case 4: goto L4; + default: goto L5; /* Phasen in einellarc */ + } + L0: + return 1; + L1: + freieselement(&elsel); + x1[elsel] = x; + y1_[elsel] = y; + if (selmenue[mparallel]==true) { + strcpy(pr4, " line, parallel to major axis? "); + return 2; + } + strcpy(pr4, prxachse); + return 3; + L2: + sucheelement((long)nurgerade, &elselg,xa, ya); + if (elselg==0) return 2; + setzewinkel(elsel, x1[elselg], y1_[elselg], x2[elselg], y2[elselg]); + strcpy(pr4, prxachse); + return 3; + L3: + xy_ell(x1[elsel], y1_[elsel], crw[elsel], srw[elsel], x, y, &xpr_, &ypr_); + laenge1[elsel] = si_fabs(xpr_); + if (laenge1[elsel] < dminein) return 3; + strcpy(pr4, pryachse); + return 4; + L4: + xy_ell(x1[elsel], y1_[elsel], crw[elsel], srw[elsel], x, y, &xpr_, &ypr_); + laenge2[elsel] = si_fabs(ypr_); + if (laenge2[elsel] < dminein) return 4; + setlineattribute(0L, elsel); + lineende[elsel] = 0; + if ((selmenue[mbogen]!=true)&&(selmenue[mgefuellt]!=true)) { + typ[elsel] = tell; + berechneminmax(elsel); + ausel(elsel, paint); + return 0; + } + if ((selmenue[mbogen]!=true)&&(selmenue[mgefuellt]==true)) { + typ[elsel] = tellgef; + berechneminmax(elsel); + ausel(elsel, paint); + return 0; + } + phase=phase2; + L5: + return (einellarc(x,y,elsel,taste,phase)); +} + + + +Static long einlinepp(x,y,xa,ya,elsel,taste,msel,phase) + long *msel, elsel,taste,phase; + double x,y,xa,ya; + /* Endpunkt der Strecke durch Punkt gegeben */ +{ + phase -= phase2; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + } + L0: + strcpy(pr4, pr3menue[*msel]); + return (phase2+1); + L1: + x2[elsel]=x; + y2[elsel]=y; + createline(0L, x1[elsel], y1_[elsel], x2[elsel], y2[elsel]); + return 0; +} + + +Static long einlinepg(x,y,xa,ya,elsel,taste,msel,phase) + long *msel, elsel,taste,phase; + double x,y,xa,ya; + /* Endpunkt durch parallele Linie */ +{ + double dx, dy, dxu, dyu; + long i; + phase -= phase2; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + } + L0: + strcpy(pr4, pr2menue[mparallel]); + return (phase2+1); + L1: + x2[elsel]=x; + y2[elsel]=y; + strcpy(pr4, pr3menue[mparallel]); + return (phase2+2); + L2: + sucheelement((long)nurgerade, &i, xa, ya); + if (i==0) return 2; + dx = x2[i] - x1[i]; + dy = y2[i] - y1_[i]; + dxu = x2[elsel] - x1[elsel]; + dyu = y2[elsel] - y1_[elsel]; + if (si_fabs(dx) > si_fabs(dy)) { + if (fsign(dxu)!=fsign(dx)){dx = -dx; dy = -dy;} + } + else { + if (fsign(dyu)!=fsign(dy)){dx = -dx; dy = -dy;} + } + x2[elsel] = x1[elsel] + dx; + y2[elsel] = y1_[elsel] + dy; + createline(0L, x1[elsel], y1_[elsel], x2[elsel], y2[elsel]); + return 0; +} + + +Static long einlinelot(x,y,xa,ya,elsel,taste,msel,phase) + long *msel, elsel,taste,phase; + double x,y,xa,ya; + /* Endpunkt der Geraden durch Lot auf andere Gerade */ +{ + double dx, dy, xs, ys; + long i; + phase -= phase2; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + } + L0: + strcpy(pr4, pr3menue[mlot]); + return (phase2+1); + L1: + sucheelement((long)nurgerade, &i, xa, ya); + if (i==0) return (phase2+1); + dx = x2[i] - x1[i]; + dy = y2[i] - y1_[i]; + if (lot(x1[i], y1_[i], dx, dy, x1[elsel], y1_[elsel], &xs, &ys)==true) + createline(0L, x1[elsel], y1_[elsel], xs, ys); + return 0; +} + + +Static long einline(x,y,xa,ya,taste,msel,phase) + long *msel,taste,phase; + double x,y,xa,ya; +/* Eingabe einer Strecke */ +{ + static long elsel, art; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + default: goto L2; /* fuer einlinelot,einlinepg,einlinepp */ + } + L0: + strcpy(pr4, pr2menue[*msel]); + freieselement(&elsel); + return 1; + L1: + /* erster Punkt */ + x1[elsel]=x; + y1_[elsel]=y; + /*zweiter Punkt */ + art=0; + if (selmenue[mparallel]==true) art=1; + if (selmenue[mlot]==true) art=2; + phase=phase2; + L2: + switch (art){ + case 0: + phase=einlinepp(x,y,xa,ya,elsel,taste,msel,phase); + break; + case 1: + phase=einlinepg(x,y,xa,ya,elsel,taste,msel,phase); + break; + case 2: + phase=einlinelot(x,y,xa,ya,elsel,taste,msel,phase); + break; + } + if (phase!=0) return phase; + return 0; +} /*line*/ + + +Static Void ergbox(el1, el2) +long el1, el2; +{ + long i, j; + double xx[4], yy[4]; + + xx[0] = x1[el1]; + yy[0] = y1_[el1]; + xx[1] = x2[el1]; + yy[1] = y2[el1]; + xx[2] = x1[el2]; + yy[2] = y1_[el2]; + xx[3] = x2[el2]; + yy[3] = y2[el2]; + for (i = 0; i <= 1; i++) { + for (j = 2; j <= 3; j++) { + if (si_fabs(xx[i] - xx[j]) < 5.0 && + si_fabs(yy[i] - yy[j]) < 5.0) + goto _L1; + } + } + goto _L2; +_L1: + if (i == 0) { + ftausch(&xx[0], &xx[1]); + ftausch(&yy[0], &yy[1]); + } + if (j == 3) { + ftausch(&xx[2], &xx[3]); + ftausch(&yy[2], &yy[3]); + } + /* punkte 1 und 2 sind in der Naehe nun*/ + createline(el2, xx[0], yy[0], xx[0] + xx[3] - xx[2], yy[0] + yy[3] - yy[2]); + createline(el1, xx[3], yy[3], xx[3] + xx[0] - xx[1], yy[3] + yy[0] - yy[1]); +_L2: ; +} + +Static long geteingabezeile(datdeskr) +FILE *datdeskr; +{ /* Zeile lesen, Zahl Zeichen zurueck, Grenze maxstrl */ + + long anz; + + if (fgets(eingabezeile,maxstrl+1,datdeskr)==NULL) + anz = 1; + else + anz = strlen(eingabezeile); + anz--; + eingabezeile[anz] = '\0'; + return anz; +} + +Static Void eindateigruppen(datdeskr) +FILE *datdeskr; +{ + long i, erfolg, gruppe, element, vorg; + /* den einzelnen Zeichnungselementen Gruppennummern zuordnen */ + fscanf(datdeskr, "%ld", &gruppe); + while ((gruppe > 0)&&(gruppe <= maxgruppen)) { + fscanf(datdeskr, "%ld", &element); + while ((element > 0)&&(element <= zelmax)) { + if (typ[element]==0) fehler(11); + if (group[element] != 0) fehler(12); + group[element] = gruppe; + fscanf(datdeskr, "%ld", &element); + } + if (element != 0) fehler(12); + fscanf(datdeskr, "%ld", &gruppe); + } + if (gruppe != 0) fehler(13); + /* Gruppenbaum aufbauen */ + fscanf(datdeskr, "%ld%ld", &gruppe, &vorg); + while ((gruppe > 0)&&(gruppe <= maxgruppen)) { + if ((vorg <=0)||(vorg >maxgruppen)) fehler(15); + if (vater[gruppe] != -1) fehler(15); /* Doppeldefinition */ + vater[gruppe] = vorg; + fscanf(datdeskr, "%ld%ld", &gruppe, &vorg); + } + if (gruppe != 0) fehler(14); + /* Baum vervollstaendigen */ + for (i=1;i<=maxgruppen;i++) { + if (vater[i] >0) { + if (vater[vater[i]] == -1) { + /* Gruppennummer noch nicht vergeben */ + vater[vater[i]] = 0; /* ist ein oberster Knoten */ + } + } + } + /* Sicherstellung, dass alle elementaren Gruppen im Baum */ + /* aber auch keine unnoetigen */ + grumax = maxgruppen; + aenderunggruppen = true; + unbenutztegruppenfreigeben(); +} + + +Static long ausdateigruppen() +{ + long i, j, anz, gruppe, element, vorg; + + /* Elemente sind komprimiert!!! */ + for (i=1; i<=zelmax;i++) blink[i] = false; + for (i=1; i<=zelmax;i++) { + if ((blink[i] == false)&&(group[i] !=0)) { + anz = 0; + gruppe = group[i]; + fprintf(datdeskr, "%ld ",gruppe); + for (j=i; j<=zelmax; j++) { + if (group[j]==gruppe) { + blink[j] = true; + anz++; + fprintf(datdeskr, "%ld ",j); + if (anz >10) { + anz = 0; + fprintf(datdeskr, "\n"); + } + }/*if*/ + }/* for j*/ + fprintf(datdeskr, " 0\n"); /* Abschluss einer Gruppe */ + } + }/*for i*/ + fprintf(datdeskr, " 0 \n"); /* Abschluss elementare Gruppen */ + /* Ausgabe der relevanten Teile des Baums */ + for (i=1;i<=grumax;i++) { + if (vater[i] > 0) { + fprintf(datdeskr, "%ld %ld\n", i, vater[i]); + } + } + fprintf(datdeskr, "0 0"); /* Abschluss Knoten-Vater-Paare */ +} + +Static Void einvorspannepc(datdeskr) +FILE *datdeskr; +{ + /* wegen readstdin ist die erste Zeile immer schon gelesen */ + sscanf(eingabezeile, "%*[^123456789]%lg", &version); + geteingabezeile(datdeskr); + sscanf(eingabezeile, "%lg", &texfaktor); + geteingabezeile(datdeskr); + sscanf(eingabezeile, "%lg", &texdashl); + geteingabezeile(datdeskr); + sscanf(eingabezeile, "%lg", &texdotg); + geteingabezeile(datdeskr); + sscanf(eingabezeile, "%lg", &texinterd); + if (version < 4.0) { + geteingabezeile(datdeskr); + sscanf(eingabezeile, "%lg", &gridw0); + } + if (version >= 10.0) { + geteingabezeile(datdeskr); + sscanf(eingabezeile, "%lg%lg%lg%lg%lg%lg%lg%lg", + &gridw0, &gridw, &gridx0, &gridy0, + &gridwx1, &gridwy1, &gridwx2, &gridwy2); + } + if (version >= 11.0) { + geteingabezeile(datdeskr); + sscanf(eingabezeile, "%*lg%*lg%*lg%*lg%*lg%*lg%lg%lg%d%d", + &breite,&hoehe,&mitvorspann,&querformat); + } +} + +Static long einlesenelement(datdeskr,elseladr) +FILE *datdeskr; +long *elseladr; +{ /* auszuwertender String in eingabezeile bereits gelesen !!!! */ + long i,k,anz; + + freieselement(&i); + *elseladr = i; + typ[i]=0; + anz=sscanf(eingabezeile, + "%ld%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%ld%ld%ld%lg%lg%lg", + &typ[i], &x1[i], &y1_[i], &x2[i], &y2[i], &xb1[i], &yb1[i], + &xb2[i], &yb2[i], &wanf[i], &wend[i], &linedicke[i], + &lineende[i], &linetype[i], &laenge1[i], &laenge2[i], &rotwi[i]); + if (typ[i] <= 0) + return anz; + if (rotwi[i] != 0.0) { + crw[i] = cos(rotwi[i] * fgradbo); + srw[i] = sin(rotwi[i] * fgradbo); + } + switch (typ[i]) { + + case tgerade: + laenge1[i] = ppabstand(x1[i], y1_[i], x2[i], y2[i]); + laenge2[i] = laenge1[i]; + break; + + case trechteckgef: + /*setzewinkel(i, x1[i], y1_[i], xb1[i], yb1[i]);*/ + break; + + case tellbogen: + case tellsektorgef: + ellanfendpunkt(i); + break; + + case tkreisbogen: + case tkreissektorgef: + kreisanfendpunkt(i); + break; + + case ttext: + freiestextel(&k); + textno[i] = k; + geteingabezeile(datdeskr); + strcpy(texte[k],eingabezeile); + textparam(i); + break; + }/*case*/ + berechneminmax(i); + return anz; +} + + + +Static long eindatei(msel,dateiname,taste,phase) +Char *dateiname; +long *msel, taste, phase; +{ + long i, k, anz; + double xxmin,xxmax,yymin,yymax; + Static Void init_neuezeichnung(); + +switch (phase) { + case 0: goto L0; + case 1: goto L1; + case 2: goto L1B; + default: goto L1; + } + + L0: + inittastaturtext(dateiname, pr2menue[*msel],0L); + return 1; + L1: + strcpy(dateiname,EinText); + if(istnullstr(dateiname)==true) goto L3; /*ohne Initialisieren*/ + L1B: + /* Einsprung nur fuer automatische Ausgabe */ + datdeskr = fopen(dateiname, "r"); + protokoll("open input file: ",dateiname); + init_neuezeichnung(); /* mit Initialisieren */ + if (datdeskr == NULL) { + protokoll("can't open file ",dateiname); + goto L3; + } + /* wegen readstdin muss die erste Zeile immer schon gelesen sein*/ + geteingabezeile(datdeskr); + einvorspannepc(datdeskr); + + while (1) { + anz = geteingabezeile(datdeskr); + if (anz == 0) + fehler(3L); + anz = einlesenelement(datdeskr,&i); + if (typ[i] <= 0) + goto L2; + } /*while*/ + + L2: /*Ende*/ + if (version >= 13.0) {/* Gruppen sind da!*/ + eindateigruppen(datdeskr); + } + if (version < 11.0) { + minmax(&xxmin,&xxmax,&yymin,&yymax); + breite=(xxmax-xxmin)*texfaktor; + hoehe=(yymax-yymin)*texfaktor; + } + + if (datdeskr != NULL) fclose(datdeskr); + datdeskr = NULL; + L3: + selmenloeschen(msel); + ausalles(); + konkat(winname,window_name,": "); + konkat(winname,winname,dateiname); + XStoreName(display,win,winname); + return 0; +} + +Static double dashlength() +{ + return (texdashl / texfaktor); +} + + +Static double dotgap(i) +{ + if (i==0) return (texdotg / texfaktor); + else return (texdotg*(1+0.15*getlinedicke(i)) / texfaktor); +} + + +Static double interdotgap() +{ + double h; + + h = texinterd / texfaktor; + return h; +} + + +Static Void texpfeilaus(i, ende, xa, ya, dx, dy) +long i, ende; +double xa, ya, dx, dy; +{ + long dxv, dyv; + double w; + + if (lineende[i] == 0) return; + if (lineende[i] == 4) return; + if (ende == 1 && (lineende[i] == 1 || lineende[i] == 3)) { /*am Anfang*/ + w = 2.0 * pi - winkel0(-dx, -dy, 1.0, 1.0) * fgradbo; + fprintf(datdeskr, "\\aLdPfeil{%.3f,%.3f}{%.3f}{%d}\n", + xa, ya, w, getlinedicke(i)); + fputs(einrueck, datdeskr); + } + if (ende == 2 && (lineende[i] == 2 || lineende[i] == 3)) { /*am Ende*/ + w = 2.0 * pi - winkel0(-dx, -dy, 1.0, 1.0) * fgradbo; + fprintf(datdeskr, "\\eLdPfeil{%.3f,%.3f}{%.3f}{%d}\n", + xa, ya, w, getlinedicke(i)); + fputs(einrueck, datdeskr); + } +} + +Static Void texpfeilep(i,xa,ya,xe,ye) +long i; +double xa,ya,xe,ye; /* reduzierte Punkte */ + /*bei tex ging put voraus*/ +{ double x0, y0, x, y, dx, dy; + + x0=x1[i]; + y0=y1_[i]; + x=x0; + y=y0; + dx=xa-x; + dy=ya-y; + texpfeilaus(i, 1L, x-x0, y-y0, dx, dy); + x=x2[i]; + y=y2[i]; + dx=xe-x; + dy=ye-y; + texpfeilaus(i, 2L, x-x0, y-y0, dx, dy); +} + + +Static Void texpfeilew(i,redwa,redwe) +long i; +double redwa,redwe; /* Winkel im Bogenmass fuer reduzierten Bogen */ + /*bei tex ging put und bei Ell. ggf rotiert voraus*/ +{ double lx, ly, w, x, y, dx, dy; + + lx = laenge1[i]; + ly = laenge2[i]; + w = wanf[i] * fgradbo; + x = lx * cos(w); + y = ly * sin(w); + dx = lx * cos(redwa) - x; + dy = ly * sin(redwa) - y; + texpfeilaus(i, 1L, x, y, dx, dy); + w = wend[i] * fgradbo; + x = lx * cos(w); + y = ly * sin(w); + dx = lx * cos(redwe) - x; + dy = ly * sin(redwe) - y; + texpfeilaus(i, 2L, x, y, dx, dy); +} + + +Static double kuerzungsstrecke(elsel) + long elsel; +{ /* Kuerzungsstrecke fuer Pfeile am Ende */ + /* beim Aufrufer umzusetzen in Winkel bzw. Kuerzungsfaktoren */ + double z; + + /*z ist zu kuerzende Strecke in pixels, abhaengig von Formel fuer */ + /*stdpfeile in pst-latexdraw.sty */ + /* Der Faktor 1.5 ergibt sich durch Vergroesserung des Faktors 1.33, */ + /* welcher die x-Koordinate angibt, die beim Pfeil die Breite */ + /* ergibt, die der Linienstaerke der Linie entspricht. Pfeil u.a. */ + /* definiert in pst-latexdraw.sty durch */ + /* (-8,-3) */ + /* (1.33,0.5) */ + /* (-8,0) (1.33,0) (0,0) */ + /*jeweils skaliert mit Faktor f=linienstaerke in pts * 0.27 + 0.4 */ + /* gemaess Makro .... \code{#1 .27 mul .4 add dup scale .... */ + z=(getlinedicke(elsel)*lw2pt*0.27+0.4)*2.0/texfaktor; + return z; +} + + +Static void pfeilreduktiongerade(elsel,xa,ya,xe,ye) + long elsel; + double *xa,*ya,*xe,*ye; +{ /* Verkuerzung der Geraden wegen Pfeilen am Ende */ + double d,z,k,dx,dy; + + z = kuerzungsstrecke(elsel); + d=ppabstand(*xa,*ya,*xe,*ye);/*Laenge der Geraden*/ + if (d<=0.0) d=1.0; + k=z/d; + if (k > 0.5) k = 0.5; + dx = k * (*xe); + dy = k * (*ye); + + switch (lineende[elsel]) { + + case 1: + *xa = dx; + *ya = dy; + break; + + case 2: + *xe -= dx; + *ye -= dy; + break; + + case 3: + *xa = dx; + *ya = dy; + *xe -= dx; + *ye -= dy; + break; + }/*case*/ +} + +Static double kuerzungswinkel(z,a,b,wa,wgr) +double z,a,b,wa,wgr; +/* Bestimmung von dw, um den Bogen bei wa zu kuerzen ist */ +/* alle Winkel im Bogenmass, mathematisch */ +/* wa und wgr begrenzen das sinnvolle Intervall und geben Richtung! */ +{ double xa,ya,dxa,dya,x,y,acw,asw,r,w,dw; + + xa = a*cos(wa); + ya = b*sin(wa); + dxa = a*sin(wa); + dya = b*cos(wa); + r = sqrt(dxa*dxa+dya*dya)+1.0; + dw=z/r*fsign(wgr-wa)*0.05; + w=wa; +LL: + x = a*cos(w); + y = b*sin(w); + if (ppabstand(x,y,xa,ya) >= z) { + dw = w-wa-dw; + return dw; + } + w += dw; + if ( ((dw>0)&&(w<=wgr))||((dw<0)&&(w>=wgr)) ) + goto LL; + dw = w-wa-dw; + return dw; +} + +Static void pfeilreduktionbogen(elsel,redwa,redwe) + long elsel; + double *redwa,*redwe; +{ /* Verkuerzung der Boegen wegen Pfeilen am Ende */ + /* redwa, redwe sind im Bogenmass, mathematisch, redwe > redwa */ + /* redwa, redwe vorbesetzt!!! */ + double mitte, a, b, z, dwa,dwe; + + a = laenge1[elsel]; + b = laenge2[elsel]; + if (*redwe <= *redwa) + *redwe += 2.0*pi; + mitte = (*redwe + *redwa)*0.5; + z = kuerzungsstrecke(elsel); + dwa = kuerzungswinkel(z, a, b, *redwa, mitte); + dwe = kuerzungswinkel(z, a, b, *redwe, mitte); + switch (lineende[elsel]) { + + case 1: + *redwa += dwa; + break; + + case 2: + *redwe += dwe; + break; + + case 3: + *redwa += dwa; + *redwe += dwe; + break; + }/*case*/ +} + +Static Void austexgerade(i) +long i; +{ + double xa, ya, xe, ye, oxe, oye; + + /*relativ zu x1,y1*/ + xa = 0.0; + ya = 0.0; + xe = x2[i] - x1[i]; /*relative Koordinaten*/ + ye = y2[i] - y1_[i]; + oxe=xe; + oye=ye; + putc('{', datdeskr); + if (lineende[i] == 0) { + if (linetype[i]==1) + fprintf(datdeskr, "\\ldline(%.3f,%.3f)(%.3f,%.3f)}\n", + xa, ya, xe, ye); + else + fprintf(datdeskr, "\\ldline[%d](%.3f,%.3f)(%.3f,%.3f)}\n", + linetype[i], xa, ya, xe, ye); + } + else if (lineende[i] == 4) { /* capprojecting */ + if (linetype[i]==1) + fprintf(datdeskr, "\\ldcpline(%.3f,%.3f)(%.3f,%.3f)}\n", + xa, ya, xe, ye); + else + fprintf(datdeskr, "\\ldcpline[%d](%.3f,%.3f)(%.3f,%.3f)}\n", + linetype[i], xa, ya, xe, ye); + } + else { + pfeilreduktiongerade(i,&xa,&ya,&xe,&ye); + texpfeilep(i,xa+x1[i],ya+y1_[i],xe+x1[i],ye+y1_[i]); + /* oxe,oye = Originalkoordinaten Endpunkt nicht verkuerzt */ + fprintf(datdeskr, + "\\LdpLine{%d}{(%.3f,%.3f)}[%d](%.3f,%.3f)(%.3f,%.3f)}\n", + lineende[i], oxe, oye, linetype[i], xa, ya, xe, ye); + /* zweite }, damit put geschlossen wird */ + } +} + +Static double radwinkeltotex(radianw) +double radianw; +{ return (2.0 * pi - radianw); } + +Static double gradwinkeltotex(w) +double w; +{ return (2.0 * pi - w * fgradbo);} + + +Static Void texwinkel(wa,we, texwa, texwe) +double wa, we, *texwa, *texwe; +{ /* Umrechnung math. Darstellung der Winkel in Darstellung in latex */ + /* alle Winkel im Bogenmass */ + *texwa = radwinkeltotex(we); + *texwe = radwinkeltotex(wa); + if (*texwe <= *texwa) + *texwe += 2.0 * pi; +} + + +Static Void austexgefrechteck(i) +long i; +{ + double dx, dy; + + /* put bzgl. x1,y1 ging voraus*/ + dx = ppabstand(x1[i], y1_[i], xb1[i], yb1[i]); + dy = ppabstand(x1[i], y1_[i], xb2[i], yb2[i]); + fprintf(datdeskr, "{\\rule{%.3lf\\unitlength}{%.3lf\\unitlength}}\n", + dx,dy); +} + +Static Void austexgefdreieck(i) +long i; +{ + double x2rel,y2rel, xb1rel, yb1rel; + + /* put bzgl. x1,y1 ging voraus*/ + x2rel = x2[i]-x1[i]; + y2rel = y2[i]-y1_[i]; + xb1rel = xb1[i]-x1[i]; + yb1rel = yb1[i]-y1_[i]; + fprintf(datdeskr, "{\\gefdreieck(%.3lf,%.3lf)(%.3lf,%.3lf)}\n", + x2rel,y2rel,xb1rel,yb1rel); + /* erster und dritter Punkt ist Nullpunkt (d.h. relativ zu put!)*/ +} + +Static Void austexgefviereck(i) +long i; +{ + double x2rel,y2rel, xb1rel, yb1rel, xb2rel, yb2rel; + + /* put bzgl. x1,y1 ging voraus*/ + x2rel = x2[i]-x1[i]; + y2rel = y2[i]-y1_[i]; + xb1rel = xb1[i]-x1[i]; + yb1rel = yb1[i]-y1_[i]; + xb2rel = xb2[i]-x1[i]; + yb2rel = yb2[i]-y1_[i]; + fprintf(datdeskr, "{\\gefviereck(%.3lf,%.3lf)(%.3lf,%.3lf)(%.3lf,%.3lf)}\n", + xb1rel,yb1rel,x2rel,y2rel,xb2rel,yb2rel); + /* erster und vierter Punkt ist Nullpunkt (d.h. relativ zu put!)*/ +} + + +Static Void austexkreis(i) +long i; +{ + double wa, we, redwa, redwe, texwa, texwe, lx, zlx, otexwa,otexwe; + + /* put bzgl. x1,y1 ging voraus*/ + putc('{', datdeskr); + lx = laenge1[i]; + zlx=2.0 * lx; + wa = wanf[i] * fgradbo; + we = wend[i] * fgradbo; + redwa = wa; + redwe = we; + texwinkel(wa, we, &texwa, &texwe); + otexwa = texwa; /*Originalwerte vor Adaption an Pfeile*/ + otexwe = texwe; + + switch (typ[i]) { + + case tkreis: + if (linetype[i]== 1) + fprintf(datdeskr, "\\circle{%.3f}}\n", zlx); + else + fprintf(datdeskr, "\\circle[%d]{%.3f}}\n", linetype[i], zlx); + break; + + case tkreisgef: + fprintf(datdeskr, "\\circle*{%.3f}}\n", zlx); + break; + + case tkreisbogen: + if (lineende[i]==0) { + if (linetype[i]== 1) + fprintf(datdeskr, "\\arc{%.3f}{%.3f}{%.3f}}\n", zlx, texwa, texwe); + else + fprintf(datdeskr, "\\arc[%d]{%.3f}{%.3f}{%.3f}}\n", + linetype[i], zlx, texwa, texwe); + } + else { + pfeilreduktionbogen(i, &redwa, &redwe); + texpfeilew(i,redwa,redwe); + texwinkel(redwa, redwe, &texwa, &texwe); + /* otexwa,otexwe = Originalwerte der Endpunkte */ + fprintf(datdeskr, "\\LdpArc{%d}{%.3f}{%.3f}[%d]{%.3f}{%.3f}{%.3f}}\n", + lineende[i],otexwa,otexwe,linetype[i], zlx, texwa, texwe); + } + break; + + case tkreissektorgef: + wa=0.1*wanf[i]; + we=0.1*wend[i]; + fprintf(datdeskr,"\\pieslice{%.3f}{%.3f}{%.2f}{%.2f}}\n", + zlx,zlx,wa,we); + break; + } +} + +Static Void austexell(i) +long i; +{ + double wa, we, redwa, redwe, texwa, texwe, lx, ly, zlx, zly, otexwa, otexwe; + + /* put bzgl. x1,y1 ging voraus*/ + putc('{', datdeskr); + lx = laenge1[i]; + ly = laenge2[i]; + zlx=2.0 * lx; + zly=2.0 * ly; + wa = wanf[i] * fgradbo; + we = wend[i] * fgradbo; + redwa = wa; + redwe = we; + texwinkel(wa, we, &texwa, &texwe); + otexwa=texwa; + otexwe=texwe; + + switch (typ[i]) { + case tell: + if (linetype[i]== 1) + fprintf(datdeskr, "\\ellipse{%.3f}{%.3f}}\n", zlx, zly); + else + fprintf(datdeskr, "\\ellipse[%d]{%.3f}{%.3f}}\n", + linetype[i], zlx, zly); + break; + case tellgef: + fprintf(datdeskr, "\\ellipse*{%.3f}{%.3f}}\n", zlx, zly); + break; + + case tellbogen: + if (lineende[i]==0) { + if (linetype[i]== 1) + fprintf(datdeskr, "\\ellarc{%.3f}{%.3f}{%.3f}{%.3f}}\n", + zlx, zly,texwa, texwe); + else + fprintf(datdeskr, "\\ellarc[%d]{%.3f}{%.3f}{%.3f}{%.3f}}\n", + linetype[i], zlx, zly, texwa, texwe); + } + else { + pfeilreduktionbogen(i, &redwa,&redwe); + texpfeilew(i,redwa,redwe); + texwinkel(redwa, redwe, &texwa, &texwe); + /* otexwa,otexwe = Originalwerte der Endpunkte */ + fprintf(datdeskr, + "\\LdpEllarc{%d}{%.3f}{%.3f}[%d]{%.3f}{%.3f}{%.3f}{%.3f}}\n", + lineende[i],otexwa,otexwe,linetype[i], zlx, zly, texwa, texwe); + } + break; + + case tellsektorgef: + wa=0.1*wanf[i]; + we=0.1*wend[i]; + fprintf(datdeskr,"\\pieslice{%.3f}{%.3f}{%.2f}{%.2f}}\n", + zlx,zly,wa,we); + break; + } +} + +Static Void pfeilreduktionbezier(elsel,nx0,ny0,nx1,ny1,nx2,ny2,nx3,ny3) +long elsel; +double *nx0,*ny0,*nx1,*ny1,*nx2,*ny2,*nx3,*ny3; +{ double z,d1,d2,t1,t2,dxdt,dydt; + + z = kuerzungsstrecke(elsel); + d1= ppabstand(x1[elsel],y1_[elsel],xb1[elsel],yb1[elsel]); + d2= ppabstand(x2[elsel],y2[elsel],xb2[elsel],yb2[elsel]); + t1= z/(3.0*d1); + t2= 1.0-z/(3.0*d2); + switch (lineende[elsel]) { + + case 1: + t2=1.0; + break; + + case 2: + t1=0.0; + break; + + case 3: + break; + }/*case*/ + punkt_bezier(elsel,t1,nx0,ny0); + ableitung_bezier(elsel,t1,&dxdt,&dydt); + *nx1=dxdt/3.0 + *nx0; + *ny1=dydt/3.0 + *ny0; + punkt_bezier(elsel,t2,nx3,ny3); + ableitung_bezier(elsel,t2,&dxdt,&dydt); + *nx2=-dxdt/3.0 + *nx3; + *ny2=-dydt/3.0 + *ny3; +} + +Static Void austexbezier(i) +long i; +{ double nx0,ny0,nx1,ny1,nx2,ny2,nx3,ny3; + /* neue Werte der Stuetzpunkte wegen Pfeilen*/ + + putc('{', datdeskr); + if (lineende[i]==0) { + if (linetype[i]==1) + fprintf(datdeskr, "\\bezier(%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)}\n", + xb1[i] - x1[i], yb1[i] - y1_[i], + xb2[i] - x1[i], yb2[i] - y1_[i], + x2[i] - x1[i], y2[i] - y1_[i]); + else + fprintf(datdeskr, "\\bezier[%d](%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)}\n", + linetype[i], xb1[i] - x1[i], yb1[i] - y1_[i], + xb2[i] - x1[i], yb2[i] - y1_[i], + x2[i] - x1[i], y2[i] - y1_[i]); + } + else { + pfeilreduktionbezier(i,&nx0,&ny0,&nx1,&ny1,&nx2,&ny2,&nx3,&ny3); + texpfeilep(i,nx0,ny0,nx3,ny3); + /*zunaechst Originalstuetzpunkte, dann neue Stuetzpunkte wegen Pfeilen */ + fprintf(datdeskr, "\\LdpBezier{%d}(%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)[%d](%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)}\n", + lineende[i], xb1[i] - x1[i], yb1[i] - y1_[i], + xb2[i] - x1[i], yb2[i] - y1_[i], + x2[i] - x1[i], y2[i] - y1_[i], + linetype[i], nx0 - x1[i], ny0 - y1_[i], + nx1 - x1[i], ny1 - y1_[i], + nx2 - x1[i], ny2 - y1_[i], + nx3 - x1[i], ny3 - y1_[i]); + } +} + + +Static Void austexbeziergef(i) +long i; +{ + + putc('{', datdeskr); + fprintf(datdeskr, "\\beziergef(%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)}\n", + xb1[i] - x1[i], yb1[i] - y1_[i], + xb2[i] - x1[i], yb2[i] - y1_[i], + x2[i] - x1[i], y2[i] - y1_[i]); +} + + +Static Void austextext(i) +long i; +{ + long lage, fontart; + fontart = linetype[i]; + lage = (long)floor(laenge2[i] + 0.5); + fprintf(datdeskr, "{\\makebox(0,0)%s{%s%s}}\n", + textausrichtung[lage],textfontmakro[fontart],texte[textno[i]]); +} + + +Static Void austexelement(i, xmin, ymin) +long i; +double xmin, ymin; +{ + double rrot, xa, ya; + long zcolor; + + zcolor=getzcolor(i,paint); + rrot = 2.0 * pi - rotwi[i] * fgradbo; + xa = x1[i] - xmin; + ya = y1_[i] - ymin; + if (rotwi[i] == 0.0) { + if (zcolor==schwarz) fprintf(datdeskr, "\\put(%.3f,%.3f)",xa,ya); + else fprintf(datdeskr, "\\putc(%.3f,%.3f){%d}", xa, ya, zcolor); + } + else { + if (zcolor==schwarz) + fprintf(datdeskr, "\\rput[%.3f](%.3f,%.3f)", rrot,xa,ya); + else + fprintf(datdeskr, "\\rputc[%.3f](%.3f,%.3f){%d}", rrot,xa,ya,zcolor); + } + + switch (typ[i]) { /*case*/ + + case ttext: + austextext(i); + break; + + case tgerade: + austexgerade(i); + break; + + case trechteckgef: + austexgefviereck(i); + break; + + case tdreieckgef: + austexgefdreieck(i); + break; + + case tviereckgef: + austexgefviereck(i); + break; + + case tkreis: + case tkreisgef: + case tkreisbogen: + case tkreissektorgef: + austexkreis(i); + break; + + case tell: + case tellgef: + case tellbogen: + case tellsektorgef: + austexell(i); + break; + + case tbezier: + austexbezier(i); + break; + case tbeziergef: + austexbeziergef(i); + break; + } +} + + +Static Void auslinedicke(istdicke,solldicke) +long *istdicke,solldicke; +{ + double ptdicke; + if (*istdicke != solldicke) + { *istdicke=solldicke; + ptdicke=lw2pt*solldicke; + fprintf(datdeskr,"\\ldlinewidth{%d}{%.1lf}\n",solldicke,ptdicke); + } +} + + +Static long austexdatei(msel, dateiname, taste, phase) +Char *dateiname; +long *msel,taste, phase; + +{ + long i, akttexldicke; + double deltax, deltay, xxmax, yymax, xxmin, yymin; + double fx, fy; + Char altbh[maxstrl+1]; + + LANF: + switch (phase) { + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + case 3: goto L3; + case 4: goto L4; + case 5: goto L5; + case 6: goto L6; + case 7: goto L7; + } + L0: + strcpy(texdateiname,dateiname); + trenneextension(texdateiname); + konkat(texdateiname,texdateiname,".tex"); + inittastaturtext(texdateiname,pr3menue[*msel],0L); + return 1; + L1: + strcpy(texdateiname,EinText); + if (istnullstr(texdateiname)==true) return 0; + inittastaturtext(nullstr, + "change output options ? (y/...)",0L); + return 2; + L2: + if (*EinText!='y') goto L7; + inittastaturtext(nullstr, + "LaTeX file ready to copy into LaTeX source ? (y/...)",0L); + return 3; + L3: + nmitvorspann=true; + if (*EinText=='y') nmitvorspann=false; + inittastaturtext(nullstr, "use old unitlength ? (y/...)",0L); + return 4; + L4: + oldunitlength=false; + if (*EinText=='y') { + nbreite=breite; + nhoehe=hoehe; + oldunitlength=true; + goto L5B; + } + L4B: + sprintf(altbh,"%.1f %.1f",breite,hoehe); + inittastaturtext(altbh, + "maximum width and height of LaTeX picture in mm? (DIN A4:210 296): ",0L); + return 5; + L5: + i=sscanf(EinText,"%lg%lg",&nbreite,&nhoehe); + if ((i!=2)||(nbreite<10.0)||(nhoehe<10.0)) goto L4B; + L5B: + inittastaturtext(nullstr,"rotate LaTeX picture? (y/...)",0L); + return 6; + L6: + /*Aenderungen erst durchfuehren, wenn Ausgabe wirklich erfolgt*/ + querformat=true; + if (*EinText=='y') querformat=false; + mitvorspann=nmitvorspann; + hoehe=nhoehe; + breite=nbreite; + if (oldunitlength==false) { + minmax(&xxmin, &xxmax, &yymin, &yymax); + deltax = xxmax - xxmin; + if (deltax == 0.0) deltax = 1.0; + deltay = yymax - yymin; + if (deltay == 0.0) deltay = 1.0; + fx = breite / deltax; + fy = hoehe / deltay; + if (fx <= fy) + texfaktor = fx; + else + texfaktor = fy; + } + + L7: + minmax(&xxmin, &xxmax, &yymin, &yymax); + deltax = xxmax - xxmin; + if (deltax == 0.0) deltax = 1.0; + deltay = yymax - yymin; + if (deltay == 0.0) deltay = 1.0; + datdeskr = fopen(texdateiname, "w"); + protokoll(extfiletext,texdateiname); + if (datdeskr == NULL) { + protokoll("can't open file ",texdateiname); + return 0; + } + if (mitvorspann==true) { + fprintf(datdeskr, + "%s\n",docstyle); + fprintf(datdeskr, "\\begin{document}\n"); + } + + fprintf(datdeskr, "\\setlength{\\unitlength}{%.3lfmm}\n",texfaktor); + if (querformat==false) { + fprintf(datdeskr, "\\begin{picture}(%.3f,%.3f)\n", deltay,deltax); + fprintf(datdeskr, "\\rput[4.7124](%.3f,0){\n", deltay); + } + fprintf(datdeskr, "\\begin{picture}(%.3f,%.3f)\n", deltax,deltay); + akttexldicke = -1; + for (i = 1; i <= zelmax; i++) { + if (typ[i] > 0) { + auslinedicke(&akttexldicke,getlinedicke(i)); + austexelement(i, xxmin, yymin); + } + } + fprintf(datdeskr, "\\end{picture}\n"); + if (querformat==false) + fprintf(datdeskr, "}\\end{picture}\n"); + if (mitvorspann==true) { + fprintf(datdeskr, "\\end{document}\n"); + } + fprintf(datdeskr, "%s\n", blank); + if (datdeskr != NULL) + fclose(datdeskr); + datdeskr = NULL; + return 0; +} + + +Static Void ausskalieren() +{ + double xmin, ymin, xmax, ymax, dx, dy, fx, fy, f; + + minmax(&xmin, &xmax, &ymin, &ymax); + dx = xmax - xmin; + dy = ymax - ymin; + fx = 1.0; + fy = 1.0; + if (dx != 0.0) { + if (dx < 0.5 * xzmax) + fx = 0.5 * xzmax / dx; + if (dx > 4.0 * xzmax) + fx = 4.0 * xzmax / dx; + } + if (dy != 0.0) { + if (dy < 0.5 * yzmax) + fy = 0.5 * yzmax / dy; + if (dy > 4.0 * yzmax) + fy = 4.0 * yzmax / dy; + } + if (fx > fy) + f = fy; + else + f = fx; + pskalieren(&xmin, &ymin, 0.0, 0.0, f); + pskalieren(&xmax, &ymax, 0.0, 0.0, f); + dx = xmittelzei - (xmax + xmin) * 0.5; + dy = ymittelzei - (ymax + ymin) * 0.5; + elskalieren(&gridw, dx, dy, f); +} + +Static long schreibenausdatei(msel,dateiname,taste,phase) +Char *dateiname; +long *msel,taste,phase; +{ + long i; + double xxmin, xxmax, yymin, yymax, dxpixel, dypixel; + + if (istnullstr(dateiname) == true) return 0; + datdeskr = fopen(dateiname, "w"); + if (datdeskr == NULL) { + protokoll("can't open file ",dateiname); + return 0; + } + + kompakt(); + protokoll(intfiletext,dateiname); + minmax(&xxmin, &xxmax, &yymin, &yymax); + dxpixel=xxmax-xxmin; + dypixel=yymax-yymin; + fprintf(datdeskr, "%s\n", window_name); + fprintf(datdeskr, "% .5E (TEXFAKTOR)\n", texfaktor); + fprintf(datdeskr, "% .5E (TEXDASHLAENGE)\n", texdashl); + fprintf(datdeskr, "% .5E (TEXDOTGAP)\n", texdotg); + fprintf(datdeskr, "% .5E (TEXINTERDOTGAP)\n", texinterd); + fprintf(datdeskr, "%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f (GITTERWERTE)\n", + gridw0, gridw, gridx0, gridy0, + gridwx1, gridwy1, gridwx2, gridwy2); + fprintf(datdeskr, + "%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %d %d (AUSGABEOPTIONEN)\n", + xxmin, yymin, xxmax, yymax, dxpixel, dypixel, + breite, hoehe, mitvorspann, querformat); + for (i = 1; i <= zelmax; i++) { + if (typ[i] > 0) { + fprintf(datdeskr, + "%ld %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %ld %ld %ld %.3lf %.3lf %.3lf\n", + typ[i],x1[i],y1_[i],x2[i],y2[i],xb1[i],yb1[i],xb2[i], yb2[i], + wanf[i],wend[i],linedicke[i],lineende[i],linetype[i], + laenge1[i],laenge2[i],rotwi[i]); + if (typ[i] == ttext) /*text*/ + fprintf(datdeskr, "%s\n", texte[textno[i]]); + } + } + fprintf(datdeskr,"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"); + ausdateigruppen(); + if (datdeskr != NULL) fclose(datdeskr); + datdeskr = NULL; + return 0; +} + + +Static long ausdatei(msel,dateiname,taste,phase) +Char *dateiname; +long *msel,taste,phase; +{ + long i; + + switch(phase) { + case 0: goto L0; + default: goto L1; + } + + L0: + inittastaturtext(dateiname,pr2menue[*msel],0L); + return 1; + L1: + strcpy(dateiname,EinText); + return schreibenausdatei(msel,dateiname,taste,phase); +} + +Static long extendline(elsel, xa, ya) +long elsel; +double xa, ya; +{ + double deltax, deltay, d1, d2, f, dx, dy; + dx = x2[elsel] - x1[elsel]; + dy = y2[elsel] - y1_[elsel]; + d1 = ppabstand(xa, ya, x1[elsel], y1_[elsel]); + d2 = ppabstand(xa, ya, x2[elsel], y2[elsel]); + deltax = 0.0; + deltay = 0.0; + f = dx * dx + dy * dy; + f = verlline / sifsqrt(1.0, f); + deltax = dx * f; + deltay = dy * f; + if (d2 < d1) { /*verl bei x2,y2*/ + x2[elsel] += deltax; + y2[elsel] += deltay; + } else { /*verl bei x1,y1*/ + x1[elsel] -= deltax; + y1_[elsel] -= deltay; + } +} + +Static long extendbogen(elsel, xa, ya) +long elsel; +double xa, ya; +{ + double wa, we, wi; + + wa = wanf[elsel]; + we = wend[elsel]; + if (we < wa) we += wg; + switch (typ[elsel]) { + case tkreisbogen: + case tkreissektorgef: + wi = winkelk(x1[elsel], y1_[elsel], xa, ya); + break; + case tellsektorgef: + case tellbogen: + wi = winkelell(x1[elsel], y1_[elsel], laenge1[elsel], + laenge2[elsel], crw[elsel], srw[elsel], xa, ya); + break; + } + if (!((wi >= wa) && (wi <= we))) wi += wg; + if (si_fabs(wi-wa) < si_fabs(wi-we)) { /* wa ausdehnen */ + wa -= 150.0; + } else {/* we ausdehnen */ + we += 150.0; + } + if ((we-wa) >= wg) {/* voller Kreis bzw. volle Ellipse */ + wanf[elsel] = 0.0; + wend[elsel] = wg; + switch (typ[elsel]) { + case tkreisbogen: + typ[elsel] = tkreis; + break; + case tkreissektorgef: + typ[elsel] =tkreisgef; + break; + case tellsektorgef: + typ[elsel] =tellgef; + break; + case tellbogen: + typ[elsel] =tell; + break; + } + return; + } + /* Bogen bleibt */ + while (wa > wg) wa -= wg; + while (we > wg) we -= wg; + while (wa < 0.0) wa += wg; + while (we < 0.0) we += wg; + wanf[elsel] = wa; + wend[elsel] = we; + switch (typ[elsel]) { + case tkreisbogen: + case tkreissektorgef: + kreisanfendpunkt(elsel);wi = winkelk(x1[elsel], y1_[elsel], xa, ya); + break; + case tellsektorgef: + case tellbogen: + ellanfendpunkt(elsel); + break; + } +} + +Static long extend(xa, ya, msel, phase) +long *msel,phase; +double xa, ya; +{ + long elsel; + double deltax, deltay, d1, d2, f, dx, dy; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + } + L0: + return 1; + L1: + sucheelement((long)nurextendel, &elsel, xa, ya); + if (elsel==0) return 1; + ausel(elsel, erase); + switch (typ[elsel]) { + case tgerade: + extendline(elsel, xa, ya); + break; + case tkreisbogen: + case tkreissektorgef: + case tellsektorgef: + case tellbogen: + extendbogen(elsel, xa, ya); + break; + } + berechneminmax(elsel); + auselemente(); + return 1; +} + + +Static long einbox(x,y,taste,msel,phase) + long *msel,taste,phase; + double x,y; +{ + static long elsel; + double dx, dy; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + } + L0: + return 1; + L1: + freieselement(&elsel); + x1[elsel]=x; + y1_[elsel]=y; + strcpy(pr4, pr3menue[*msel]); + return 2; + L2: + x2[elsel]=x; + y2[elsel]=y; + dx = x2[elsel] - x1[elsel]; + dy = y2[elsel] - y1_[elsel]; + if (si_fabs(dx) < 2.0 || si_fabs(dy) < 2.0) return 2; + if (dx < 0) { + dx = -dx; + ftausch(&x1[elsel], &x2[elsel]); + } + if (dy < 0) { + dy = -dy; + ftausch(&y1_[elsel], &y2[elsel]); + } + xb1[elsel] = x1[elsel] + dx; + yb1[elsel] = y1_[elsel]; + xb2[elsel] = x1[elsel]; + yb2[elsel] = y1_[elsel] + dy; + if (selmenue[mgefuellt]==true) { /*gefuelltes Rechteck*/ + typ[elsel] = trechteckgef; + setlineattribute(0L, elsel); + berechneminmax(elsel); + ausel(elsel, paint); + return 0; + } + createline(0L, x1[elsel], y1_[elsel], xb1[elsel], yb1[elsel]); + createline(0L, xb1[elsel], yb1[elsel], x2[elsel], y2[elsel]); + createline(0L, x2[elsel], y2[elsel], xb2[elsel], yb2[elsel]); + createline(0L, xb2[elsel], yb2[elsel], x1[elsel], y1_[elsel]); + typ[elsel] = 0; + return 0; +} + + +Static long einboxll(xa,ya,msel,phase) + long *msel,phase; + double xa, ya; +/* Ergaenzung zum Parallelogramm */ +{ + static long elsel1, elsel2; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + } + L0: + strcpy(pr4, pr2menue[*msel]); + return 1; + L1: + sucheelement((long)nurgerade, &elsel1, xa, ya); + if (elsel1==0) return 1; + strcpy(pr4, pr3menue[*msel]); + return 2; + L2: + sucheelement((long)nurgerade, &elsel2, xa, ya); + if (elsel2==0) return 2; + ergbox(elsel1, elsel2); + return 0; +} + +Static long eindreieck(x,y,taste,msel,phase) + long *msel,taste,phase; + double x,y; +{ + static long elsel; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + case 3: goto L3; + } + L0: + return 1; + L1: + freieselement(&elsel); + x1[elsel]=x; + y1_[elsel]=y; + strcpy(pr4, pr3menue[*msel]); + return 2; + L2: + x2[elsel]=x; + y2[elsel]=y; + if (ppabstand(x2[elsel], y2[elsel],x1[elsel],y1_[elsel]) < 3.0) + return 2; + strcpy(pr4,prpoint3); + return 3; + L3: + xb1[elsel]=x; + yb1[elsel]=y; + if (ppabstand(xb1[elsel], yb1[elsel],x1[elsel],y1_[elsel]) < 3.0) + return 3; + if (ppabstand(xb1[elsel], yb1[elsel],x2[elsel],y2[elsel]) < 3.0) + return 3; + if (selmenue[mgefuellt]==true) { /*gefuelltes Dreieck*/ + typ[elsel] = tdreieckgef; + setlineattribute(0L, elsel); + berechneminmax(elsel); + ausel(elsel, paint); + return 0; + } + createline(0L, x1[elsel], y1_[elsel], xb1[elsel], yb1[elsel]); + createline(0L, xb1[elsel], yb1[elsel], x2[elsel], y2[elsel]); + createline(0L, x2[elsel], y2[elsel], x1[elsel], y1_[elsel]); + typ[elsel] = 0; + return 0; +} + +Static long einviereck(x,y,taste,msel,phase) + long *msel,taste,phase; + double x,y; +{ + static long elsel; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + case 3: goto L3; + case 4: goto L4; + } + L0: + return 1; + L1: + freieselement(&elsel); + x1[elsel]=x; + y1_[elsel]=y; + strcpy(pr4, pr3menue[*msel]); + return 2; + L2: + xb1[elsel]=x; + yb1[elsel]=y; + if (ppabstand(xb1[elsel], yb1[elsel],x1[elsel],y1_[elsel]) < 3.0) + return 2; + strcpy(pr4,prpoint3); + return 3; + L3: + x2[elsel]=x; + y2[elsel]=y; + if (ppabstand(x2[elsel], y2[elsel],xb1[elsel],yb1[elsel]) < 3.0) + return 3; + if (ppabstand(x2[elsel], y2[elsel],x1[elsel],y1_[elsel]) < 3.0) + return 3; + strcpy(pr4,prpoint4); + return 4; + L4: + xb2[elsel]=x; + yb2[elsel]=y; + if (ppabstand(xb2[elsel], yb2[elsel],x1[elsel],y1_[elsel]) < 3.0) + return 4; + if (ppabstand(xb2[elsel], yb2[elsel],xb1[elsel],yb1[elsel]) < 3.0) + return 4; + if (ppabstand(xb2[elsel], yb2[elsel],x2[elsel],y2[elsel]) < 3.0) + return 4; + if (selmenue[mgefuellt]==true) { /*gefuelltes Viereck*/ + typ[elsel] = tviereckgef; + setlineattribute(0L, elsel); + berechneminmax(elsel); + ausel(elsel, paint); + return 0; + } + createline(0L, x1[elsel], y1_[elsel], xb1[elsel], yb1[elsel]); + createline(0L, xb1[elsel], yb1[elsel], x2[elsel], y2[elsel]); + createline(0L, x2[elsel], y2[elsel], xb2[elsel], yb2[elsel]); + createline(0L, xb2[elsel], yb2[elsel], x1[elsel], y1_[elsel]); + typ[elsel] = 0; + return 0; +} + +Static Void setlagetext(elsel) + long elsel; +{ /* Lage Text relativ zum Anklickpunkt bestimmen und alle davon */ + /* abhaengigen Parameter im Zeichnungselement setzen */ + long lrtb; + + lrtb = 1; + if (selmenue[mbtext]==true) + lrtb = 3; + if (selmenue[mttext]==true) + lrtb = 6; + if (selmenue[mltext]==true) { + lrtb = 7; + if (selmenue[mbtext]==true) + lrtb = 0; + if (selmenue[mttext]==true) + lrtb = 4; + } + if (selmenue[mrtext]==true) { + lrtb = 8; + if (selmenue[mbtext]==true) + lrtb = 2; + if (selmenue[mttext]==true) + lrtb = 5; + } + laenge2[elsel] = lrtb; + textparam(elsel); + berechneminmax(elsel); +} + + +Static long eintext(x,y,xa,ya,taste,msel,phase) + long *msel,taste,phase; + double x,y,xa,ya; +{ + static long elsel, tsel; + long elselg; + double dx,dy; + + switch (phase) + { + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + case 3: goto L3; + case 4: goto L4; + case 5: goto L5; + default: goto L6; /*fuer Textzeichen */ + } + + L0: + texterase=0L; + return 1; + L1: + for (elsel = 1; elsel <= zelmax; elsel++) { + if (typ[elsel] != ttext) continue; + if (si_fabs(y1_[elsel] - y) > 0.5) continue; + if (si_fabs(x1[elsel] - x) > 0.5) continue; + tsel = textno[elsel]; + ausel(elsel, erase); + texterase=elsel; + zeichnen = true; + setzeakttextfont(elsel); + goto L5; /*Text zu modifizieren*/ + } + texterase=0L; + freieselement(&elsel); + freiestextel(&tsel); + x1[elsel] = x; + y1_[elsel] = y; + if (selmenue[mparallel]==false) goto L4; + strcpy(pr4, pr2menue[mparallel]); + return 2; + L2: + x2[elsel] = xa; + y2[elsel] = ya; + strcpy(pr4, pr3menue[mparallel]); + return 3; + L3: + sucheelement((long)nurgerade, &elselg, xa, ya); + if (elselg==0) return 3; + strcpy(pr4,pr2menue[*msel]); + dx = si_fabs(x2[elselg] - x1[elselg]); + if ((x2[elsel] - x1[elsel]) < 0.0) dx = -dx; + dy = si_fabs(y2[elselg] - y1_[elselg]); + if ((y2[elsel] - y1_[elsel]) < 0.0) dy = - dy; + x2[elsel] = x1[elsel] + dx; + y2[elsel] = y1_[elsel] + dy; + setzewinkel(elsel, x1[elsel], y1_[elsel], x2[elsel], y2[elsel]); + L4: + setlineattribute(0L,elsel); + linetype[elsel] = stdfontnummer; + textno[elsel] = tsel; + strcpy(texte[tsel],nullstr); + L5: + inittastaturtext(texte[tsel], "text: ",0L); + return 6; + L6: + strcpy(texte[tsel], EinText); + if (istnullstr(texte[tsel]) == true) { + typ[elsel] = 0; + texterase=0L; + return 0; + } + typ[elsel] = ttext; + if (fontnummer != stdfontnummer) + linetype[elsel] = fontnummer; + setlagetext(elsel); + texterase=0L; + ausel(elsel, paint); + return 0; +} + +Static Void initelemente() +{ + long i; + + for (i = 0; i <= zel; i++) { + typ[i] = 0; /*Element frei*/ + textno[i] = 0; + } + for (i = 1; i <= zstr; i++) + strcpy(texte[i],nullstr); + zelmax = 0; +} + + +Static Void drehpunkt(x1r, y1r, dx, dy, cd, sd, v, xp, yp) +double x1r, y1r, dx, dy, cd, sd, v, *xp, *yp; +{ + double xx, yy; + + /*Drehpunkt x1r,y1r*/ + /*positiver Drehwinkel def. durch cd,sd*/ + /*Vergroesserung v*/ + /*Translation um dx,dy*/ + translation(x1r, y1r, *xp, *yp, &xx, &yy); + xx *= v; + yy *= v; + rotation(cd, -sd, &xx, &yy); + translation(-dx, -dy, xx, yy, xp, yp); +} + + +Static Void drehpunkt1(i, x1r, y1r, dx, dy, cd, sd, v) +long i; +double x1r, y1r, dx, dy, cd, sd, v; +{ + drehpunkt(x1r, y1r, dx, dy, cd, sd, v, &x1[i], &y1_[i]); +} + + +Static Void drehpunkt2(i, x1r, y1r, dx, dy, cd, sd, v) +long i; +double x1r, y1r, dx, dy, cd, sd, v; +{ + drehpunkt(x1r, y1r, dx, dy, cd, sd, v, &x2[i], &y2[i]); +} + + +Static Void drehpunktb(i, x1r, y1r, dx, dy, cd, sd, v) +long i; +double x1r, y1r, dx, dy, cd, sd, v; +{ + drehpunkt(x1r, y1r, dx, dy, cd, sd, v, &xb1[i], &yb1[i]); + drehpunkt(x1r, y1r, dx, dy, cd, sd, v, &xb2[i], &yb2[i]); +} + + +Static Void drehell0(i, xr1, yr1, dx, dy, cd, sd, v) +long i; +double xr1, yr1, dx, dy, cd, sd, v; +{ + double xl, yl, lx, ly; + + lx = laenge1[i]; + ly = laenge2[i]; + ell_xy(x1[i], y1_[i], lx, ly, crw[i], srw[i], lx, 0.0, &xl, &yl); + drehpunkt(xr1, yr1, dx, dy, cd, sd, v, &xl, &yl); + drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v); + laenge1[i] = lx * v; + laenge2[i] = ly * v; + setzewinkel(i, x1[i], y1_[i], xl, yl); +} + + +Static Void drehell(i, xr1, yr1, dx, dy, cd, sd, v) +long i; +double xr1, yr1, dx, dy, cd, sd, v; +{ + drehell0(i, xr1, yr1, dx, dy, cd, sd, v); +} + + +Static Void drehellbogen(i, xr1, yr1, dx, dy, cd, sd, v) +long i; +double xr1, yr1, dx, dy, cd, sd, v; +{ + double xm, ym, lx, ly, cr, sr; + + drehpunktb(i, xr1, yr1, dx, dy, cd, sd, v); + drehell0(i, xr1, yr1, dx, dy, cd, sd, v); + ellpar(i, &xm, &ym, &lx, &ly, &cr, &sr); + wanf[i] = winkelell(xm, ym, lx, ly, cr, sr, xb1[i], yb1[i]); + wend[i] = winkelell(xm, ym, lx, ly, cr, sr, xb2[i], yb2[i]); + ellanfendpunkt(i); +} + + +Static Void drehkbogen(i, xr1, yr1, dx, dy, cd, sd, v) +long i; +double xr1, yr1, dx, dy, cd, sd, v; +{ + drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v); + drehpunktb(i, xr1, yr1, dx, dy, cd, sd, v); + laenge1[i] *= v; + laenge2[i] *= v; + wanf[i] = winkelk(x1[i], y1_[i], xb1[i], yb1[i]); + wend[i] = winkelk(x1[i], y1_[i], xb2[i], yb2[i]); +} + + +Static boolean testnotin(x, y, xa, ya, xe, ye) +double x, y, xa, ya, xe, ye; +{ + boolean Result; + + Result = true; + if (xa > xe) ftausch(&xa,&xe); + if (x < xa) goto _L1; + if (x > xe) goto _L1; + if (ya > ye) ftausch(&ya,&ye); + if (y < ya) goto _L1; + if (y > ye) goto _L1; + Result = false; +_L1: + return Result; +} + +Static boolean schnittellgeradeda(elsel,xa,ya,xe,ye) +long elsel; +double xa,ya,xe,ye; +{ + long i, anz; + double w; + terg wgerade, well; + Static Void gell00schnittp(); + + gell00schnittp(xa,ya,xe,ye,elsel,&anz,wgerade,well,false); + if (anz==0) return false; + for (i = 1; i <= anz; i++) { + if ((wgerade[i]>=0.0)&&(wgerade[i] <= 1.0)) return true; + } + return false; +} + +Static boolean elementinre(xa, ya, xe, ye, i) +double xa, ya, xe, ye; +long i; +{ + boolean Result; + + if (typ[i] <= 0) + return false; + if (xa > xe) ftausch(&xa,&xe); + if (ya > ye) ftausch(&ya,&ye); + if ((elxmin[i] >= xa)&&(elxmax[i] <= xe)&& + (elymin[i] >= ya)&&(elymax[i] <= ye)) + return true; + return false; +} + + +Static boolean blinkgruppeninre(xa,ya,xe,ye,elselmin) +double xa,ya,xe,ye; +long elselmin; +{ /* Gruppen im Rechteck, aber erst ab elselmin beachtet */ + /* Nur neu selektierte Elemente: blink == true */ + /* Nur neu selektierte Gruppen : gruppentag == true */ + long i,j,g, etwasgetan, anz; + + /* blinkenan(); schon gegeben in blinkelemente !! */ + /* blinkend = false; schon gegeben in blinkelemente !! */ + initgruppentag(unbekannt); + anz = 0; + for (i=elselmin;i<=zelmax;i++) { + if (typ[i]>0) { + g = group[i]; + if (g==0) { + if (elementinre(xa, ya, xe, ye, i)==true) { + anz++; + blink[i] = true; + } + continue; + } + if (gruppentag[g] == false) + continue; + /* gruppentag unbekannt oder true */ + if (elementinre(xa, ya, xe, ye, i)==true) { + gruppentag[g] = true; + } + else + markteilbaum(g,false); + } + } + /* jetzt Gruppenbaum untersuchen */ + etwasgetan = true; + while (etwasgetan == true) { + etwasgetan = false; + for (i=1;i<=grumax;i++) { + if ( (gruppentag[i] == unbekannt)|| + (gruppentag[i] == true) ) { + j = 1; + while ( (g=sohn(j,i)) != 0) {/* j. Sohn von i untersuchen */ + j++; + if (gruppentag[g] == true) + continue; + if (gruppentag[g] == unbekannt) + break; + if (gruppentag[g] == false) { + markteilbaum(i, false); + etwasgetan = true; + break; + } + } + if (g==0) { /* Schleife normal zu Ende, alle Soehne true */ + if (gruppentag[i] != true) { + gruppentag[i] = true; + etwasgetan = true; + } + } + }/* end if unbekannt */ + }/*end Durchlauf durch Gruppen */ + }/*solange etwas getan */ + /* Alle Gruppen muessten jetzt bekannt sein, kein Test dafuer! */ + /* Elemente nur in Rechteck, wenn Gruppe in Rechteck */ + for (i=elselmin;i<=zelmax;i++) { + if (typ[i]>0) { + g = group[i]; + if ((g != 0) && (gruppentag[g] == true)) { + anz++; + blink[i] = true; + } + } + } + if (anz > 0) return true; + blinkenaus(); + return false; +} + +Static boolean zukleineselement(i) +long i; +{/*Pruefung, ob Element i zu klein beim kopieren */ + + double minabm; + minabm = 0.1; + + if (typ[i] <= 0) + return true; + switch (typ[i]) { + case ttext: /*Text*/ + return false; + + case tgerade: /*Gerade*/ + if (ppabstand(x1[i], y1_[i], x2[i], y2[i]) < minabm) + goto zuklein; + break; + + case trechteckgef: + case tviereckgef: + if (ppabstand(x1[i], y1_[i], x2[i], y2[i]) < minabm) + goto zuklein; + break; + + case tdreieckgef: + if (ppabstand(x1[i], y1_[i], x2[i], y2[i]) < minabm) + goto zuklein; + break; + + case tkreis: + case tkreisgef: /*Kreis*/ + if (laenge1[i] < minabm) + goto zuklein; + break; + + case tkreisbogen: /*Kreisbogen*/ + case tkreissektorgef: + if (laenge1[i] < minabm) + goto zuklein; + break; + + case tell: + case tellgef: /*Ellipse*/ + if ((laenge1[i] < minabm) ||(laenge2[i] < minabm)) + goto zuklein; + break; + + case tellbogen: /*Ellipsenbogen*/ + case tellsektorgef: + if ((laenge1[i] < minabm)|| (laenge2[i] < minabm)) + goto zuklein; + break; + + case tbezier: /*Bezier*/ + case tbeziergef: + if (ppabstand(x1[i], y1_[i], xb1[i], yb1[i]) < minabm) + goto zuklein; + if (ppabstand(x2[i], y2[i], xb2[i], yb2[i]) < minabm) + goto zuklein; + break; + }/*case*/ + return false; + /* zu klein */ + zuklein: + typ[i] = 0; + return true; +} + + +Static long duplikat0(i,vollst) +long i; +boolean vollst; +{/* Nummer j eines Zeichnungselements ist Ergebnis */ + /* falls j != 0 ist j ein vorhandenes Duplikat zu i */ + /* falls vollst == false werden */ + /* lineende[i], linedicke[i], linetype[i] nicht beruecksichtigt */ + + long j; + + for (j = 1; j <= zelmax; j++) { + if (typ[j] <= 0) + continue; + if ((typ[i] != typ[j]) || (i == j)) + continue; + if (group[i] != group[j]) + continue; + if (nglx(x1[i], x1[j])== false) + continue; + if (nglx(y1_[i], y1_[j])== false) + continue; + if (nglw(rotwi[i], rotwi[j])==false) + continue; + if (vollst == true) { + if (lineende[i] != lineende[j]) + continue; + if (linedicke[i] != linedicke[j]) + continue; + if (linetype[i] != linetype[j]) + continue; + } + switch (typ[i]) { + + case ttext: /*Text*/ + if (strvergl(texte[textno[i]], texte[textno[j]])==true) + goto gleich; + break; + + case tgerade: /*Gerade*/ + if (nglx(x2[i], x2[j])==false) + continue; + if (nglx(y2[i], y2[j])==false) + continue; + goto gleich; + + case trechteckgef: + case tviereckgef: + if (nglx(x2[i], x2[j])==false) + continue; + if (nglx(y2[i], y2[j])==false) + continue; + if (nglx(xb1[i], xb1[j])==false) + continue; + if (nglx(yb1[i], yb1[j])==false) + continue; + if (nglx(xb2[i], xb2[j])==false) + continue; + if (nglx(yb2[i], yb2[j])==false) + continue; + goto gleich; + + case tdreieckgef: + if (nglx(x2[i], x2[j])==false) + continue; + if (nglx(y2[i], y2[j])==false) + continue; + if (nglx(xb1[i], xb1[j])==false) + continue; + if (nglx(yb1[i], yb1[j])==false) + continue; + goto gleich; + + case tkreis: + case tkreisgef: /*Kreis*/ + if (nglx(laenge1[i], laenge1[j])==false) + continue; + goto gleich; + + case tkreisbogen: /*Kreisbogen*/ + case tkreissektorgef: + if (nglx(laenge1[i], laenge1[j])==false) + continue; + if (nglw(wanf[i], wanf[j])==false) + continue; + if (nglw(wend[i], wend[j])==false) + continue; + goto gleich; + + case tell: + case tellgef: /*Ellipse*/ + if (nglx(laenge1[i], laenge1[j])==false) + continue; + if (nglx(laenge2[i], laenge2[j])==false) + continue; + goto gleich; + + case tellbogen: /*Ellipsenbogen*/ + case tellsektorgef: + if (nglx(laenge1[i], laenge1[j])==false) + continue; + if (nglx(laenge2[i], laenge2[j])==false) + continue; + if (nglw(wanf[i], wanf[j])==false) + continue; + if (nglw(wend[i], wend[j])==false) + continue; + goto gleich; + + case tbezier: /*Bezier*/ + case tbeziergef: + if (nglx(x2[i], x2[j])==false) + continue; + if (nglx(y2[i], y2[j])==false) + continue; + if (nglx(xb1[i], xb1[j])==false) + continue; + if (nglx(yb1[i], yb1[j])==false) + continue; + if (nglx(xb2[i], xb2[j])==false) + continue; + if (nglx(yb2[i], yb2[j])==false) + continue; + goto gleich; + }/*case*/ + } /*for j*/ + /*keine Duplikate*/ + return 0; +gleich: /* Duplikat */ + return j; +} + +Static boolean duplikat(i) +long i; +{/* zu kleine Abmessungen oder volles Duplikat */ + long j; + + if (zukleineselement(i)==true) + return true; + if ( (j=duplikat0(i,true))==0) + return false; + loescheelement(i); + return true; +} + +Static Void kopeinel(elsel, xr1, yr1, dx, dy, v, cd, sd, kop, loeschen) +long elsel; +double xr1, yr1, dx, dy, v, cd, sd; +boolean kop; long loeschen; +{ + long i; + + if (kop==true) { /*kopieren*/ + freieselement(&i); + kopunv(elsel, i); + } else { /*verschieben*/ + i = elsel; + if (loeschen==1) ausel(i, erase); + zeichnen = true; + } + switch (typ[i]) { + + case ttext: /*Text*/ + drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v); + drehpunkt2(i, xr1, yr1, dx, dy, cd, sd, v); + drehpunktb(i, xr1, yr1, dx, dy, cd, sd, v); + setzewinkel(i, xb1[i], yb1[i], xb2[i], yb2[i]); + textparam(i); + break; + + case tgerade: + drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v); + drehpunkt2(i, xr1, yr1, dx, dy, cd, sd, v); + break; + + case trechteckgef: + drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v); + drehpunkt2(i, xr1, yr1, dx, dy, cd, sd, v); + drehpunktb(i, xr1, yr1, dx, dy, cd, sd, v); + /*setzewinkel(i, x1[i], y1_[i], xb1[i], yb1[i]);*/ + break; + + case tdreieckgef: + case tviereckgef: + drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v); + drehpunkt2(i, xr1, yr1, dx, dy, cd, sd, v); + drehpunktb(i, xr1, yr1, dx, dy, cd, sd, v); + break; + + case tkreis: + case tkreisgef: + drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v); + laenge1[i] *= v; + laenge2[i] *= v; + break; + + case tkreisbogen: + case tkreissektorgef: + drehkbogen(i, xr1, yr1, dx, dy, cd, sd, v); + break; + + case tell: + case tellgef: + drehell(i, xr1, yr1, dx, dy, cd, sd, v); + break; + + case tellbogen: + case tellsektorgef: + drehellbogen(i, xr1, yr1, dx, dy, cd, sd, v); + break; + + case tbezier: + case tbeziergef: + drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v); + drehpunkt2(i, xr1, yr1, dx, dy, cd, sd, v); + drehpunktb(i, xr1, yr1, dx, dy, cd, sd, v); + break; + }/*case*/ + if (kop==true) { /*kopieren*/ + bestimmeneuegruppe(i); + if (duplikat(i)==false) { + berechneminmax(i); + ausel(i, paint); + } + } + else /*verschieben*/ + berechneminmax(i); + ausel(i, paint); +} + + +Static boolean testkop(elsel, relsel, zelsel, kop) +long elsel, relsel, zelsel; +boolean kop; +{ + if (kop==true) /*Referenzstrecke und Zielstrecke mitkopieren*/ + return (elsel != 0); + else /*Referenzstrecke und Zielstrecke nicht verschieben*/ + if (elsel != 0 && elsel != zelsel && elsel != relsel) return true; + else return false; +} + + +Static Void kopel(xanf, yanf, xend, yend, xr1, yr1, dx, dy, v, cd, sd, msel, + kop, relsel, zelsel) +double xanf, yanf, xend, yend, xr1, yr1, dx, dy, v, cd, sd; +long *msel; +boolean kop; +long relsel, zelsel; +{ + long elsel,elselmin,zelmaxalt; + + elselmin = 1; + while (blinkelemente(xanf, yanf, xend, yend,elselmin) == true) { + if (kop == true) + gruppenumbenennen(); + zelmaxalt = zelmax; + for (elsel=elselmin;elsel <= zelmaxalt; elsel++) { + if (blink[elsel] == true) { + if (testkop(elsel, relsel, zelsel, kop)==true) { + kopeinel(elsel, xr1, yr1, dx, dy, v, cd, sd, kop, 1L); + } + } + } + unbenutztegruppenfreigeben(); + if (xanf == xend) { /*Ein Element angeklickt*/ + blinkenaus(); + return; + } + /* Auswahlrechteck, evtl. neue Elemente darin */ + elselmin = zelmaxalt+1; + if (tastegedrueckt()!=0) return; + } /*while */ +} + + +Static long abbundkopieren(x,y,xanf,yanf,xend,yend,taste,msel,phase,kop) +long *msel,phase,taste; +double x,y,xanf,yanf,xend,yend; +boolean kop; +{ + static long relsel, zelsel; + double x1r, y1r, x1z, y1z, dx, dy, dr, dz, v, cr, sr, cz, sz, cd, sd; + + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + case 3: goto L3; + } + L0: + /* kompakt(); */ + strcpy(pr4, pr2menue[*msel]); + return 1; + L1: + sucheelement((long)nurgerade, &relsel, xanf, yanf); + if (relsel==0) return 1; + dr = ppabstand(x1[relsel], y1_[relsel], x2[relsel], y2[relsel]); + if (dr == 0.0) return 1; + strcpy(pr4, pr3menue[*msel]); + return 2; + L2: + sucheelement((long)nurgerade, &zelsel, xanf, yanf); + if (zelsel==0) return 2; + dz = ppabstand(x1[zelsel], y1_[zelsel], x2[zelsel], y2[zelsel]); + if (dz == 0.0) return 2; + strcpy(pr4," object(s)?"); + return 3; + L3: + x1r = x1[relsel]; + y1r = y1_[relsel]; + x1z = x1[zelsel]; + y1z = y1_[zelsel]; + dx = x2[zelsel] - x1[zelsel]; + dy = y2[zelsel] - y1_[zelsel]; + dz = ppabstand(x1[zelsel], y1_[zelsel], x2[zelsel], y2[zelsel]); + dr = ppabstand(x1[relsel], y1_[relsel], x2[relsel], y2[relsel]); + v = dz / dr; + cz = dx / dz; + sz = dy / dz; + dx = x2[relsel] - x1[relsel]; + dy = y2[relsel] - y1_[relsel]; + cr = dx / dr; + sr = dy / dr; + addtheorem(cz, sz, cr, -sr, &cd, &sd); /*wz-wr*/ + kopel(xanf, yanf, xend, yend, x1r, y1r, x1z, y1z, v, cd, sd, msel, kop, + relsel, zelsel); + return 3; +} + +Static long translundkopieren(x,y,xanf,yanf,xend,yend,taste,msel,phase,kop) +long *msel,phase,taste; +double x,y,xanf,yanf,xend,yend; +boolean kop; +{ + long i, elsel; + static long relsel; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + case 3: goto L3; + } + L0: + freieselement(&relsel); + strcpy(pr4," object(s)?"); + return 1; + L1: + if (blinkelemente(xanf,yanf,xend,yend,1L) == false) + return 1; + blinkend = true; + if (xanf == xend) {/* ein Element war selektiert */ + x1[relsel] = x; + y1_[relsel] = y; + strcpy(pr4, pr3menue[mkopbewmaus]); + return 3; + } + /* Auswahlrechteck war gegeben */ + strcpy(pr4, pr2menue[mkopbewmaus]); + return 2; + L2: + /*Referenzpunkt angeben*/ + x1[relsel] = x; + y1_[relsel] = y; + strcpy(pr4, pr3menue[mkopbewmaus]); + return 3; + L3: + if (kop==true) + gruppenumbenennen(); + /*Zielpunkt angeben*/ + for (elsel = 1; elsel <= zelmax; elsel++) { + if (blink[elsel] == true) + kopeinel(elsel, x1[relsel], y1_[relsel], x, y, 1.0, 1.0, 0.0, kop,1L); + } + if (kop==true) + return 3; + strcpy(pr4," object(s)?"); + blinkenaus(); + return 1; +} + + +Static long kopieren(x,y,xa,ya,xe,ye,taste,msel,phase) +long *msel,phase,taste; +double x,y,xa,xe,ya,ye; +{ + if (selmenue[mkopbewmaus]==true) + phase=translundkopieren(x,y,xa,ya,xe,ye,taste,msel,phase,true); + else + phase=abbundkopieren(x,y,xa,ya,xe,ye,taste,msel,phase,true); + return phase; +} + + +Static long bewegen(x,y,xa,ya,xe,ye,taste,msel,phase) +long *msel,phase,taste; +double x,y,xa,xe,ya,ye; +{ + if (selmenue[mkopbewmaus]==true) + phase=translundkopieren(x,y,xa,ya,xe,ye,taste,msel,phase,false); + else + phase=abbundkopieren(x,y,xa,ya,xe,ye,taste,msel,phase,false); + return phase; +} + +Static long rotieren(x,y,xanf,yanf,xend,yend,taste,msel,phase) +long *msel,phase,taste; +double x,y,xanf,yanf,xend,yend; +/* Rotation ein Objekt, eine Gruppe um den Anklickpunkt*/ +{ + double xr,yr,xz,yz,v,cd,sd,wi; + long elsel, elselmin; + boolean kop; + static boolean auswrechteck; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + } + L0: + auswrechteck = false; + return 1; + L1: + if (blinkelemente(xanf,yanf,xend,yend,1L) == false) + return 1; + blinkend = true; + if (xanf == xend) /* ein Element war selektiert */ + goto L2; + /* Auswahlrechteck war gegeben, Drehpunkt abfragen */ + auswrechteck = true; + strcpy(pr4, pr3menue[mrot]); + return 2; + L2: + /*Drehpunkt jetzt bekannt*/ + v = 1.0; + xr = x; + yr = y; + xz = xr; + yz = yr; + wi= winkelrotate; + wi = wi*pi/180.0; + cd = cos(wi); + sd = sin(wi); + kop = false; + for (elsel=1;elsel <= zelmax; elsel++) { + if (blink[elsel] == true) { + kopeinel(elsel, xr, yr, xz, yz, v, cd, sd, kop, 1L); + } + } + if (auswrechteck == false) { + /* kein Auswahlrechteck, neue Objekte selektieren */ + strcpy(pr4,pr2menue[mrot]); + blinkenaus(); + return 1; + } + /* Auswahlrechteck vorhanden, neue Drehung?? */ + return 2; +} + +Static long vorber_export(x,y,xa,ya,xe,ye,taste,msel,phase) +long *msel,phase,taste; +double x,y,xa,xe,ya,ye; +{ + long i, elsel; + static long kmark, relsel; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + } + L0: + XSetSelectionOwner(display,latexdraw_selection,win,requesttime); + if (XGetSelectionOwner(display,latexdraw_selection) != win) + { protokoll("XGetSelectionOwner"," failed"); return 0;} + freieselement(&relsel); + wartendexport = true; + kmark = 0; /*kmark, keine Objekte definiert */ + export_relsel = relsel; + export_kmark = kmark; + strcpy(pr4, pr2menue[mcut]); + return 1; + L1: + /*Referenzpunkt angeben*/ + x1[relsel] = x; + y1_[relsel] = y; + x2[relsel] = x; + y2[relsel] = y; + strcpy(pr4," object(s)?"); + return 2; + L2: + strcpy(pr4," object(s)?"); + if (blinkelemente(xa,ya,xe,ye,1L)== false){ + if (kmark==0) + return 2; + } + else { + /* Elemente in der bisherigen Sequenz muessen unveraendert bleiben */ + for (elsel = 1; elsel <= zelmax; elsel++) { + if (blink[elsel] == true) { + /* schon vorhanden ? */ + for (i=1;i <=kmark;i++) { + if (sequenz[i] == elsel) + goto LL; + } + kmark++; + sequenz[kmark] = elsel; + } + LL:; + } /*for*/ + } + blinkend = true; + /*alle Blinkelemente wieder setzen */ + for (i=1;i <= kmark;i++) + blink[sequenz[i]] = true; + export_kmark = kmark; + return 2; +} + +Static Void event_senden(r) +long r; +{ XEvent sendevent; + sendevent.xselection.type=selnotify[r].type; + sendevent.xselection.requestor=selnotify[r].requestor; + sendevent.xselection.selection=selnotify[r].selection; + sendevent.xselection.target=selnotify[r].target; + sendevent.xselection.property=selnotify[r].property; + sendevent.xselection.time=selnotify[r].time; + +XSendEvent(display,selnotify[r].requestor,True,NoEventMask, + &sendevent); +} + +Static Void exportieren() +{ long r, kakt,relsel,i,kmark,ls1,ls2; + char s1[255],s2[255]; + + if (selmenue[mcut]==false){ /* nichts geht mehr zurueck */ + for (r=0;r<zrequw;r++) { + if (requestaktiv[r]==true && requestbelegt[r]==true){ + selnotify[r].property=None; + event_senden(r); + } + requestbelegt[r]=false; + } + wartendexport=false; + return; + } + + relsel=export_relsel; /* von vorber_export */ + kmark=export_kmark; /* von vorber_export */ + /* wenn nichts da, dann bleibt Wunsch stehen. Durch zyklischen Aufruf + in der Eventschleife werden alle Objekt gesendet, die bereits + definiert sind oder noch definiert werden */ + for (r=0;r<zrequw;r++) { + if (requestaktiv[r]==true && requestbelegt[r]==true){ + kakt=requestkakt[r]; + if (kakt < kmark) { /* ewas zu senden da */ + requestaktiv[r]=false; + requestkakt[r] += 1; + kakt++; + i = sequenz[kakt]; + sprintf(s1, +"%.3lf %.3lf %.3lf %.3lf %ld %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %ld %ld %ld %.3lf %.3lf %.3lf\n", + x1[relsel],y1_[relsel],x2[relsel],y2[relsel], + typ[i],x1[i],y1_[i],x2[i],y2[i],xb1[i],yb1[i],xb2[i], yb2[i], + wanf[i],wend[i],linedicke[i],lineende[i],linetype[i], + laenge1[i],laenge2[i],rotwi[i]); + ls1=strlen(s1); + XChangeProperty(display,selnotify[r].requestor,latexdraw_object, + latexdraw_object,8,PropModeReplace,s1,ls1); + if (typ[i] == ttext) { /*text*/ + sprintf(s2, "%s\n", texte[textno[i]]); + ls2=strlen(s2); + XChangeProperty(display,selnotify[r].requestor,latexdraw_text, + latexdraw_text,8,PropModeReplace,s2,ls2); + } + event_senden(r); + } /*if kakt < kmark */ + } /* if requestaktiv */ + }/* for r*/ +} + + +Static Void request_export(xsrrequestor,xsrproperty,xsrtarget,xsrtime) +Window xsrrequestor; +Atom xsrproperty,xsrtarget; +Time xsrtime; +{ /* Aufruf durch SelectionRequest */ + long r; + + /* gibt es noch alten request von dem requestor, dann nehmen */ + for (r=0;r<zrequw;r++) { + if (requestbelegt[r]==true) { + if (xsrrequestor == selnotify[r].requestor) { + if (xsrtime > selnotify[r].time) goto L0; + goto L1; + } + } + } + + /* Neueintrag in offene Requests */ + for (r=0;r<zrequw;r++) { + if (requestbelegt[r]==false) goto L0;} + protokoll("too many requests:", "request ignored"); + return; + + L0: + requestbelegt[r]=true; + requestkakt[r]=0; + L1: + requestaktiv[r]=true; + selnotify[r].type=SelectionNotify; + selnotify[r].requestor=xsrrequestor; + selnotify[r].selection=latexdraw_selection; + selnotify[r].target=xsrtarget; + selnotify[r].property=xsrproperty; + selnotify[r].time=xsrtime; + exportieren(); +} + + +Static long vorber_import(x,y,taste,msel,phase) +long *msel,phase,taste; +double x,y; +{ + long i, kmark, elsel; + static long zelsel; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + } + L0: + requesttime=lasteventtime; + freieselement(&zelsel); + import_zelsel=zelsel; + strcpy(pr4, pr2menue[mpaste]); + return 1; + L1: + /*Zielpunkt angeben*/ + x1[zelsel] = x; + y1_[zelsel] = y; + x2[zelsel] = x; + y2[zelsel] = y; + strcpy(pr4, " select objects in other window"); + /* SelectionRequest beim anderen Fenster */ + XConvertSelection(display,latexdraw_selection,latexdraw_object, + latexdraw_object, win, requesttime); + L2: + return 2; +} + +Static Void deleteprop() +{ XDeleteProperty(display,win, latexdraw_object); + XDeleteProperty(display,win, latexdraw_text); +} + +Static Void importieren(xsnproperty, xsntime, msel) +Atom xsnproperty; Time xsntime; long *msel; +{ /* Aufruf durch SelectionNotify */ + long zelsel, i, k, ls1, ls2, bytesafter,anz; + Atom actualtype; + double xr1,yr1,xr2,yr2; + unsigned char *data; + int actualformat; + + if (xsnproperty==None){ + if (requesttime != xsntime) return; + if (selmenue[mpaste]==false) return; + selmenloeschen(msel); + return; + } + if (selmenue[mpaste]==false) {deleteprop(); return;} + if (requesttime != xsntime) {deleteprop(); return;} + zelsel=import_zelsel; /* von Vorbereiten import */ + XGetWindowProperty(display, win, latexdraw_object,0,70,True, + latexdraw_object,&actualtype, &actualformat, + &ls1, &bytesafter,&data); + freieselement(&i); + anz=sscanf(data, + "%lg%lg%lg%lg%ld%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%ld%ld%ld%lg%lg%lg", + &xr1,&yr1,&xr2,&yr2, + &typ[i], &x1[i], &y1_[i], &x2[i], &y2[i], &xb1[i], &yb1[i], + &xb2[i], &yb2[i], &wanf[i], &wend[i], &linedicke[i], + &lineende[i], &linetype[i], &laenge1[i], &laenge2[i], &rotwi[i]); + XFree(data); + if ((typ[i] <= 0)|| (anz != 21)) {typ[i]=0; goto L0;} + if (rotwi[i] != 0.0) { + crw[i] = cos(rotwi[i] * fgradbo); + srw[i] = sin(rotwi[i] * fgradbo); + } + switch (typ[i]) { + + case tgerade: + laenge1[i] = ppabstand(x1[i], y1_[i], x2[i], y2[i]); + laenge2[i] = laenge1[i]; + break; + + case trechteckgef: + /*setzewinkel(i, x1[i], y1_[i], xb1[i], yb1[i]);*/ + break; + + case tellbogen: + case tellsektorgef: + ellanfendpunkt(i); + break; + + case tkreisbogen: + case tkreissektorgef: + kreisanfendpunkt(i); + break; + + case ttext: + freiestextel(&k); + textno[i] = k; + XGetWindowProperty(display, win, latexdraw_text,0,70,True, + latexdraw_text,&actualtype, &actualformat, + &ls2, &bytesafter,&data); + strcpy(texte[k],data); + XFree(data); + textparam(i); + break; + }/*case*/ + kopeinel(i, xr1,yr1,x1[zelsel], y1_[zelsel], 1.0, 1.0, 0.0,false,0L); + duplikat(i); + L0: + deleteprop(); + /* neuen Request vorsichtshalber absetzen */ + XConvertSelection(display,latexdraw_selection,latexdraw_object, + latexdraw_object, win, requesttime); +} + + +Static Void eldelete(elsel) +long elsel; +{ + ausel(elsel, erase); + typ[elsel] = -typ[elsel]; +} + + +Static Void UnDelete() +{ + long i, phase; + + for (i = 1; i <= zelmax; i++) { + if (typ[i] < -1) { + typ[i] = -typ[i]; + } /*if*/ + } + auselemente(); +} + + +Static long loeschen(xanf,yanf,xend,yend,taste,msel,phase) + long *msel,phase,taste; + double xanf,yanf,xend,yend; +{ + long elsel; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + } + L0: + strcpy(pr4, " UNDO = backspace oder delete oder undo"); + return 1; + L1: + if (blinkelemente(xanf,yanf,xend,yend,1L)== false) + return 1; + for (elsel = 1; elsel <= zelmax; elsel++) { + if (blink[elsel] == true) { + if (group[elsel] != 0) + aenderunggruppen = true; + eldelete(elsel); + } + } + auselemente (); + return 1; +} /*loeschen*/ + + +Static Void vorbsortieren() +/* Vorbereiten Sortieren der Zeichnungselemente */ +/* sequenz enthaelt Sortierreihenfolge */ +/* Vorbereiten = jetzige Reihenfolge */ +{long i; + for (i=1; i<= zelmax; i++) { + if (typ[i] !=0) sequenz[i]=i; + else sequenz[i]= 3*zelmax; + } +} + +Static Void sortieren() +/* Sortieren der Zeichnungselemente gemaess sequenzwert */ +{ long i,j,temp; + if (typ[zel]!=0) fehler(10L); /*letztes Element muesste frei sein ! */ + temp=zel; + /* nur im Bereich belegte Elemente sortieren */ + for (i=1;i<=zelmax;i++) { + for (j=zelmax;j>i;j--) { + if (sequenz[j] < sequenz[i]) { + kopunvotext(i,temp); + kopunvotext(j,i); + kopunvotext(temp,j); + } + } + } + typ[temp]=0; +} + +Static long up(xanf,yanf,xend,yend,taste,msel,phase) + long *msel,phase,taste; + double xanf,yanf,xend,yend; +{/* Elemente in Vordergrund bringen */ + long elsel, maxnr; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + } + L0: + return 1; + L1: + maxnr = zelmax; + if (blinkelemente(xanf,yanf,xend,yend,1L)== false) + return; + vorbsortieren(); + for (elsel=zelmax; elsel >= 1; elsel--) { + if (blink[elsel] == true ) + sequenz[elsel] = ++maxnr; + } + sortieren(); + auselemente(); + return 1; +} /*end up*/ + + +Static long down(xanf,yanf,xend,yend,taste,msel,phase) + long *msel,phase,taste; + double xanf,yanf,xend,yend; +{/* Elemente in Vordergrund bringen */ + long elsel, maxnr; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + } + L0: + return 1; + L1: + maxnr = -zelmax-1; + if (blinkelemente(xanf,yanf,xend,yend,1L)== false) + return; + vorbsortieren(); + for (elsel=1;elsel<=zelmax; elsel++) { + if (blink[elsel] ==true) + sequenz[elsel] = ++maxnr; + } + sortieren(); + auselemente(); + return 1; +} /*end up*/ + +Static Void elchangelineattr(elsel) +long elsel; +{ long ltyp1, ldicke1, lende1, lcolor1; + long ltyp2, ldicke2, lende2, lcolor2; + getlineattribute(elsel, typ[elsel], <yp1, &ldicke1, &lende1, &lcolor1); + ausel(elsel, erase); + getlineattribute(0L, typ[elsel], <yp2, &ldicke2, &lende2, &lcolor2); + if (changelende == true) + lineende[elsel] = lende2; + if ((changelstyle == true)&&(typ[elsel] != ttext)) + linetype[elsel] = ltyp2; + if (changelwidth == true) + ldicke1 = ldicke2; + if (changecolor == true) + lcolor1 = lcolor2; + linedicke[elsel] = 100*lcolor1+ldicke1; + if ((typ[elsel] == ttext)&&(changefont == true)) { + linetype[elsel] = fontnummer; + textparam(elsel); + berechneminmax(elsel); + } + if ((typ[elsel] == ttext)&&(changeposition == true)) + setlagetext(elsel); + zeichnen = true; +} + +Static long changelineattr(xanf,yanf,xend,yend,taste,msel,phase) + long *msel,phase,taste; + double xanf,yanf,xend,yend; +{/* Farbe Elemente veraendern*/ + long elsel; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + } + L0: + /* nur aendern, falls nach chatt entspr. Element angeklickt wurde*/ + changelende = false; + changelstyle = false; + changelwidth = false; + changecolor = false; + changefont = false; + changeposition = false; + return 1; + L1: + if (blinkelemente(xanf,yanf,xend,yend,1L)==false) + return 1; + for (elsel=1; elsel <= zelmax; elsel++) { + if (blink[elsel] == true) + elchangelineattr(elsel); + } /*for elsel*/ + auselemente(); + return 1; +} /*end changelineattr*/ + +Static long queryattr(xanf,yanf,taste,msel,phase) + long *msel,phase,taste; + double xanf,yanf; +{/* Farbe eines Elements erfragen und einstellen */ + long elsel, ltyp, lende; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + } + L0: + return 1; + L1: + if (blinkelemente(xanf,yanf,xend,yend,1L)== true) { + for (elsel=1;elsel<=zelmax; elsel++) { + if (blink[elsel] ==true){ + getlineattribute(elsel, typ[elsel], <yp, &aktldicke, &lende, + &aktcolor); + strichsymbol(); + ausmenueelement(mdick); + colorsymbol(); + ausmenueelement(mcolor); + if (typ[elsel]==ttext) + setzeakttextfont(elsel); + return 1; + } + } + } + return 1; +} /*end welchefarbe*/ + + + + +Static Void spgp(xg, yg, dx, dy, xp, yp) +double xg, yg, dx, dy, *xp, *yp; +{ + double xs, ys; + boolean g; + + /*Geradendefinition durch xg,yg,dx,dy*/ + g = lot(xg, yg, dx, dy, *xp, *yp, &xs, &ys); + *xp += 2.0 * (xs - *xp); + *yp += 2.0 * (ys - *yp); +} + + +Static Void spg1(i, xg, yg, dx, dy) +long i; +double xg, yg, dx, dy; +{ + spgp(xg, yg, dx, dy, &x1[i], &y1_[i]); +} + + +Static Void spg2(i, xg, yg, dx, dy) +long i; +double xg, yg, dx, dy; +{ + spgp(xg, yg, dx, dy, &x2[i], &y2[i]); +} + + +Static Void spgb(i, xg, yg, dx, dy) +long i; +double xg, yg, dx, dy; +{ + spgp(xg, yg, dx, dy, &xb1[i], &yb1[i]); + spgp(xg, yg, dx, dy, &xb2[i], &yb2[i]); +} + + +Static Void spgell0(i, xg, yg, dx, dy) +long i; +double xg, yg, dx, dy; +{ + double xl, yl, lx, ly; + + lx = laenge1[i]; + ly = laenge2[i]; + ell_xy(x1[i], y1_[i], lx, ly, crw[i], srw[i], lx, 0.0, &xl, &yl); + spgp(xg, yg, dx, dy, &xl, &yl); + /*gespiegelter Endpunkt x_Achse der Ellipse*/ + spg1(i, xg, yg, dx, dy); + setzewinkel(i, x1[i], y1_[i], xl, yl); +} + + +Static Void spgell(i, xg, yg, dx, dy) +long i; +double xg, yg, dx, dy; +{ + spgell0(i, xg, yg, dx, dy); +} + + +Static Void spgellbogen(i, xg, yg, dx, dy) +long i; +double xg, yg, dx, dy; +{ + double xm, ym, lx, ly, cr, sr; + + lx = laenge1[i]; + ly = laenge2[i]; + ftausch(&xb1[i], &xb2[i]); + ftausch(&yb1[i], &yb2[i]); + spgb(i, xg, yg, dx, dy); + spgell0(i, xg, yg, dx, dy); + xm = x1[i]; + ym = y1_[i]; + cr = crw[i]; + sr = srw[i]; + wanf[i] = winkelell(xm, ym, lx, ly, cr, sr, xb1[i], yb1[i]); + wend[i] = winkelell(xm, ym, lx, ly, cr, sr, xb2[i], yb2[i]); + ellanfendpunkt(i); +} + + +Static Void spgkbogen(i, xg, yg, dx, dy) +long i; +double xg, yg, dx, dy; +{ + ftausch(&xb1[i], &xb2[i]); + ftausch(&yb1[i], &yb2[i]); + spgb(i, xg, yg, dx, dy); + spg1(i, xg, yg, dx, dy); + wanf[i] = winkelk(x1[i], y1_[i], xb1[i], yb1[i]); + wend[i] = winkelk(x1[i], y1_[i], xb2[i], yb2[i]); +} + + +Static Void einelspiegeln(elsel, xg, yg, dx, dy) +long elsel; +double xg, yg, dx, dy; +{ + long i; + + freieselement(&i); + kopunv(elsel, i); + switch (typ[i]) { + + case ttext: + spg1(i, xg, yg, dx, dy); + spg2(i, xg, yg, dx, dy); + spgb(i, xg, yg, dx, dy); + setzewinkel(i, xb1[i], yb1[i], xb2[i], yb2[i]); + textparam(i); + break; + + case tgerade: + spg1(i, xg, yg, dx, dy); + spg2(i, xg, yg, dx, dy); + break; + + case trechteckgef: + spg1(i, xg, yg, dx, dy); + spg2(i, xg, yg, dx, dy); + spgb(i, xg, yg, dx, dy); + /*setzewinkel(i, x1[i], y1_[i], xb1[i], yb1[i]);*/ + break; + + case tdreieckgef: + case tviereckgef: + spg1(i, xg, yg, dx, dy); + spg2(i, xg, yg, dx, dy); + spgb(i, xg, yg, dx, dy); + break; + + case tkreis: + case tkreisgef: + spg1(i, xg, yg, dx, dy); + break; + + case tkreisbogen: + case tkreissektorgef: + spgkbogen(i, xg, yg, dx, dy); + break; + + case tell: + case tellgef: + spgell(i, xg, yg, dx, dy); + break; + + case tellbogen: + case tellsektorgef: + spgellbogen(i, xg, yg, dx, dy); + break; + + case tbezier: + case tbeziergef: + spg1(i, xg, yg, dx, dy); + spg2(i, xg, yg, dx, dy); + spgb(i, xg, yg, dx, dy); + break; + }/*case*/ + bestimmeneuegruppe(i); + if (duplikat(i)==false) { + berechneminmax(i); + ausel(i, paint); + } +} /*einelspiegeln*/ + + +Static Void elspiegeln(xanf, yanf, xend, yend, xg, yg, dx, dy) +double xanf, yanf, xend, yend, xg, yg, dx, dy; +{ + long elsel; + + if (blinkelemente(xanf, yanf, xend, yend, 1L) == false ) + return; + gruppenumbenennen(); + for (elsel=1;elsel <=zelmax;elsel++) { + if (blink[elsel] == true) { + einelspiegeln(elsel, xg, yg, dx, dy); + } + } + unbenutztegruppenfreigeben(); +} /*elspiegeln*/ + + +Static long spiegeln(x,y,xanf,yanf,xend,yend,taste,msel,phase) +long *msel,taste,phase; +double x,y,xanf,yanf,xend,yend; +{ + static long elselg; + double xg, yg, dx, dy; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + } + L0: + strcpy(pr4, pr2menue[*msel]); + return 1; + L1: + sucheelement((long)nurgerade, &elselg, xanf, yanf); + if (elselg==0) return 1; + strcpy(pr4,pr3menue[*msel]); + return 2; + L2: + dx = x2[elselg] - x1[elselg]; + dy = y2[elselg] - y1_[elselg]; + xg = x1[elselg]; + yg = y1_[elselg]; + elspiegeln(xanf, yanf, xend, yend, xg, yg, dx, dy); + return 2; +} + + +Static long einpolygon(x,y,taste,msel,phase) + long *msel,taste,phase; + double x,y; +{ + double r, dwi, cd, sd, cwi, swi, xx1, yy1, xx2, yy2; + static long elsel; + long n, k, anz; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + default: goto L3; + } + L0: + freieselement(&elsel); + return 1; + L1: + x1[elsel] = x; + y1_[elsel] = y; + strcpy(pr3,nullstr); + strcpy(pr4, pr3menue[*msel]); + return 2; + L2: + r = ppabstand(x, y, x1[elsel], y1_[elsel]); + if (r < 2.0) r = 2.0; + laenge1[elsel]=r; + L2B: + if (selmenue[mverbunden]==true) + strcpy(pr3, "(connected) "); + else + strcpy(pr3, nullstr); + strcpy(pr4,nullstr); + inittastaturtext(nullstr, " number of edges?",1L); + return 3; + L3: + if (istnullstr(EinText) == true) goto L4; + anz=sscanf(EinText,"%ld",&n); + if ((anz!=1)|| (n == 0) || (n < 3)) goto L2B; + r=laenge1[elsel]; + dwi = pi / n; + cd = cos(dwi); + sd = sin(dwi); + /*Anfang Winkel 0*/ + cwi = 1.0; + swi = 0.0; + addtheorem(cd, sd, cd, sd, &cd, &sd); /*Winkel verdoppeln*/ + xx1 = x1[elsel] + r * cwi; + yy1 = y1_[elsel] + r * swi; + for (k = 1; k <= n; k++) { + addtheorem(cd, sd, cwi, swi, &cwi, &swi); + xx2 = x1[elsel] + r * cwi; + yy2 = y1_[elsel] + r * swi; + if (selmenue[mverbunden]==true) + createline(0L, x1[elsel], y1_[elsel], xx2, yy2); + createline(0L, xx1, yy1, xx2, yy2); + xx1 = xx2; + yy1 = yy2; + } + L4: + strcpy(pr3,nullstr); + strcpy(pr4,pr2menue[*msel]); + return 1; +} /*Polygon*/ + +Static Void size_change(display,ix,iy) + Display *display; + long ix,iy; +{ double xmalt,ymalt,dxm,dym; + + ixzmax=ix; + xzmax=ix; + iyzmax=iy; + yzmax= iy; + xmalt = xmittelzei; + ymalt = ymittelzei; + xmittelzei = (xzmax - xgr) / 2.0 + xgr; + ymittelzei = (yzmax - yprompt - 12.0) / 2.0 + yprompt + 12.0; + setze_clip_bereiche(display); + /* fuer readstdin vermerken, welche Skalierungen durchgef"uhrt wurden */ + dxm = xmalt-xmittelzei; + dym = ymalt-ymittelzei; + readdxx = readdxx + dxm*(1.0-readf); + readdyy = readdyy + dym*(1.0-readf); + /* Ende dieser Vermerke */ +} + + +Static Void initmisc() +{ + long i; + xmittelzei = (xzmax - xgr) / 2.0 + xgr; + ymittelzei = (yzmax - yprompt - 12.0) / 2.0 + yprompt + 12.0; + fgradbo = pi / wh; + fbograd = wh / pi; + + *nullstr = '\0'; + + strcpy(textausrichtung[0], "[bl]"); + strcpy(textausrichtung[1],nullstr); + strcpy(textausrichtung[2], "[br]"); + strcpy(textausrichtung[3], "[b]"); + strcpy(textausrichtung[4], "[tl]"); + strcpy(textausrichtung[5], "[tr]"); + strcpy(textausrichtung[6], "[t]"); + strcpy(textausrichtung[7], "[l]"); + strcpy(textausrichtung[8], "[r]"); +} + +Static Void initcutpaste() +{ + long i; + wartendexport=false; + requesttime = 0; + lasteventtime = 0; + for (i=0;i<zrequw;i++) requestbelegt[i]=false; + latexdraw_object=XInternAtom(display,"latexdraw_object",False); + latexdraw_text =XInternAtom(display,"latexdraw_text",False); + latexdraw_selection =XInternAtom(display,"latexdraw_selection",False); +} + + +Static Void gell00schnittp(xx1,yy1,xx2,yy2,elsel,anz,wgerade,well,instrecke) +long elsel, *anz; +double xx1,yy1,xx2,yy2; +double *wgerade, *well; +boolean instrecke; +{ + double dx, dy, xm, ym, lx, ly, cr, sr, wwg, wwell, px, + py, a2, a1, a0; + long i, anzl; + terg wgl; + + ellpar(elsel, &xm, &ym, &lx, &ly, &cr, &sr); + xy_ell(xm, ym, cr, sr, xx1, yy1, &xx1, &yy1); + xy_ell(xm, ym, cr, sr, xx2, yy2, &xx2, &yy2); + dx = xx2 - xx1; + dy = yy2 - yy1; + a2 = dx * dx / (lx * lx) + dy * dy / (ly * ly); + a1 = 2.0 * (xx1 * dx / (lx * lx) + yy1 * dy / (ly * ly)); + a0 = xx1 * xx1 / (lx * lx) + yy1 * yy1 / (ly * ly) - 1.0; + glzweiterord(a2, a1, a0, &anzl, wgl); + *anz = 0; + for (i = 1; i <= anzl; i++) { + wwg = wgl[i]; + if (instrecke == true) { + /* Pruefung, ob Schnittpunkt in Strecke*/ + if ( (wwg < -0.1) || (wwg > 1.1) ) + goto weiter; /* kein Schnittpunkt */ + } + + px = xx1 + dx * wwg; + py = yy1 + dy * wwg; + wwell = winkel0(px, py, lx, ly); /* w fuer Ellipse */ + if (si_fabs(wwell - wanf[elsel]) < 0.1) + wwell = wanf[elsel]; + if (si_fabs(wwell - wend[elsel]) < 0.1) + wwell = wend[elsel]; + (*anz)++; + wgerade[*anz] = wwg; + well[*anz] = wwell; + if ((typ[elsel] == tkreisbogen || typ[elsel] == tellbogen || + typ[elsel] == tkreissektorgef || + typ[elsel] == tellsektorgef) && + (inwinkel(elsel, wwell)==false)) + /* Punkt ist doch kein Schnittpunkt */ + (*anz)--; + weiter:; + } /*for*/ +} + +Static Void gell0schnittp(elselg,elsel,anz,wgerade,well,instrecke) +long elselg, elsel, *anz; +double *wgerade, *well; +boolean instrecke; +{ + double xx1, yy1, xx2, yy2; + + xx1 = x1[elselg]; + yy1 = y1_[elselg]; + xx2 = x2[elselg]; + yy2 = y2[elselg]; + gell00schnittp(xx1,yy1,xx2,yy2,elsel,anz,wgerade,well,instrecke); +} + + +Static Void testwawe(wp, wa, we, w) +double wp, *wa, *we, w; +{ + if (si_fabs(w - wp) <= 0.001) + /* der Schnittpunkt ist so nahe am Anclickpunkt, dass eine */ + /* Entscheidung sinnlos ist, bzw. der Schnittpunkt igoriert werden */ + /* sollte, insbesondere im Zusammenhang von connect, wo */ + /* Grenzpunkte als Clickpunkte verwendet werden. */ + return; + if ((w < wp) && (w > *wa)) + *wa = w; + if ((w > wp) && (w < *we)) + *we = w; +} + + +Static Void testxyell(elsel, elsel1, xx1, yy1, wp, wa, we) +long elsel, elsel1; +double xx1, yy1, wp, *wa, *we; +{ + double w1, w, xxp, yyp, xx, yy, xm1, ym1, lx1, ly1, cr1, sr1, xm, ym, lx, + ly, cr, sr; + + ellpar(elsel, &xm, &ym, &lx, &ly, &cr, &sr); /*Bezugsellipse elselp*/ + ellpar(elsel1, &xm1, &ym1, &lx1, &ly1, &cr1, &sr1); + w1 = winkel0(xx1, yy1, lx1, ly1); + ell_xy(xm1, ym1, lx1, ly1, cr1, sr1, xx1, yy1, &xxp, &yyp); + /*testkreis(xxp,yyp,7.0);*/ + if (inwinkel(elsel1, w1)==false) + goto _L1; + w = winkelell(xm, ym, lx, ly, cr, sr, xxp, yyp); + /*testkreis(xxp,yyp,6.0);*/ + if (inwinkel(elsel, w)==false) + goto _L1; + ellw_xy(xm, ym, lx, ly, cr, sr, w, &xx, &yy); + /*testkreis(xx,yy,5.0);*/ + if (ppabstand(xxp, yyp, xx, yy) > 5.0) + goto _L1; + /*testkreis(xx,yy,3.0);*/ + testwawe(wp, wa, we, w); + testwawe(wp, wa, we, w + wg); + testwawe(wp, wa, we, w - wg); +_L1: ; +} + + +Static Void ellellschnittp(elselp, elsel1, wp, wa, we) +long elselp, elsel1; +double *wp, *wa, *we; +{ + long i, anz; + terg x1erg; + double xm1, ym1, lx1, ly1, cr1, sr1, xm, ym, lx, ly, cr, sr, qlv, axx, axy, + ax0, ayx, ayy, ay0, bxx, byy, bx, by, bxy, b, c4, c3, c2, c1, c0, + xx1, yy1; + + ellpar(elselp, &xm, &ym, &lx, &ly, &cr, &sr); + ellpar(elsel1, &xm1, &ym1, &lx1, &ly1, &cr1, &sr1); + qlv = ly1 / lx1; + qlv *= qlv; + axx = (cr * cr1 + sr * sr1) / lx; + axy = (sr * cr1 - cr * sr1) / lx; + ax0 = (cr * (xm1 - xm) + sr * (ym1 - ym)) / lx; + ayx = (cr * sr1 - sr * cr1) / ly; + ayy = (sr * sr1 + cr * cr1) / ly; + ay0 = (sr * (xm - xm1) + cr * (ym1 - ym)) / ly; + bxx = axx * axx + ayx * ayx; + byy = axy * axy + ayy * ayy; + bx = 2.0 * (axx * ax0 + ayx * ay0); + by = 2.0 * (axy * ax0 + ayy * ay0); + bxy = 2.0 * (axx * axy + ayx * ayy); + b = ax0 * ax0 + ay0 * ay0 - 1.0; + bxx -= qlv * byy; + b += byy * ly1 * ly1; + c4 = bxx * bxx + qlv * bxy * bxy; + c3 = 2.0 * (bxx * bx + qlv * by * bxy); + c2 = 2.0 * bxx * b + bx * bx + qlv * by * by - ly1 * ly1 * bxy * bxy; + c1 = 2.0 * (bx * b - ly1 * ly1 * by * bxy); + c0 = b * b - ly1 * ly1 * by * by; + glvierterord(c4, c3, c2, c1, c0, &anz, x1erg); + for (i = 1; i <= anz; i++) { + xx1 = x1erg[i]; + yy1 = xx1 / lx1; + yy1 = 1.0 - yy1 * yy1; + yy1 = sisqrt(1.0, yy1); + if (yy1 >= 0.0) { + yy1 = ly1 * yy1; + testxyell(elselp, elsel1, xx1, yy1, *wp, wa, we); + testxyell(elselp, elsel1, xx1, -yy1, *wp, wa, we); + } + } +} + + +Static boolean ellbozuklein(r, wa, we) +double r, wa, we; +{ + double dw; + + dw = we - wa; + if (dw < 0.0) + dw += wg; + dw = r * dw * fgradbo; + if (dw < 3.0) return true; + else return false; +} + + +Static Void ellauftrennen(elselp, wa, we) +long elselp; +double wa, we; +{ + long i; + double lmax; + + if (laenge1[elselp] > laenge2[elselp]) + lmax = laenge1[elselp]; + else + lmax = laenge2[elselp]; + while (wa < 0.0) + wa += wg; + while (wa >= wg) + wa -= wg; + while (we < 0.0) + we += wg; + while (we >= wg) + we -= wg; + if (si_fabs(wanf[elselp] - wa) < 0.5) + wa = wanf[elselp]; + if (si_fabs(wend[elselp] - we) < 0.5) + we = wend[elselp]; + if (wa == wanf[elselp] && we == wend[elselp]) + goto _L1; + switch (typ[elselp]) { + + + case tkreis: + case tkreisgef: + if (wa == we) + goto _L1; + ausel(elselp, erase); + wanf[elselp] = we; + wend[elselp] = wa; + if (typ[elselp] == tkreis) typ[elselp] = tkreisbogen; + else typ[elselp] = tkreissektorgef; + kreisanfendpunkt(elselp); + if (ellbozuklein(lmax, wanf[elselp], wend[elselp])==true) + typ[elselp] = 0; + else + berechneminmax(elselp); + ausel(elselp, paint); + break; + + case tell: + case tellgef: + if (wa == we) + goto _L1; + ausel(elselp, erase); + wanf[elselp] = we; + wend[elselp] = wa; + if (typ[elselp] == tell) typ[elselp] = tellbogen; + else typ[elselp] = tellsektorgef; + ellanfendpunkt(elselp); + if (ellbozuklein(lmax, wanf[elselp], wend[elselp])==true) + typ[elselp] = 0; + else + berechneminmax(elselp); + ausel(elselp, paint); + break; + + case tkreisbogen: + case tellbogen: + case tkreissektorgef: + case tellsektorgef: + ausel(elselp, erase); + if ((wa != wanf[elselp]) & + (ellbozuklein(lmax, wa, wanf[elselp])==false)) { + freieselement(&i); + kopunv(elselp, i); + wend[i] = wa; + ellanfendpunkt(i); + berechneminmax(i); + ausel(i, paint); + } + if ((we != wend[elselp]) & + (ellbozuklein(lmax, we, wend[elselp])==false)) { + freieselement(&i); + kopunv(elselp, i); + wanf[i] = we; + ellanfendpunkt(i); + berechneminmax(i); + ausel(i, paint); + } + typ[elselp] = 0; + break; + }/*case*/ +_L1: ; +} + + +Static Void ellgschnittp(elsel, elselg, wp, wa, we, instrecke) +long elsel, elselg; +double *wp, *wa, *we; +boolean instrecke; +{ + long i, anz; + double w; + terg wgerade, well; + + gell0schnittp(elselg, elsel, &anz, wgerade, well, instrecke); + for (i = 1; i <= anz; i++) { + w = well[i]; + while (w > wg) + w -= wg; + while (w < 0.0) + w += wg; + testwawe(*wp, wa, we, w); + testwawe(*wp, wa, we, w + wg); + testwawe(*wp, wa, we, w - wg); + } +} + +Static Void ellgischnittp(elsel, i, xx1,yy1,xx2,yy2, wp,wa,we, instrecke) +long elsel, i; +double xx1,yy1,xx2,yy2,*wp, *wa, *we; +boolean instrecke; +{ /* i ist freies Element, xx1, ... definieren Endpunkte einer Strecke */ + /* mit der die Ellipse elsel geschnitten wird */ + /* instrecke = true, dann muss der Schnittpunkt auch in der */ + /* Strecke i liegen */ + + + typ[i] = tgerade; + x1[i] = xx1; + y1_[i] = yy1; + x2[i] = xx2; + y2[i] = yy2; + ellgschnittp(elsel, i, wp, wa, we, instrecke); + typ[i] = -1; +} + + + +Static Void ellschnittp(elselp, elsel, wp, wa, we, instrecke) +long elselp, elsel; +double *wp, *wa, *we; +boolean instrecke; +/* instrecke = true, dann muss der Schnittpunkt auch in der */ +/* Strecke elsel liegen, falls elsel Strecke */ +{ + long i, e; + boolean sonderfall; /* fuer Schnittpunktberuecksichtigung in Strecken */ + + sonderfall = true; + e = elsel; + switch (typ[elsel]) { + case ttext: + break; + case tgerade: + ellgschnittp(elselp, elsel, wp, wa, we, instrecke); + break; + case tkreis: + case tkreisgef: + case tkreisbogen: + case tell: + case tellgef: + case tellbogen: + ellellschnittp(elselp, elsel, wp, wa, we); + break; + case tkreissektorgef: + case tellsektorgef: + freieselement(&i); + ellellschnittp(elselp, elsel, wp, wa, we); + ellgischnittp(elselp,i,x1[e],y1_[e],xb1[e],yb1[e],wp,wa,we,sonderfall); + ellgischnittp(elselp,i,x1[e],y1_[e],xb2[e],yb2[e],wp,wa,we,sonderfall); + break; + case tdreieckgef: + freieselement(&i); + ellgischnittp(elselp,i,x1[e],y1_[e],x2[e],y2[e],wp,wa,we,sonderfall); + ellgischnittp(elselp,i,x2[e],y2[e],xb1[e],yb1[e],wp,wa,we,sonderfall); + ellgischnittp(elselp,i,xb1[e],yb1[e],x1[e],y1_[e],wp,wa,we,sonderfall); + break; + case trechteckgef: + case tviereckgef: + freieselement(&i); + ellgischnittp(elselp,i,x1[e],y1_[e],xb1[e],yb1[e],wp,wa,we,sonderfall); + ellgischnittp(elselp,i,xb1[e],yb1[e],x2[e],y2[e],wp,wa,we,sonderfall); + ellgischnittp(elselp,i,x2[e],y2[e],xb2[e],yb2[e],wp,wa,we,sonderfall); + ellgischnittp(elselp,i,xb2[e],yb2[e],x1[e],y1_[e],wp,wa,we,sonderfall); + break; + case tbezier: + case tbeziergef: + break; + }/*case*/ +} + + +Static Void etrim(elselp, elsel1, elsel2, xp, yp, instrecke) +long elselp, elsel1, elsel2; +double xp, yp; +boolean instrecke; +{ + double xm, ym, lx, ly, cr, sr, wa, we, wp; + + ellpar(elselp, &xm, &ym, &lx, &ly, &cr, &sr); + wp = winkelell(xm, ym, lx, ly, cr, sr, xp, yp); + wa = wanf[elselp]; + we = wend[elselp]; + if (typ[elselp] == tkreis || typ[elselp] == tell || + typ[elselp] == tkreisgef || typ[elselp] == tellgef) { + wa -= wg; + we += wg; + } + if (wp < wa) + wp += wg; + if (we <= wa) + we += wg; + ellschnittp(elselp, elsel1, &wp, &wa, &we, instrecke); + if (elsel1 != elsel2) + ellschnittp(elselp, elsel2, &wp, &wa, &we, instrecke); + ellauftrennen(elselp, wa, we); +} + + +Static Void gellschnittp(elselp, elsel, wp, wa, we) +long elselp, elsel; +double *wp, *wa, *we; +{ + double w; + long anz, i; + terg wg_, well; + + gell0schnittp(elselp, elsel, &anz, wg_, well, false); + for (i = 1; i <= anz; i++) { + w = wg_[i]; + if (w > *wa && w < *we) { + if (w < *wp) + *wa = w; + else + *we = w; + } + } /*for i*/ +} + + +Static double winkelg(elsel, xp, yp) +long elsel; +double xp, yp; +{ + double dx, dy; + + dx = x2[elsel] - x1[elsel]; + dy = y2[elsel] - y1_[elsel]; + if (si_fabs(dx) > si_fabs(dy)) + return ((xp - x1[elsel]) / dx); + else + return ((yp - y1_[elsel]) / dy); +} + + +Static Void ggschnittp(elselp, elsel, wp, wa, we, instrecke) +long elselp, elsel; +double *wp, *wa, *we; +boolean instrecke; +{ /* Schnittpunkt zweier Geraden, Schnittpunkt liegt in der durch */ + /* elselp definierten Strecke. Falls instrecke true liegt der */ + /* Schnittpunkt auch in der durch elsel definierten Strecke */ + double dxp, dyp, dx, dy, xx1p, yy1p, xx1, yy1, n, z, vz, w; + + xx1p = x1[elselp]; + yy1p = y1_[elselp]; + dxp = x2[elselp] - xx1p; + dyp = y2[elselp] - yy1p; + xx1 = x1[elsel]; + yy1 = y1_[elsel]; + dx = x2[elsel] - xx1; + dy = y2[elsel] - yy1; + n = dxp * dy - dx * dyp; /*xs,ys sei Schnittpunkt, n = nenner bei */ + /* Ausdruck fuer xs, n==0: parallel */ + if (n == 0.0) + goto L1; + /* m = (xs-xx1p)/dxp = z/n */ + vz = fsign(n); + n = si_fabs(n); + z = vz * (dy * (xx1 - xx1p) + dx * (yy1p - yy1)); + if (z <= -0.01 || z >= 1.01*n) + /* Schnittpunkt ausserhalb Strecke elselp */ + goto L1; + w = z / n; + if (w <= *wa || w >= *we) + goto L1; + if (instrecke == true) { + /* Test, ob Schnittpunkt auch in zweiter Strecke */ + z = vz*(dyp*(xx1-xx1p)+dxp*(yy1p-yy1)); + if ((z < -0.01)||(z > 1.01*n)) + goto L1; + } + testwawe(*wp, wa, we, w); +L1: ; +} + + +Static Void ggischnittp(elselg, i, xx1,yy1,xx2,yy2, wp,wa,we, instrecke) +long elselg, i; +double xx1,yy1,xx2,yy2,*wp, *wa, *we; +boolean instrecke; +{ /* i ist freies Element, xx1, ... definieren Endpunkte einer Strecke */ + /* mit der die Strecke elselg geschnitten wird */ + /* instrecke = true, dann muss der Schnittpunkt auch in der */ + /* Strecke i liegen */ + + + typ[i] = tgerade; + x1[i] = xx1; + y1_[i] = yy1; + x2[i] = xx2; + y2[i] = yy2; + ggschnittp(elselg, i, wp, wa, we, instrecke); + typ[i] = -1; +} + + + +Static Void gschnittp(elselg, elsel, wp, wa, we, instrecke) +long elselg, elsel; +double *wp, *wa, *we; +boolean instrecke; +{ /* Bestimmung wa und we fuer Schnittpunkt auf Strecke elselg mit */ + /* anderem Zeichnungselement elsel. Falls elsel eine Strecke und */ + /* instrecke = true, dann muss der Schnittpunkt auch in der */ + /* Strecke elsel liegen */ + + long i, e; + boolean sonderfall; /* fuer Schnittpunkt in Strecke */ + + sonderfall = true; + e = elsel; + switch (typ[elsel]) { + case ttext: + break; + case tgerade: + ggschnittp(elselg, elsel, wp, wa, we, instrecke); + break; + case tkreis: + case tkreisgef: + case tkreisbogen: + case tell: + case tellgef: + case tellbogen: + gellschnittp(elselg, elsel, wp, wa, we); + break; + case tkreissektorgef: + case tellsektorgef: + freieselement(&i); + gellschnittp(elselg, elsel, wp, wa, we); + ggischnittp(elselg,i,x1[e],y1_[e],xb1[e],yb1[e],wp,wa,we,sonderfall); + ggischnittp(elselg,i,x1[e],y1_[e],xb2[e],yb2[e],wp,wa,we,sonderfall); + break; + case tdreieckgef: + freieselement(&i); + ggischnittp(elselg,i,x1[e],y1_[e],x2[e],y2[e],wp,wa,we,sonderfall); + ggischnittp(elselg,i,x2[e],y2[e],xb1[e],yb1[e],wp,wa,we,sonderfall); + ggischnittp(elselg,i,xb1[e],yb1[e],x1[e],y1_[e],wp,wa,we,sonderfall); + break; + case trechteckgef: + case tviereckgef: + freieselement(&i); + ggischnittp(elselg,i,x1[e],y1_[e],xb1[e],yb1[e],wp,wa,we,sonderfall); + ggischnittp(elselg,i,xb1[e],yb1[e],x2[e],y2[e],wp,wa,we,sonderfall); + ggischnittp(elselg,i,x2[e],y2[e],xb2[e],yb2[e],wp,wa,we,sonderfall); + ggischnittp(elselg,i,xb2[e],yb2[e],x1[e],y1_[e],wp,wa,we,sonderfall); + break; + case tbezier: + case tbeziergef: + break; + }/*case*/ +} + + +Static Void gauftrennen(elsel, wa, we) +long elsel; +double wa, we; +{ + double xa, ya, xe, ye, xx1, yy1, xx2, yy2; + + ausel(elsel, erase); + xx1 = x1[elsel]; + yy1 = y1_[elsel]; + xx2 = x2[elsel]; + yy2 = y2[elsel]; + xa = xx1 + (xx2 - xx1) * wa; + ya = yy1 + (yy2 - yy1) * wa; + xe = xx1 + (xx2 - xx1) * we; + ye = yy1 + (yy2 - yy1) * we; + if (wa == 0.0 && we == 1.0) /*beide Punkte bleiben*/ + goto L1; + if (wa == 0.0) { /*Punkt 2 bleibt*/ + x1[elsel] = xe; + y1_[elsel] = ye; + goto L1; + } + if (we == 1.0) { /*Punkt 1 bleibt*/ + x2[elsel] = xa; + y2[elsel] = ya; + goto L1; + } + /*Ausschnitt entfaellt*/ + if (ppabstand(xx1, yy1, xa, ya) > 3) + createline(elsel, xx1, yy1, xa, ya); + x1[elsel] = xe; + y1_[elsel] = ye; +L1: + /* connect davon abhaengig, dass altes Element verwendet wird */ + if (ppabstand(x1[elsel], y1_[elsel], x2[elsel], y2[elsel]) > 3){ + berechneminmax(elsel); + ausel(elsel, paint); + return; + } + typ[elsel] = 0; +} + + +Static Void gtrim(elselp, elsel1, elsel2, xp, yp, instrecke) +long elselp, elsel1, elsel2; +double xp, yp; +{ /* Trim mit der Geraden und nicht nur mit der Strecke, falls elsel1 */ + /* oder elsel2 Strecken sind, falls instrecke = true */ + double wa, we, wp; + + wa = 0.0; + we = 1.0; + wp = winkelg(elselp, xp, yp); + if (wp > wa && wp < we) { + gschnittp(elselp, elsel1, &wp, &wa, &we, instrecke); + if (elsel1 != elsel2) + gschnittp(elselp, elsel2, &wp, &wa, &we, instrecke); + } + gauftrennen(elselp, wa, we); +} + + +Static long trim(xa,ya,msel,phase) + long *msel,phase; + double xa,ya; +{ + static long elselp, elsel1, elsel2, relsel; + double xp,yp; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + case 3: goto L3; + } + L0: + return 1; + L1: + sucheelement((long)nurtrimel, &elselp, xa, ya); + if (elselp==0) return 1; + freieselement(&relsel); + x1[relsel] = xa; + y1_[relsel] = ya; + strcpy(pr4, " bounding object 1?"); + return 2; + L2: + sucheelement((long)nurboundel, &elsel1, xa, ya); + if ((elsel1==0)||(elsel1==elselp)) + return 2; + strcpy(pr4, " bounding object 2?"); + return 3; + L3: + sucheelement((long)nurboundel, &elsel2, xa, ya); + if ((elsel2==0)||(elsel2==elselp)) + return 3; + xp=x1[relsel]; + yp=y1_[relsel]; + switch (typ[elselp]) { + case tgerade: + gtrim(elselp, elsel1, elsel2, xp, yp, false); + break; + case tkreis: + case tkreisgef: + case tkreisbogen: + case tkreissektorgef: + etrim(elselp, elsel1, elsel2, xp, yp, false); + break; + case tell: + case tellgef: + case tellbogen: + case tellsektorgef: + etrim(elselp, elsel1, elsel2, xp, yp, false); + break; + }/*case*/ + auselemente(); + return 0; +} /*trim*/ + +Static Void schwerpunkt(elsel,xs,ys) + long elsel; + double *xs,*ys; +{/* Schwerpunkt Dreieck */ + double dx1,dy1,dx2,dy2; + + dx1 = (x2[elsel]+xb1[elsel])/2.0-x1[elsel]; + dy1 = (y2[elsel]+yb1[elsel])/2.0-y1_[elsel]; + dx2 = (x1[elsel]+xb1[elsel])/2.0-x2[elsel]; + dy2 = (y1_[elsel]+yb1[elsel])/2.0-y2[elsel]; + *xs = (x1[elsel]*dy1*dx2-x2[elsel]*dy2*dx1+(y2[elsel]-y1_[elsel])*dx1*dx2) + /(dy1*dx2-dy2*dx1); + *ys = (*xs-x1[elsel])*dy1/dx1+y1_[elsel]; +} + + +Static Void fontwahl(taste) +long taste; +{ + selmenue[mfont] = false; + if (taste==1) fontnummer = folgefont[fontnummer]; + if (taste==3) fontnummer = prevfont[fontnummer]; + strcpy(menue[mfont],textfontlabel[fontnummer]); + ausmenueelement(mfont); +} + +Static Void dickenwahl(taste) +long taste; +{ + selmenue[mdick]=false; + ausmenueelement(mdick); + if (taste==1) aktldicke = aktldicke +1; + if (taste==3) aktldicke = aktldicke -1; + if (aktldicke>maxldicke) aktldicke=1; + if (aktldicke<1) aktldicke=maxldicke; + strichsymbol(); + ausmenueelement(mdick); +} + +Static Void readzeitwahl(taste) +long taste; +{ + long f; + + f = 5; + if (aktreadzeit < 50) f = 2; + if (aktreadzeit < 20) f = 1; + selmenue[mreadzeit]=false; + if (taste==1) aktreadzeit += 1*f; + if (taste==3) aktreadzeit -= 1*f; + if (aktreadzeit>120) aktreadzeit = 120; + if (aktreadzeit<0) aktreadzeit = 0; + readzeitsymbol(); + ausmenueelement(mreadzeit); +} + + +Static Void colorwahl(taste) +long taste; +{ + long posnr; +/* Fortschaltung mit Farbnummern und nicht Positionsnummern */ + + posnr = aktcolor; +/* posnr = farbposfarbnr[aktcolor]; */ + selmenue[mcolor]=false; + if (taste==1) posnr += 1; + if (taste==3) posnr -= 1; + if (posnr>=aktzahlfarben) posnr=0; + if (posnr<0) posnr=aktzahlfarben-1; + aktcolor = posnr; +/* aktcolor = farbnrfarbpos[posnr]; */ + colorsymbol(); + ausmenueelement(mcolor); +} + +Static Void somencolorwahl(i) +long i; +{ + aktcolor = farbnrfarbpos[i]; + colorsymbol(); + ausmenueelement(mcolor); +} + +Static Void winkelsymbol() +{ + Char sss[10]; + + sprintf(sss,"%3ld",winkelrotate); + strcpy(menue[mwinkelrot],sss); +} + +Static Void setwinkelrot(x) + long x; +{ + winkelrotate = x; + winkelsymbol(); + ausmenueelement(mwinkelrot); +} + +Static Void winkelwahl(taste) + long taste; +{ + selmenue[mwinkelrot]=false; + if (taste==1) winkelrotate += 5; + if (taste==3) winkelrotate += 30; + if (winkelrotate > 360) + winkelrotate -= 360; + winkelsymbol(); + ausmenueelement(mwinkelrot); +} + +Static long savedateien(msel,dateiname,taste,phase) +Char *dateiname; +long *msel,taste,phase; +{ long iphase; + + iphase = phase; + switch (phase){ + case 0: goto L0; + case 100: goto L1; + default: goto L2; + } + L0: + inittastaturtext(dateiname,pr2menue[*msel],0L); + return 100; + L1: + strcpy(dateiname, EinText); + iphase = 0; + L2: + iphase = austexdatei(msel,dateiname,taste,iphase); + if (iphase != 0) return iphase; + iphase=schreibenausdatei(msel,dateiname,taste,iphase); + selmenloeschen(msel); + return 0; +} + +Static long fuellen(x, y, msel, phase) +long *msel,phase; +double x, y; +{ + static long i; + long k; + double xx1, yy1, xs, ys; + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + } + L0: + vorbsortieren(); + return 1; + L1: + sucheelement((long)nurfillel, &k, x, y); + if (k == 0) return 1; + freieselement(&i); + kopunvotext(k,i); + typ[i] = -1; + switch (typ[k]) { + case tgerade: + xb1[i] = x; + yb1[i] = y; + strcpy(pr4, pr3menue[*msel]); + return 2; + case tkreis: + typ[i] = tkreisgef; + break; + case tkreisbogen: + typ[i] = tkreissektorgef; + break; + case tell: + typ[i] = tellgef; + break; + case tellbogen: + typ[i] = tellsektorgef; + break; + case tbezier: + typ[i] = tbeziergef; + break; + } + goto L4; + + L2: /* wird Dreieck oder Viereck */ + sucheelement((long)nurgerade, &k, x, y); + if (k == 0) return 2; + xx1 = xb1[i]; + yy1 = yb1[i]; + typ[i]=tgerade; + /* wenn Schnittpunkt, dann Dreieck */ + if (gschnittpunkt(x1[i],y1_[i],x2[i]-x1[i],y2[i]-y1_[i], + x1[k],y1_[k],x2[k]-x1[k],y2[k]-y1_[k], + &xs, &ys) == true) { + if ((inxystrecke(x1[i], y1_[i], x2[i], y2[i], xs, ys)== true)&& + (inxystrecke(x1[k], y1_[k], x2[k], y2[k], xs, ys)== true)) { + /*triangle*/ + if (ppabstand(x1[i],y1_[i],xx1,yy1) > ppabstand(x1[i],y1_[i],xs,ys)) { + x1[i] = x2[i]; + y1_[i] = y2[i]; + } + x2[i] = xs; + y2[i] = ys; + xb1[i] = x1[k]; + yb1[i] = y1_[k]; + if (ppabstand(x1[k],y1_[k],x,y) > ppabstand(x1[k],y1_[k],xs,ys)) { + xb1[i] = x2[k]; + yb1[i] = y2[k]; + } + typ[i] = tdreieckgef; + goto L3; + } + } + /* Durch zwei Linien sind vier Punkte fuer ein Viereck (quadrangle) */ + /* definiert. Da die zu verbindenden Punkte so noch nicht eindeutig */ + /* definiert sind, wird vereinbart: Verbunden werden die beiden, dem */ + /* jeweiligen Klickpunkt am naechsten liegenden Punkte */ + if (ppabstand(x1[i],y1_[i],xx1,yy1) < ppabstand(x2[i],y2[i],xx1,yy1)) { + xb1[i] = x1[i]; + yb1[i] = y1_[i]; + x1[i] = x2[i]; + y1_[i] = y2[i]; + } + else { + xb1[i] = x2[i]; + yb1[i] = y2[i]; + } + if (ppabstand(x1[k],y1_[k],x,y) < ppabstand(x2[k],y2[k],x,y)) { + x2[i] = x1[k]; + y2[i] = y1_[k]; + xb2[i] = x2[k]; + yb2[i] = y2[k]; + } + else { + x2[i] = x2[k]; + y2[i] = y2[k]; + xb2[i] = x1[k]; + yb2[i] = y1_[k]; + } + typ[i] = tviereckgef; + L3: + berechneminmax(i); + L4: + setlineattribute(0L, i); + sequenz[i]= -10; /*wird erstes Element */ + sortieren(); + auselemente(); + return 0; +} /* end of fuellen */ + +Static long showgroup(xanf,yanf,taste,msel,phase) +double xanf,yanf; +long taste, *msel,phase; +{ + long elsel; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + } + L0: + return 1; + L1: + sucheelement((long)alleelem, &elsel, xanf, yanf); + if (elsel != 0) { + blinkenan(); + initgruppentag(false); + blinkgruppe(elsel); + } + return 1; +} + +Static long newgroup(xanf,yanf,xend,yend,taste,msel,phase) +double xanf,yanf,xend,yend; +long taste, *msel,phase; +{ + long i,elsel,gelsel,gi; + static long wurzel; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + } + L0: + wurzel = 0; + /* alte Markierungen loeschen, da spaeter sonst verwertet */ + for (i=1;i<=zelmax;i++) + blink[i] = false; + return 1; + L1: + if (blinkelemente(xanf, yanf, xend, yend, 1L)==false) + goto L0B; + if (wurzel == 0) { + /* alle bisher selektierten Elemente kennzeichen */ + for (i=1;i<=zelmax;i++) + blink[i] = blink[i] || blinkalt[i]; + /* Pruefen ob mindestens zwei verschiedene Gruppen */ + elsel = 0; + for (i=1;i<=zelmax;i++) { + if ( (typ[i]>0)&&(blink[i]==true) ) { + if (elsel == 0) { + elsel = i; + gelsel = group[elsel]; + } + else { + gi = group[i]; + if ( (gi == 0) || (gelsel == 0) || + (gruppenwurzel(i) != gruppenwurzel(elsel)) ) { + /* zwei Gruppen */ + wurzel = freiegruppe(); + break; + } + } + } + } + }/* end if wurzel == 0 */ + if (wurzel == 0) { + /* nichts zu gruppieren */ + goto L0B; + } + /* Neue Gruppe da und evtl. Elemente zu gruppieren */ + for (i=1;i<=zelmax;i++) { + if ( (typ[i]>0)&&(blink[i]==true)&& + (gruppenwurzel(i) != wurzel) ){/* zufuegen */ + gruppieren(i, wurzel); + } + } + L0B: + /* alle bisher selektierten Elemente kennzeichen */ + for (i=1;i<=zelmax;i++) { + blink[i] = blink[i] || blinkalt[i]; + if (blink[i] == true) + blinkend = true; + } + return 1; +} + +Static long ungroup(xanf,yanf,taste,msel,phase) +double xanf,yanf; +long taste, *msel,phase; +{ + static long elsel; + long g; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + } + L0: + elsel = 0; + return 1; + L1: + sucheelement((long)alleelem, &elsel, xanf, yanf); + if (elsel != 0) { + blinkenan(); + initgruppentag(false); + blinkgruppe(elsel); + } + return 1; + L2: /* bei OK gedrueckt */ + if (elsel==0) return 0; + loeschegruppe(elsel); + blinkenan(); + initgruppentag(false); + blinkgruppe(elsel); + return 1; +} + +Static long groupok(msel, phase) +long *msel, phase; +{ + selmenue[mgroupok]=false; + ausmenueelement(mgroupok); + if (*msel==mungroup) + return ungroup(0.0, 0.0, 1, msel,2); + return phase; +} + + +Static Void connectpunkt(elsel, xa, ya, xc, yc) +long elsel; +double xa, ya, *xc, *yc; +{ + long e; + + switch (typ[elsel]) { + case ttext: + case tkreis : + case tkreisgef: + case tkreisbogen: + case tell: + case tellgef: + case tellbogen: + case tkreissektorgef: + case tellsektorgef: + *xc = x1[elsel]; + *yc = y1_[elsel]; + return; + case tgerade: + case trechteckgef: + *xc = (x1[elsel]+x2[elsel])*0.5; + *yc = (y1_[elsel]+y2[elsel])*0.5; + return; + case tviereckgef: + e = elsel; + if (gschnittpunkt(x1[e],y1_[e],xb2[e]-x1[e],yb2[e]-y1_[e], + x2[e],y2[e], xb1[e]-x2[e],yb1[e]-y2[e], + xc, yc) == true) { + if ((inxystrecke(x1[e],y1_[e],xb2[e],yb2[e], *xc,*yc)== true)&& + (inxystrecke(x2[e],y2[e], xb1[e],yb1[e], *xc,*yc)== true)) { + return; + } + } + if (gschnittpunkt(x1[e],y1_[e],xb1[e]-x1[e],yb1[e]-y1_[e], + x2[e],y2[e], xb2[e]-x2[e],yb2[e]-y2[e], + xc, yc) == true) { + if ((inxystrecke(x1[e],y1_[e],xb1[e],yb1[e], *xc,*yc)== true)&& + (inxystrecke(x2[e],y2[e], xb2[e],yb2[e], *xc,*yc)== true)) { + return; + } + } + *xc = (x1[elsel]+x2[elsel])*0.5; + *yc = (y1_[elsel]+y2[elsel])*0.5; + return; + case tdreieckgef: + schwerpunkt(elsel,xc,yc); + return; + case tbezier: + case tbeziergef: + if (ppabstand(xa,ya,x1[elsel],y1_[elsel]) <= + ppabstand(xa,ya,x2[elsel],y2[elsel])) { + *xc = x1[elsel]; + *yc = y1_[elsel]; + } + else { + *xc = x2[elsel]; + *yc = y2[elsel]; + } + return; + } +} + +Static Void conngschnittp(elselg, elsel, wp, wa, we) +long elselg, elsel; +double *wp, *wa, *we; +{ /* Trimmen der durch elselg bezeichneten Strecke mit elsel fuer */ + /* connect. Der Schnittpunkt ist nur relevant, falls er bei Strecken */ + /* in beiden Strecken liegt. Deshalb true beim Aufruf von gschnittp. */ + + + *wa = 0.0; + *we = 1.0; + + if (elsel == 0) return; /*nichts zu trimmen!*/ + + switch (typ[elsel]) { + case ttext: + break; + case tgerade: + case tkreis : + case tkreisgef: + case tkreisbogen: + case tell: + case tellgef: + case tellbogen: + case tkreissektorgef: + case tellsektorgef: + case tdreieckgef: + case trechteckgef: + case tviereckgef: + gschnittp(elselg, elsel, wp, wa, we, true); + break; + case tbezier: + case tbeziergef: + break; + }/*of switch */ +} + +Static Void conntrim(art, elselg, elsel1, elsel2) +long art, elselg, elsel1, elsel2; +{ /* Trimmen fuer connect, erst mit elsel1, dann mit elsel2. Der */ + /* Schnittpunkt ist nur relevant, falls er bei Strecken in beiden */ + /* Strecken liegt. Deshalb true beim Aufruf. */ + + double wa, we, wp; + + switch (art) { + + case 1: + wp = 0.0; + conngschnittp(elselg, elsel1, &wp, &wa, &we, true); + break; + case 2: + wp = 1.0; + conngschnittp(elselg, elsel2, &wp, &wa, &we, true); + break; + case 3: + wp = 0.0; + conngschnittp(elselg, elsel1, &wp, &wa, &we, true); + gauftrennen(elselg, wa, we); + if (typ[elselg] == 0) return; + wp = 1.0; + conngschnittp(elselg, elsel2, &wp, &wa, &we, true); + break; + } + gauftrennen(elselg, wa, we); +} + +Static long connect(xs,ys,xa,ya,taste,msel,phase) +double xs,ys,xa,ya; +long taste,phase,*msel; +{/* Verbindung zweier Elemente */ + + static long elsel1,elsel2, relsel; + long i1,i2; + double xc1,yc1,xc2,yc2; + + switch (phase){ + case 0: goto L0; + case 1: goto L1; + case 2: goto L2; + } + L0: + return 1; + L1: + sucheelement((long)alleelem, &elsel1, xa, ya); + if (elsel1 == 0) return 1; + freieselement(&relsel); + connectpunkt(elsel1, xa, ya, &xc1, &yc1); + x1[relsel] = xc1; + y1_[relsel] = yc1; + strcpy(pr4, pr3menue[*msel]); + return 2; + L2: + if (selmenue[mconnpoint] == false) {/*zweites Objekt gegeben*/ + sucheelement((long)alleelem, &elsel2, xa, ya); + if ((elsel2 == 0)|| (elsel2 == elsel1)) return 2; + connectpunkt(elsel2, xa, ya, &xc2, &yc2); + } + else {/*Punkt anstelle eines zweiten Objekts */ + xc2 = xs; + yc2 = ys; + elsel2 = 0L; + } + xc1 = x1[relsel]; + yc1 = y1_[relsel]; + if (selmenue[mconnxy] == true) { + i1 = interncreateline(0L, xc1,yc1,xc2,yc1); + i2 = interncreateline(0L, xc2,yc1,xc2,yc2); + goto L3; + } + if (selmenue[mconnyx] == true) { + i1 = interncreateline(0L, xc1,yc1,xc1,yc2); + i2 = interncreateline(0L, xc1,yc2,xc2,yc2); + goto L3; + } + /* direkte Verbindung */ + i1 = interncreateline(0L, xc1,yc1,xc2,yc2); + if (i1 == 0) + return 0; + conntrim(3,i1, elsel1, elsel2); + return 0; + L3: + if ((i1 == 0) && (i2 == 0)) + return 0; + if (i1 == 0) { + conntrim(3,i2, elsel1, elsel2); + return 0; + } + if (i2 == 0) { + conntrim(3,i1, elsel1, elsel2); + return 0; + } + lineende[i1] = 0L; + lineende[i2] = 0L; + if (selmenue[mcapprojecting] == true) { + lineende[i1] = 4L; + lineende[i2] = 4L; + } + if (selmenue[mpfeilanf] == true) + lineende[i1] = 1L; + if (selmenue[mpfeilende] == true) + lineende[i2] = 2L; + conntrim(1,i1, elsel1, elsel2); + conntrim(2,i2, elsel1, elsel2); + return 0; +} + +Static long readstdin(msel,phase) +long phase,*msel; +{ long i,j,k,anz; + double xxmin,xxmax,yymin,yymax; + + switch (readphase) { + case 0: + /* erster Aufruf */ + readphase = 1; + case 1: + /* evtl. kommt jetzt Vorspann */ + if (geteingabezeile(stdin)==0) + return readphase; + /* Vorspann lesen, falls da */ + if (NULL != strstr(eingabezeile,"LaTeXdraw (Siegert, TUM, C")) { + /* es kommt epc-Vorspann */ + readphase = 2; + } + else { + /* es kommen nur Zeichnungselemente */ + readphase = 6; + } + return readphase; + case 2: + /* es beginnt neue Zeichnung, loesche alte Elemente !!*/ + for (i = 1; i <= zelmax; i++) + typ[i] = 0; + kompakt(); + /* EPC-Vorspann lesen, erste Zeile schon da */ + einvorspannepc(stdin); + readphase = 3; + return readphase; + case 3: + /* einzelne Zeichnungslemente lesen */ + anz = geteingabezeile(stdin); + if (anz == 0) + fehler(3L); + anz=einlesenelement(stdin,&i); + if (typ[i] == 0) { + /* das ist das Ende eines Bildes, es kommt noch Gruppeninformation */ + readphase = 4; + } + else + skalieren(i,readdxx,readdyy,readf); + return readphase; + case 4: + /* Gruppeninformation kommt */ + if (version >= 13.0) /* Gruppen sind da!*/ + eindateigruppen(stdin); + if (version < 11.0) { + minmax(&xxmin,&xxmax,&yymin,&yymax); + breite=(xxmax-xxmin)*texfaktor; + hoehe=(yymax-yymin)*texfaktor; + } + ausfastalles(); + readphase = 1; + if (aktreadzeit != 0) + ltd_usleep(aktreadzeit,0L); /* readzeit Sekunden warten */ + return readphase; + case 5: + /* Zeichnungselement, wenn nur Zeichnungslemente */ + anz = geteingabezeile(stdin); + if (anz == 0) + fehler(3L); + case 6: + readphase = 5; + anz=einlesenelement(stdin,&i); + if (typ[i] == 0) { + /* das ist das Ende eines Bildes, es kommt */ + /* ggf. neues Bild oder weitere Elemente */ + readphase = 1; + kompakt(); + ausfastalles(); + if (aktreadzeit != 0) + ltd_usleep(aktreadzeit,0L); /* readzeit Sekunden warten */ + return readphase; + } + /*Zeichnungselement gelesen */ + skalieren(i,readdxx,readdyy,readf); + + if (typ[i] < 0) { + /* entsprechendes Element loeschen, falls da */ + typ[i] = -typ[i]; + if ( (j=duplikat0(i,true))!=0 ) + loescheelement(j); + loescheelement(i); + } + else { + if ( (j = duplikat0(i,false))!=0 ) { + lineende[j] = lineende[i]; + linedicke[j] = linedicke[i]; + linetype[j] = linetype[i]; + loescheelement(i); + } + } + kompakt(); + return readphase; + }/* end of switch */ +} + +/* diese Prozedur wird als Thread ausgefuehrt !!!!! */ +/* kein Zugriff auf Display in dieser Prozedur */ +Static void* threadreadstdin(vpar) + void *vpar; +{ /* threadaktiv und threadausel sind globale Variable*/ + + /* threadausel == 1 signalisiert der Umgebung, dass */ + /* eingelesene Zeichnungselemente ausgegeben werden sollen */ + /* Abfrage in Schleife bevor auf Event geprueft wird */ + + long i,j,k,anz; + double xxmin,xxmax,yymin,yymax; + + while (1) { + if (aktreadzeit != 0) + ltd_usleep(aktreadzeit,0L); /* grundsaetzlich readzeit Sekunden warten */ + while (threadaktiv==0){ + ltd_usleep(5L,0L); + } + /* jetzt versuchen zu lesen */ + /* evtl. kommt jetzt Vorspann */ + while (geteingabezeile(stdin)==0) {}; + /* Vorspann lesen, falls da */ + if (NULL == strstr(eingabezeile,"LaTeXdraw (Siegert, TUM, C")) { + /* es kommen nur Zeichnungselemente */ + goto einzelelemente; + } + /* es kommt epc-Vorspann */ + /* es beginnt neue Zeichnung, loesche alte Elemente !!*/ + for (i = 1; i <= zelmax; i++) + typ[i] = 0; + kompakt(); + /* EPC-Vorspann lesen, erste Zeile schon da */ + einvorspannepc(stdin); + while (1) { + /* einzelne Zeichnungslemente lesen */ + anz = geteingabezeile(stdin); + if (anz == 0) + fehler(3L); + anz=einlesenelement(stdin,&i); + if (typ[i] == 0) { + /* das ist das Ende eines Bildes, es kommt noch Gruppeninformation */ + goto gruppeninformation; + } + skalieren(i,readdxx,readdyy,readf); + } + gruppeninformation: + /* Gruppeninformation kommt */ + if (version >= 13.0) /* Gruppen sind da!*/ + eindateigruppen(stdin); + if (version < 11.0) { + minmax(&xxmin,&xxmax,&yymin,&yymax); + breite=(xxmax-xxmin)*texfaktor; + hoehe=(yymax-yymin)*texfaktor; + } + threadausel=1; + continue; + einzelelemente: + anz=einlesenelement(stdin,&i); + if (typ[i] == 0) { + /* das ist das Ende eines Bildes, es kommt */ + /* ggf. neues Bild oder weitere Elemente */ + } + else { + /*Zeichnungselement gelesen */ + skalieren(i,readdxx,readdyy,readf); + if (typ[i] < 0) { + /* entsprechendes Element loeschen, falls da */ + typ[i] = -typ[i]; + if ( (j=duplikat0(i,true))!=0 ) + loescheelement(j); + loescheelement(i); + } + else { + if ( (j = duplikat0(i,false))!=0 ) { + lineende[j] = lineende[i]; + linedicke[j] = linedicke[i]; + linetype[j] = linetype[i]; + loescheelement(i); + } + } + } + threadausel=1; + }/* while (1) wird von thread nicht verlassen */ +} + + +Static long aktion(msel,xs,ys,xa,ya,xe,ye,taste,phase) +double xs,ys,xa,ya,xe,ye; +long taste,phase,*msel; +{ + long i, elsel; + LA: + XDefineCursor(display,win,busycursor); + LM: + if (taste==0) goto LZ; /*es erfolgte eine Tastatureingabe*/ + if ((xa < xgr) && (koordinateneingegeben==false)) { + /*x in Menuebereich */ + if (xa<=xgrf) { + i=somenbesti(xa,ya); + if (i < 0) return phase; + if (i<ztextfonts) { + changefont=true; somenfontwahl(i); return phase; + } + i = i-ztextfonts; + if (i<aktzahlfarben) { + changecolor=true; somencolorwahl(i); return phase; + } + return phase; + } + menueloc(xa, ya, &i); + if (i == 0) return phase; + /* Sonderbehandlungen */ + if (selmenue[mreadzeit]==true) + readzeitwahl(taste); + if (selmenue[mfont]==true) + fontwahl(taste); + if (selmenue[mdick]==true) + dickenwahl(taste); + if (selmenue[mcolor]==true) + colorwahl(taste); + if (selmenue[mwinkelrot] == true) + winkelwahl(taste); + if (selmenue[mlschieben]==true) + verschieben((long)mlschieben); + if (selmenue[mrschieben]==true) + verschieben((long)mrschieben); + if (selmenue[moschieben]==true) + verschieben((long)moschieben); + if (selmenue[muschieben]==true) + verschieben((long)muschieben); + if (selmenue[mgross]==true) + verschieben((long)mgross); + if (selmenue[mklein]==true) + verschieben((long)mklein); + if (selmenue[mcenter]==true) + verschieben((long)mcenter); + if (i==mxytastatur) { + if (selmenue[mxytastatur]==false) { + erwartet=click_erwartet; + strcpy(pr5,nullstr); + strcpy(pr6,nullstr); + } + if (selmenue[mxytastatur]==true) { + if ((erwartet==tastatur_erwartet)||(*msel==0)) { + selmenue[mxytastatur]=false; + ausmenueelement(mxytastatur); + } + if ((erwartet==click_erwartet)&&(*msel!=0)) { + phasexyein=0; + phasexyein=xyein(&xsnap, &ysnap,taste,phasexyein); + } + } + } + if ((i==mdegrees) && (winerwartet != 0)) { + if (selmenue[mdegrees]==true) { + if (selmenue[mxytastatur]==true) { + selmenue[mxytastatur]=false; + ausmenueelement(mxytastatur); + } + inittastaturtext(nullstr,pr2menue[mdegrees],1L); + } + if (selmenue[mdegrees]==false) { + erwartet=click_erwartet; + strcpy(pr5,nullstr); + strcpy(pr6,nullstr); + } + } + if (selmenue[mgroupok]==true) + phase=groupok(msel, phase); + if ( (i == mkopbewmaus) && + ((*msel == mkopieren)||(*msel == mbewegen)) ) + i =*msel; + if (radiogroup[i] != 1) return phase; + /*zurueck, falls kein neue Aktion erforderlich*/ + /* Auswahl eines neuen Zeichenvorgangs */ + /* falls Editieren Text abgebrochen wurde, Text wieder ausgeben */ + if ((*msel == mtext)&&(texterase != 0L)) { + elsel = texterase; + texterase = 0L; + ausel(elsel, paint); + } + kompakt(); /*vorlauefig belegte Elemente freigeben*/ + if (*msel == mloeschen) + unbenutztegruppenfreigeben(); + + *msel = i; + if (zeichnen==true) + { /*nach delete oder move wieder auszugeben*/ + auselemente(); + } + threadaktiv = 0; +#ifdef THREAD + if (*msel == mread) { + threadaktiv = 1; + if (threadrunning == 0) { + threadrunning = 1; + pthread_create(&threadID,pthread_attr_default, (void*)threadreadstdin, NULL); + } + } +#endif + phase=0; + erwartet = click_erwartet; + winerwartet = 0; + if (selmenue[mxytastatur]==true) { + selmenue[mxytastatur]=false; + ausmenueelement(mxytastatur); + } + /* Ende Aktion im Menuebereich */ + } + LZ: if (phase == 0) { + blinkenaus(); + strcpy(pr1, "select/ "); + strcpy(pr2, menue[*msel]); + strcpy(pr3, nullstr); + strcpy(pr4, pr2menue[*msel]); + strcpy(pr5, nullstr); + strcpy(pr6, nullstr); + } + koordinateneingegeben=false; + /* Aktion im Zeichenbereich */ + if (*msel==0) return 0; + else if (*msel==mladen) + phase=eindatei(msel,dateiname,taste,phase); + else if (*msel==mende) { + phase=ausdatei(msel,dateiname,taste,phase); + if (phase==0) schluss(0); /* exit */ + } + else if (*msel==msave) /*zwischenspeichern*/ + phase = savedateien(msel,dateiname,taste,phase); + else if (*msel == mtext) + phase=eintext(xs,ys,xa,ya,taste,msel,phase); + else if (*msel == mgerade) + phase=einline(xs,ys,xa,ya,taste,msel,phase); + else if (*msel == mkreis) + phase=eincircle(xs,ys,taste,msel,phase); + else if (*msel == mell) + phase=einellipse(xs,ys,xa,ya,taste,msel,phase); + else if (*msel == mrechteck) + phase=einbox(xs,ys,taste,msel,phase); + else if (*msel == mdreieck) + phase=eindreieck(xs,ys,taste,msel,phase); + else if (*msel == mviereck) + phase=einviereck(xs,ys,taste,msel,phase); + else if (*msel == mbezier) + phase=einbezier(xs,ys,taste,msel,phase); + else if (*msel == mpolygon) + phase=einpolygon(xs,ys,taste,msel,phase); + else if (*msel == mspiegeln) + phase=spiegeln(xs,ys,xa,ya,xe,ye,taste,msel,phase); + else if (*msel == mkopieren) + phase=kopieren(xs,ys,xa,ya,xe,ye,taste,msel,phase); + else if (*msel == mbewegen) + phase=bewegen(xs,ys,xa,ya,xe,ye,taste,msel,phase); + else if (*msel == mergaenzen) + phase=einboxll(xa,ya,msel,phase); + else if (*msel == mausdehnen) + phase=extend(xa, ya, msel,phase); + else if (*msel == mbrechen) + phase=trim(xa,ya,msel,phase); + else if (*msel == mloeschen) + phase=loeschen(xa,ya,xe,ye,taste,msel,phase); + else if (*msel == mup) + phase=up(xa,ya,xe,ye,taste,msel,phase); + else if (*msel == mdown) + phase=down(xa,ya,xe,ye,taste,msel,phase); + else if (*msel == mchangelineattr) + phase=changelineattr(xa,ya,xe,ye,taste,msel,phase); + else if (*msel == mgitter) + phase=eingitter(xs,ys,msel,phase); + else if (*msel == mcut) + phase=vorber_export(xs,ys,xa,ya,xe,ye,taste,msel,phase); + else if (*msel == mpaste) + phase=vorber_import(xs,ys,taste,msel,phase); + else if (*msel == mfill) + phase=fuellen(xa,ya,msel,phase); + else if (*msel == mshowgroup) + phase=showgroup(xa,ya,taste,msel,phase); + else if (*msel== mnewgroup) + phase=newgroup(xa,ya,xe,ye,taste,msel,phase); + else if (*msel== mungroup) + phase=ungroup(xa,ya,taste,msel,phase); + else if (*msel == mconnect) + phase = connect(xs,ys,xa,ya,taste,msel,phase); + else if (*msel == mrot) + phase=rotieren(xs,ys,xa,ya,xe,ye,taste,msel,phase); + else if (*msel == mqueryattr) + phase=queryattr(xa,ya,taste,msel,phase); +#ifndef THREAD + /* nur bei keinem Thread */ + else if (*msel == mread) + phase=readstdin(msel,phase); +#endif + else return phase; + /* Ende im Zeichenbereich */ + LE: + if (phase==0) goto LZ; + return phase; + +} /* Ende Aktion */ + +Static Void init_neuezeichnung() +{ long i; + + texfaktor = texfaktorv; + breite=xzmax0*texfaktor; + hoehe=yzmax0*texfaktor; + mitvorspann=false; + querformat=true; + texdashl = 2.0; + texdotg = 1.8; + texinterd = 0.8; + version = 15.0; + initelemente(); + initgrid(); + fontnummer = stdfontnummer; + strcpy(menue[mfont],textfontlabel[fontnummer]); + aktldicke = 1; + strichsymbol(); + readdxx = 0.0; + readdyy = 0.0; + readf = 1.0; + aktreadzeit = 2; + readzeitsymbol(); + aktcolor = schwarz; + colorsymbol(); + for (i = 1; i <= 4; i++) + bmarker[i] = false; + for (i=0;i<=maxgruppen;i++) { + vater[i] = -1; + umbenennung[i] = 0; + gruppentag[i] = false; + } + vater[0] = 0; + grumax = 0; +} + +main(argc, argv) +int argc; +Char *argv[]; +{ + long i, k, taste, iv, msel, elsel; + + xzmax0 = xzmax00; /* Voreinstellung Gr"o\ss{}e Zeichenfenster */ + yzmax0 = yzmax00; + quer0format=false; + tablett = false; + nur_texausgabe=false; /*Normalmodus interaktiv von latexdraw */ + strcpy(docstyle, docstylestd); /* erste LaTeX-Zeile Standard */ + strcpy(menuefont,xfont); /* Standard-Menuefont */ + for (iv=1;iv<argc;iv++) { +#ifdef TABLETT + if (strvergl(argv[iv],"-t")==true) tablett = true; +#endif + if (strvergl(argv[iv],"-q")==true) + quer0format= true; + if (strvergl(argv[iv],"-l")==true) + quer0format= true; + if (strvergl(argv[iv],"-2e")==true) + strcpy(docstyle, docstyle2e); /* erste LaTeX-Zeile f"ur LaTeX2e */ + if ((strvergl(argv[iv],"-d")==true)&&((iv+1) < argc)) + strcpy(docstyle,argv[iv+1]); /* erste LaTeX-Zeile vom Benutzer */ + if ((strvergl(argv[iv],"-f")==true)&&((iv+1) < argc)) + strcpy(menuefont,argv[iv+1]); /* Menuefont des Benutzers */ + if ((strvergl(argv[iv],"-s")==true)&&((iv+1) < argc)) { + /* Gr"o\ss{}e Zeichenfenster vom Benutzer, Form z.B. 480x375 */ + i = sscanf(argv[iv+1],"%lgx%lg",&xzmax,&yzmax); + if ((i==2)&&(xzmax>0)&&(xzmax<2000)&&(yzmax>0)&&(yzmax<2000)) { + xzmax0 = xzmax; + yzmax0 = yzmax; + } + } + if ((strvergl(argv[iv],"-io")==true)&&((iv+2) < argc)) { + nur_texausgabe=true; /* nur LaTex-Ausgabedatei erzeugen!! */ + strcpy(dateiname,argv[iv+1]); /* Name LaTexDraw-Eingabedatei */ + strcpy(texdateiname,argv[iv+2]); /* Name LaTex-Ausgabedatei */ + } + } + + init_tmenue(); + if (( display = XOpenDisplay(display_name))== NULL) fehler(6); + screen = DefaultScreen(display); + nocolors = false; /* Farben verfuegbar */ + if (DisplayPlanes(display,screen)<=2) + /*monochrom oder wenige Graustufen*/ nocolors = true; + initfarbnamen(); + init_window_font(display); + win = XCreateSimpleWindow( + display,RootWindow(display,screen),0,0,ixzmax,iyzmax,4, + BlackPixel(display,screen), WhitePixel(display,screen)); + initfarben(screen, display, win); + reihenfolgefarben(); + initGC(screen, display, win); + setze_clip_bereiche(display); + size_hints.flags = PPosition | PSize ; + size_hints.x = 0; + size_hints.y = 0; + size_hints.width = ixzmax; + size_hints.height = iyzmax; + XSetStandardProperties(display,win,window_name,icon_name,None, + argv,argc,&size_hints); + XSelectInput(display,win,ExposureMask | KeyPressMask | KeyReleaseMask | + ButtonPressMask | ButtonReleaseMask | + StructureNotifyMask | Button1MotionMask); + clickcursor=XCreateFontCursor(display,XC_left_ptr); + busycursor=XCreateFontCursor(display,XC_heart); + textcursor=XCreateFontCursor(display,XC_dotbox); + if (nur_texausgabe == false) + XMapWindow(display,win); + XSetInputFocus(display,PointerRoot,RevertToPointerRoot,CurrentTime); + XSetErrorHandler(myerrorhandler); + geoeffnet=0; + init_kmenue(); + initmisc(); + initcutpaste(); +#ifdef TABLETT + /* Falls ein Digitizer angeschlossen ist, initialisieren */ + if (tablett) { + if (init_digitizer(display) == -1) + fehler(18); + } +#endif + msel = 0; + datdeskr = NULL; + erwartet=click_erwartet; + winerwartet = 0; + phase=0; + if (nur_texausgabe == false) + strcpy(dateiname,nullstr); + curs_x = -100.0; + curs_y = -100.0; + LNEU: + init_neuezeichnung(); + xlast=0.0; + ylast=0.0; + for (i = 1; i <= zmenue; i++) + selmenue[i] = false; + selmenue[msel] = true; + selmenue[meinrasten] = true; + selmenue[mltext] = true; + selmenue[mbtext] = true; + selmenue[mgroupmode] = true; + strcpy(pr1, "select/ "); + strcpy(pr2, menue[msel]); + strcpy(pr3, nullstr); + strcpy(pr4, nullstr); + strcpy(pr5, nullstr); + strcpy(pr6, nullstr); + taste=0; + button1gedrueckt =0; + button2gedrueckt =0; + button3gedrueckt =0; + controlan = 0; + blinkend = false; + koordinateneingegeben=false; + dragbox=0; + setwinkelrot(90); + + if (nur_texausgabe == true) { + /* nur Erzeugung der LaTeX-Ausgabedatei */ + /* Option -io bei Aufruf von latexdraw */ + taste = 0; + msel = mladen; + phase = 2; + eindatei(&msel,dateiname,taste,phase); + msel = msave; + phase = 7; + austexdatei(&msel,dateiname,taste,phase); + schluss(0); + } + +/* Event-Schleife */ +while (1) { + if (geoeffnet==1) { + if (phase==0) { + strcpy(pr1,"select/"); + strcpy(pr2,nullstr); + strcpy(pr3,nullstr); + strcpy(pr4,nullstr); + strcpy(pr5,nullstr); + strcpy(pr6,nullstr); + if (msel != 0) { + strcpy(pr1, "select/ "); + strcpy(pr2, menue[msel]); + strcpy(pr4, pr2menue[msel]); + } + } + prompt(); + if (erwartet==click_erwartet) + XDefineCursor(display,win,clickcursor); + else { + XDefineCursor(display,win,textcursor); + cursan(curs_x,curs_y); + } + } + if ((blinkend==true)&&(geoeffnet==1)) { + while ( (int)XEventsQueued(display, QueuedAfterFlush) == 0) { +#ifdef TABLETT + if (tablett) + process_digitizer(display, win); +#endif + ausblinkelemente(); + } + /* folgende zwei Befehle, damit nach Klick die Elemente */ + /* ggf. sofort wieder geloescht dargestellt werden */ + blinkfarbe = erase; + blinkintervallzaehler = 0; + } + + /* Eingabe ueber digitizer oder STDIN, solange kein X-Event */ + while ( (int)XEventsQueued(display, QueuedAfterFlush) == 0) { + +#ifdef TABLETT + if (tablett) { + process_digitizer(display, win); + } +#endif + +#ifdef THREAD + if (threadausel==1) { + threadausel=0; + kompakt(); + ausfastalles(); + /* nachfolgendes sleep kleiner als sleep in thread (derzeit Sekunden) */ + /* sonst geht Abfrage von threadausel nicht */ + } +#endif + +#ifndef THREAD + if (msel == mread) { + phase = readstdin(&msel,phase); + } +#endif + + + ltd_usleep(0L,30000); /* 30 ms Wartezeit */ + } + + + + XNextEvent(display, &report); + if (dragbox==1) xorrechteck(xanf,yanf,xend,yend); + dragbox=0; + switch (report.type) + { + case Expose: + geoeffnet = 1; + /* weitere vorhandene Expose-Events ignorieren */ + while (XCheckTypedEvent(display,Expose,&report)) ; + ausalles(); + break; + case ConfigureNotify: +#ifdef TABLETT + if (tablett) + save_win_pos(report.xconfigure.x, report.xconfigure.y, + report.xconfigure.width,report.xconfigure.height); +#endif + size_change(display, + report.xconfigure.width,report.xconfigure.height); + break; + case ButtonPress: + if (report.xbutton.button==button1) button1gedrueckt=1; + if (report.xbutton.button==button2) button2gedrueckt=1; + if (report.xbutton.button==button3) button3gedrueckt=1; + + taste=0; + if (button1gedrueckt==1) taste = 1; + if (button2gedrueckt==1) taste = 10*taste+2; + if (button3gedrueckt==1) taste = 10*taste+3; + + getweltkoord(&xanf,&yanf); + xend=xanf; + yend=yanf; + break; + + case MotionNotify: + while (XCheckMaskEvent(display,Button1MotionMask,&report)); + if (erwartet != click_erwartet) break; + if (button1gedrueckt==0) break; + if (!XQueryPointer(display, win, &rootwin, &childwin, + &irootx, &irooty,&iwinx, &iwiny, + &keysbuttons)) break; + getmotionweltkoord(iwinx, iwiny, &xsnap, &ysnap); + if ((dragbox == 1)&&(si_iabs(xsnap-xend) < 2)&& + (si_iabs(ysnap-yend) < 2)) + break; + xend = xsnap; + yend = ysnap; + xorrechteck(xanf,yanf,xend,yend); + dragbox=1; + break; + + case ButtonRelease: + if (report.xbutton.button==button1) button1gedrueckt=0; + if (report.xbutton.button==button2) button2gedrueckt=0; + if (report.xbutton.button==button3) button3gedrueckt=0; + lasteventtime=report.xbutton.time; + getweltkoord(&xend,¥d); + if (xanf<xgr) {/* in Menue */ + phase = aktion(&msel,xanf,yanf,xanf,yanf,xanf,yanf,taste,phase); + break; + } + if (erwartet != click_erwartet) break; + if (report.xbutton.button!=button1) break; + xsnap=xanf; + ysnap=yanf; + if (selmenue[meinrasten]==true) elsnap(&xsnap, &ysnap); + if (selmenue[mmittelpunkt]==true){ + sucheelement((long)nurmpel, &elsel, xanf, yanf); + if (elsel!=0) + { + xsnap = x1[elsel]; + ysnap = y1_[elsel]; + if (typ[elsel] == tgerade || typ[elsel] == trechteckgef) + { + xsnap = (x1[elsel] + x2[elsel]) / 2; + ysnap = (y1_[elsel] + y2[elsel]) / 2; + } + if (typ[elsel] == tdreieckgef) + schwerpunkt(elsel,&xsnap,&ysnap); + } + } + if ((si_fabs(xanf-xend)>15.0)||(si_fabs(yanf-yend)>15.0)) { + if (si_fabs(xanf-xend) > si_fabs(yanf-yend)) { + /*horizontaler Strich, also horizontale Ausrichtung*/ + if (si_fabs(xanf-xend)>15.0) + ysnap=ylast; /*Ausrichtung Punkt */ + } + else { + /*vertikaler Strich, also vertikale Ausrichtung*/ + if (si_fabs(yanf-yend)>15.0) + xsnap=xlast; /*Ausrichtung Punkt */ + } + } + xlast=xsnap; + ylast=ysnap; + neueclickmarke(xsnap,ysnap); + if ((si_fabs(xanf-xend)<5.0)||(si_fabs(yanf-yend)<5.0)){ + xend=xanf; + yend=yanf; + } + phase = aktion(&msel,xsnap,ysnap,xanf,yanf,xend,yend,taste,phase); + break; + + case KeyPress: + taste=XLookupString(&report.xkey,symstr,maxstrl,&keysym,&compose); + if (keysym==NoSymbol) break; + taste= keysym; + control(taste, 1L); + if (erwartet != tastatur_erwartet) {/* Sondertasten */ + if ( (msel==mloeschen)&& + ((taste==tastebackspace)|| + (taste==tasteundo)||(taste == tastedelete)) ) { + /*loeschen ist aktiv, backspace bedeutet undo*/ + UnDelete(); + phase = 1; + } + sondertaste (taste); + break; + } + if (tastaturtext(taste)!=0) break; + taste = 0; + if (selmenue[mxytastatur]==true) { + phasexyein = xyein(&xsnap, &ysnap,taste,phasexyein); + xanf=xsnap; + yanf=ysnap; + xend=xsnap; + yend=ysnap; + neueclickmarke(xsnap,ysnap); + taste = 1; + koordinateneingegeben=true; + /* initialisierung in aktion ! */ + } + phase = + aktion(&msel,xsnap,ysnap,xanf,yanf,xend,yend,taste,phase); + break; + case KeyRelease: + taste=XLookupString(&report.xkey,symstr,maxstrl,&keysym,&compose); + if (keysym==NoSymbol) break; + taste= keysym; + control(taste, 0L); + break; + case SelectionClear: + if (selmenue[mcut] == true) + {selmenloeschen(&msel); exportieren();} + break; + case SelectionNotify: + importieren(report.xselection.property,report.xselection.time,&msel); + break; + case SelectionRequest: + request_export(report.xselectionrequest.requestor, + report.xselectionrequest.property, + report.xselectionrequest.target, + report.xselectionrequest.time); + break; + } /* of case */ + if (wartendexport==true) exportieren(); + } /*end of while Event*/ +} /* End. */ + + + + + + + + + + + + + + |