1 /*----------------------------------------------------------------------------
2                  frame2.cc (functions related to frame objects)
3                        This file is a part of topaz systems
4                   Copyright: Hisao Kawaura, All rights reserved
5                                    1997 - 98
6 
7 
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 
22 ----------------------------------------------------------------------------*/
23 
24 #include <string>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <math.h>
28 #include "frame.h"
29 #include "graph.h"
30 #include "axis.h"
31 #include "data.h"
32 #include "gdi.h"
33 #include "vectdefs.h"
34 #include "pointdefs.h"
35 #include "topazvalues.h"
36 
37 extern void message(const char *msg);
38 extern void StyleLinePath(bool flag, FILE *f, doublepointarray *array, int no_of_point, int style, int width,
39 			  bool Clip, intrect *AxisRect, intrect *boundrect);
40 extern bool IsValidConstant(std::string *str);
41 extern bool IsValidFunction(std::string *str);
42 
paint(bool flag,FILE * f)43 bool frame::paint(bool flag, FILE* f)
44 {
45   intpointarray *ia;
46   ia = new intpointarray;
47 
48   plinestyle(flag, f, scale(framelinestyle.width), framelinestyle.cap, framelinestyle.join, framelinestyle.style);
49   pfillstyle(flag, f, framebodyfillstyle.fillrule, framebodyfillstyle.style);
50   psetforecolor(flag, f, framelinecolor.red, framelinecolor.green, framelinecolor.blue);
51   psetbackcolor(flag, f, framebodycolor.red, framebodycolor.green, framebodycolor.blue);
52 
53   ia->setbuff(0);
54   ia->add(new intpoint(wtov_x(0), wtov_y(0)));
55   ia->add(new intpoint(wtov_x(p2.x - p1.x), wtov_y(0)));
56   ia->add(new intpoint(wtov_x(p2.x - p1.x), wtov_y(p2.y - p1.y)));
57   ia->add(new intpoint(wtov_x(0), wtov_y(p2.y - p1.y)));
58   ppolygon(flag, f, ia);
59 
60   delete ia;
61   return true;
62 }
63 
wtov_x(int wx)64 int frame::wtov_x(int wx)
65 {
66   return (wx + p1.x);
67 }
68 
wtov_y(int wy)69 int frame::wtov_y(int wy)
70 {
71   return (wy + p1.y);
72 }
73 
scale(int x)74 int frame::scale(int x)
75 {
76   return x;
77 }
78 
doubleworld_to_view_x(double wx)79 double frame::doubleworld_to_view_x(double wx)
80 {
81   return (wx + (double)p1.x);
82 }
83 
doubleworld_to_view_y(double wy)84 double frame::doubleworld_to_view_y(double wy)
85 {
86   return (wy + (double)p1.y);
87 }
88 
doubleworldtoshortworld(double x)89 int frame::doubleworldtoshortworld(double x)
90 {
91   if (fabs(x) >= (double)MAXSHORT)
92     return MAXSHORT;
93   else
94     return ((int)x);
95 }
96 
97 
vtow_x(int vx)98 int frame::vtow_x(int vx)
99 {
100   return (vx - p1.x);
101 }
102 
vtow_y(int vy)103 int frame::vtow_y(int vy)
104 {
105   return (vy - p1.y);
106 }
107 
doubleview_to_world_x(double vx)108 double frame::doubleview_to_world_x(double vx)
109 {
110   return ((double)vx - (double)p1.x);
111 }
112 
doubleview_to_world_y(double vy)113 double frame::doubleview_to_world_y(double vy)
114 {
115   return ((double)vy - (double)p1.y);
116 }
117 
arrangeaxes()118 void frame::arrangeaxes()
119 {
120   axis *ax, *ay, *at, *ar;
121   intpoint ip;
122   int itemp;
123 
124   ax = &(*axarray)[0];
125   ay = &(*axarray)[1];
126   at = &(*axarray)[2];
127   ar = &(*axarray)[3];
128 
129   switch(frametype)
130     {
131     case FRAME_BOX:
132       ax->origin.x      = 0;
133       ax->origin.y      = p2.y - p1.y;
134       ax->length        = p2.x - p1.x;
135       ax->angle         = 0.0;
136       ax->fo.angle      = 0.0;
137 
138       ay->display       = ax->display;
139       ay->origin.x      = 0;
140       ay->origin.y      = p2.y - p1.y;
141       ay->length        = p2.y - p1.y;
142       ay->angle         = 90.0;
143       ay->tickwidth     = ax->tickwidth;
144       ay->ticklength    = ax->ticklength;
145       ay->fo.angle      = 270.0;
146 
147 
148       at->display       = ax->display;
149       at->origin.x      = 0;
150       at->origin.y      = 0;
151       at->length        = p2.x - p1.x;
152       at->angle         = 0.0;
153       at->crosspoint    = ax->crosspoint;
154       at->autocrosspoint = ax->autocrosspoint;
155       at->tickwidth     = ax->tickwidth;
156       at->ticklength    = ax->ticklength;
157       at->fo.angle      = 0.0;
158 
159       if (ax->commonset)
160 	{
161 	  at->scaling      = ax->scaling;
162 	  at->invertscale  = ax->invertscale;
163 	  at->start        = ax->start;
164 	  at->end          = ax->end;
165 	  at->unit         = ax->unit;
166 
167 	  switch(ax->tickparity)
168 	    {
169 	    case TICKPARITY_NULL:
170 	    case TICKPARITY_BOTH:
171 	      at->tickparity   = ax->tickparity;
172 	      break;
173 	    case TICKPARITY_PLUS:
174 	      at->tickparity   = TICKPARITY_MINUS;
175 	      break;
176 	    case TICKPARITY_MINUS:
177 	      at->tickparity   = TICKPARITY_PLUS;
178 	      break;
179 	    }
180 
181 	  at->division     = ax->division;
182 	  at->baselinestyle = ax->baselinestyle;
183 	  at->basecolor     = ax->basecolor;
184 	  at->tickarea_start = ax->tickarea_start;
185 	  at->tickarea_end  = ax->tickarea_end;
186 
187 	  at->majorticklinecolor = ax->majorticklinecolor;
188 	  at->minorticklinecolor = ax->minorticklinecolor;
189 	  at->majorticklinestyle = ax->majorticklinestyle;
190 	  at->minorticklinestyle = ax->minorticklinestyle;
191 	  at->fo.face       = ax->fo.face;
192 	  at->fo.size       = ax->fo.size;
193 	  at->fontcolor     = ax->fontcolor;
194 	  at->addplus       = ax->addplus;
195 	  at->offset        = ax->offset;
196 	  at->skip          = ax->skip;
197 	  at->autoprecision = ax->autoprecision;
198 	  at->intprecision  = ax->intprecision;
199 	  at->decimalprecision = ax->decimalprecision;
200 	}
201 
202       ar->display       = ax->display;
203       ar->origin.x      = p2.x - p1.x;
204       ar->origin.y      = p2.y - p1.y;
205       ar->length        = p2.y - p1.y;
206       ar->angle         = 90.0;
207       ar->crosspoint    = ay->crosspoint;
208       ar->autocrosspoint = ay->autocrosspoint;
209       ar->tickwidth     = ax->tickwidth;
210       ar->ticklength    = ax->ticklength;
211       ar->fo.angle      = 270.0;
212 
213       if (ay->commonset)
214 	{
215 	  ar->scaling      = ay->scaling;
216 	  ar->invertscale  = ay->invertscale;
217 	  ar->start        = ay->start;
218 	  ar->end          = ay->end;
219 	  ar->unit         = ay->unit;
220 
221 	  switch(ay->tickparity)
222 	    {
223 	    case TICKPARITY_NULL:
224 	    case TICKPARITY_BOTH:
225 	      ar->tickparity   = ay->tickparity;
226 	      break;
227 	    case TICKPARITY_PLUS:
228 	      ar->tickparity   = TICKPARITY_MINUS;
229 	      break;
230 	    case TICKPARITY_MINUS:
231 	      ar->tickparity   = TICKPARITY_PLUS;
232 	      break;
233 	    }
234 
235 	  ar->division     = ay->division;
236 	  ar->baselinestyle = ay->baselinestyle;
237 	  ar->basecolor     = ay->basecolor;
238 	  ar->tickarea_start = ay->tickarea_start;
239 	  ar->tickarea_end  = ay->tickarea_end;
240 	  ar->majorticklinecolor = ay->majorticklinecolor;
241 	  ar->minorticklinecolor = ay->minorticklinecolor;
242 	  ar->majorticklinestyle = ay->majorticklinestyle;
243 	  ar->minorticklinestyle = ay->minorticklinestyle;
244 	  ar->fo.face       = ay->fo.face;
245 	  ar->fo.size       = ay->fo.size;
246 	  ar->fontcolor     = ay->fontcolor;
247 	  ar->addplus       = ay->addplus;
248 	  ar->offset        = ay->offset;
249 	  ar->skip          = ay->skip;
250 	  ar->autoprecision = ay->autoprecision;
251 	  ar->intprecision  = ay->intprecision;
252 	  ar->decimalprecision = ay->decimalprecision;
253 	}
254 
255       break;
256     case FRAME_XY:
257 
258       if (ay->autocrosspoint)
259 	{
260 	  itemp = p2.y - p1.y;
261 	}
262       else
263 	{
264 	  ip = ay->virtual_to_world(ay->crosspoint);
265 	  itemp = ip.y;
266 	}
267 
268       if (itemp < 0 || itemp > p2.y - p1.y)
269 	itemp = 0;
270 
271 
272       ax->origin.x      = 0;
273       ax->origin.y      = itemp;
274       ax->length        = p2.x - p1.x;
275       ax->angle         = 0.0;
276       ax->crosspointoffset = ay->offset;
277       ax->fo.angle      = 0.0;
278 
279       if (ax->autocrosspoint)
280 	{
281 	  itemp = 0;
282 	}
283       else
284 	{
285 	  ip = ax->virtual_to_world(ax->crosspoint);
286 	  itemp = ip.x;
287 	}
288 
289       if (itemp < 0 || itemp > p2.x - p1.x)
290 	itemp = 0;
291 
292       ay->display       = ax->display;
293       ay->origin.x      = itemp;
294       ay->origin.y      = p2.y - p1.y;
295       ay->length        = p2.y - p1.y;
296       ay->angle         = 90.0;
297       ay->baselinestyle = ax->baselinestyle;
298       ay->basecolor     = ax->basecolor;
299       ay->tickwidth     = ax->tickwidth;
300       ay->ticklength    = ax->ticklength;
301       ay->crosspointoffset = ax->offset;
302       ay->fo.angle      = 270.0;
303 
304       at->display       = false;
305       at->origin.x      = 0;
306       at->origin.y      = 0;
307       at->length        = p2.x - p1.x;
308       at->angle         = 0.0;
309       at->baselinestyle = ax->baselinestyle;
310       at->basecolor     = ax->basecolor;
311       at->crosspoint    = ax->crosspoint;
312       at->autocrosspoint = ax->autocrosspoint;
313       at->tickwidth     = ax->tickwidth;
314       at->ticklength    = ax->ticklength;
315       at->fo.angle      = 0.0;
316 
317       if (ax->commonset)
318 	{
319 	  at->scaling      = ax->scaling;
320 	  at->tickarea_start = ax->tickarea_start;
321 	  at->tickarea_end  = ax->tickarea_end;
322 	  at->invertscale  = ax->invertscale;
323 	  at->start        = ax->start;
324 	  at->end          = ax->end;
325 	  at->unit         = ax->unit;
326 	  at->tickparity   = ax->tickparity;
327 	  at->division     = ax->division;
328 	  at->majorticklinecolor = ax->majorticklinecolor;
329 	  at->minorticklinecolor = ax->minorticklinecolor;
330 	  at->majorticklinestyle = ax->majorticklinestyle;
331 	  at->minorticklinestyle = ax->minorticklinestyle;
332 	  at->fo.face       = ax->fo.face;
333 	  at->fo.size       = ax->fo.size;
334 	  at->fontcolor     = ax->fontcolor;
335 	  at->addplus       = ax->addplus;
336 	  at->offset        = ax->offset;
337 	  at->skip          = ax->skip;
338 	  at->autoprecision = ax->autoprecision;
339 	  at->intprecision  = ax->intprecision;
340 	  at->decimalprecision = ax->decimalprecision;
341 	}
342 
343       ar->display       = false;
344       ar->origin.x      = p2.x - p1.x;
345       ar->origin.y      = p2.y - p1.y;
346       ar->length        = p2.y - p1.y;
347       ar->angle         = 90.0;
348       ar->baselinestyle = ax->baselinestyle;
349       ar->basecolor     = ax->basecolor;
350       ar->crosspoint    = ay->crosspoint;
351       ar->autocrosspoint = ay->autocrosspoint;
352       ar->tickwidth     = ax->tickwidth;
353       ar->ticklength    = ax->ticklength;
354       ar->fo.angle      = 270.0;
355 
356       if (ay->commonset)
357 	{
358 	  ar->scaling      = ay->scaling;
359 	  ar->tickarea_start = ay->tickarea_start;
360 	  ar->tickarea_end  = ay->tickarea_end;
361 	  ar->invertscale  = ay->invertscale;
362 	  ar->start        = ay->start;
363 	  ar->end          = ay->end;
364 	  ar->unit         = ay->unit;
365 	  ar->tickparity   = ay->tickparity;
366 	  ar->division     = ay->division;
367 	  ar->majorticklinecolor = ay->majorticklinecolor;
368 	  ar->minorticklinecolor = ay->minorticklinecolor;
369 	  ar->majorticklinestyle = ay->majorticklinestyle;
370 	  ar->minorticklinestyle = ay->minorticklinestyle;
371 	  ar->fo.face       = ay->fo.face;
372 	  ar->fo.size       = ay->fo.size;
373 	  ar->fontcolor     = ay->fontcolor;
374 	  ar->addplus       = ay->addplus;
375 	  ar->offset        = ay->offset;
376 	  ar->skip          = ay->skip;
377 	  ar->autoprecision = ay->autoprecision;
378 	  ar->intprecision  = ay->intprecision;
379 	  ar->decimalprecision = ay->decimalprecision;
380 	}
381       break;
382     case FRAME_INDIV:
383       /*
384       ax->angle         = 0.0;
385       ay->angle         = 90.0;
386       at->angle         = 0.0;
387       ar->angle         = 90.0;
388       ax->fo.angle      = 0.0;
389       ay->fo.angle      = 270.0;
390       at->fo.angle      = 0.0;
391       ar->fo.angle      = 270.0;
392       */
393       break;
394     }
395 }
396 
axispaintmajorline(bool flag,FILE * f,axis * axis)397 bool frame::axispaintmajorline(bool flag, FILE *f, axis *axis)
398 {
399   int linestart, lineend;
400   double virstart, virend, startval, endval;
401   double delta;
402   int itercount;
403   intpoint valpos, fixedpos;
404   doublepoint tempdpoint;
405   double fa;
406   doublepointarray *da;
407   intrect axisrect, cliprect;
408 
409   if (axis->display == false)
410     return true;
411 
412   da = new doublepointarray;
413 
414   // determine tickstart, tickend
415   switch(axis->axistype)
416     {
417     case AXISTYPE_X:
418     case AXISTYPE_T:
419       linestart = wtov_y(0); lineend = wtov_y(p2.y - p1.y);
420       break;
421     case AXISTYPE_Y:
422     case AXISTYPE_R:
423       linestart = wtov_x(0); lineend = wtov_x(p2.x - p1.x);
424       break;
425     default:
426       return false;
427     }
428 
429   // majorline style
430   plinestyle(flag, f, scale(axis->majorticklinestyle.width), axis->majorticklinestyle.cap,
431 	     axis->majorticklinestyle.join, LINESTYLESOLID);
432 
433   //majorlinecolor
434   psetforecolor(flag, f, axis->majorticklinecolor.red, axis->majorticklinecolor.green, axis->majorticklinecolor.blue);
435 
436   switch(axis->scaling)
437     {
438     case SCALE_LINEAR:
439     case SCALE_LOGLINEAR:
440     case SCALE_INVLINEAR:
441 
442       if (axis->unit == 0.0)
443 	{
444 	  message("Invalid unit!!\n");
445 	  delete da;
446 	  return false;
447 	}
448 
449       virstart = floor(axis->start / axis->unit) * axis->unit;
450       virend = floor(axis->end / axis->unit) * axis->unit;
451       virend += axis->unit;
452       delta           = DELTA_AXIS * (axis->end - axis->start);
453       startval        = axis->start      - delta;
454       endval          = axis->end        + delta;
455       itercount = (int)((virend - virstart) / axis->unit) + 2;
456 
457       if (itercount >100)
458 	{
459 	  message("Too much ticks!!\n");
460 	  delete da;
461 	  return false;
462 	}
463 
464       for (int i = 0; i <= itercount; i++)
465 	{
466 	  fa = virstart + (double)i * axis->unit;
467 	  if ((fa >= startval) && (fa <= endval))
468 	    {
469 	      switch(axis->axistype)
470 		{
471 		case AXISTYPE_X:
472 		case AXISTYPE_T:
473 		  tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
474 		  valpos.x = wtov_x((int)tempdpoint.x);
475 		  valpos.y = linestart;
476 		  tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
477 		  fixedpos.x = wtov_x((int)tempdpoint.x);
478 		  fixedpos.y = lineend;
479 		  break;
480 		case AXISTYPE_Y:
481 		case AXISTYPE_R:
482 		  tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
483 		  valpos.x = linestart;
484 		  valpos.y = wtov_y((int)tempdpoint.y);
485 		  tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
486 		  fixedpos.x = lineend;
487 		  fixedpos.y = wtov_y((int)tempdpoint.y);
488 		  break;
489 	      }
490 
491 
492 	      pbeginpath(flag, f);
493 	      da->setbuff(0);
494 	      da->add(new doublepoint(fixedpos.x, fixedpos.y));
495 	      da->add(new doublepoint(valpos.x, valpos.y));
496 	      StyleLinePath(flag, f, da, da->getarraylength() - 1,
497 			    axis->majorticklinestyle.style, axis->majorticklinestyle.width,
498 			    false, &axisrect, &cliprect);
499 	      pstroke(flag, f);
500 	    }
501 	}
502       break;
503     case SCALE_LOG:
504     case SCALE_INV:
505       virstart = pow(10.0, floor(log10(axis->start)));
506       virend   = pow(10.0, floor(log10(axis->end)));
507       virend += 1.0;
508       delta           = DELTA_AXIS * (log10(axis->end) - log10(axis->start));
509       startval        = axis->start      / pow(10.0, delta);
510       endval          = axis->end        * pow(10.0, delta);
511 
512       itercount = (int)(log10(virend / virstart)) + 2;
513       for (int i = 0; i <= itercount; i++)
514 	{
515 	  fa = virstart * pow(10.0, (double)i);
516 	  if ((fa >= startval) && (fa <= endval))
517 	    {
518 	      switch(axis->axistype)
519 		{
520 		case AXISTYPE_X:
521 		case AXISTYPE_T:
522 		  tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
523 		  valpos.x = wtov_x((int)tempdpoint.x);
524 		  valpos.y = linestart;
525 		  tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
526 		  fixedpos.x = wtov_x((int)tempdpoint.x);
527 		  fixedpos.y = lineend;
528 		  break;
529 		case AXISTYPE_Y:
530 		case AXISTYPE_R:
531 		  tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
532 		  valpos.x = linestart;
533 		  valpos.y = wtov_y((int)tempdpoint.y);
534 		  tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
535 		  fixedpos.x = lineend;
536 		  fixedpos.y = wtov_y((int)tempdpoint.y);
537 		  break;
538 	      }
539 
540 	      pbeginpath(flag, f);
541 	      da->setbuff(0);
542 	      da->add(new doublepoint(fixedpos.x, fixedpos.y));
543 	      da->add(new doublepoint(valpos.x, valpos.y));
544 	      StyleLinePath(flag, f, da, da->getarraylength() - 1,
545 			    axis->majorticklinestyle.style, axis->majorticklinestyle.width,
546 			    false, &axisrect, &cliprect);
547 	      pstroke(flag, f);
548 	    }
549 	}
550       break;
551     }
552 
553   delete da;
554   return true;
555 }
556 
axispaintminorline(bool flag,FILE * f,axis * axis)557 bool frame::axispaintminorline(bool flag, FILE* f, axis *axis)
558 {
559   int linestart, lineend;
560   double virstart, virend, startval, endval;
561   double delta;
562   int itercount;
563   intpoint valpos, fixedpos;
564   doublepoint tempdpoint;
565   double fa;
566   int logminortickstart, logminortickend, logminortickunit;
567   doublepointarray *da;
568   intrect axisrect, cliprect;
569 
570   if (axis->display == false)
571     return true;
572 
573   da = new doublepointarray;
574 
575   // determine tickstart, tickend
576   switch(axis->axistype)
577     {
578     case AXISTYPE_X:
579     case AXISTYPE_T:
580       linestart = wtov_y(0); lineend = wtov_y(p2.y - p1.y);
581       break;
582     case AXISTYPE_Y:
583     case AXISTYPE_R:
584       linestart = wtov_x(0); lineend = wtov_x(p2.x - p1.x);
585       break;
586     default:
587       return false;
588     }
589 
590   // majorline style
591   plinestyle(flag, f, scale(axis->minorticklinestyle.width), axis->minorticklinestyle.cap,
592 	     axis->minorticklinestyle.join, LINESTYLESOLID);
593 
594   //majorlinecolor
595   psetforecolor(flag, f, axis->minorticklinecolor.red, axis->minorticklinecolor.green, axis->minorticklinecolor.blue);
596 
597   switch(axis->scaling)
598     {
599     case SCALE_LINEAR:
600     case SCALE_LOGLINEAR:
601     case SCALE_INVLINEAR:
602 
603       if (axis->unit == 0.0)
604 	{
605 	  message("Invalid unit!!\n");
606 	  delete da;
607 	  return false;
608 	}
609 
610       virstart = floor(axis->start / axis->unit) * axis->unit;
611       virend = floor(axis->end / axis->unit) * axis->unit;
612       virend += axis->unit;
613       delta           = DELTA_AXIS * (axis->end - axis->start);
614       startval        = axis->start      - delta;
615       endval          = axis->end        + delta;
616       itercount = (int)((virend - virstart) / axis->unit * (double)axis->division) + 2;
617 
618       if (itercount >100)
619 	{
620 	  message("Too much ticks!!\n");
621 	  delete da;
622 	  return false;
623 	}
624 
625       for (int i = 0; i <= itercount; i++)
626 	{
627 	  fa = virstart + (double)i * axis->unit / (double)axis->division;
628 	  if ((fa >= startval) && (fa <= endval))
629 	    {
630 	      if ((i % axis->division) != 0)         // except tick position
631 		{
632 		  switch(axis->axistype)
633 		    {
634 		    case AXISTYPE_X:
635 		    case AXISTYPE_T:
636 		      tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
637 		      valpos.x = wtov_x((int)tempdpoint.x);
638 		      valpos.y = linestart;
639 		      tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
640 		      fixedpos.x = wtov_x((int)tempdpoint.x);
641 		      fixedpos.y = lineend;
642 		      break;
643 		    case AXISTYPE_Y:
644 		    case AXISTYPE_R:
645 		      tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
646 		      valpos.x = linestart;
647 		      valpos.y = wtov_y((int)tempdpoint.y);
648 		      tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
649 		      fixedpos.x = lineend;
650 		      fixedpos.y = wtov_y((int)tempdpoint.y);
651 		      break;
652 		    }
653 
654 		  pbeginpath(flag, f);
655 		  da->setbuff(0);
656 		  da->add(new doublepoint(fixedpos.x, fixedpos.y));
657 		  da->add(new doublepoint(valpos.x, valpos.y));
658 		  StyleLinePath(flag, f, da, da->getarraylength() - 1,
659 				axis->minorticklinestyle.style, axis->minorticklinestyle.width,
660 				false, &axisrect, &cliprect);
661 		  pstroke(flag, f);
662 		}
663 	    }
664 	}
665       break;
666     case SCALE_LOG:
667     case SCALE_INV:
668       switch(axis->division)
669 	{
670 	case 1:
671 	  logminortickstart       = 1;
672 	  logminortickend         = -1;
673 	  logminortickunit        = 1;
674 	  break;
675 	case 2:
676 	  logminortickstart       = 5;
677 	  logminortickend         = 5;
678 	  logminortickunit        = 1;
679 	  break;
680 	case 5:
681 	  logminortickstart       = 2;
682 	  logminortickend         = 8;
683 	  logminortickunit        = 2;
684 	  break;
685 	case 10:
686 	default:
687 	  logminortickstart       = 2;
688 	  logminortickend         = 9;
689 	  logminortickunit        = 1;
690 	  break;
691 	}
692 
693       virstart = pow(10.0, floor(log10(axis->start)));
694       virend   = pow(10.0, floor(log10(axis->end)));
695       virend += 1.0;
696       delta           = DELTA_AXIS * (log10(axis->end) - log10(axis->start));
697       startval        = axis->start      / pow(10.0, delta);
698       endval          = axis->end        * pow(10.0, delta);
699 
700       itercount = (int)(log10(virend / virstart)) + 2;
701       for (int i = 0; i <= itercount; i++)
702 	{
703 	  for (int j = logminortickstart; j <= logminortickend; j = j + logminortickunit)
704 	    {
705 	      fa = virstart * pow(10.0, (double)i) * (double)j;
706 	      if ((fa >= startval) && (fa <= endval))
707 		{
708 		  switch(axis->axistype)
709 		    {
710 		    case AXISTYPE_X:
711 		    case AXISTYPE_T:
712 		      tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
713 		      valpos.x = wtov_x((int)tempdpoint.x);
714 		      valpos.y = linestart;
715 		      tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
716 		      fixedpos.x = wtov_x((int)tempdpoint.x);
717 		      fixedpos.y = lineend;
718 		      break;
719 		    case AXISTYPE_Y:
720 		    case AXISTYPE_R:
721 		      tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
722 		      valpos.x = linestart;
723 		      valpos.y = wtov_y((int)tempdpoint.y);
724 		      tempdpoint = axis->axis_to_world(axis->virtual_to_axis(fa), 0);
725 		      fixedpos.x = lineend;
726 		      fixedpos.y = wtov_y((int)tempdpoint.y);
727 		      break;
728 		    }
729 
730 		  pbeginpath(flag, f);
731 		  da->setbuff(0);
732 		  da->add(new doublepoint(fixedpos.x, fixedpos.y));
733 		  da->add(new doublepoint(valpos.x, valpos.y));
734 		  StyleLinePath(flag, f, da, da->getarraylength() - 1,
735 				axis->minorticklinestyle.style, axis->minorticklinestyle.width,
736 				false, &axisrect, &cliprect);
737 		  pstroke(flag, f);
738 		}
739 	    }
740 	}
741       break;
742     }
743   delete da;
744   return true;
745 }
746 
setaxisid(int arrayno)747 bool frame::setaxisid(int arrayno)
748 {
749   // calc max id
750   int maxid = -1;
751   for (int i = 0; i < axarray->getarraylength(); i++)
752     {
753       if (i != arrayno && maxid < (*axarray)[i].id)
754 	maxid = (*axarray)[i].id;
755     }
756 
757   if (maxid == -1)
758     {
759       (*axarray)[arrayno].id = 0;
760       return true;
761     }
762 
763   // create table
764   bool *buf = new bool [(maxid + 1) * sizeof(bool)];
765   if (buf == 0)
766     return false;
767   memset(buf, 0, (maxid + 1) * sizeof(bool));
768 
769   // set table
770   for (int i = 0; i < axarray->getarraylength(); i++)
771     {
772       if (i != arrayno)
773 	buf[(*axarray)[i].id] = true;
774     }
775 
776   // search id
777   for (int i = 0; i <= maxid; i++)
778     {
779       if (buf[i] == 0)
780 	{
781 	  (*axarray)[arrayno].id = i;
782 	  delete buf;
783 	  return true;
784 	}
785     }
786   delete buf;
787   (*axarray)[arrayno].id = maxid + 1;
788   return true;
789 }
790 
getaxisindex(int id)791 int frame::getaxisindex(int id)
792 {
793   for (int i = 0; i < axarray->getarraylength(); i++)
794     {
795       if (id == (*axarray)[i].id)
796 	return i;
797     }
798   return -1;
799 }
800 
setdataid(int arrayno)801 bool frame::setdataid(int arrayno)
802 {
803   // calc max id
804   int maxid = -1;
805   for (int i = 0; i < darray->getarraylength(); i++)
806     {
807       if (i != arrayno && maxid < (*darray)[i].id)
808 	maxid = (*darray)[i].id;
809     }
810 
811   if (maxid == -1)
812     {
813       (*darray)[arrayno].id = 0;
814       return true;
815     }
816 
817   // create table
818   bool *buf = new bool [(maxid + 1) * sizeof(bool)];
819   if (buf == 0)
820     return false;
821   memset(buf, 0, (maxid + 1) * sizeof(bool));
822 
823   // set table
824   for (int i = 0; i < darray->getarraylength(); i++)
825     {
826       if (i != arrayno)
827 	buf[(*darray)[i].id] = true;
828     }
829 
830   // search id
831   for (int i = 0; i <= maxid; i++)
832     {
833       if (buf[i] == 0)
834 	{
835 	  (*darray)[arrayno].id = i;
836 	  delete buf;
837 	  return true;
838 	}
839     }
840   delete buf;
841   (*darray)[arrayno].id = maxid + 1;
842   return true;
843 }
844 
getdataindex(int id)845 int frame::getdataindex(int id)
846 {
847   for (int i = 0; i < darray->getarraylength(); i++)
848     {
849       if (id == (*darray)[i].id)
850 	return i;
851     }
852   return -1;
853 }
854 
setpartsid(int arrayno)855 bool frame::setpartsid(int arrayno)
856 {
857   // calc max id
858   int maxid = -1;
859   for (int i = 0; i < parray->getarraylength(); i++)
860     {
861       if (i != arrayno && maxid < (*parray)[i].id)
862 	maxid = (*parray)[i].id;
863     }
864 
865   if (maxid == -1)
866     {
867       (*parray)[arrayno].id = 0;
868       return true;
869     }
870 
871   // create table
872   bool *buf = new bool [(maxid + 1) * sizeof(bool)];
873   if (buf == 0)
874     return false;
875   memset(buf, 0, (maxid + 1) * sizeof(bool));
876 
877   // set table
878   for (int i = 0; i < parray->getarraylength(); i++)
879     {
880       if (i != arrayno)
881 	buf[(*parray)[i].id] = true;
882     }
883 
884   // search id
885   for (int i = 0; i <= maxid; i++)
886     {
887       if (buf[i] == 0)
888 	{
889 	  (*parray)[arrayno].id = i;
890 	  delete buf;
891 	  return true;
892 	}
893     }
894   delete buf;
895   (*parray)[arrayno].id = maxid + 1;
896   return true;
897 }
898 
899 
getpartsindex(int id)900 int frame::getpartsindex(int id)
901 {
902   for (int i = 0; i < parray->getarraylength(); i++)
903     {
904       if (id == (*parray)[i].id)
905 	return i;
906     }
907   return -1;
908 }
909 
getBBbox(intrect * r)910 void frame::getBBbox(intrect *r)
911 {
912   r->left   = wtov_x(0);
913   r->top    = wtov_y(0);
914   r->right  = wtov_x(p2.x - p1.x);
915   r->bottom = wtov_y(p2.y - p1.y);
916 }
917 
readframe(FILE * fp)918 bool frame::readframe(FILE *fp)
919 {
920   char stemp[10000];
921   std::string str, label, value;
922   char *p;
923   int no;
924   int readversion;
925 
926   // version
927   if (getnextline(stemp, sizeof(stemp), fp))
928   {
929     if (nextitem(stemp, &str) != 0)
930       readversion = atoi(str.c_str());
931     else
932       return false;
933   }
934   else
935     return false;
936 
937   // id
938   if (getnextline(stemp, sizeof(stemp), fp))
939   {
940     if (nextitem(stemp, &str) != 0)
941       id = atoi(str.c_str());
942     else
943       return false;
944   }
945   else
946     return false;
947 
948   // frametype
949   if (getnextline(stemp, sizeof(stemp), fp))
950   {
951 
952     if (nextitem(stemp, &str) != 0)
953       frametype = atoi(str.c_str());
954     else
955       return false;
956   }
957   else
958     return false;
959 
960   // p1, p2
961   if (getnextline(stemp, sizeof(stemp), fp))
962   {
963     p = stemp;
964     // p1.x
965     p = nextitem(p, &str);
966     if (p != 0)
967       p1.x = atoi(str.c_str());
968     else
969       return false;
970     // p1.y
971     p = nextitem(p, &str);
972     if (p != 0)
973       p1.y = atoi(str.c_str());
974     else
975       return false;
976     // p2.x
977     p = nextitem(p, &str);
978     if (p != 0)
979       p2.x = atoi(str.c_str());
980     else
981       return false;
982     // p2.y
983     p = nextitem(p, &str);
984     if (p != 0)
985       p2.y = atoi(str.c_str());
986     else
987       return false;
988   }
989   else
990     return false;
991 
992   // framelinecolor
993   if (getnextline(stemp, sizeof(stemp), fp))
994   {
995     p = stemp;
996     // framelinecolor.red
997     p = nextitem(p, &str);
998     if (p != 0)
999       framelinecolor.red = atoi(str.c_str());
1000     else
1001       return false;
1002     // framelinecolor.green
1003     p = nextitem(p, &str);
1004     if (p != 0)
1005       framelinecolor.green = atoi(str.c_str());
1006     else
1007       return false;
1008     // framelinecolor.blue
1009     p = nextitem(p, &str);
1010     if (p != 0)
1011       framelinecolor.blue = atoi(str.c_str());
1012     else
1013       return false;
1014   }
1015   else
1016     return false;
1017 
1018 
1019   // framebodycolor
1020   if (getnextline(stemp, sizeof(stemp), fp))
1021   {
1022     p = stemp;
1023     // framebodycolor.red
1024     p = nextitem(p, &str);
1025     if (p != 0)
1026       framebodycolor.red = atoi(str.c_str());
1027     else
1028       return false;
1029     // framebodycolor.green
1030     p = nextitem(p, &str);
1031     if (p != 0)
1032       framebodycolor.green = atoi(str.c_str());
1033     else
1034       return false;
1035     // framebodycolor.blue
1036     p = nextitem(p, &str);
1037     if (p != 0)
1038       framebodycolor.blue = atoi(str.c_str());
1039     else
1040       return false;
1041   }
1042   else
1043     return false;
1044 
1045   // framelinestyle
1046   if (getnextline(stemp, sizeof(stemp), fp))
1047   {
1048     p = stemp;
1049     // framelinestyle.width
1050     p = nextitem(p, &str);
1051     if (p != 0)
1052       framelinestyle.width = atoi(str.c_str());
1053     else
1054       return false;
1055     // framelinestyle.cap
1056     p = nextitem(p, &str);
1057     if (p != 0)
1058       framelinestyle.cap = atoi(str.c_str());
1059     else
1060       return false;
1061     // framelinestyle.join
1062     p = nextitem(p, &str);
1063     if (p != 0)
1064       framelinestyle.join = atoi(str.c_str());
1065     else
1066       return false;
1067     // framelinestyle.style
1068     p = nextitem(p, &str);
1069     if (p != 0)
1070       framelinestyle.style = atoi(str.c_str());
1071     else
1072       return false;
1073   }
1074   else
1075     return false;
1076 
1077   // framebodyfillstyle
1078   if (getnextline(stemp, sizeof(stemp), fp))
1079   {
1080     p = stemp;
1081     // framebodyfillstyle.fillrule
1082     p = nextitem(p, &str);
1083     if (p != 0)
1084       framebodyfillstyle.fillrule = atoi(str.c_str());
1085     else
1086       return false;
1087     // framebodyfillstyle.style
1088     p = nextitem(p, &str);
1089     if (p != 0)
1090       framebodyfillstyle.style = atoi(str.c_str());
1091     else
1092       return false;
1093   }
1094   else
1095     return false;
1096 
1097   // withdata
1098   if (getnextline(stemp, sizeof(stemp), fp))
1099   {
1100     if (nextitem(stemp, &str) != 0)
1101       withdata = atoi(str.c_str());
1102     else
1103       return false;
1104   }
1105   else
1106     return false;
1107 
1108   // paintorder
1109   if (readversion < 2)
1110       *paintorder = std::string("frame,data,axis,axisline,parts");
1111   else
1112     {
1113       if (getnextline(stemp, sizeof(stemp), fp))
1114 	{
1115 	  if (nextitem(stemp, &str) != 0)
1116 	    *paintorder = str;
1117 	  else
1118 	    return false;
1119 	}
1120       else
1121 	return false;
1122     }
1123 
1124   // user const
1125   // number
1126   usrconst->setbuff(0);
1127   if (getnextline(stemp, sizeof(stemp), fp))
1128     no = atoi(stemp);
1129   else
1130     return false;
1131   for (int i = 0; i < no; i++)
1132     {
1133       if (getnextline(stemp, sizeof(stemp), fp))
1134 	{
1135 	  // label
1136 	  if (nextitem(stemp, &str) != 0)
1137 	    label = str;
1138 	  else
1139 	    return false;
1140 	}
1141       else
1142 	return false;
1143       if (getnextline(stemp, sizeof(stemp), fp))
1144 	{
1145 	  // value
1146 	  if (nextitem(stemp, &str) != 0)
1147 	    value = str;
1148 	  else
1149 	    return false;
1150 	}
1151       else
1152 	return false;
1153       usrconst->add(&label, &value);
1154     }
1155 
1156   // user function
1157   // number
1158   usrfnc->setbuff(0);
1159   if (getnextline(stemp, sizeof(stemp), fp))
1160     no = atoi(stemp);
1161   else
1162     return false;
1163   for (int i = 0; i < no; i++)
1164     {
1165       // label
1166       if (getnextline(stemp, sizeof(stemp), fp))
1167 	{
1168 	  if (gettxt(stemp, &str))
1169 	    label = str;
1170 	  else
1171 	    return false;
1172 	}
1173       else
1174 	return false;
1175       //value
1176       if (getnextline(stemp, sizeof(stemp), fp))
1177 	{
1178 	  if (gettxt(stemp, &str))
1179 	    value = str;
1180 	  else
1181 	    return false;
1182 	}
1183       else
1184 	return false;
1185       usrfnc->add(&label, &value);
1186     }
1187   return true;
1188 }
1189 
writeframe(FILE * fp)1190 bool frame::writeframe(FILE *fp)
1191 {
1192   fprintf(fp, "[frame]\n");
1193   fprintf(fp, "%d\n", version);
1194   fprintf(fp, "%d\n", id);
1195   fprintf(fp, "%d\n", frametype);
1196   fprintf(fp, "%d %d %d %d\n", p1.x, p1.y, p2.x, p2.y);
1197   fprintf(fp, "%u %u %u\n", framelinecolor.red, framelinecolor.green, framelinecolor.blue);
1198   fprintf(fp, "%u %u %u\n", framebodycolor.red, framebodycolor.green, framebodycolor.blue);
1199   fprintf(fp, "%d %d %d %d\n", framelinestyle.width, framelinestyle.cap, framelinestyle.join, framelinestyle.style);
1200   fprintf(fp, "%d %d\n", framebodyfillstyle.fillrule, framebodyfillstyle.style);
1201   fprintf(fp, "%d\n", withdata);
1202   fprintf(fp, "%s\n", paintorder->c_str());
1203   fprintf(fp, "%d\n", usrconst->getarraylength());
1204   for (int i = 0; i < usrconst->getarraylength(); i++)
1205     {
1206       fprintf(fp, "%s\n", (*usrconst)[i].label.c_str());
1207       fprintf(fp, "%.15e\n", atof((*(*usrconst)[i].value)[0].c_str()));
1208     }
1209   fprintf(fp, "%d\n", usrfnc->getarraylength());
1210   for (int i = 0; i < usrfnc->getarraylength(); i++)
1211     {
1212       fprintf(fp, "\"%s\"\n", (*usrfnc)[i].label.c_str());
1213       fprintf(fp, "\"%s\"\n",(*(*usrfnc)[i].value)[0].c_str());
1214     }
1215 
1216   return true;
1217 }
1218 
setwithdata()1219 void frame::setwithdata()
1220 {
1221   for (int i = 0; i < darray->getarraylength(); i++)
1222     (*darray)[i].virgin = !withdata;
1223 }
1224