1 /********************************************************************
2 This file is part of the abs 0.907 distribution.  abs is a spreadsheet
3 with graphical user interface.
4 
5 Copyright (C) 1998-2001  Andr� Bertin (Andre.Bertin@ping.be)
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version if in the same spirit as version 2.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 Concact: abs@pi.be
22          http://home.pi.be/bertin/abs.shtml
23 
24 *********************************************************************/
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 #include "sheetdrawer.h"
53 #include "gr_interf.h"
54 #include "application.h"
55 #include "mainwin.h"
56 #include "finite_state.h"
57 
58 #include "param.h"
59 
60 #include "callback.h"
61 
62 extern int is_selecting ();
63 
64 #define AW ActiveWorksheet
65 #define CW worksheet_getcolw
66 #define LH worksheet_getrowh
67 #define SW worksheet_setcolw
68 #define SH worksheet_setrowh
69 #define Letext ActiveMainwin->commandline_obj->text
70 #define Drawarea ActiveMainwin->draw
71 #define linindex ActiveMainwin->linindex
72 #define colindex ActiveMainwin->colindex
73 #define corner ActiveMainwin->corner
74 #define toplevel ActiveMainwin->toplevel
75 #define Infoarea ActiveMainwin->info
76 #define DrawAreaPixmap ActiveMainwin->DrawAreaPixmap
77 #define linpixmap ActiveMainwin->LinPixmap
78 #define colpixmap ActiveMainwin->ColPixmap
79 #define cornerpixmap ActiveMainwin->CornerPixmap
80 
81 #define dpy ActiveMainwin->dpy
82 #define screen ActiveMainwin->screen
83 #define AMwin  ActiveMainwin->draw_window
84 #define Height ActiveMainwin->height
85 #define Width ActiveMainwin->width
86 
87 
88 
89 
90 
91 int
create_active_mainwin_pixmaps(int width,int height)92 create_active_mainwin_pixmaps (int width, int height)
93 {
94 
95   Height = height;
96   Width = width;
97 
98 
99   DrawAreaPixmap = createpixmap (Drawarea, width, height);
100   setbackpix (Drawarea, DrawAreaPixmap);
101   linpixmap = createpixmap (linindex, 40, height);
102   colpixmap = createpixmap (colindex, width, 20);
103   cornerpixmap = createpixmap (corner, 40, 20);
104   setbackpix (linindex, linpixmap);
105   setbackpix (colindex, colpixmap);
106   setbackpix (corner, cornerpixmap);
107   setbackpix (Drawarea, DrawAreaPixmap);
108 
109   return 0;
110 }
111 
112 int
cb_resize(int width,int height)113 cb_resize (int width, int height)
114 {
115   freepixmap (Drawarea, DrawAreaPixmap);
116   freepixmap (linindex, linpixmap);
117   freepixmap (colindex, colpixmap);
118 
119   Height = height - 20;
120   Width = width - 40;
121 
122 
123   DrawAreaPixmap = createpixmap (Drawarea, width - 40, height - 20);
124   setbackpix (Drawarea, DrawAreaPixmap);
125 
126   linpixmap = createpixmap (linindex, 40, height - 20);
127   colpixmap = createpixmap (colindex, width - 40, 20);
128 
129   setbackpix (linindex, linpixmap);
130   setbackpix (colindex, colpixmap);
131   xrepaint ("cb_resize");
132   return 0;
133 }
134 
135 
136 
137 
138 
139 
140 int
xfit(int ii,int jj)141 xfit (int ii, int jj)
142 {
143   int ret = 0;
144   ret = xfitcolumn (ii, jj);
145   if (!ret)
146     ret = xfitline (ii, jj);
147   return ret;
148 }
149 
150 int
xfitcolumn(int ii,int jj)151 xfitcolumn (int ii, int jj)
152 {
153   int cwidth;
154 
155   int font, fontw, fonts;
156   char *name;
157   Cell *cell;
158 
159   if (AW == NULL)
160     return -1;
161   if (ii < 0 || ii > AW->nblin || jj < 0 || jj > AW->nbcol)
162     return -1;
163 
164   cell = (Cell *) applicationcell (ii, jj, -1);
165   if (cell == NULL)
166     return -1;
167   name = cell_gettext (cell);
168   if (name == NULL)
169     return 0;
170   if (strlen (name) < 1)
171     return 0;
172 
173   font = cell_getfont (cell);
174   fontw = cell_getfontw (cell);
175   fonts = cell_getfonts (cell);
176 
177   cwidth = gettextw (name, strlen (name), font, fontw, fonts) + 2;
178 
179   if (CW (AW, jj + 1) - CW (AW, jj) < cwidth)
180     {
181       SW (AW, jj, cwidth);
182     }
183   return 0;
184 }
185 
186 int
xfitline(int ii,int jj)187 xfitline (int ii, int jj)
188 {
189   int cheight;
190 
191   int font, fontw, fonts;
192   char *name;
193   Cell *cell;
194 
195   if (AW == NULL)
196     return -1;
197   if (ii < 0 || ii > AW->nblin || jj < 0 || jj > AW->nbcol)
198     return -1;
199 
200   cell = (Cell *) applicationcell (ii, jj, -1);
201   if (cell == NULL)
202     return -1;
203 
204   name = cell_gettext (cell);
205   if (name == NULL)
206     return 0;
207   if (strlen (name) < 1)
208     return 0;
209 
210   font = cell_getfont (cell);
211   fontw = cell_getfontw (cell);
212   fonts = cell_getfonts (cell);
213 
214   cheight = gettexth (name, strlen (name), font, fontw, fonts) + 2;
215 
216   if (LH (AW, ii + 1) - LH (AW, ii) < cheight)
217     {
218       SW (AW, ii, cheight);
219     }
220   return 0;
221 }
222 
223 
224 
225 
226 
227 
228 
229 
230 
231 
232 static int numover = 0;
233 
234 int
checkwidth(char * name,int width,Cell * cell,int r,int c,int type)235 checkwidth (char *name, int width, Cell * cell, int r, int c, int type)
236 {
237   int cwidth;
238   int nchar;
239   int i, j;
240   int color, just, font, fontw, fonts;
241   int delta;
242   char *formula = NULL;
243   Cell *cl;
244 
245   if (name == NULL)
246     return width;
247   nchar = strlen (name);
248   if (nchar < 1)
249     return width;
250 
251   color = cell_getfg (cell);
252   just = cell_getjust (cell);
253   font = cell_getfont (cell);
254   fontw = cell_getfontw (cell);
255   fonts = cell_getfonts (cell);
256 
257   cwidth = gettextw (name, nchar, font, fontw, fonts);
258   if (type == 2 || type == 3)
259     delta = CW (AW, c + 1 + numover) - CW (AW, c + 1);
260   else
261     delta = 0;
262 
263 
264   if (cwidth > width - 2 + delta && (type != 2 && type != 3))
265     {
266 
267       i = r;
268       j = c;
269       cl = (Cell *) applicationcell (i, j + 1, -1);
270       if (cl != NULL)
271 	formula = cell_getformula (cl);
272       else
273 	formula = NULL;
274       while (((cwidth > width - 2 + delta && formula == NULL) ||
275 	      (cwidth > width - 2 + delta && (type == 2 || type == 3))
276 	     ) &&
277 	     (width < 1000)
278 	)
279 	{
280 	  j++;
281 	  if (type == 2 || type == 3)
282 	    numover++;
283 	  delta = CW (AW, j + 1) - CW (AW, c + 1);
284 	  cl = (Cell *) applicationcell (i, j + 1, -1);
285 	  if (cl != NULL)
286 	    formula = cell_getformula (cl);
287 	  else
288 	    formula = NULL;
289 	}
290 
291     }
292 
293   return width + delta;
294 
295 }
296 
297 int
xdrawstring(char * name,int x,int y,int width,int widthmax,int height,int type,Cell * cell)298 xdrawstring (char *name, int x, int y, int width, int widthmax, int height, int type, Cell * cell)
299 {
300   int textx, texty;
301 
302   int cheight, cwidth;
303   int nchar;
304   int color, just, font, fontw, fonts;
305 
306 
307   if (FS->l1 == StBatch || BatchMode)
308     return 0;
309   if (name == NULL)
310     return 0;
311   nchar = strlen (name);
312   if (nchar < 1)
313     return 0;
314 
315   font = cell_getfont (cell);
316   fontw = cell_getfontw (cell);
317   fonts = cell_getfonts (cell);
318 
319   cheight = gettexth (name, nchar, font, fontw, fonts);
320   cwidth = gettextw (name, nchar, font, fontw, fonts);
321   if (height < (cheight + 2))
322     return width;
323 
324 
325   while (cwidth > widthmax - 2 && nchar > 0)
326     {
327       nchar--;
328       cwidth = gettextw (name, nchar, font, fontw, fonts);
329     }
330   if (nchar < 1)
331     return 0;
332 
333   color = cell_getfg (cell);
334   just = cell_getjust (cell);
335 
336 
337   if (type == 3)
338     just = 0;
339 
340 
341 
342   textx = x + 1;
343 
344 
345 
346   if (just == 1)
347     textx = x + width / 2 - cwidth / 2;
348   if (just == 2)
349     textx = x + width - cwidth;
350   if (textx < x + 1)
351     textx = x + 1;
352   texty = y + height / 2 + cheight / 2 + 1;
353 
354   setfont2 (color, font, fontw, fonts);
355   drawstring (XtDisplay (Drawarea), DrawAreaPixmap, color, textx, texty, name, nchar, CW (AW, AW->cc), LH (AW, AW->ll));
356 
357   return 0;
358 }
359 
360 int
xdrawrrect(int x,int y,int width,int height,int type,Cell * cell)361 xdrawrrect (int x, int y, int width, int height, int type, Cell * cell)
362 {
363 
364   int bg = cell_getbg (cell);
365   int fg = cell_getfg (cell);
366   if (FS->l1 == StBatch || BatchMode)
367     return 0;
368 
369   if (bg < 0)
370     bg = 0;
371   if (fg < 0)
372     fg = 5;
373   switch (type)
374     {
375     case 0:
376       {
377 	fillrectangle (dpy, DrawAreaPixmap, bg, x + 1, y + 1, width - 1, height - 1, CW (AW, AW->cc), LH (AW, AW->ll), 0);
378 	break;
379       }
380     case 4:
381       {
382 	fillrectangle (dpy, DrawAreaPixmap, 2, x, y, width, height, CW (AW, AW->cc), LH (AW, AW->ll), 0);
383 	fillrectangle (dpy, DrawAreaPixmap, bg, x + 1, y + 1, width - 1, height - 1, CW (AW, AW->cc), LH (AW, AW->ll), 1);
384 	break;
385       }
386     case 7:
387       {
388 	fillrectangle (dpy, DrawAreaPixmap, 2, x, y, width, height, 0, 0, 0);
389 	fillrectangle (dpy, DrawAreaPixmap, bg, x + 1, y + 1, width - 1, height - 1, CW (AW, AW->cc), LH (AW, AW->ll), 0);
390 	break;
391       }
392     case 5:
393       {
394 	if (bg != 0 && bg != 45)
395 	  fillrectangle (dpy, DrawAreaPixmap, bg, x + 1, y + 1, width - 1, height - 1, CW (AW, AW->cc), LH (AW, AW->ll), 5);
396 	break;
397       }
398     case 2:
399       {
400 	fillrectangle (dpy, DrawAreaPixmap, bg, x + 2, y + 2, width - 3, height - 3, CW (AW, AW->cc), LH (AW, AW->ll), 0);
401 	break;
402       }
403     case 3:
404       {
405 	fillrectangle (dpy, DrawAreaPixmap, bg, x + 2, y + 2, width - 3, height - 3, CW (AW, AW->cc), LH (AW, AW->ll), 0);
406 	break;
407       }
408     case 6:
409       {
410 	fillrectangle (dpy, DrawAreaPixmap, bg, x + 2, y + 2, width - 3, height - 3, CW (AW, AW->cc), LH (AW, AW->ll), 0);
411 	break;
412       }
413     }
414 
415 
416   if (cell_gettop (cell))
417     {
418       drawline (dpy, DrawAreaPixmap, fg, x, y, x + width, y, CW (AW, AW->cc), LH (AW, AW->ll));
419     }
420   if (cell_getbot (cell))
421     {
422       drawline (dpy, DrawAreaPixmap, fg, x + width, y + height, x, y + height, CW (AW, AW->cc), LH (AW, AW->ll));
423     }
424   if (cell_getrig (cell))
425     {
426       drawline (dpy, DrawAreaPixmap, fg, x + width, y, x + width, y + height, CW (AW, AW->cc), LH (AW, AW->ll));
427     }
428   if (cell_getlef (cell))
429     {
430       drawline (dpy, DrawAreaPixmap, fg, x, y, x, y + height, CW (AW, AW->cc), LH (AW, AW->ll));
431     }
432   return 0;
433 }
434 
435 int
xdrawcursor(int pop,int selmove)436 xdrawcursor (int pop, int selmove)
437 {
438   int x1, x2, y1, y2;
439   int i, j;
440   int d = 4;
441   if (ActiveWorksheet == NULL)
442     return 0;
443   if (ActiveCell == NULL)
444     return 0;
445   if (FS->l1 == StBatch || FS->l1 == 0 || BatchMode)
446     return 0;
447 
448 
449 
450   i = ActiveWorksheet->cur_r;
451   j = ActiveWorksheet->cur_c;
452 
453 
454   x1 = CW (AW, j) - CW (AW, AW->cc);
455 
456   y1 = LH (AW, i) - LH (AW, AW->ll);
457 
458   x2 = CW (AW, j + 1) - CW (AW, AW->cc);
459   y2 = LH (AW, i + 1) - LH (AW, AW->ll);
460 
461 
462 
463 
464 
465 
466 
467 
468 
469 
470   if (is_selecting ())
471     d = 0;
472   setlineattributes (dpy, 1, 2, LineSolid, CapProjecting, JoinBevel);
473   drawline (dpy, AMwin, 5, x1, y1, x2, y1, CW (AW, AW->cc), LH (AW, AW->ll));
474   drawline (dpy, AMwin, 5, x2 + 1, y1, x2 + 1, y2 - d, CW (AW, AW->cc), LH (AW, AW->ll));
475   drawline (dpy, AMwin, 5, x2 - d, y2 + 1, x1, y2 + 1, CW (AW, AW->cc), LH (AW, AW->ll));
476   drawline (dpy, AMwin, 5, x1, y2 + 1, x1, y1, CW (AW, AW->cc), LH (AW, AW->ll));
477   {
478     if (!is_selecting ())
479       {
480 	drawline (dpy, AMwin, 1, x2 - 1, y2 + 2, x2 + 2, y2 + 2, 0, 0);
481 	drawline (dpy, AMwin, 1, x2 + 2, y2 - 1, x2 + 2, y2 + 1, 0, 0);
482       }
483   }
484   setlineattributes (dpy, 1, 1, LineSolid, CapButt, JoinBevel);
485 
486   return 0;
487 }
488 
489 
490 int
xdrawlincell(int i,int j,int color)491 xdrawlincell (int i, int j, int color)
492 {
493   char label[8];
494   int height;
495   int top;
496   int act = 0;
497   int zoom = AW->zoom;
498   if (FS->l1 == StBatch || BatchMode)
499     return 0;
500   if (i <= 0)
501     return -1;
502   if (i > ActiveWorksheet->nblin)
503     return -1;
504   height = (LH (AW, i + 1) - LH (AW, i)) * zoom / 100 - 1;
505   top = (LH (AW, i) - LH (AW, AW->ll)) * zoom / 100 + 1;
506   sprintf (label, "%d", i);
507   desactivate_zoom ();
508 
509 /*haut */ drawline (XtDisplay (linindex), linpixmap, 0, 2, top, 38, top, 0, 0);
510 
511   if (AW != NULL)
512     if (AW->cur_r == i)
513       act = 1;
514 
515   fillrectangle (XtDisplay (linindex), linpixmap, 2, 2, top + 1, 37, height - 1, 0, 0, 0);
516 
517   if (act)
518     {
519       drawline (XtDisplay (linindex), linpixmap, 1, 2, (top + height), 38, (top + height), 0, 0);
520       /*bas-in */ drawline (XtDisplay (linindex), linpixmap, 3, 3, (top + height) - 1, 37, (top + height) - 1, 0, 0);
521       /*gauch */ drawline (XtDisplay (linindex), linpixmap, 0, 2, 1 + top, 2, (top + height) - 1, 0, 0);
522       /*droi */ drawline (XtDisplay (linindex), linpixmap, 1, 39, top, 39, (top + height), 0, 0);
523       /*droi-in */ drawline (XtDisplay (linindex), linpixmap, 3, 38, top + 1, 38, (top + height) - 1, 0, 0);
524       /*droi-in-top */ drawline (XtDisplay (linindex), linpixmap, 2, 38, top, 38, top, 0, 0);
525     }
526   else
527     {
528       drawline (XtDisplay (linindex), linpixmap, 3, 2, (top + height), 38, (top + height), 0, 0);
529       /*gauch */ drawline (XtDisplay (linindex), linpixmap, 2, 2, top + 1, 2, (top + height) - 1, 0, 0);
530       /*droi */ drawline (XtDisplay (linindex), linpixmap, 3, 39, top, 39, (top + height), 0, 0);
531     }
532   reactivate_zoom ();
533 
534   setfont2 (0, 1, 0, 3);
535   drawstring (XtDisplay (linindex), linpixmap, 1, 1 + 3 * 100 / zoom, (top + height - 4) * 100 / zoom, label, strlen (label), 0, 0);
536   return 0;
537 }
538 
539 int
xdrawcolcell(int i,int j,int color)540 xdrawcolcell (int i, int j, int color)
541 {
542   char label[4];
543   int width;
544   int left;
545   int act = 0;
546   int zoom = AW->zoom;
547   if (FS->l1 == StBatch || BatchMode)
548     return 0;
549   if (j <= 0)
550     return -1;
551   if (j > ActiveWorksheet->nbcol)
552     return -1;
553   width = CW (AW, j + 1) - CW (AW, j);
554   left = CW (AW, j) - CW (AW, AW->cc);
555 
556   if (j <= 26)
557     {
558       label[0] = 'A' + j - 1;
559       label[1] = '\0';
560     }
561   else
562     {
563       label[0] = 'A' + (j - 1) / 26 - 1;
564       label[1] = 'A' + j - 26 * ((j - 1) / 26) - 1;
565       label[2] = '\0';
566     }
567 
568 
569   if (AW != NULL)
570     if (AW->cur_c == j)
571       act = 1;
572 
573   desactivate_zoom ();
574   fillrectangle (XtDisplay (colindex), colpixmap, 2, left * zoom / 100 + 1, 2, width * zoom / 100 - 1, 17, 0, 0, 0);
575 
576   if (act)
577     {
578       drawline (XtDisplay (colindex), colpixmap, 0, left * zoom / 100 + 1, 2, left * zoom / 100 + 1, 19, 0, 0);
579       drawline (XtDisplay (colindex), colpixmap, 1, (left + width) * zoom / 100, 2, (left + width) * zoom / 100, 19, 0, 0);
580       drawline (XtDisplay (colindex), colpixmap, 1, left * zoom / 100 + 1, 19, (left + width) * zoom / 100 - 1, 19, 0, 0);
581       drawline (XtDisplay (colindex), colpixmap, 0, left * zoom / 100 + 1, 2, (left + width) * zoom / 100 - 1, 2, 0, 0);
582       drawline (XtDisplay (colindex), colpixmap, 3, left * zoom / 100 + 1, 18, (left + width) * zoom / 100 - 1, 18, 0, 0);
583       drawline (XtDisplay (colindex), colpixmap, 2, left * zoom / 100 + 1, 18, left * zoom / 100 + 1, 18, 0, 0);
584       drawline (XtDisplay (colindex), colpixmap, 3, (left + width) * zoom / 100 - 1, 3, (left + width) * zoom / 100 - 1, 18, 0, 0);
585     }
586   else
587     {
588       drawline (XtDisplay (colindex), colpixmap, 0, left * zoom / 100 + 1, 2, left * zoom / 100 + 1, 19, 0, 0);
589       drawline (XtDisplay (colindex), colpixmap, 3, (left + width) * zoom / 100, 2, (left + width) * zoom / 100, 19, 0, 0);
590       drawline (XtDisplay (colindex), colpixmap, 3, left * zoom / 100 + 1, 19, (left + width) * zoom / 100 - 1, 19, 0, 0);
591       drawline (XtDisplay (colindex), colpixmap, 2, left * zoom / 100 + 2, 2, (left + width) * zoom / 100 - 1, 2, 0, 0);
592     }
593   reactivate_zoom ();
594 
595   setfont2 (0, 1, 0, 3);
596   drawstring (XtDisplay (colindex), colpixmap, 1, left + width / 2 - 5, 15 * 100 / zoom, label, strlen (label), 0, 0);
597   return 0;
598 }
599 
600 int
xdrawcell(int i,int j,int type,int noclear)601 xdrawcell (int i, int j, int type, int noclear)
602 {
603   Cell *cell = (Cell *) applicationcell (i, j, -1);
604   return xdrawcell2 (cell, type, noclear);
605 }
606 
607 
608 
609 int
xdrawcell2(Cell * cell,int type,int noclear)610 xdrawcell2 (Cell * cell, int type, int noclear)
611 {
612   int left, top, width, widthmax, height;
613   char *buf = NULL;
614   int i, j;
615 
616 
617   if (FS->l1 == StBatch || FS->l1 == 0)
618     return 0;
619 
620   if (cell == NULL)
621     return -1;
622 
623   i = cell->r;
624   j = cell->c;
625 
626   if (type == 2)
627     numover = 0;
628 
629   if (cell == NULL && (type == 4 || type == 5))
630     return 0;
631 
632   if (type == DRAW_FORCED)
633     numover = 0;
634 
635   width = CW (AW, j + 1) - CW (AW, j);
636   left = CW (AW, j) - CW (AW, AW->cc);
637   height = LH (AW, i + 1) - LH (AW, i);
638   top = LH (AW, i) - LH (AW, AW->ll);
639 
640   if (cell != NULL)
641     buf = (char *) cell_gettext (cell);
642 
643   if (type == 2 && cell != NULL)
644     buf = (char *) cell_getformula (cell);
645 
646   if (type == 3)
647     {
648       buf = (char *) GetEntryString (Letext);
649     }
650 
651   widthmax = width;
652   if (buf != NULL)
653     {
654       if (type == 3 || type == 2 || (cell_getrig (cell) == 0))
655 	widthmax = checkwidth (buf, width, cell, i, j, type);
656       if (type == 2)
657 	{
658 	  left += 2;
659 	  top += 2;
660 	  width -= 4;
661 	  height -= 4;
662 	}
663 
664     }
665   xdrawrrect (left, top, widthmax, height, type, cell);
666 
667   if (buf != NULL)
668     xdrawstring (buf, left, top, width, widthmax, height, type, cell);
669 
670   if (!noclear)
671     cleararea (dpy, AMwin, left, top, widthmax + 1, height + 1, False);
672 
673   return 0;
674 }
675 
676 
677 static int i0;
678 static int j0;
679 static int li;
680 static int lj;
681 
682 int
initselectbox(int _i0,int _j0)683 initselectbox (int _i0, int _j0)
684 {
685   i0 = _i0;
686   j0 = _j0;
687   drawselectbox (i0, j0, i0, j0);
688   li = i0;
689   lj = j0;
690   return 0;
691 }
692 
693 
694 int
extendselectbox(int i,int j)695 extendselectbox (int i, int j)
696 {
697   int di = i - li;
698   int dj = j - lj;
699   if (!(di) && !(dj))
700     return -1;
701   set_visible (i, j);
702   copypix ("extendselectbox");
703   drawselectbox (i0, j0, i, j);
704   return 0;
705 }
706 
707 int
drawselectbox(int i1,int j1,int i2,int j2)708 drawselectbox (int i1, int j1, int i2, int j2)
709 {
710   int x1, y1, x2, y2;
711   double fact = 100.0 / AW->zoom;
712   if (i2 >= i1 && j2 >= j1)
713     {
714       i2++;
715       j2++;
716     }
717   if (i2 < i1 && j2 >= j1)
718     {
719       j2++;
720       i1++;
721     }
722   if (i2 >= i1 && j2 < j1)
723     {
724       i2++;
725       j1++;
726     }
727   if (i2 < i1 && j2 < j1)
728     {
729       i1++;
730       j1++;
731     }
732   ijtoxy (i1, j1, &x1, &y1);
733   ijtoxy (i2, j2, &x2, &y2);
734 
735   if (x1 < 0)
736     x1 = 0;
737   if (x2 < 0)
738     x2 = 0;
739   if (y1 < 0)
740     y1 = 0;
741   if (y2 < 0)
742     y2 = 0;
743   if (x1 > Width * fact)
744     x1 = Width * fact;
745   if (x2 > Width * fact)
746     x2 = Width * fact;
747   if (y1 > Height * fact)
748     y1 = Height * fact;
749   if (y2 > Height * fact)
750     y2 = Height * fact;
751 
752   setlineattributes (dpy, 1, 3, LineDoubleDash, CapButt, JoinBevel);
753   drawline (dpy, AMwin, 1, x1, y1, x2, y1, 0, 0);
754   drawline (dpy, AMwin, 1, x2, y1, x2, y2 - 4, 0, 0);
755   drawline (dpy, AMwin, 1, x2 - 4, y2, x1, y2, 0, 0);
756   drawline (dpy, AMwin, 1, x1, y2, x1, y1, 0, 0);
757   setlineattributes (dpy, 1, 3, LineSolid, CapButt, JoinBevel);
758   drawline (dpy, AMwin, 1, x2 - 2, y2 + 2, x2 + 2, y2 + 2, 0, 0);
759   drawline (dpy, AMwin, 1, x2 + 2, y2 - 2, x2 + 2, y2 + 4, 0, 0);
760   setlineattributes (dpy, 1, 1, LineSolid, CapButt, JoinBevel);
761 
762   return 0;
763 }
764 
765 
766 
767 
768 int
xytoij(int x,int y,int * i,int * j)769 xytoij (int x, int y, int *i, int *j)
770 {
771   int jj = 0;
772   int x1, x2, y1, y2;
773   x += CW (AW, AW->cc);
774   y += LH (AW, AW->ll);
775   get_visible (&x1, &x2, &y1, &y2);
776   while (x > CW (AW, jj))
777     {
778       jj++;
779     }
780   *j = jj - 1;
781   jj = 0;
782   while (y > LH (AW, jj))
783     {
784       jj++;
785     }
786   *i = jj - 1;
787 
788   if (*i < 1)
789     *i = 1;
790   if (*j < 1)
791     *j = 1;
792   if (*i > AW->nblin - 1)
793     *i = AW->nblin - 1;
794   if (*j > AW->nbcol - 1)
795     *j = AW->nbcol - 1;
796 
797   if (x < x1 + CW (AW, 1))
798     *j = 1;
799   if (y < y1 + LH (AW, 1))
800     *i = 1;
801 
802   return 1;
803 }
804 
805 int
ijtoxy(int i,int j,int * x,int * y)806 ijtoxy (int i, int j, int *x, int *y)
807 {
808   if (AW == NULL)
809     return -1;
810 
811 
812   *x = CW (AW, j);
813   *y = LH (AW, i);
814 
815   *x -= CW (AW, AW->cc);
816   *y -= LH (AW, AW->ll);
817 
818   return 1;
819 }
820 
821 int
absijtoxy(int i,int j,int * x,int * y)822 absijtoxy (int i, int j, int *x, int *y)
823 {
824   if (AW == NULL)
825     return -1;
826 
827 
828   *x = CW (AW, j);
829   *y = LH (AW, i);
830 
831 
832 
833 
834 
835   return 1;
836 }
837 
838 
839 int
xytoclotherij(int x,int y,int * i,int * j)840 xytoclotherij (int x, int y, int *i, int *j)
841 {
842   int jj = 0;
843   x += CW (AW, AW->cc);
844   y += LH (AW, AW->ll);
845   while (x > CW (AW, jj))
846     {
847       jj++;
848     }
849   *j = jj - 1;
850   if (CW (AW, jj) - x < x - CW (AW, jj - 1))
851     *j = jj;
852   jj = 0;
853   while (y > LH (AW, jj))
854     {
855       jj++;
856     }
857   *i = jj - 1;
858   if (LH (AW, jj) - y < y - LH (AW, jj - 1))
859     *i = jj;
860 
861   if (*i < 1)
862     *i = 1;
863   if (*j < 1)
864     *j = 1;
865   if (*i > AW->nblin - 1)
866     *i = AW->nblin - 1;
867   if (*j > AW->nbcol - 1)
868     *j = AW->nbcol - 1;
869 
870   return 1;
871 }
872 
873 
874 
875 
876 int
get_visible(int * x1,int * x2,int * y1,int * y2)877 get_visible (int *x1, int *x2, int *y1, int *y2)
878 {
879   *x1 = CW (AW, AW->cc);
880   *y1 = LH (AW, AW->ll);
881   *x2 = *x1 + Width * 100 / AW->zoom;
882   *y2 = *y1 + Height * 100 / AW->zoom;
883   return 0;
884 }
885 
886 int
get_visible_cells(int * i1,int * j1,int * i2,int * j2)887 get_visible_cells (int *i1, int *j1, int *i2, int *j2)
888 {
889   *i1 = AW->ll;
890   *j1 = AW->cc;
891   *i2 = *i1;
892   *j2 = *j1;
893 
894   while (LH (AW, *i2) < LH (AW, AW->ll) + Height * 100 / AW->zoom && *i2 < AW->nblin)
895     {
896       (*i2)++;
897     }
898 
899   while (CW (AW, *j2) < CW (AW, AW->cc) + Width * 100 / AW->zoom && *j2 < AW->nbcol)
900     {
901       (*j2)++;
902     }
903   return 0;
904 }
905 
906 
907 
908 int
resizegra()909 resizegra ()
910 {
911   Graph *gr;
912   gr = (Graph *) getlastgra ();
913   freepixmap (Drawarea, gr->pixmap);
914   gr->pixmap = createpixmap (Drawarea,
915 			     gr->w * gr->zoom / 100, gr->h * gr->zoom / 100);
916   fillrectangle (dpy, gr->pixmap, 0, 0, 0, gr->w, gr->h, 0, 0, 0);
917   return 0;
918 }
919 
920 int
redrawbt(Button * btn)921 redrawbt (Button * btn)
922 {
923   int x1, x2, y1, y2;
924 
925   x1 = btn->x1 - CW (AW, AW->cc);
926   y1 = btn->y1 - LH (AW, AW->ll);
927   x2 = btn->x2 - CW (AW, AW->cc);
928   y2 = btn->y2 - LH (AW, AW->ll);
929   drawbuttonup (dpy, DrawAreaPixmap, x1, y1, x2, y2, button_getlabel (btn), CW (AW, AW->cc), LH (AW, AW->ll));
930   return 0;
931 }
932 
933 int
redrawbtdown(Button * btn)934 redrawbtdown (Button * btn)
935 {
936   int x1, x2, y1, y2;
937   char *label;
938 
939   x1 = btn->x1 - CW (AW, AW->cc);
940   y1 = btn->y1 - LH (AW, AW->ll);
941   x2 = btn->x2 - CW (AW, AW->cc);
942   y2 = btn->y2 - LH (AW, AW->ll);
943 
944   drawline (dpy, DrawAreaPixmap, 2, x1, y1, x2 - 1, y1, CW (AW, AW->cc), LH (AW, AW->ll));
945   drawline (dpy, DrawAreaPixmap, 2, x1, y1, x1, y2, CW (AW, AW->cc), LH (AW, AW->ll));
946 
947   drawline (dpy, DrawAreaPixmap, 1, x1 + 1, y1 + 1, x2 - 1, y1 + 1, CW (AW, AW->cc), LH (AW, AW->ll));
948   drawline (dpy, DrawAreaPixmap, 1, x1 + 1, y1 + 2, x1 + 1, y2 - 1, CW (AW, AW->cc), LH (AW, AW->ll));
949 
950   drawline (dpy, DrawAreaPixmap, 1, x2, y1, x2, y2, CW (AW, AW->cc), LH (AW, AW->ll));
951   drawline (dpy, DrawAreaPixmap, 1, x1, y2, x2, y2, CW (AW, AW->cc), LH (AW, AW->ll));
952   drawline (dpy, DrawAreaPixmap, 0, x2 - 1, y1, x2 - 1, y2 - 1, CW (AW, AW->cc), LH (AW, AW->ll));
953   drawline (dpy, DrawAreaPixmap, 0, x1 + 1, y2 - 1, x2 - 1, y2 - 1, CW (AW, AW->cc), LH (AW, AW->ll));
954   fillrectangle (dpy, DrawAreaPixmap, 2, x1 + 2, y1 + 2, x2 - x1 - 3, y2 - y1 - 3, CW (AW, AW->cc), LH (AW, AW->ll), 1);
955   label = button_getlabel (btn);
956   drawstring (dpy, DrawAreaPixmap, 1, x1 + 10, (y1 + y2) / 2, label, strlen (label), CW (AW, AW->cc), LH (AW, AW->ll));
957   return 0;
958 }
959 
960 int
redrawdr(Drawing * dr)961 redrawdr (Drawing * dr)
962 {
963   int centerx, centery, width, height, a1 = 0, a2 = 0;
964   int pi = 90 * 64;
965   int x1, x2, y1, y2;
966 
967   x1 = dr->x1 - CW (AW, AW->cc);
968   y1 = dr->y1 - LH (AW, AW->ll);
969   x2 = dr->x2 - CW (AW, AW->cc);
970   y2 = dr->y2 - LH (AW, AW->ll);
971 
972 
973   switch (dr->type)
974     {
975 
976     case LINE:
977       {
978 	drawline (dpy, DrawAreaPixmap, 1, x1, y1, x2, y2, CW (AW, AW->cc), LH (AW, AW->ll));
979 	break;
980       }
981     case RECT:
982       {
983 	drawline (dpy, DrawAreaPixmap, 1, x1, y1, x2, y1, CW (AW, AW->cc), LH (AW, AW->ll));
984 	drawline (dpy, DrawAreaPixmap, 1, x2, y1, x2, y2, CW (AW, AW->cc), LH (AW, AW->ll));
985 	drawline (dpy, DrawAreaPixmap, 1, x2, y2, x1, y2, CW (AW, AW->cc), LH (AW, AW->ll));
986 	drawline (dpy, DrawAreaPixmap, 1, x1, y2, x1, y1, CW (AW, AW->cc), LH (AW, AW->ll));
987 	break;
988       }
989     case ARC:
990       {
991 	centerx = x1;
992 	centery = y1;
993 	width = 2 * abs (x1 - x2);
994 	height = 2 * abs (y1 - y2);
995 
996 	if (x1 <= x2 && y1 <= y2)
997 	  {
998 	    a1 = 0;
999 	    a2 = pi;
1000 	    centery += height / 2;
1001 	  }
1002 	if (x1 >= x2 && y1 <= y2)
1003 	  {
1004 	    a1 = -pi;
1005 	    a2 = pi;
1006 	    centerx -= width / 2;
1007 	  }
1008 	if (x1 >= x2 && y1 >= y2)
1009 	  {
1010 	    a1 = 2 * pi;
1011 	    a2 = pi;
1012 	    centery -= height / 2;
1013 	  }
1014 	if (x1 <= x2 && y1 >= y2)
1015 	  {
1016 	    a1 = pi;
1017 	    a2 = pi;
1018 	    centerx += width / 2;
1019 	  }
1020 	drawarc
1021 	  (dpy, DrawAreaPixmap, 1, centerx - width / 2, centery - height / 2, width, height, a1, a2, CW (AW, AW->cc), LH (AW, AW->ll));
1022 	break;
1023       }
1024     case CIRCLE:
1025       {
1026 	centerx = (x1 + x2) / 2;
1027 	centery = (y1 + y2) / 2;
1028 	width = abs (x1 - x2);
1029 	height = abs (y1 - y2);
1030 	drawarc
1031 	  (dpy, DrawAreaPixmap, 1, centerx - width / 2, centery - height / 2, width, height, 0, 360 * 64,
1032 	   CW (AW, AW->cc), LH (AW, AW->ll));
1033 	break;
1034       }
1035     }
1036   return 0;
1037 }
1038 
1039 
1040 
1041 Pixmap
createpixmapforgraph(Graph * gr)1042 createpixmapforgraph (Graph * gr)
1043 {
1044   gr->pixmap = createpixmap (Drawarea, gr->w, gr->h);
1045   fillrectangle (dpy, gr->pixmap, 0, 0, 0, gr->w, gr->h, 0, 0, 0);
1046   return gr->pixmap;
1047 
1048 }
1049 
1050 Pixmap
getpixmap(Graph * gr,int * x,int * y,int * w,int * h)1051 getpixmap (Graph * gr, int *x, int *y, int *w, int *h)
1052 {
1053   *x = gr->x;
1054   *y = gr->y;
1055 
1056   *w = gr->w;
1057   *h = gr->h;
1058   return gr->pixmap;
1059 }
1060