home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume17 / xtexcad1 / part03 < prev    next >
Encoding:
Text File  |  1992-04-20  |  50.5 KB  |  1,968 lines

  1. Newsgroups: comp.sources.x
  2. Path: uunet!zaphod.mps.ohio-state.edu!mips!msi!dcmartin
  3. From: Fritz Haubensak <hsk@informatik.uni-wuerzburg.de>
  4. Subject: v17i067: TeXcad (X) version 1.2, Part03/10
  5. Message-ID: <1992Apr21.130820.2239@msi.com>
  6. Originator: dcmartin@fascet
  7. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  8. Nntp-Posting-Host: fascet
  9. Organization: Molecular Simulations, Inc.
  10. References: <csx-17i065-xtexcad-1.2@uunet.UU.NET>
  11. Date: Tue, 21 Apr 1992 13:08:20 GMT
  12. Approved: dcmartin@msi.com
  13. Lines: 1953
  14.  
  15. Submitted-by: Fritz Haubensak <hsk@informatik.uni-wuerzburg.de>
  16. Posting-number: Volume 17, Issue 67
  17. Archive-name: xtexcad-1.2/part03
  18.  
  19. # this is part.03 (part 3 of a multipart archive)
  20. # do not concatenate these parts, unpack them in order with /bin/sh
  21. # file graphics.c continued
  22. #
  23. if test ! -r _shar_seq_.tmp; then
  24.     echo 'Please unpack part 1 first!'
  25.     exit 1
  26. fi
  27. (read Scheck
  28.  if test "$Scheck" != 3; then
  29.     echo Please unpack part "$Scheck" next!
  30.     exit 1
  31.  else
  32.     exit 0
  33.  fi
  34. ) < _shar_seq_.tmp || exit 1
  35. if test ! -f _shar_wnt_.tmp; then
  36.     echo 'x - still skipping graphics.c'
  37. else
  38. echo 'x - continuing file graphics.c'
  39. sed 's/^X//' << 'SHAR_EOF' >> 'graphics.c' &&
  40. X            /* the global variable <shadow> decides, which shadow */
  41. X            /* will be drawn */
  42. X            left();
  43. X        }
  44. X        graph_action='D';
  45. X        print_head(graph_action);
  46. X        leave_translation();
  47. X        set_first();    
  48. X        break;    /* dashedBox terminated */
  49. X
  50. X    case 'F':    /* filledBox_curr points to incomplete structure */
  51. X        /* forget translations */
  52. X        XtUninstallTranslations(pboard); 
  53. X        filledBox_curr->h = (float) x;
  54. X        filledBox_curr->v = (float) y;
  55. X        norm_rectangle(&filledBox_curr->x, &filledBox_curr->y,
  56. X                   &filledBox_curr->h, &filledBox_curr->v);
  57. X        if (zoomed == True)
  58. X        {
  59. X            /* translate first coordinate to real-system */
  60. X            a1 = filledBox_curr->x;
  61. X            a2 = filledBox_curr->y;
  62. X            zoomed2real(&a1, &a2);
  63. X            filledBox_curr->x = a1;
  64. X            filledBox_curr->y = a2;
  65. X
  66. X            /* translate second coordinate to real-system */
  67. X
  68. X            e1 = filledBox_curr->h;
  69. X            e2 = filledBox_curr->v;
  70. X            zoomed2real(&e1, &e2);
  71. X            filledBox_curr->h = e1;
  72. X            filledBox_curr->v = e2;
  73. X        }
  74. X        graph_action='F';
  75. X        print_head(graph_action);
  76. X        leave_translation();
  77. X        set_first();
  78. X        break;    /* filledBox terminated */
  79. X
  80. X    case 'C':    /* correct coordinates */
  81. X        /* forget translations */
  82. X        XtUninstallTranslations(pboard); 
  83. X        valid_kreis_coords((int) kreis_curr->x, (int) kreis_curr->y, &x, &y, &r);
  84. X        /* kreis_curr points to incomplete srtucture */
  85. X        kreis_curr->h = (float) x;
  86. X        kreis_curr->v = (float) y;
  87. X        kreis_curr->radius = r;
  88. X        if (zoomed == True)
  89. X            zoomed2real(&kreis_curr->x, &kreis_curr->y);
  90. X        kreis_curr->next = NULL;
  91. X        graph_action='C';
  92. X        leave_translation();
  93. X        set_first();
  94. X        break;
  95. X
  96. X    case 'B':    /* correct coordinates */
  97. X        /* forget translations */
  98. X        XtUninstallTranslations(pboard); 
  99. X        valid_disc_coords((int) disc_curr->x, (int) disc_curr->y, &x, &y, &r);
  100. X        /* disc_curr points to incomplete srtucture */
  101. X        disc_curr->h = (float) x;
  102. X        disc_curr->v = (float) y;
  103. X        disc_curr->radius = r;
  104. X        if (zoomed == True)
  105. X            zoomed2real(&disc_curr->x, &disc_curr->y);
  106. X        disc_curr->next = NULL;
  107. X        graph_action='B';
  108. X        leave_translation();
  109. X        set_first();
  110. X        break;
  111. X
  112. X    case 'O':    /* oval_curr points to incomplete structure */
  113. X        /* forget translations */
  114. X        XtUninstallTranslations(pboard); 
  115. X        oval_curr->h = (float) x;
  116. X        oval_curr->v = (float) y;
  117. X        norm_rectangle(&oval_curr->x, &oval_curr->y,
  118. X                   &oval_curr->h, &oval_curr->v);
  119. X        if (zoomed == True)
  120. X        {
  121. X            /* translate first coordinate to real-system */
  122. X            a1 = oval_curr->x;
  123. X            a2 = oval_curr->y;
  124. X            zoomed2real(&a1, &a2);
  125. X            oval_curr->x = a1;
  126. X            oval_curr->y = a2;
  127. X
  128. X            /* translate second coordinate to real-system */
  129. X
  130. X            e1 = oval_curr->h;
  131. X            e2 = oval_curr->v;
  132. X            zoomed2real(&e1, &e2);
  133. X            oval_curr->h = e1;
  134. X            oval_curr->v = e2;
  135. X        }
  136. X        graph_action='O';
  137. X        print_head(graph_action);
  138. X        leave_translation();
  139. X        set_first();
  140. X        break;    /* oval terminated */
  141. X
  142. X    default:
  143. X        break;
  144. X
  145. X    }    /* switch */
  146. }
  147. X
  148. X
  149. X
  150. X
  151. X
  152. void
  153. enable_tracker()
  154. {
  155. X    /* Add to Translation Manager */
  156. X    XtTranslations  trans_table;
  157. X    char            destination[80] = "<MotionNotify> : track_it() \n";
  158. X    static XtActionsRec actions[80] = {{"track_it", track_it}};
  159. X    XtAddActions(actions, XtNumber(actions));
  160. X    trans_table = XtParseTranslationTable(destination);
  161. X    XtOverrideTranslations(pboard, trans_table);
  162. }
  163. X
  164. X
  165. void
  166. disable_tracker()
  167. {
  168. X    /* Add to Translation Manager */
  169. X    XtTranslations  trans_table;
  170. X    char            destination[80] = "<MotionNotify> : dummy()\n";
  171. X    static XtActionsRec actions[80] = {{"dummy", dummy}};
  172. X    XtAddActions(actions, XtNumber(actions));
  173. X    trans_table = XtParseTranslationTable(destination);
  174. X    XtOverrideTranslations(pboard, trans_table);
  175. }
  176. X
  177. X
  178. void
  179. track_it(int *x0, int *y0)
  180. {
  181. X    Display        *disp;
  182. X    Drawable        win;
  183. X    int             x, y, r, r2;
  184. X    float           x_old, y_old, h_old, v_old;
  185. X    unsigned int    mask;
  186. X
  187. X
  188. X    disp = XtDisplay(pboard);
  189. X    win = XtWindow(pboard);
  190. X    if ((graph_action == 'N') || (graph_action == 'F') || 
  191. X            (graph_action == 'D') || (graph_action == 'O') ||
  192. X        (graph_action == 'I'))
  193. X        snapPointerPosition(&x, &y, &mask);
  194. X    else
  195. X        PointerPosition(&x, &y, &mask);
  196. X
  197. X    /* rubber-band-effect */
  198. X    switch (graph_action)
  199. X    {
  200. X    case 'I':
  201. X        x_old = bezier_curr->ax;    /* get old coordinates (firstpress) */
  202. X        y_old = bezier_curr->ay;
  203. X
  204. X        h_old = bezier_curr->ex;
  205. X        v_old = bezier_curr->ey;
  206. X        if (h_old != -999)
  207. X            XDrawLine(disp, win, gc, (int) x_old, (int) y_old, (int) h_old, (int) v_old);
  208. X        /* old line deleted */
  209. X        /* -999 is an impossible coordinate and used as marker */
  210. X        bezier_curr->ex = (float) x;    /* save new coordinates */
  211. X        bezier_curr->ey = (float) y;
  212. X        /* draw new line */
  213. X        XDrawLine(disp, win, gc, (int) x_old, (int) y_old, x, y);    /* draw new */
  214. X        /* return coordinates */
  215. X        (*x0) = x;
  216. X        (*y0) = y;
  217. X        break;
  218. X
  219. X    case 'L':
  220. X        x_old = strich_curr->x;    /* get old coordinates (firstpress) */
  221. X        y_old = strich_curr->y;
  222. X
  223. X        h_old = strich_curr->h;
  224. X        v_old = strich_curr->v;
  225. X        if (h_old != -999)
  226. X            XDrawLine(disp, win, gc, (int) x_old, (int) y_old, (int) h_old, (int) v_old);
  227. X        /* old line deleted */
  228. X        /* -999 is an impossible coordinate and used as marker */
  229. X        valid_line_coords((int) x_old, (int) y_old, &x, &y);
  230. X        strich_curr->h = (float) x;    /* save new coordinates */
  231. X        strich_curr->v = (float) y;
  232. X        /* draw new line */
  233. X        XDrawLine(disp, win, gc, (int) x_old, (int) y_old, x, y);    /* draw new */
  234. X        /* return coordinates */
  235. X        (*x0) = x;
  236. X        (*y0) = y;
  237. X        break;
  238. X
  239. X    case 'V':
  240. X        x_old = pfeil_curr->x;    /* get old coordinates (firstpress) */
  241. X        y_old = pfeil_curr->y;
  242. X
  243. X        h_old = pfeil_curr->h;
  244. X        v_old = pfeil_curr->v;
  245. X        if (h_old != -999)
  246. X            XDrawLine(disp, win, gc, (int) x_old, (int) y_old, (int) h_old, (int) v_old);
  247. X        /* old line deleted */
  248. X        /* -999 is an impossible coordinate and used as marker */
  249. X        valid_vector_coords((int) x_old, (int) y_old, &x, &y);
  250. X        pfeil_curr->h = (float) x;    /* save new coordinates */
  251. X        pfeil_curr->v = (float) y;
  252. X        /* draw new line */
  253. X        XDrawLine(disp, win, gc, (int) x_old, (int) y_old, x, y);    /* draw new */
  254. X        /* return coordinates */
  255. X        (*x0) = x;
  256. X        (*y0) = y;
  257. X        break;
  258. X
  259. X    case 'N':    /* normate (x,y)-coordinates --> upper left corner.  */
  260. X        if (((framedBox_curr->h) != (float) x) || ((framedBox_curr->v) != (float) y))
  261. X        {    /* redraw is necessary !! */
  262. X            x_old = (framedBox_curr->x);
  263. X            y_old = (framedBox_curr->y);
  264. X            h_old = (framedBox_curr->h);
  265. X            v_old = (framedBox_curr->v);
  266. X            norm_rectangle(&x_old, &y_old, &h_old, &v_old);
  267. X            if ((framedBox_curr->h) != -999)
  268. X                XDrawRectangle(disp, win, gc, (int) x_old, (int) y_old,
  269. X                         (unsigned int) (h_old - x_old),
  270. X                        (unsigned int) (v_old - y_old));
  271. X            (framedBox_curr->h) = (float) x;
  272. X            (framedBox_curr->v) = (float) y;
  273. X            /* new line */
  274. X            x_old = (framedBox_curr->x);
  275. X            y_old = (framedBox_curr->y);
  276. X            h_old = (framedBox_curr->h);
  277. X            v_old = (framedBox_curr->v);
  278. X            norm_rectangle(&x_old, &y_old, &h_old, &v_old);
  279. X            XDrawRectangle(disp, win, gc, (int) x_old, (int) y_old,
  280. X                       (unsigned int) (h_old - x_old),
  281. X                       (unsigned int) (v_old - y_old));
  282. X        }    /* redraw was necessary */
  283. X        (*x0) = x;
  284. X        (*y0) = y;
  285. X        break;
  286. X
  287. X    case 'D':    /* normate (x,y)-coordinates --> upper left corner.  */
  288. X        if (((dashedBox_curr->h) != (float) x) || ((dashedBox_curr->v) != (float) y))
  289. X        {    /* redraw is necessary !! */
  290. X            x_old = (dashedBox_curr->x);
  291. X            y_old = (dashedBox_curr->y);
  292. X            h_old = (dashedBox_curr->h);
  293. X            v_old = (dashedBox_curr->v);
  294. X            norm_rectangle(&x_old, &y_old, &h_old, &v_old);
  295. X            XSetLineAttributes(disp, gc, 0, LineOnOffDash, CapButt, JoinMiter);
  296. X            if ((dashedBox_curr->h) != -999)
  297. X                XDrawRectangle(disp, win, gc, (int) x_old, (int) y_old,
  298. X                         (unsigned int) (h_old - x_old),
  299. X                        (unsigned int) (v_old - y_old));
  300. X            (dashedBox_curr->h) = (float) x;
  301. X            (dashedBox_curr->v) = (float) y;
  302. X            /* new line */
  303. X            x_old = (dashedBox_curr->x);
  304. X            y_old = (dashedBox_curr->y);
  305. X            h_old = (dashedBox_curr->h);
  306. X            v_old = (dashedBox_curr->v);
  307. X            norm_rectangle(&x_old, &y_old, &h_old, &v_old);
  308. X            XDrawRectangle(disp, win, gc, (int) x_old, (int) y_old,
  309. X                       (unsigned int) (h_old - x_old),
  310. X                       (unsigned int) (v_old - y_old));
  311. X            XSetLineAttributes(disp, gc, 0, LineSolid, CapButt, JoinMiter);
  312. X        }    /* redraw was necessary */
  313. X        (*x0) = x;
  314. X        (*y0) = y;
  315. X        break;
  316. X
  317. X    case 'F':    /* normate (x,y)-coordinates --> upper left corner.  */
  318. X        if (((filledBox_curr->h) != (float) x) || ((filledBox_curr->v) != (float) y))
  319. X        {    /* redraw is necessary !! */
  320. X            x_old = (filledBox_curr->x);
  321. X            y_old = (filledBox_curr->y);
  322. X            h_old = (filledBox_curr->h);
  323. X            v_old = (filledBox_curr->v);
  324. X            norm_rectangle(&x_old, &y_old, &h_old, &v_old);
  325. X            if ((filledBox_curr->h) != -999)
  326. X                XFillRectangle(disp, win, gc, (int) x_old, (int) y_old,
  327. X                         (unsigned int) (h_old - x_old),
  328. X                        (unsigned int) (v_old - y_old));
  329. X            (filledBox_curr->h) = (float) x;
  330. X            (filledBox_curr->v) = (float) y;
  331. X            /* new line */
  332. X            x_old = (filledBox_curr->x);
  333. X            y_old = (filledBox_curr->y);
  334. X            h_old = (filledBox_curr->h);
  335. X            v_old = (filledBox_curr->v);
  336. X            norm_rectangle(&x_old, &y_old, &h_old, &v_old);
  337. X            XFillRectangle(disp, win, gc, (int) x_old, (int) y_old,
  338. X                       (unsigned int) (h_old - x_old),
  339. X                       (unsigned int) (v_old - y_old));
  340. X        }    /* redraw was necessary */
  341. X        (*x0) = x;
  342. X        (*y0) = y;
  343. X        break;
  344. X
  345. X    case 'C':
  346. X        r2 = kreis_curr->radius;    /* old radius */
  347. X        x_old = kreis_curr->x;    /* get old coordinates (firstpress) */
  348. X        y_old = kreis_curr->y;
  349. X        valid_kreis_coords((int) x_old, (int) y_old, &x, &y, &r);
  350. X        if (r != r2)
  351. X        {    /* r is new radius *//* redraw is necessary !! */
  352. X            h_old = kreis_curr->h;
  353. X            if (zoomed == True)
  354. X                r2 = r2 * 10;
  355. X            if (h_old != -999)
  356. X                XDrawArc(disp, win, gc,
  357. X                     (int) (x_old) - r2, (int) (y_old) - r2,
  358. X                     (unsigned int) (r2 + r2), (unsigned int) (r2 + r2),
  359. X                     0, 360 * 64);
  360. X
  361. X            /* old line deleted */
  362. X            /*
  363. X             * -999 is an impossible coordinate and used as
  364. X             * marker
  365. X             */
  366. X            kreis_curr->h = (float) x;    /* save new coordinates */
  367. X            kreis_curr->v = (float) y;
  368. X            kreis_curr->radius = r;
  369. X            if (zoomed == True)
  370. X                r = r * 10;
  371. X            /* draw new line */
  372. X            XDrawArc(disp, win, gc,
  373. X            (int) (x_old - (float) r), (int) (y_old - (float) r),
  374. X                 (unsigned int) (r + r), (unsigned int) (r + r), 0, 360 * 64);
  375. X            /* return coordinates */
  376. X        }    /* redraw was necessary */
  377. X        (*x0) = x;
  378. X        (*y0) = y;
  379. X        break;
  380. X
  381. X    case 'B':
  382. X        r2 = disc_curr->radius;    /* old radius */
  383. X        x_old = disc_curr->x;    /* get old coordinates (firstpress) */
  384. X        y_old = disc_curr->y;
  385. X        valid_disc_coords((int) x_old, (int) y_old, &x, &y, &r);
  386. X        if (r != r2)
  387. X        {    /* r is new radius *//* redraw is necessary !! */
  388. X            h_old = disc_curr->h;
  389. X            if (zoomed == True)
  390. X                r2 = r2 * 10;
  391. X            if (h_old != -999)
  392. X                XFillArc(disp, win, gc,
  393. X                     (int) (x_old) - r2, (int) (y_old) - r2,
  394. X                     (unsigned int) (r2 + r2), (unsigned int) (r2 + r2),
  395. X                     0, 360 * 64);
  396. X
  397. X            /* old line deleted */
  398. X            /*
  399. X             * -999 is an impossible coordinate and used as
  400. X             * marker
  401. X             */
  402. X            disc_curr->h = (float) x;    /* save new coordinates */
  403. X            disc_curr->v = (float) y;
  404. X            disc_curr->radius = r;
  405. X            if (zoomed == True)
  406. X                r = r * 10;
  407. X            /* draw new line */
  408. X            XFillArc(disp, win, gc,
  409. X            (int) (x_old - (float) r), (int) (y_old - (float) r),
  410. X                 (unsigned int) (r + r), (unsigned int) (r + r), 0, 360 * 64);
  411. X            /* return coordinates */
  412. X        }    /* redraw was necessary */
  413. X        (*x0) = x;
  414. X        (*y0) = y;
  415. X        break;
  416. X
  417. X    case 'O':    /* normate (x,y)-coordinates --> upper left corner.  */
  418. X        if (((oval_curr->h) != (float) x) || ((oval_curr->v) != (float) y))
  419. X        {    /* redraw is necessary !! */
  420. X            x_old = (oval_curr->x);
  421. X            y_old = (oval_curr->y);
  422. X            h_old = (oval_curr->h);
  423. X            v_old = (oval_curr->v);
  424. X            norm_rectangle(&x_old, &y_old, &h_old, &v_old);
  425. X            if ((oval_curr->h) != -999)
  426. X                DrawOval((int) x_old, (int) y_old, (int) h_old, (int) v_old);
  427. X            (oval_curr->h) = (float) x;
  428. X            (oval_curr->v) = (float) y;
  429. X            /* new line */
  430. X            x_old = (oval_curr->x);
  431. X            y_old = (oval_curr->y);
  432. X            h_old = (oval_curr->h);
  433. X            v_old = (oval_curr->v);
  434. X            norm_rectangle(&x_old, &y_old, &h_old, &v_old);
  435. X            DrawOval((int) x_old, (int) y_old, (int) h_old, (int) v_old);
  436. X        }    /* redraw was necessary */
  437. X        (*x0) = x;
  438. X        (*y0) = y;
  439. X        break;
  440. X
  441. X    default:
  442. X        break;
  443. X
  444. X    }    /* switch */
  445. X
  446. }/* track_it */
  447. X
  448. X
  449. X
  450. void
  451. valid_kreis_coords(int x, int y, int *h, int *v, int *rad)
  452. {
  453. X    /*
  454. X     * conclude from the coordinates, if the radius is correct (because
  455. X     * limited)
  456. X     */
  457. X    /* if not, return the correct values */
  458. X
  459. X    int             r, i, diameter, zoom;
  460. X    double          a, b;
  461. X    if (zoomed == True)
  462. X        zoom = 10;
  463. X    else
  464. X        zoom = 1;
  465. X    a = (*h) - x;
  466. X    b = (*v) - y;
  467. X    if (a < 0)
  468. X        a = a * (-1);
  469. X    if (b < 0)
  470. X        b = b * (-1);
  471. X    r = (int) sqrt((double) (a * a + b * b));
  472. X
  473. X    if (circle_diameter[0] == -1)
  474. X    {    /* no diameter restriction */
  475. X        (*rad) = r;
  476. X        if (zoomed == True)
  477. X        {
  478. X            a = (double) r;
  479. X            a = a / 10;
  480. X            if (a < 1.0)
  481. X                a = 1.0;
  482. X            (*rad) = (int) a;
  483. X        }
  484. X        return;
  485. X    }
  486. X    r += r;    /* r is  diameter */
  487. X
  488. X    i = 0;
  489. X    while (((circle_diameter[i]) != -1) && ((zoom * circle_diameter[i]) < r))
  490. X        i++;
  491. X
  492. X    if (i == 0)
  493. X        diameter = circle_diameter[i];
  494. X    else if (circle_diameter[i] == -1)
  495. X        diameter = circle_diameter[i - 1];
  496. X    else
  497. X    {
  498. X        /* circle_diameter[i]>=r */
  499. X        if ((r - (zoom * circle_diameter[i - 1])) < ((zoom * circle_diameter[i]) - r))
  500. X            diameter = circle_diameter[i - 1];
  501. X        else
  502. X            diameter = circle_diameter[i];
  503. X    }
  504. X
  505. X    /* <diameter> represents the correct LaTeX diameter */
  506. X
  507. X    r = (int) (0.5 * (float) diameter);    /* r is correct radius */
  508. X
  509. X    if (r < 1)
  510. X        r = 1;
  511. X
  512. X    (*rad) = r;
  513. X
  514. }
  515. X
  516. X
  517. void
  518. valid_disc_coords(int x, int y, int *h, int *v, int *rad)
  519. {
  520. X    /* see above */
  521. X
  522. X    int             r, i, diameter, zoom;
  523. X    double          a, b;
  524. X    if (zoomed == True)
  525. X        zoom = 10;
  526. X    else
  527. X        zoom = 1;
  528. X    a = (*h) - x;
  529. X    b = (*v) - y;
  530. X    if (a < 0)
  531. X        a = a * (-1);
  532. X    if (b < 0)
  533. X        b = b * (-1);
  534. X    r = (int) sqrt((double) (a * a + b * b));
  535. X
  536. X    if (disc_diameter[0] == -1)
  537. X    {    /* no diameter restriction */
  538. X        (*rad) = r;
  539. X        if (zoomed == True)
  540. X        {
  541. X            a = (double) r;
  542. X            a = a / 10;
  543. X            if (a < 1.0)
  544. X                a = 1.0;
  545. X            (*rad) = (int) a;
  546. X        }
  547. X        return;
  548. X    }
  549. X    r += r;    /* r is  diameter */
  550. X
  551. X    i = 0;
  552. X    while (((disc_diameter[i]) != -1) && ((zoom * disc_diameter[i]) < r))
  553. X        i++;
  554. X
  555. X    if (i == 0)
  556. X        diameter = disc_diameter[i];
  557. X    else if (disc_diameter[i] == -1)
  558. X        diameter = disc_diameter[i - 1];
  559. X    else
  560. X    {
  561. X        /* disc_diameter[i]>=r */
  562. X        if ((r - (zoom * disc_diameter[i - 1])) < ((zoom * disc_diameter[i]) - r))
  563. X            diameter = disc_diameter[i - 1];
  564. X        else
  565. X            diameter = disc_diameter[i];
  566. X    }
  567. X
  568. X    /* <diameter> represents the correct LaTeX diameter */
  569. X
  570. X    r = (int) (0.5 * (float) diameter);    /* r is correct radius */
  571. X
  572. X    if (r < 1)
  573. X        r = 1;
  574. X
  575. X
  576. X    (*rad) = r;
  577. X
  578. }
  579. X
  580. X
  581. X
  582. X
  583. X
  584. void
  585. dummy()
  586. {
  587. }
  588. X
  589. void
  590. leaving()
  591. {
  592. X    /* users had decided to leave without completion of action */
  593. X    int             i, x, y;
  594. X    Display        *disp;
  595. X    Drawable        win;
  596. X    char           *txt;
  597. X    int             zoom, rad;
  598. X
  599. X
  600. X
  601. X    if (zoomed == True)
  602. X        zoom = 10;
  603. X    else
  604. X        zoom = 1;
  605. X
  606. X    disp = XtDisplay(pboard);
  607. X    win = XtWindow(pboard);
  608. X
  609. X    /* throw away the incomplete struct */
  610. X    switch (graph_action)
  611. X    {
  612. X    case 'I':    /* delete last line of bezier*/
  613. X        if (bezier_curr == bezier_start)
  614. X        {    /* first entry */
  615. X            if (bezier_curr->ex!=-999.0)
  616. X                XDrawLine(disp, win, gc, (int) bezier_curr->ax, (int) bezier_curr->ay,
  617. X                    (int) bezier_curr->ex, (int) bezier_curr->ey);
  618. X            free(bezier_curr);    /* give memory back to system */
  619. X            bezier_curr = NULL;
  620. X            bezier_start = NULL;
  621. X        } else
  622. X        {
  623. X            for (bezier_marker = (struct fig6 *) bezier_start;
  624. X                 (bezier_marker->next != bezier_curr); bezier_marker = bezier_marker->next);
  625. X
  626. X            if (bezier_curr->ex!=-999.0)
  627. X                XDrawLine(disp, win, gc, (int) bezier_curr->ax, (int) bezier_curr->ay,
  628. X                    (int) bezier_curr->ex, (int) bezier_curr->ey);
  629. X            free(bezier_curr);
  630. X            bezier_curr = bezier_marker;    /* points to last
  631. X                             * complete struct */
  632. X        }
  633. X        break;
  634. X
  635. X    case 'L':    /* delete last line */
  636. X        if (strich_curr == strich_start)
  637. X        {    /* first entry */
  638. X            if (strich_curr->h!=-999.0)
  639. X                XDrawLine(disp, win, gc, (int) strich_curr->x, (int) strich_curr->y,
  640. X                    (int) strich_curr->h, (int) strich_curr->v);
  641. X            free(strich_curr);    /* give memory back to system */
  642. X            strich_curr = NULL;
  643. X            strich_start = NULL;
  644. X        } else
  645. X        {
  646. X            for (strich_marker = (struct fig2 *) strich_start;
  647. X                 (strich_marker->next != strich_curr); strich_marker = strich_marker->next);
  648. X
  649. X            if (strich_curr->h!=-999.0)
  650. X                XDrawLine(disp, win, gc, (int) strich_curr->x, (int) strich_curr->y,
  651. X                    (int) strich_curr->h, (int) strich_curr->v);
  652. X            free(strich_curr);
  653. X            strich_curr = strich_marker;    /* points to last
  654. X                             * complete struct */
  655. X        }
  656. X        break;
  657. X
  658. X    case 'V':    /* delete last vector */
  659. X        if (pfeil_curr == pfeil_start)
  660. X        {    /* first entry */
  661. X            if (pfeil_curr->h!=-999.0)
  662. X                XDrawLine(disp, win, gc, (int) pfeil_curr->x, (int) pfeil_curr->y,
  663. X                      (int) pfeil_curr->h, (int) pfeil_curr->v);
  664. X            free(pfeil_curr);    /* give memory back to system */
  665. X            pfeil_curr = NULL;
  666. X            pfeil_start = NULL;
  667. X        } else
  668. X        {
  669. X            for (pfeil_marker = (struct fig2 *) pfeil_start;
  670. X                 (pfeil_marker->next != pfeil_curr); pfeil_marker = pfeil_marker->next);
  671. X            if (pfeil_curr->h!=-999.0)
  672. X                XDrawLine(disp, win, gc, (int) pfeil_curr->x, (int) pfeil_curr->y,
  673. X                      (int) pfeil_curr->h, (int) pfeil_curr->v);
  674. X            free(pfeil_curr);
  675. X            pfeil_curr = pfeil_marker;    /* points to last
  676. X                             * complete struct */
  677. X        }
  678. X        break;
  679. X
  680. X    case 'N':    /* framed box: pointer was moved out of pboard ->
  681. X             * cancel operation ! */
  682. X        norm_rectangle(&framedBox_curr->x, &framedBox_curr->y,
  683. X                   &framedBox_curr->h, &framedBox_curr->v);
  684. X        if (framedBox_curr == framedBox_start)
  685. X        {    /* first entry */
  686. X            XDrawRectangle(disp, win, gc, (int) framedBox_curr->x, (int) framedBox_curr->y,
  687. X                       (unsigned int) ((int) ((framedBox_curr->h) - (framedBox_curr->x))),
  688. X                       (unsigned int) ((int) ((framedBox_curr->v) - (framedBox_curr->y))));
  689. X            free(framedBox_curr);    /* give memory back to system */
  690. X            framedBox_curr = NULL;
  691. X            framedBox_start = NULL;
  692. X        } else
  693. X        {
  694. X            for (framedBox_marker = (struct fig3 *) framedBox_start;
  695. X                 (framedBox_marker->next != framedBox_curr); framedBox_marker = framedBox_marker->next);
  696. X            XDrawRectangle(disp, win, gc, (int) framedBox_curr->x, (int) framedBox_curr->y,
  697. X                       (unsigned int) ((int) ((framedBox_curr->h) - (framedBox_curr->x))),
  698. X                       (unsigned int) ((int) ((framedBox_curr->v) - (framedBox_curr->y))));
  699. X            free(framedBox_curr);
  700. X            framedBox_curr = framedBox_marker;    /* points to last
  701. X                                 * complete struct */
  702. X        }
  703. X        break;
  704. X
  705. X    case 'D':    /* dashed box: pointer was moved out of pboard ->
  706. X             * cancel operation ! */
  707. X        norm_rectangle(&dashedBox_curr->x, &dashedBox_curr->y,
  708. X                   &dashedBox_curr->h, &dashedBox_curr->v);
  709. X        XSetLineAttributes(disp, gc, 0, LineOnOffDash, CapButt, JoinMiter);
  710. X        if (dashedBox_curr == dashedBox_start)
  711. X        {    /* first entry */
  712. X            XDrawRectangle(disp, win, gc, (int) dashedBox_curr->x, (int) dashedBox_curr->y,
  713. X                       (unsigned int) ((int) ((dashedBox_curr->h) - (dashedBox_curr->x))),
  714. X                       (unsigned int) ((int) ((dashedBox_curr->v) - (dashedBox_curr->y))));
  715. X            free(dashedBox_curr);    /* give memory back to system */
  716. X            dashedBox_curr = NULL;
  717. X            dashedBox_start = NULL;
  718. X        } else
  719. X        {
  720. X            for (dashedBox_marker = (struct fig4 *) dashedBox_start;
  721. X                 (dashedBox_marker->next != dashedBox_curr); dashedBox_marker = dashedBox_marker->next);
  722. X            XDrawRectangle(disp, win, gc, (int) dashedBox_curr->x, (int) dashedBox_curr->y,
  723. X                       (unsigned int) ((int) ((dashedBox_curr->h) - (dashedBox_curr->x))),
  724. X                       (unsigned int) ((int) ((dashedBox_curr->v) - (dashedBox_curr->y))));
  725. X            free(dashedBox_curr);
  726. X            dashedBox_curr = dashedBox_marker;    /* points to last
  727. X                                 * complete struct */
  728. X        }
  729. X        XSetLineAttributes(disp, gc, 0, LineSolid, CapButt, JoinMiter);
  730. X        break;
  731. X
  732. X    case 'F':    /* filled box: pointer was moved out of pboard ->
  733. X             * cancel operation ! */
  734. X        norm_rectangle(&filledBox_curr->x, &filledBox_curr->y,
  735. X                   &filledBox_curr->h, &filledBox_curr->v);
  736. X        if (filledBox_curr == filledBox_start)
  737. X        {    /* first entry */
  738. X            XFillRectangle(disp, win, gc, (int) filledBox_curr->x, (int) filledBox_curr->y,
  739. X                       (unsigned int) ((int) ((filledBox_curr->h) - (filledBox_curr->x))),
  740. X                       (unsigned int) ((int) ((filledBox_curr->v) - (filledBox_curr->y))));
  741. X            free(filledBox_curr);    /* give memory back to system */
  742. X            filledBox_curr = NULL;
  743. X            filledBox_start = NULL;
  744. X        } else
  745. X        {
  746. X            for (filledBox_marker = (struct fig2 *) filledBox_start;
  747. X                 (filledBox_marker->next != filledBox_curr); filledBox_marker = filledBox_marker->next);
  748. X            XFillRectangle(disp, win, gc, (int) filledBox_curr->x, (int) filledBox_curr->y,
  749. X                       (unsigned int) ((int) ((filledBox_curr->h) - (filledBox_curr->x))),
  750. X                       (unsigned int) ((int) ((filledBox_curr->v) - (filledBox_curr->y))));
  751. X            free(filledBox_curr);
  752. X            filledBox_curr = filledBox_marker;    /* points to last
  753. X                                 * complete struct */
  754. X        }
  755. X        break;
  756. X
  757. X    case 'C':    /* delete last normal circle */
  758. X        if (kreis_curr == kreis_start)
  759. X        {    /* first entry */
  760. X            rad = zoom * (kreis_curr->radius);
  761. X            XDrawArc(disp, win, gc, (int) (kreis_curr->x) - rad,
  762. X                 (int) (kreis_curr->y) - rad,
  763. X                 (unsigned int) (rad + rad),
  764. X                 (unsigned int) (rad + rad),
  765. X                 0, 360 * 64);
  766. X            free(kreis_curr);    /* give memory back to system */
  767. X            kreis_curr = NULL;
  768. X            kreis_start = NULL;
  769. X        } else
  770. X        {
  771. X            for (kreis_marker = (struct fig2 *) kreis_start;
  772. X                 (kreis_marker->next != kreis_curr); kreis_marker = kreis_marker->next);
  773. X
  774. X            rad = zoom * (kreis_curr->radius);
  775. X            XDrawArc(disp, win, gc, (int) (kreis_curr->x) - rad,
  776. X                 (int) (kreis_curr->y) - rad,
  777. X                 (unsigned int) (rad + rad),
  778. X                 (unsigned int) (rad + rad),
  779. X                 0, 360 * 64);
  780. X            free(kreis_curr);
  781. X            kreis_curr = kreis_marker;    /* points to last
  782. X                             * complete struct */
  783. X        }
  784. X        break;
  785. X
  786. X    case 'B':    /* delete last filled circle */
  787. X        if (disc_curr == disc_start)
  788. X        {    /* first entry */
  789. X            rad = zoom * (disc_curr->radius);
  790. X            XFillArc(disp, win, gc, (int) (disc_curr->x) - rad,
  791. X                 (int) (disc_curr->y) - rad,
  792. X                 (unsigned int) (rad + rad),
  793. X                 (unsigned int) (rad + rad),
  794. X                 0, 360 * 64);
  795. X            free(disc_curr);    /* give memory back to system */
  796. X            disc_curr = NULL;
  797. X            disc_start = NULL;
  798. X        } else
  799. X        {
  800. X            for (disc_marker = (struct fig2 *) disc_start;
  801. X                 (disc_marker->next != disc_curr); disc_marker = disc_marker->next);
  802. X
  803. X            rad = zoom * (disc_curr->radius);
  804. X            XFillArc(disp, win, gc, (int) (disc_curr->x) - rad,
  805. X                 (int) (disc_curr->y) - rad,
  806. X                 (unsigned int) (rad + rad),
  807. X                 (unsigned int) (rad + rad),
  808. X                 0, 360 * 64);
  809. X            free(disc_curr);
  810. X            disc_curr = disc_marker;    /* points to last
  811. X                             * complete struct */
  812. X        }
  813. X        break;
  814. X
  815. X    case 'O':    /* oval: pointer was moved out of pboard -> cancel
  816. X             * operation ! */
  817. X        norm_rectangle(&oval_curr->x, &oval_curr->y,
  818. X                   &oval_curr->h, &oval_curr->v);
  819. X        if (oval_curr == oval_start)
  820. X        {    /* first entry */
  821. X            DrawOval((int) oval_curr->x, (int) oval_curr->y,
  822. X                 (int) oval_curr->h, (int) oval_curr->v);
  823. X
  824. X            free(oval_curr);    /* give memory back to system */
  825. X            oval_curr = NULL;
  826. X            oval_start = NULL;
  827. X        } else
  828. X        {
  829. X            for (oval_marker = (struct fig1 *) oval_start;
  830. X                 (oval_marker->next != oval_curr); oval_marker = oval_marker->next);
  831. X            DrawOval((int) oval_curr->x, (int) oval_curr->y,
  832. X                 (int) oval_curr->h, (int) oval_curr->v);
  833. X            free(oval_curr);
  834. X            oval_curr = oval_marker;    /* points to last
  835. X                             * complete struct */
  836. X        }
  837. X        break;
  838. X
  839. X
  840. X    default:
  841. X        break;
  842. X
  843. X
  844. X        graph_action = '?';
  845. X
  846. X    }    /* switch */
  847. X
  848. X    /* throw away all translations */
  849. X    XtUninstallTranslations(pboard);
  850. X
  851. X    left();
  852. X
  853. }/* leaving */
  854. X
  855. X
  856. X
  857. void
  858. left(void)
  859. {
  860. X    headline(toplevel, titlename);
  861. X    graph_action = '?';
  862. }
  863. X
  864. X
  865. void
  866. norm_rectangle(float *x, float *y, float *h, float *v)
  867. {/* (x,y) and (h,v) are opposite (diagonal) coordinates  of a rectangle */
  868. X    /* this routine transforms (x,y) to the upper left... */
  869. X
  870. X    float           a1, a2;
  871. X    if (((*h) <= (*x)) && ((*v) <= (*y)))
  872. X    {
  873. X        a1 = (*x);
  874. X        a2 = (*y);
  875. X        (*x) = (*h);
  876. X        (*y) = (*v);
  877. X        (*h) = a1;
  878. X        (*v) = a2;
  879. X    } else if (((*h) >= (*x)) && ((*v) <= (*y)))
  880. X    {
  881. X        a1 = (*y);
  882. X        (*y) = (*v);
  883. X        (*v) = a1;
  884. X    } else if (((*h) <= (*x)) && ((*v) >= (*y)))
  885. X    {
  886. X        a1 = (*x);
  887. X        (*x) = (*h);
  888. X        (*h) = a1;
  889. X    }
  890. X    /*
  891. X     * if ( ((*h)>=(*x)) && ((*v)>=(*y)) )  this is already the right
  892. X     * case !
  893. X     */
  894. }
  895. X
  896. X
  897. X
  898. void
  899. zoomed2real(float *x, float *y)
  900. {
  901. X    /*
  902. X     * translates the coordinates of a zoomed screen into the
  903. X     * corresponding real-ones
  904. X     */
  905. X
  906. X    float           c,test;
  907. X
  908. X
  909. X    /* y coordinate translation */
  910. X
  911. X    c = ((float) y_A4_max - (*y)) / (*y);
  912. X    test=((float) (c + 1.0));
  913. X    test=(test==0) ? 0.0001 : test;
  914. X    (*y) = ((float) y_zoom_max + (c * (float) y_zoom_min)) / test;
  915. X
  916. X    /* x coordinate translation */
  917. X
  918. X    c = ((float) x_A4_max - (*x)) / (*x);
  919. X    test=((float) (c + 1.0));
  920. X    test=(test==0) ? 0.0001 : test;
  921. X    (*x) = ((float) x_zoom_max + c * (float) x_zoom_min) / test;
  922. X
  923. }
  924. X
  925. X
  926. X
  927. X
  928. X
  929. X
  930. X
  931. void
  932. real2zoomed(float *x, float *y)
  933. {
  934. X    /*
  935. X     * this function transfers coordinates from within the zoom-area to
  936. X     * the corresponding (zoomed) coordinates on the screen
  937. X     */
  938. X
  939. X    float           c,test;
  940. X
  941. X
  942. X    /* y coordinate translation */
  943. X    test=((*y) - (float) y_zoom_min);
  944. X    test=(test==0) ? 0.0001 : test;
  945. X    c = ((float) y_zoom_max - (*y)) / test;
  946. X    
  947. X    test=(float) (c + 1.0);
  948. X    test=(test==0) ? 0.0001 : test;
  949. X    (*y) = ((float) y_A4_max) / test;
  950. X
  951. X    /* x coordinate translation */
  952. X
  953. X    test=((*x) - (float) x_zoom_min);
  954. X    test=(test==0) ? 0.0001 : test;
  955. X    c = ((float) x_zoom_max - (*x)) / test;
  956. X    
  957. X    test=(float) (c + 1.0);
  958. X    test=(test==0) ? 0.0001 : test;
  959. X    (*x) = ((float) x_A4_max) / test;
  960. X
  961. X
  962. X
  963. X
  964. }
  965. X
  966. X
  967. X
  968. X
  969. X
  970. X
  971. int
  972. ggt(int a, int b)
  973. {
  974. X    /* compute the biggest common divisor of a and b */
  975. X    /* (c) by Euklid  */
  976. X
  977. X    int             r;
  978. X    if (b != 0)
  979. X        for (r = 1; r != 0; r = (a % b), a = b, b = r);
  980. X
  981. X    return a;
  982. }
  983. X
  984. X
  985. void
  986. valid_length(int x, int y, int *x_ret, int *y_ret)
  987. {
  988. X    /* if the length of a line/vector is less than 10 points */
  989. X    /* the coordinates have to be adjusted. this is an option in */
  990. X    /* the settings-menu */
  991. X
  992. X    float           lambda;
  993. X    int             newh, newv;
  994. X    int             h = (*x_ret);
  995. X    int             v = (*y_ret);
  996. X    int             zm = (zoomed == True) ? 10 * line_length : line_length;
  997. X
  998. X
  999. X    /* disabled ? */
  1000. X    if (line_length == 0)
  1001. X        return;
  1002. X
  1003. X
  1004. X    /* line shorter than 10 points ? */
  1005. X    if ((abs(1 + x - h) >= zm))
  1006. X        return;
  1007. X
  1008. X    if ((x == h) || (y == v))    /* there is no restriction at horiz.
  1009. X                     * and vert. lines */
  1010. X        return;
  1011. X    else
  1012. X    {
  1013. X        newh = (h < x) ? (x - zm) : (x + zm);
  1014. X
  1015. X        lambda = (newh - x) / (h - x);
  1016. X
  1017. X        newv = y + lambda * (v - y);
  1018. X    }
  1019. X
  1020. X
  1021. X    (*x_ret) = newh;
  1022. X    (*y_ret) = newv;
  1023. X
  1024. }
  1025. X
  1026. X
  1027. void
  1028. draw_vector_marker(float x, float y, float h, float v)
  1029. {
  1030. X    /* draws an arrow at the top of the line, given by the */
  1031. X    /* the coordinates. */
  1032. X
  1033. X    Display        *disp;
  1034. X    Drawable        win;
  1035. X    float           betrag;
  1036. X    float           a, b, c, d, lx, ly, rx, ry;
  1037. X    XPoint          points[3];
  1038. X    disp = XtDisplay(pboard);
  1039. X    win = XtWindow(pboard);
  1040. X
  1041. X
  1042. X    a = (h - x);
  1043. X    b = (v - y);
  1044. X    betrag = sqrt((double) (a * a + b * b));
  1045. X
  1046. X    a = a / betrag;
  1047. X    b = b / betrag;
  1048. X    /* vector |(a,b)|=1 */
  1049. X
  1050. X    /* reverse direction */
  1051. X    a = a * (-1);
  1052. X    b = b * (-1);
  1053. X
  1054. X    h = h + a;
  1055. X    v = v + b;
  1056. X
  1057. X    /* knot point (c,d) */
  1058. X    c = h + 10 * a;
  1059. X    d = v + 10 * b;
  1060. X
  1061. X    a = a * (-1);
  1062. X    rx = b;
  1063. X    b = a;
  1064. X    a = rx;
  1065. X
  1066. X    rx = c + 5 * a;
  1067. X    ry = d + 5 * b;
  1068. X
  1069. X    a = a * (-1);
  1070. X    b = b * (-1);
  1071. X
  1072. X    lx = c + 5 * a;
  1073. X    ly = d + 5 * b;
  1074. X
  1075. X    points[0].x = (short) lx;
  1076. X    points[0].y = (short) ly;
  1077. X    points[1].x = (short) rx;
  1078. X    points[1].y = (short) ry;
  1079. X    points[2].x = (short) h;
  1080. X    points[2].y = (short) v;
  1081. X
  1082. X    XFillPolygon(disp, win, gc, points, 3, Convex, CoordModeOrigin);
  1083. X    /*
  1084. X     * XDrawLine(disp,win,gc,(int)lx,(int)ly,(int)rx,(int)ry);
  1085. X     * XDrawLine(disp,win,gc,(int)rx,(int)ry,(int)h,(int)v);
  1086. X     * XDrawLine(disp,win,gc,(int)h,(int)v,(int)lx,(int)ly);
  1087. X     */
  1088. X
  1089. X
  1090. }
  1091. X
  1092. X
  1093. X
  1094. X
  1095. int
  1096. valid_vector_coords(int x_origin, int y_origin, int *x_ret, int *y_ret)
  1097. {
  1098. X    /*
  1099. X     * LaTeX supports only several arrow-slopes... this routine garantees
  1100. X     * correct LaTeX-slopes and, furthermore, dependent on different
  1101. X     * TeX-implementations, other (& unlimited) slopes, too .
  1102. X     */
  1103. X    /* slope = y/x */
  1104. X    /*
  1105. X     * input : 2 coordinates which represent the line output : 1
  1106. X     * (adjusted) coordinate
  1107. X     */
  1108. X
  1109. X    float           x, y;    /* real slope as fraction */
  1110. X    float           h, v;    /* best approximating slope as fraction */
  1111. X    int             i, sign;    /* sign indicates positive or
  1112. X                     * negative slope */
  1113. X    float           vgl, vgl2;    /* real slope */
  1114. X    float           lambda1, lambda2;
  1115. X    float           x_new, y_new;    /* (x_new,y_ret) or (x_ret,y_new) are
  1116. X                     * the best new coordinates of the
  1117. X                     * endpoint of the line */
  1118. X
  1119. X
  1120. X    /* the minimum length is 10 points */
  1121. X    /* correct it, if necessary ...call <valid_length> to do this... */
  1122. X
  1123. X    if (arrow_slope == 0)
  1124. X    {    /* unlimited slope require no coordinate-modification */
  1125. X        valid_length(x_origin, y_origin, x_ret, y_ret);
  1126. X        return -1;
  1127. X    }
  1128. X    x = (float) (*x_ret - x_origin);
  1129. X    y = (float) (*y_ret - y_origin);
  1130. X
  1131. X    /* exceptions: if slope is zero or infinite return directly */
  1132. X    if ((x == 0) || (y == 0))
  1133. X    {
  1134. X        valid_length(x_origin, y_origin, x_ret, y_ret);
  1135. X        return -2;
  1136. X    }
  1137. X    vgl = y / x;    /* the real (positive|negative) slope */
  1138. X    sign = (vgl > 0) ? 1 : -1;
  1139. X    if (vgl < 0)
  1140. X        vgl = vgl * sign;
  1141. X
  1142. X    /* searching the table */
  1143. X    for (i = 0; (a_slope[i][0] < vgl); i++);
  1144. X    /*
  1145. X     * i points to the first element, which is equal to/bigger than 'vgl'
  1146. X     * ( or it points to the marker
  1147. X     */
  1148. X    if (a_slope[i][0] == 999.0)
  1149. X    {
  1150. X        if (vgl > (float) (2 * arrow_slope))
  1151. X        {
  1152. X            *x_ret = x_origin;    /* slope is infinite */
  1153. X            valid_length(x_origin, y_origin, x_ret, y_ret);
  1154. X            return -3;
  1155. X        } else
  1156. X            i--;
  1157. X    } else if (i == 0)
  1158. X        if (vgl < (float) (0.5 * a_slope[0][0]))
  1159. X        {
  1160. X            *y_ret = y_origin;
  1161. X            valid_length(x_origin, y_origin, x_ret, y_ret);
  1162. X            return -4;
  1163. X        }
  1164. X    /* compute best approximating slope */
  1165. X    if (i != 0)
  1166. X        if ((vgl - a_slope[i - 1][0]) < (a_slope[i][0] - vgl))
  1167. X            i--;
  1168. X    /* i points to the best slope */
  1169. X
  1170. X
  1171. X    /* compute new coordinates */
  1172. X    /* it should be the nearest one to the original coordinate */
  1173. X    /* see documentation... */
  1174. X    h = (float) (a_slope[i][1] * sign);
  1175. X    v = a_slope[i][2];
  1176. X    vgl2 = a_slope[i][0];
  1177. X
  1178. X    /* compute new */
  1179. X
  1180. X    /* lambda first */
  1181. X    lambda1 = x / h;
  1182. X    lambda2 = y / v;
  1183. X
  1184. X    x_new = (float) x_origin + lambda2 * h;
  1185. X    y_new = (float) y_origin + lambda1 * v;
  1186. X
  1187. X
  1188. X    h = x_new - (float) (*x_ret);
  1189. X    v = y_new - (float) (*y_ret);
  1190. X    if (h < 0)
  1191. X        h *= (-1);
  1192. X    if (v < 0)
  1193. X        v *= (-1);
  1194. X    if (h < v)
  1195. X        *x_ret = (int) x_new;
  1196. X    else
  1197. X        *y_ret = (int) y_new;
  1198. X
  1199. X    /* coordinates are corrected */
  1200. X
  1201. X    valid_length(x_origin, y_origin, x_ret, y_ret);
  1202. X    return i;
  1203. X
  1204. }
  1205. X
  1206. X
  1207. int
  1208. valid_line_coords(int x_origin, int y_origin, int *x_ret, int *y_ret)
  1209. {
  1210. X    /*
  1211. X     * LaTeX supports only a small number of line-slopes... this routine
  1212. X     * garantees correct LaTeX-slopes and, furthermore, dependent on
  1213. X     * different TeX-implementations, other (& unlimited) slopes, too .
  1214. X     */
  1215. X    /* slope = y/x */
  1216. X    /*
  1217. X     * input : 2 coordinates which represent the vector output : 1
  1218. X     * (adjusted) coordinate
  1219. X     */
  1220. X
  1221. X    float           x, y;    /* real slope as fraction */
  1222. X    float           h, v;    /* best approximating slope as fraction */
  1223. X    int             i, sign;    /* sign indicates positive or
  1224. X                     * negative slope */
  1225. X    float           vgl, vgl2;    /* real slope */
  1226. X    float           lambda1, lambda2;
  1227. X    float           x_new, y_new;    /* (x_new,y_ret) or (x_ret,y_new) are
  1228. X                     * the best new coordinates of the
  1229. X                     * endpoint of the line */
  1230. X
  1231. X
  1232. X    /* the minimum length is 10 points */
  1233. X
  1234. X
  1235. X    if (line_slope == 0)
  1236. X    {    /* unlimited slope require no coordinate-modification */
  1237. X        valid_length(x_origin, y_origin, x_ret, y_ret);
  1238. X        return -1;
  1239. X    }
  1240. X    x = (float) (*x_ret - x_origin);
  1241. X    y = (float) (*y_ret - y_origin);
  1242. X
  1243. X    /* exceptions: if slope is zero or infinite return directly */
  1244. X    if ((x == 0) || (y == 0))
  1245. X    {
  1246. X        valid_length(x_origin, y_origin, x_ret, y_ret);
  1247. X        return -2;
  1248. X    }
  1249. X    vgl = y / x;    /* the real (positive|negative) slope */
  1250. X    sign = (vgl > 0) ? 1 : -1;
  1251. X    if (vgl < 0)
  1252. X        vgl = vgl * sign;
  1253. X
  1254. X    /* searching the table */
  1255. X    for (i = 0; (l_slope[i][0] < vgl); i++);
  1256. X    /*
  1257. X     * i points to the first element, which is equal to/bigger than 'vgl'
  1258. X     * ( or it points to the marker
  1259. X     */
  1260. X    if (l_slope[i][0] == 999.0)
  1261. X    {
  1262. X        if (vgl > (float) (2 * line_slope))
  1263. X        {
  1264. X            *x_ret = x_origin;    /* slope is infinite */
  1265. X            valid_length(x_origin, y_origin, x_ret, y_ret);
  1266. X            return -3;
  1267. X        } else
  1268. X            i--;
  1269. X    } else if (i == 0)
  1270. X        if (vgl < (float) (0.5 * l_slope[0][0]))
  1271. X        {
  1272. X            *y_ret = y_origin;
  1273. X            valid_length(x_origin, y_origin, x_ret, y_ret);
  1274. X            return -4;
  1275. X        }
  1276. X    /* compute best approximating slope */
  1277. X    if (i != 0)
  1278. X        if ((vgl - l_slope[i - 1][0]) < (l_slope[i][0] - vgl))
  1279. X            i--;
  1280. X    /* i points to the best slope */
  1281. X
  1282. X
  1283. X    /* compute new coordinates */
  1284. X    /* it should be the nearest one to the original coordinate */
  1285. X    /* see documentation... */
  1286. X    h = (float) (l_slope[i][1] * sign);
  1287. X    v = l_slope[i][2];
  1288. X    vgl2 = l_slope[i][0];
  1289. X
  1290. X    /* compute new */
  1291. X
  1292. X    /* lambda first */
  1293. X    lambda1 = x / h;
  1294. X    lambda2 = y / v;
  1295. X
  1296. X    x_new = (float) x_origin + lambda2 * h;
  1297. X    y_new = (float) y_origin + lambda1 * v;
  1298. X
  1299. X
  1300. X    h = x_new - (float) (*x_ret);
  1301. X    v = y_new - (float) (*y_ret);
  1302. X    if (h < 0)
  1303. X        h *= (-1);
  1304. X    if (v < 0)
  1305. X        v *= (-1);
  1306. X    if (h < v)
  1307. X        *x_ret = (int) x_new;
  1308. X    else
  1309. X        *y_ret = (int) y_new;
  1310. X
  1311. X    /* coordinates are corrected */
  1312. X
  1313. X    valid_length(x_origin, y_origin, x_ret, y_ret);
  1314. X    return i;
  1315. }
  1316. X
  1317. X
  1318. X
  1319. void
  1320. shorten(int *x, int *y)
  1321. {
  1322. X    int             divi;
  1323. X    divi = ggt(*x, *y);
  1324. X    (*x) /= divi;
  1325. X    (*y) /= divi;
  1326. }
  1327. X
  1328. X
  1329. X
  1330. X
  1331. X
  1332. void
  1333. init_l_slope()
  1334. {
  1335. X    /* builds the line-slope-table */
  1336. X
  1337. X    int             x, y;
  1338. X    float           r;
  1339. X    l_slope[0][0] = 999.0;    /* init marker */
  1340. X    for (x = line_slope; x != 0; x--)
  1341. X        for (y = line_slope; y != 0; y--)
  1342. X        {
  1343. X            r = (float) x / (float) y;
  1344. X            l_insert(r, y, x);
  1345. X            r = (float) y / (float) x;
  1346. X            l_insert(r, x, y);
  1347. X        }
  1348. X    /* slope-table for LaTeX' lines now prepared */
  1349. X
  1350. X
  1351. X
  1352. }
  1353. X
  1354. X
  1355. void
  1356. l_insert(float value, int x, int y)
  1357. {
  1358. X    /* insertion sort into the table */
  1359. X
  1360. X    int             i, j, k;
  1361. X    /* kuerzen */
  1362. X    shorten(&x, &y);
  1363. X
  1364. X    /* searching for insertion position */
  1365. X    j = 0;
  1366. X    while ((l_slope[j][0] != 999.0) && (l_slope[j][0] < value))
  1367. X        j++;
  1368. X    /*
  1369. X     * j is new insertion point; it may point to 999 or any value, bigger
  1370. X     * than 'value'
  1371. X     */
  1372. X
  1373. X    /* testing, if value already in table */
  1374. X    if (l_slope[j][0] == value)
  1375. X        return;    /* no entry */
  1376. X
  1377. X    /* searching for the end of the table */
  1378. X    i = 0;
  1379. X    if (l_slope[0][0] != 999.0)
  1380. X        do
  1381. X            i += 1;
  1382. X        while (l_slope[i][0] != 999.0);
  1383. X    /* i points to 999 */
  1384. X
  1385. X    /* insert data */
  1386. X    l_slope[i + 1][0] = 999.0;
  1387. X    for (k = i; k != j; k--)
  1388. X    {
  1389. X        l_slope[k][0] = l_slope[k - 1][0];
  1390. X        l_slope[k][1] = l_slope[k - 1][1];
  1391. X        l_slope[k][2] = l_slope[k - 1][2];
  1392. X    }
  1393. X    /* insert new data at j */
  1394. X    l_slope[j][0] = value;
  1395. X    l_slope[j][1] = x;
  1396. X    l_slope[j][2] = y;
  1397. }/* end */
  1398. X
  1399. X
  1400. X
  1401. X
  1402. X
  1403. X
  1404. X
  1405. X
  1406. X
  1407. void
  1408. init_a_slope()
  1409. {
  1410. X    /* see above */
  1411. X
  1412. X    int             x, y;
  1413. X    float           r;
  1414. X    a_slope[0][0] = 999.0;    /* init marker */
  1415. X    for (x = arrow_slope; x != 0; x--)
  1416. X        for (y = arrow_slope; y != 0; y--)
  1417. X        {
  1418. X            r = (float) x / (float) y;
  1419. X            a_insert(r, y, x);
  1420. X            r = (float) y / (float) x;
  1421. X            a_insert(r, x, y);
  1422. X        }
  1423. X    /* slope-table for LaTeX' arrows now prepared */
  1424. X
  1425. X
  1426. }
  1427. X
  1428. X
  1429. X
  1430. void
  1431. a_insert(float value, int x, int y)
  1432. {
  1433. X    /* see above */
  1434. X
  1435. X    int             i, j, k;
  1436. X    /* kuerzen */
  1437. X    shorten(&x, &y);
  1438. X
  1439. X    /* searching for insertion position */
  1440. X    j = 0;
  1441. X    while ((a_slope[j][0] != 999.0) && (a_slope[j][0] < value))
  1442. X        j++;
  1443. X    /*
  1444. X     * j is new insertion point; it may point to 999 or any value, bigger
  1445. X     * than 'value'
  1446. X     */
  1447. X
  1448. X    /* testing, if value already in table */
  1449. X    if (a_slope[j][0] == value)
  1450. X        return;    /* no entry */
  1451. X
  1452. X    /* searching for the end of the table */
  1453. X    i = 0;
  1454. X    if (a_slope[0][0] != 999.0)
  1455. X        do
  1456. X            i += 1;
  1457. X        while (a_slope[i][0] != 999.0);
  1458. X    /* i points to 999 */
  1459. X
  1460. X    /* insert data */
  1461. X    a_slope[i + 1][0] = 999.0;
  1462. X    for (k = i; k != j; k--)
  1463. X    {
  1464. X        a_slope[k][0] = a_slope[k - 1][0];
  1465. X        a_slope[k][1] = a_slope[k - 1][1];
  1466. X        a_slope[k][2] = a_slope[k - 1][2];
  1467. X    }
  1468. X    /* insert new data at j */
  1469. X    a_slope[j][0] = value;
  1470. X    a_slope[j][1] = x;
  1471. X    a_slope[j][2] = y;
  1472. }/* end */
  1473. X
  1474. X
  1475. X
  1476. X
  1477. X
  1478. X
  1479. void
  1480. graphics_init()
  1481. {
  1482. X
  1483. X    make_GCcontext();    /* GC Kreiren */
  1484. X
  1485. X    init_l_slope();
  1486. X    init_a_slope();
  1487. }
  1488. X
  1489. X
  1490. void
  1491. set_zoom_window()
  1492. {
  1493. X    Widget          w;
  1494. X    caddr_t         call_data;
  1495. X    /* Add to Translation Manager */
  1496. X    XtTranslations  trans_table;
  1497. X    char            destination[150] = "<MotionNotify> : frame_track() \n\
  1498. X                <Btn1Down> : zoom_it() \n\
  1499. X            <LeaveWindow> : cancel_zoom()\n";
  1500. X    static XtActionsRec actions[150] = {{"frame_track", frame_track},
  1501. X    {"zoom_it", zoom_it},
  1502. X    {"cancel_zoom", cancel_zoom}};
  1503. X    XtAddActions(actions, XtNumber(actions));
  1504. X    trans_table = XtParseTranslationTable(destination);
  1505. X    XtOverrideTranslations(pboard, trans_table);
  1506. X
  1507. X    if (zoomed == True)
  1508. X    {
  1509. X        zoomed = False;
  1510. X        refresh(w, point, call_data);    /* force refresh */
  1511. X    }
  1512. X    x_zoom_min = -999;
  1513. }
  1514. X
  1515. X
  1516. void
  1517. frame_track(int *x0, int *y0)
  1518. {
  1519. X    /* tracks the zoom-frame */
  1520. X
  1521. X    Display        *disp;
  1522. X    Drawable        win;
  1523. X    int             x, y;
  1524. X    unsigned int    mask;
  1525. X
  1526. X
  1527. X    disp = XtDisplay(pboard);
  1528. X    win = XtWindow(pboard);
  1529. X    PointerPosition(&x, &y, &mask);
  1530. X
  1531. X    if ((x != x_zoom_min) || (y != x_zoom_max))
  1532. X    {    /* redraw of frame is necessary */
  1533. X        if (x_zoom_min != -999)    /* delete last frame */
  1534. X            XDrawRectangle(disp, win, gc, x_zoom_min, x_zoom_max, 60, 84);
  1535. X        /* draw current frame */
  1536. X        XDrawRectangle(disp, win, gc, x, y, 60, 84);
  1537. X        x_zoom_min = x;
  1538. X        x_zoom_max = y;
  1539. X    }
  1540. X    (*x0) = x;
  1541. X    (*y0) = y;
  1542. X
  1543. }
  1544. X
  1545. void
  1546. zoom_it()
  1547. {
  1548. X    /* zoom the area */
  1549. X
  1550. X    Display        *disp;
  1551. X    Drawable        win;
  1552. X    int             x, y;
  1553. X    disp = XtDisplay(pboard);
  1554. X    win = XtWindow(pboard);
  1555. X    frame_track(&x, &y);
  1556. X    zoomed = True;
  1557. X    /* delete last frame */
  1558. X    XDrawRectangle(disp, win, gc, x_zoom_min, x_zoom_max, 60, 84);
  1559. X    /* set coordinates */
  1560. X    /* 84x60 are the proportions of a DIN A4 page */
  1561. X    if (x > 600 - 60)
  1562. X        x = 540;
  1563. X    if (y > (840 - 84))
  1564. X        y = (840 - 84);
  1565. X    x_zoom_min = x;
  1566. X    x_zoom_max = x + 59;
  1567. X    y_zoom_min = y;
  1568. X    y_zoom_max = y + 83;
  1569. X    /* terminate zoom */
  1570. X    /* display zoomed graphics */
  1571. X    show_zoomed_objects();
  1572. X    graph_action = '?';
  1573. X    /* uninstall zoom-translations */
  1574. X    XtUninstallTranslations(pboard);
  1575. X    left();
  1576. X
  1577. }
  1578. X
  1579. X
  1580. X
  1581. void
  1582. clear_zoom()
  1583. {
  1584. X    int             x, y;
  1585. X    x_zoom_min = -999;
  1586. X    graph_action = '?';
  1587. X    /* uninstall zoom-translations */
  1588. X    XtUninstallTranslations(pboard);
  1589. X
  1590. }
  1591. X
  1592. X
  1593. void
  1594. cancel_zoom()
  1595. {
  1596. X    int             x, y;
  1597. X    Display        *disp;
  1598. X    Drawable        win;
  1599. X    disp = XtDisplay(pboard);
  1600. X    win = XtWindow(pboard);
  1601. X    /* redraw last frame */
  1602. X    frame_track(&x, &y);
  1603. X    XDrawRectangle(disp, win, gc, x, y, 60, 84);
  1604. X    clear_zoom();
  1605. X    left();
  1606. }
  1607. X
  1608. X
  1609. X
  1610. void
  1611. refresh(Widget cmd, char id, caddr_t call_data)
  1612. {
  1613. X    /* refreshes the screen. May occur by an user request, but */
  1614. X    /* usually by an expose event */
  1615. X
  1616. X    Display        *disp;
  1617. X    Drawable        win;
  1618. X
  1619. X
  1620. X    /* needed for correct cross painting... */
  1621. X    h_cross = -999;
  1622. X    v_cross = -999;
  1623. X
  1624. X    if ((zoomed == True) && (id != '.'))
  1625. X    {
  1626. X        /* refresh button was NOT pressed, it was NO forced refresh */
  1627. X        /* it was an expose refresh */
  1628. X        show_zoomed_objects();
  1629. X        return;
  1630. X    }
  1631. X    disp = XtDisplay(pboard);
  1632. X    win = XtWindow(pboard);
  1633. X
  1634. X    zoomed = False;
  1635. X    /* clear window */
  1636. X    XClearWindow(disp, win);
  1637. X
  1638. X    if (ruler == True)
  1639. X        ruler_on();
  1640. X
  1641. X    if (raster == True)
  1642. X        raster_on();
  1643. X
  1644. X    if (cross == True)
  1645. X        draw_coords(cmd, (caddr_t) id, call_data);    /* dummy parameter */
  1646. X
  1647. X
  1648. X    /* redraw objects */
  1649. X
  1650. X    /* bezier */
  1651. X    if (bezier_start != NULL)
  1652. X    {    /* min. 1 entry */
  1653. X        bezier_marker = bezier_start;
  1654. X        while (bezier_marker != bezier_curr)
  1655. X        {
  1656. X            DrawBezier(bezier_marker->ax,bezier_marker->ay,
  1657. X                       bezier_marker->ex,bezier_marker->ey,
  1658. X                   bezier_marker->sx,bezier_marker->sy);
  1659. X            bezier_marker = bezier_marker->next;
  1660. X        }
  1661. X        /* last curve */
  1662. X            DrawBezier(bezier_curr->ax,bezier_curr->ay,
  1663. X                     bezier_curr->ex,bezier_curr->ey,
  1664. X                   bezier_curr->sx,bezier_curr->sy);
  1665. X    }    /* bezier curves */
  1666. X
  1667. X    /* lines */
  1668. X    if (strich_start != NULL)
  1669. X    {    /* min. 1 entry */
  1670. X        strich_marker = strich_start;
  1671. X        while (strich_marker != strich_curr)
  1672. X        {
  1673. X            XDrawLine(disp, win, gc, (int) strich_marker->x, (int) strich_marker->y,
  1674. X                (int) strich_marker->h, (int) strich_marker->v);
  1675. X            strich_marker = strich_marker->next;
  1676. X        }
  1677. X        /* last line */
  1678. X        XDrawLine(disp, win, gc, (int) strich_curr->x, (int) strich_curr->y,
  1679. X              (int) strich_curr->h, (int) strich_curr->v);
  1680. X    }    /* lines */
  1681. X    /* vectors */
  1682. X    if (pfeil_start != NULL)
  1683. X    {    /* min. 1 entry */
  1684. X        pfeil_marker = pfeil_start;
  1685. X        while (pfeil_marker != pfeil_curr)
  1686. X        {
  1687. X            XDrawLine(disp, win, gc, (int) pfeil_marker->x, (int) pfeil_marker->y,
  1688. X                  (int) pfeil_marker->h, (int) pfeil_marker->v);
  1689. X            draw_vector_marker(pfeil_marker->x, pfeil_marker->y,
  1690. X                       pfeil_marker->h, pfeil_marker->v);
  1691. X            pfeil_marker = pfeil_marker->next;
  1692. X        }
  1693. X        /* last line */
  1694. X        XDrawLine(disp, win, gc, (int) pfeil_curr->x, (int) pfeil_curr->y,
  1695. X              (int) pfeil_curr->h, (int) pfeil_curr->v);
  1696. X        draw_vector_marker(pfeil_curr->x, pfeil_curr->y, pfeil_curr->h, pfeil_curr->v);
  1697. X    }    /* vectors */
  1698. X    /* text */
  1699. X    if (message_start != NULL)
  1700. X    {    /* min. 1 entry */
  1701. X        message_marker = message_start;
  1702. X        while (message_marker != message_curr)
  1703. X        {
  1704. X            XDrawString(disp, win, gc, message_marker->x, message_marker->y,
  1705. X                    message_marker->text, 1);
  1706. X            message_marker = message_marker->next;
  1707. X        }
  1708. X        /* last text */
  1709. X        XDrawString(disp, win, gc, message_curr->x, message_curr->y,
  1710. X                message_curr->text, 1);
  1711. X    }    /* text */
  1712. X    /* boxes */
  1713. X    /* FRAMED */
  1714. X    if (framedBox_start != NULL)
  1715. X    {    /* min. 1 entry */
  1716. X        framedBox_marker = framedBox_start;
  1717. X        while (framedBox_marker != framedBox_curr)
  1718. X        {
  1719. X            XDrawRectangle(disp, win, gc, (int) framedBox_marker->x, (int) framedBox_marker->y,
  1720. X                       (unsigned int) ((int) ((framedBox_marker->h) - (framedBox_marker->x))),
  1721. X                       (unsigned int) ((int) ((framedBox_marker->v) - (framedBox_marker->y))));
  1722. X
  1723. X            print_box_text(framedBox_marker->textpos, framedBox_marker->x,
  1724. X                   framedBox_marker->y, framedBox_marker->h,
  1725. X                   framedBox_marker->v, framedBox_marker->text);
  1726. X
  1727. X            framedBox_marker = framedBox_marker->next;
  1728. X        }
  1729. X        /* last one */
  1730. X        XDrawRectangle(disp, win, gc, (int) framedBox_curr->x, (int) framedBox_curr->y,
  1731. X                   (unsigned int) ((int) ((framedBox_curr->h) - (framedBox_curr->x))),
  1732. X                   (unsigned int) ((int) ((framedBox_curr->v) - (framedBox_curr->y))));
  1733. X
  1734. X        print_box_text(framedBox_curr->textpos, framedBox_curr->x,
  1735. X                   framedBox_curr->y, framedBox_curr->h,
  1736. X                   framedBox_curr->v, framedBox_curr->text);
  1737. X
  1738. X    }    /* framed */
  1739. X    /* DASHED */
  1740. X    if (dashedBox_start != NULL)
  1741. X    {    /* min. 1 entry */
  1742. X        XSetLineAttributes(disp, gc, 0, LineOnOffDash, CapButt, JoinMiter);
  1743. X
  1744. X        dashedBox_marker = dashedBox_start;
  1745. X        while (dashedBox_marker != dashedBox_curr)
  1746. X        {
  1747. X            XDrawRectangle(disp, win, gc, (int) dashedBox_marker->x, (int) dashedBox_marker->y,
  1748. X                       (unsigned int) ((int) ((dashedBox_marker->h) - (dashedBox_marker->x))),
  1749. X                       (unsigned int) ((int) ((dashedBox_marker->v) - (dashedBox_marker->y))));
  1750. X
  1751. X            print_box_text(dashedBox_marker->textpos, dashedBox_marker->x,
  1752. X                   dashedBox_marker->y, dashedBox_marker->h,
  1753. X                   dashedBox_marker->v, dashedBox_marker->text);
  1754. X
  1755. X            dashedBox_marker = dashedBox_marker->next;
  1756. X        }
  1757. X        /* last one */
  1758. X        XDrawRectangle(disp, win, gc, (int) dashedBox_curr->x, (int) dashedBox_curr->y,
  1759. X                   (unsigned int) ((int) ((dashedBox_curr->h) - (dashedBox_curr->x))),
  1760. X                   (unsigned int) ((int) ((dashedBox_curr->v) - (dashedBox_curr->y))));
  1761. X
  1762. X        print_box_text(dashedBox_curr->textpos, dashedBox_curr->x,
  1763. X                   dashedBox_curr->y, dashedBox_curr->h,
  1764. X                   dashedBox_curr->v, dashedBox_curr->text);
  1765. X
  1766. X        XSetLineAttributes(disp, gc, 0, LineSolid, CapButt, JoinMiter);
  1767. X
  1768. X    }    /* dashed */
  1769. X    /* FILLED */
  1770. X    if (filledBox_start != NULL)
  1771. X    {    /* min. 1 entry */
  1772. X        filledBox_marker = filledBox_start;
  1773. X        while (filledBox_marker != filledBox_curr)
  1774. X        {
  1775. X            /* fill it */
  1776. X            XFillRectangle(disp, win, gc, (int) filledBox_marker->x,
  1777. X                       (int) (filledBox_marker->y),
  1778. X                       (unsigned int) ((filledBox_marker->h) - (filledBox_marker->x)),
  1779. X                       (unsigned int) ((filledBox_marker->v) - (filledBox_marker->y)));
  1780. X
  1781. X            filledBox_marker = filledBox_marker->next;
  1782. X        }
  1783. X        /* last one */
  1784. X        XFillRectangle(disp, win, gc, (int) filledBox_curr->x,
  1785. X                   (int) (filledBox_curr->y),
  1786. X         (unsigned int) ((filledBox_curr->h) - (filledBox_curr->x)),
  1787. X        (unsigned int) ((filledBox_curr->v) - (filledBox_curr->y)));
  1788. X
  1789. X    }    /* filled */
  1790. X    /* circle */
  1791. X    /* normal */
  1792. X    if (kreis_start != NULL)
  1793. X    {    /* min. 1 entry */
  1794. X        kreis_marker = kreis_start;
  1795. X        while (kreis_marker != kreis_curr)
  1796. X        {
  1797. X            XDrawArc(disp, win, gc, (int) (kreis_marker->x) - (kreis_marker->radius),
  1798. X               (int) (kreis_marker->y) - (kreis_marker->radius),
  1799. X                 (unsigned int) ((kreis_marker->radius) + (kreis_marker->radius)),
  1800. X                 (unsigned int) ((kreis_marker->radius) + (kreis_marker->radius)),
  1801. X                 0, 360 * 64);
  1802. X            kreis_marker = kreis_marker->next;
  1803. X        }
  1804. X        /* last circle */
  1805. X        XDrawArc(disp, win, gc, (int) (kreis_curr->x) - (kreis_curr->radius),
  1806. X             (int) (kreis_curr->y) - (kreis_curr->radius),
  1807. X        (unsigned int) ((kreis_curr->radius) + (kreis_curr->radius)),
  1808. X        (unsigned int) ((kreis_curr->radius) + (kreis_curr->radius)),
  1809. X             0, 360 * 64);
  1810. X    }    /* normal circle */
  1811. X    /* filled */
  1812. X    if (disc_start != NULL)
  1813. X    {    /* min. 1 entry */
  1814. X        disc_marker = disc_start;
  1815. X        while (disc_marker != disc_curr)
  1816. X        {
  1817. X            XFillArc(disp, win, gc, (int) (disc_marker->x) - (disc_marker->radius),
  1818. X                 (int) (disc_marker->y) - (disc_marker->radius),
  1819. X                 (unsigned int) ((disc_marker->radius) + (disc_marker->radius)),
  1820. X                 (unsigned int) ((disc_marker->radius) + (disc_marker->radius)),
  1821. X                 0, 360 * 64);
  1822. X            disc_marker = disc_marker->next;
  1823. X        }
  1824. X        /* last circle */
  1825. X        XFillArc(disp, win, gc, (int) (disc_curr->x) - (disc_curr->radius),
  1826. X             (int) (disc_curr->y) - (disc_curr->radius),
  1827. X         (unsigned int) ((disc_curr->radius) + (disc_curr->radius)),
  1828. X         (unsigned int) ((disc_curr->radius) + (disc_curr->radius)),
  1829. X             0, 360 * 64);
  1830. X    }    /* filled circle */
  1831. X    /* oval */
  1832. X    if (oval_start != NULL)
  1833. X    {    /* min. 1 entry */
  1834. X        oval_marker = oval_start;
  1835. X        while (oval_marker != oval_curr)
  1836. X        {
  1837. X            DrawOval((int) oval_marker->x, (int) oval_marker->y,
  1838. X                 (int) oval_marker->h, (int) oval_marker->v);
  1839. X            oval_marker = oval_marker->next;
  1840. X        }
  1841. X        /* last circle */
  1842. X        DrawOval((int) oval_curr->x, (int) oval_curr->y,
  1843. X             (int) oval_curr->h, (int) oval_curr->v);
  1844. X
  1845. X    }    /* oval circle */
  1846. }
  1847. X
  1848. X
  1849. X
  1850. void
  1851. show_zoomed_objects()
  1852. {
  1853. X    /* in case of zoom, rebuild screen. */
  1854. X    /* this is a refresh to the zoomed-area */
  1855. X
  1856. X    Display        *disp;
  1857. X    Drawable        win;
  1858. X    float           a1, a2, e1, e2, rad;
  1859. X    int             r;
  1860. X
  1861. X
  1862. X
  1863. X    disp = XtDisplay(pboard);
  1864. X    win = XtWindow(pboard);        
  1865. X
  1866. X    XClearWindow(disp, win);
  1867. X
  1868. X    /* needed for correct cross painting... */
  1869. X    h_cross = -999;
  1870. X    v_cross = -999;
  1871. X
  1872. X    if (raster == True)
  1873. X        raster_on();
  1874. X    if (ruler == True)
  1875. X        ruler_on();
  1876. X    if (cross == True)
  1877. X        draw_coords(pboard, (caddr_t) DUMMY, (caddr_t) DUMMY);
  1878. X
  1879. X    /* bezier */
  1880. X    if (bezier_start != NULL)
  1881. X    {    /* min. 1 entry */
  1882. X        bezier_marker = bezier_start;
  1883. X        while (bezier_marker != bezier_curr)
  1884. X        {
  1885. X            a1=bezier_marker->sx;
  1886. X            a2=bezier_marker->sy;
  1887. X            real2zoomed(&a1,&a2); /* sx,sy are expected to be in zoom-mode */
  1888. X            DrawBezier(bezier_marker->ax,bezier_marker->ay,
  1889. X                       bezier_marker->ex,bezier_marker->ey,
  1890. X                   a1,a2);
  1891. X            bezier_marker = bezier_marker->next;
  1892. X        }
  1893. X        /* last line */
  1894. X        a1 = bezier_curr->sx;
  1895. X        a2 = bezier_curr->sy;
  1896. X        real2zoomed(&a1, &a2);
  1897. X        DrawBezier(bezier_curr->ax,bezier_curr->ay,
  1898. X            bezier_curr->ex,bezier_curr->ey,
  1899. X            a1,a2);
  1900. X    }    /* bezier curves */
  1901. X
  1902. X    /* lines */
  1903. X    if (strich_start != NULL)
  1904. X    {    /* min. 1 entry */
  1905. X        strich_marker = strich_start;
  1906. X        while (strich_marker != strich_curr)
  1907. X        {
  1908. X            a1 = strich_marker->x;
  1909. X            a2 = strich_marker->y;
  1910. X            e1 = strich_marker->h;
  1911. X            e2 = strich_marker->v;
  1912. X            real2zoomed(&a1, &a2);
  1913. X            real2zoomed(&e1, &e2);
  1914. X            XDrawLine(disp, win, gc, (int) a1, (int) a2, (int) e1, (int) e2);
  1915. X            strich_marker = strich_marker->next;
  1916. X        }
  1917. X        /* last line */
  1918. X        a1 = strich_curr->x;
  1919. X        a2 = strich_curr->y;
  1920. X        e1 = strich_curr->h;
  1921. X        e2 = strich_curr->v;
  1922. X        real2zoomed(&a1, &a2);
  1923. X        real2zoomed(&e1, &e2);
  1924. X        XDrawLine(disp, win, gc, (int) a1, (int) a2, (int) e1, (int) e2);
  1925. X    }    /* lines */
  1926. X    /* vectors */
  1927. X    if (pfeil_start != NULL)
  1928. X    {    /* min. 1 entry */
  1929. X        pfeil_marker = pfeil_start;
  1930. X        while (pfeil_marker != pfeil_curr)
  1931. X        {
  1932. X            a1 = pfeil_marker->x;
  1933. X            a2 = pfeil_marker->y;
  1934. X            e1 = pfeil_marker->h;
  1935. X            e2 = pfeil_marker->v;
  1936. X            real2zoomed(&a1, &a2);
  1937. X            real2zoomed(&e1, &e2);
  1938. X            XDrawLine(disp, win, gc, (int) a1, (int) a2, (int) e1, (int) e2);
  1939. X            draw_vector_marker(a1, a2, e1, e2);
  1940. X            pfeil_marker = pfeil_marker->next;
  1941. X        }
  1942. X        /* last vector */
  1943. X        a1 = pfeil_curr->x;
  1944. X        a2 = pfeil_curr->y;
  1945. X        e1 = pfeil_curr->h;
  1946. X        e2 = pfeil_curr->v;
  1947. X        real2zoomed(&a1, &a2);
  1948. X        real2zoomed(&e1, &e2);
  1949. X        XDrawLine(disp, win, gc, (int) a1, (int) a2, (int) e1, (int) e2);
  1950. X        draw_vector_marker(a1, a2, e1, e2);
  1951. X    }    /* vectors */
  1952. X    /* text */
  1953. X    if (message_start != NULL)
  1954. X    {    /* min. 1 entry */
  1955. X        message_marker = message_start;
  1956. SHAR_EOF
  1957. true || echo 'restore of graphics.c failed'
  1958. fi
  1959. echo 'End of  part 3'
  1960. echo 'File graphics.c is continued in part 4'
  1961. echo 4 > _shar_seq_.tmp
  1962. exit 0
  1963. -- 
  1964. --
  1965. Molecular Simulations, Inc.            mail: dcmartin@msi.com
  1966. 796 N. Pastoria Avenue                uucp: uunet!dcmartin
  1967. Sunnyvale, California 94086            at&t: 408/522-9236
  1968.