1 /*----------------------------------------------------------------------------
2                             parts.cc (parts object)
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 <stdio.h>
25 #include <stdlib.h>
26 #include <math.h>
27 #include <ctype.h>
28 #include <string>
29 #include <time.h>
30 #include "graph.h"
31 #include "frame.h"
32 #include "parts.h"
33 #include "data.h"
34 #include "defcharwidth.h"
35 #include "gdi.h"
36 #include "pointdefs.h"
37 #include "vectdefs.h"
38 #include "spline.h"
39 #include "minmax.h"
40 #include "filepoint.h"
41 #include "kanji.h"
42 #include "topazvalues.h"
43 #include "convtxt.h"
44 
45 extern void StyleLinePath(bool flag, FILE* f, doublepointarray *array, int no_of_point, int style, int width,
46 			  bool Clip, intrect *AxisRect, intrect *boundrect);
47 
48 extern FileHandleArray *fhvuff;
49 
parts()50 parts::parts():plobj()
51 {
52   version                 = 1;
53   id                      = 0;
54   label                   = new std::string("");
55   selected                = false;
56   type                    = 0;
57 
58   /* font */
59   text = new std::string("");
60   fo.init();
61   fontcolor.setblack();
62   linespacing             = 1.0;
63 
64   /* common */
65   linecolor.setblack();
66   bodycolor.setwhite();
67   linestyle.init();
68   bodystyle.init();
69   legendlength            = 100;
70   interpolate             = PARTS_INTER_POLYLINE;
71   interpolatediv          = 50;
72   p1.x                    = 0;
73   p1.y                    = 0;
74   p2.x                    = 0;
75   p2.y                    = 0;
76   p1_arrow                = false;
77   p2_arrow                = false;
78   arrowlength             = 250;
79   arrowhalfangle          = 10;
80 
81   nodes                   = new intpointarray;
82 
83 }
84 
~parts()85 parts::~parts()
86 {
87   delete label;
88   delete text;
89   delete nodes;
90 }
91 
operator =(const parts & parts)92 parts& parts::operator = (const parts&  parts)
93 {
94 //  id                   = parts.id;
95   selected             = parts.selected;
96   type                 = parts.type;
97   *text                = *parts.text;
98   fo                   = parts.fo;
99   fontcolor            = parts.fontcolor;
100   linespacing          = parts.linespacing;
101   linecolor            = parts.linecolor;
102   bodycolor            = parts.bodycolor;
103   linestyle            = parts.linestyle;
104   bodystyle            = parts.bodystyle;
105   legendlength         = parts.legendlength;
106   interpolate          = parts.interpolate;
107   interpolatediv       = parts.interpolatediv;
108   p1.x                 = parts.p1.x;
109   p1.y                 = parts.p1.y;
110   p2.x                 = parts.p2.x;
111   p2.y                 = parts.p2.y;
112   p1_arrow             = parts.p1_arrow;
113   p2_arrow             = parts.p2_arrow;
114   arrowlength          = parts.arrowlength;
115   arrowhalfangle       = parts.arrowhalfangle;
116   *nodes               = *parts.nodes;
117 
118   return *this;
119 }
120 
121 
get(std::string * member,tokenbuff * outvalue)122 bool parts::get(std::string* member, tokenbuff* outvalue)
123 {
124   std::string out;
125   int iid;
126   char stemp[100];
127 
128   if (topobject(member, &out, &iid) == true)
129     {
130       if (out == std::string("id") && iid == -1)
131 	{
132 	  sprintf(stemp, "%d", id);
133 	  outvalue->value->add(stemp);
134 	  return true;
135 	}
136       else if (out == std::string("label") && iid == -1)
137 	{
138 	  outvalue->value->add(label->c_str());
139 	  return true;
140 	}
141       else if (out == std::string("selected") && iid == -1)
142 	{
143 	  sprintf(stemp, "%d", selected);
144 	  outvalue->value->add(stemp);
145 	  return true;
146 	}
147       else if (out == std::string("type") && iid == -1)
148 	{
149 	  sprintf(stemp, "%d", type);
150 	  outvalue->value->add(stemp);
151 	  return true;
152 	}
153       else if (out == std::string("text") && iid == -1)
154 	{
155 	  outvalue->value->add(text->c_str());
156 	  return true;
157 	}
158       else if (out == std::string("fontface") && iid == -1)
159 	{
160 	  sprintf(stemp, "%d", fo.face);
161 	  outvalue->value->add(stemp);
162 	  return true;
163 	}
164       else if (out == std::string("jpfontface") && iid == -1)
165 	{
166 	  sprintf(stemp, "%d", fo.jpface);
167 	  outvalue->value->add(stemp);
168 	  return true;
169 	}
170       else if (out == std::string("fontsize") && iid == -1)
171 	{
172 	  sprintf(stemp, "%d", fo.size);
173 	  outvalue->value->add(stemp);
174 	  return true;
175 	}
176       else if (out == std::string("fontangle") && iid == -1)
177 	{
178 	  sprintf(stemp, "%.15g", fo.angle);
179 	  outvalue->value->add(stemp);
180 	  return true;
181 	}
182       else if (out == std::string("fontcolor_red") && iid == -1)
183 	{
184 	  sprintf(stemp, "%u", fontcolor.red);
185 	  outvalue->value->add(stemp);
186 	  return true;
187 	}
188       else if (out == std::string("fontcolor_green") && iid == -1)
189 	{
190 	  sprintf(stemp, "%u", fontcolor.green);
191 	  outvalue->value->add(stemp);
192 	  return true;
193 	}
194       else if (out == std::string("fontcolor_blue") && iid == -1)
195 	{
196 	  sprintf(stemp, "%u", fontcolor.blue);
197 	  outvalue->value->add(stemp);
198 	  return true;
199 	}
200       else if (out == std::string("linespacing") && iid == -1)
201 	{
202 	  sprintf(stemp, "%.15g", linespacing);
203 	  outvalue->value->add(stemp);
204 	  return true;
205 	}
206       else if (out == std::string("linecolor_red") && iid == -1)
207 	{
208 	  sprintf(stemp, "%u", linecolor.red);
209 	  outvalue->value->add(stemp);
210 	  return true;
211 	}
212       else if (out == std::string("linecolor_green") && iid == -1)
213 	{
214 	  sprintf(stemp, "%u", linecolor.green);
215 	  outvalue->value->add(stemp);
216 	  return true;
217 	}
218       else if (out == std::string("linecolor_blue") && iid == -1)
219 	{
220 	  sprintf(stemp, "%u", linecolor.blue);
221 	  outvalue->value->add(stemp);
222 	  return true;
223 	}
224       else if (out == std::string("bodycolor_red") && iid == -1)
225 	{
226 	  sprintf(stemp, "%u", bodycolor.red);
227 	  outvalue->value->add(stemp);
228 	  return true;
229 	}
230       else if (out == std::string("bodycolor_green") && iid == -1)
231 	{
232 	  sprintf(stemp, "%u", bodycolor.green);
233 	  outvalue->value->add(stemp);
234 	  return true;
235 	}
236       else if (out == std::string("bodycolor_blue") && iid == -1)
237 	{
238 	  sprintf(stemp, "%u", bodycolor.blue);
239 	  outvalue->value->add(stemp);
240 	  return true;
241 	}
242       else if (out == std::string("linewidth") && iid == -1)
243 	{
244 	  sprintf(stemp, "%d", linestyle.width);
245 	  outvalue->value->add(stemp);
246 	  return true;
247 	}
248       else if (out == std::string("linecap") && iid == -1)
249 	{
250 	  sprintf(stemp, "%d", linestyle.cap);
251 	  outvalue->value->add(stemp);
252 	  return true;
253 	}
254       else if (out == std::string("linejoin") && iid == -1)
255 	{
256 	  sprintf(stemp, "%d", linestyle.join);
257 	  outvalue->value->add(stemp);
258 	  return true;
259 	}
260       else if (out == std::string("linestyle") && iid == -1)
261 	{
262 	  sprintf(stemp, "%d", linestyle.style);
263 	  outvalue->value->add(stemp);
264 	  return true;
265 	}
266       else if (out == std::string("bodyfillstyle") && iid == -1)
267 	{
268 	  sprintf(stemp, "%d", bodystyle.style);
269 	  outvalue->value->add(stemp);
270 	  return true;
271 	}
272       else if (out == std::string("bodyfillrule") && iid == -1)
273 	{
274 	  sprintf(stemp, "%d", bodystyle.fillrule);
275 	  outvalue->value->add(stemp);
276 	  return true;
277 	}
278       else if (out == std::string("legendlength") && iid == -1)
279 	{
280 	  sprintf(stemp, "%d", legendlength);
281 	  outvalue->value->add(stemp);
282 	  return true;
283 	}
284       else if (out == std::string("interpolate") && iid == -1)
285 	{
286 	  sprintf(stemp, "%d", interpolate);
287 	  outvalue->value->add(stemp);
288 	  return true;
289 	}
290       else if (out == std::string("interpolatediv") && iid == -1)
291 	{
292 	  sprintf(stemp, "%d", interpolatediv);
293 	  outvalue->value->add(stemp);
294 	  return true;
295 	}
296       else if (out == std::string("x1") && iid == -1)
297 	{
298 	  sprintf(stemp, "%d", p1.x);
299 	  outvalue->value->add(stemp);
300 	  return true;
301 	}
302       else if (out == std::string("y1") && iid == -1)
303 	{
304 	  sprintf(stemp, "%d", p1.y);
305 	  outvalue->value->add(stemp);
306 	  return true;
307 	}
308       else if (out == std::string("x2") && iid == -1)
309 	{
310 	  sprintf(stemp, "%d", p2.x);
311 	  outvalue->value->add(stemp);
312 	  return true;
313 	}
314       else if (out == std::string("y2") && iid == -1)
315 	{
316 	  sprintf(stemp, "%d", p2.y);
317 	  outvalue->value->add(stemp);
318 	  return true;
319 	}
320       else if (out == std::string("arrow1") && iid == -1)
321 	{
322 	  sprintf(stemp, "%d", p1_arrow);
323 	  outvalue->value->add(stemp);
324 	  return true;
325 	}
326       else if (out == std::string("arrow2") && iid == -1)
327 	{
328 	  sprintf(stemp, "%d", p2_arrow);
329 	  outvalue->value->add(stemp);
330 	  return true;
331 	}
332       else if (out == std::string("arrowlength") && iid == -1)
333 	{
334 	  sprintf(stemp, "%d", arrowlength);
335 	  outvalue->value->add(stemp);
336 	  return true;
337 	}
338       else if (out == std::string("arrowhalfangle") && iid == -1)
339 	{
340 	  sprintf(stemp, "%.15g", arrowhalfangle);
341 	  outvalue->value->add(stemp);
342 	  return true;
343 	}
344       else if (out == std::string("node_x") && 0 <= iid)
345 	{
346 	  if (iid < nodes->getarraylength())
347 	    {
348 	      sprintf(stemp, "%d", (*nodes)[iid].x);
349 	      outvalue->value->add(stemp);
350 	      return true;
351 	    }
352 	  else
353 	    return false;
354 	}
355       else if (out == std::string("node_y") && 0 <= iid)
356 	{
357 	  if (iid < nodes->getarraylength())
358 	    {
359 	      sprintf(stemp, "%d", (*nodes)[iid].y);
360 	      outvalue->value->add(stemp);
361 	      return true;
362 	    }
363 	  else
364 	    return false;
365 	}
366       else
367 	return false;
368     }
369   else
370     return false;
371 
372   return true;
373 
374 }
375 
set(std::string * member,std::string * setvalue)376 bool parts::set(std::string* member, std::string* setvalue)
377 {
378   std::string out;
379   int iid;
380 
381   if (topobject(member, &out, &iid) == true)
382     {
383       if (out == std::string("id") && iid == -1)
384 	{
385 	  id = atoi(setvalue->c_str());
386 	  return true;
387 	}
388       else if (out == std::string("label") && iid == -1)
389 	{
390 	  *label = *setvalue;
391 	  return true;
392 	}
393       else if (out == std::string("selected") && iid == -1)
394 	{
395 	  selected = atoi(setvalue->c_str());
396 	  return true;
397 	}
398       else if (out == std::string("type") && iid == -1)
399 	{
400 	  type = atoi(setvalue->c_str());
401 	  return true;
402 	}
403       else if (out == std::string("text") && iid == -1)
404 	{
405 	  *text = *setvalue;
406 	  return true;
407 	}
408       else if (out == std::string("fontface") && iid == -1)
409 	{
410 	  fo.face = atoi(setvalue->c_str());
411 	  return true;
412 	}
413       else if (out == std::string("jpfontface") && iid == -1)
414 	{
415 	  fo.jpface = atoi(setvalue->c_str());
416 	  return true;
417 	}
418       else if (out == std::string("fontsize") && iid == -1)
419 	{
420 	  fo.size = atoi(setvalue->c_str());
421 	  return true;
422 	}
423       else if (out == std::string("fontangle") && iid == -1)
424 	{
425 	  fo.angle = atof(setvalue->c_str());
426 	  return true;
427 	}
428       else if (out == std::string("fontcolor_red") && iid == -1)
429 	{
430 	  fontcolor.red = atol(setvalue->c_str());
431 	  return true;
432 	}
433       else if (out == std::string("fontcolor_green") && iid == -1)
434 	{
435 	  fontcolor.green = atol(setvalue->c_str());
436 	  return true;
437 	}
438       else if (out == std::string("fontcolor_blue") && iid == -1)
439 	{
440 	  fontcolor.blue = atol(setvalue->c_str());
441 	  return true;
442 	}
443       else if (out == std::string("linespacing") && iid == -1)
444 	{
445 	  linespacing = atof(setvalue->c_str());
446 	  return true;
447 	}
448       else if (out == std::string("linecolor_red") && iid == -1)
449 	{
450 	  linecolor.red = atol(setvalue->c_str());
451 	  return true;
452 	}
453       else if (out == std::string("linecolor_green") && iid == -1)
454 	{
455 	  linecolor.green = atol(setvalue->c_str());
456 	  return true;
457 	}
458       else if (out == std::string("linecolor_blue") && iid == -1)
459 	{
460 	  linecolor.blue = atol(setvalue->c_str());
461 	  return true;
462 	}
463       else if (out == std::string("bodycolor_red") && iid == -1)
464 	{
465 	  bodycolor.red = atol(setvalue->c_str());
466 	  return true;
467 	}
468       else if (out == std::string("bodycolor_green") && iid == -1)
469 	{
470 	  bodycolor.green = atol(setvalue->c_str());
471 	  return true;
472 	}
473       else if (out == std::string("bodycolor_blue") && iid == -1)
474 	{
475 	  bodycolor.blue = atol(setvalue->c_str());
476 	  return true;
477 	}
478       else if (out == std::string("linewidth") && iid == -1)
479 	{
480 	  linestyle.width = atoi(setvalue->c_str());
481 	  return true;
482 	}
483       else if (out == std::string("linecap") && iid == -1)
484 	{
485 	  linestyle.cap = atoi(setvalue->c_str());
486 	  return true;
487 	}
488       else if (out == std::string("linejoin") && iid == -1)
489 	{
490 	  linestyle.join = atoi(setvalue->c_str());
491 	  return true;
492 	}
493       else if (out == std::string("linestyle") && iid == -1)
494 	{
495 	  linestyle.style = atoi(setvalue->c_str());
496 	  return true;
497 	}
498       else if (out == std::string("bodyfillstyle") && iid == -1)
499 	{
500 	  bodystyle.style = atoi(setvalue->c_str());
501 	  return true;
502 	}
503       else if (out == std::string("bodyfillrule") && iid == -1)
504 	{
505 	  bodystyle.fillrule = atoi(setvalue->c_str());
506 	  return true;
507 	}
508       else if (out == std::string("legendlength") && iid == -1)
509 	{
510 	  legendlength = atoi(setvalue->c_str());
511 	  return true;
512 	}
513       else if (out == std::string("interpolate") && iid == -1)
514 	{
515 	  interpolate = atoi(setvalue->c_str());
516 	  return true;
517 	}
518       else if (out == std::string("interpolatediv") && iid == -1)
519 	{
520 	  interpolatediv = atoi(setvalue->c_str());
521 	  return true;
522 	}
523       else if (out == std::string("x1") && iid == -1)
524 	{
525 	  p1.x = atoi(setvalue->c_str());
526 	  return true;
527 	}
528       else if (out == std::string("y1") && iid == -1)
529 	{
530 	  p1.y = atoi(setvalue->c_str());
531 	  return true;
532 	}
533       else if (out == std::string("x2") && iid == -1)
534 	{
535 	  p2.x = atoi(setvalue->c_str());
536 	  return true;
537 	}
538       else if (out == std::string("y2") && iid == -1)
539 	{
540 	  p2.y = atoi(setvalue->c_str());
541 	  return true;
542 	}
543       else if (out == std::string("arrow1") && iid == -1)
544 	{
545 	  p1_arrow = atoi(setvalue->c_str());
546 	  return true;
547 	}
548       else if (out == std::string("arrow2") && iid == -1)
549 	{
550 	  p2_arrow = atoi(setvalue->c_str());
551 	  return true;
552 	}
553       else if (out == std::string("arrowlength") && iid == -1)
554 	{
555 	  arrowlength = atoi(setvalue->c_str());
556 	  return true;
557 	}
558       else if (out == std::string("arrowhalfangle") && iid == -1)
559 	{
560 	  arrowhalfangle = atof(setvalue->c_str());
561 	  return true;
562 	}
563       else if (out == std::string("node_x") && 0 <= iid)
564 	{
565 	  if (iid < nodes->getarraylength())
566 	    {
567 	      (*nodes)[iid].x = atoi(setvalue->c_str());
568 	      return true;
569 	    }
570 	  else
571 	    return false;
572 	}
573       else if (out == std::string("node_y") && 0 <= iid)
574 	{
575 	  if (iid < nodes->getarraylength())
576 	    {
577 	      (*nodes)[iid].y = atoi(setvalue->c_str());
578 	      return true;
579 	    }
580 	  else
581 	    return false;
582 	}
583       else
584 	return false;
585     }
586   else
587     return false;
588 
589   return true;
590 
591 }
592 
exec(std::string * function,buffarray * argument,tokenbuff * outvalue)593 bool parts::exec(std::string* function, buffarray *argument, tokenbuff* outvalue)
594 {
595   std::string out, shrunk, str1;
596   int iid, arglength;
597   char stemp[100];
598   intrect bbox;
599   FILE* fp;
600   int itemp;
601   graph* gra = (graph *)(((frame *)parent)->parent);
602 
603   outvalue->value->setbuff(0);
604   if (topobject(function, &out, &iid) == true)
605     {
606       arglength = argument->getarraylength();
607 
608       // paint
609       if (out == std::string("paint") && iid == -1)
610 	{
611 	  if (arglength == 1)
612 	    {
613 	      if (fhvuff->get(&(*argument)[0], &fp, &itemp, &str1))
614 		{
615 		  paint(true, fp);
616 		  return true;
617 		}
618 	      else
619 		return false;
620 	    }
621 	  else
622 	    return false;
623 	}
624       // setbbox
625       else if (out == std::string("setbbox") && iid == -1)
626 	{
627 	  if (arglength == 1 && (*argument)[0] == std::string("null"))
628 	    {
629 	      paint(false, fp);
630 	      return true;
631 	    }
632 	  else
633 	    return false;
634 	}
635       // length
636       else if (out == std::string("length") && iid == -1)
637 	{
638 	  if (arglength == 1)
639 	    {
640 	      if ((*argument)[0] == std::string("nodes"))
641 		{
642 		  sprintf(stemp, "%d", nodes->getarraylength());
643 		  outvalue->value->add(stemp);
644 		  return true;
645 		}
646 	      else
647 		return false;
648 	    }
649 	  else
650 	    return false;
651 	}
652       // addnodepoint
653       else if (out == std::string("addnodepoint") && iid == -1)
654 	{
655 	  if (arglength == 2)
656 	    {
657 	      gra->updated = true;
658 	      if (nodes->add(new intpoint(atoi((*argument)[0].c_str()), atoi((*argument)[1].c_str()))))
659 		return true;
660 	      else
661 		return false;
662 	    }
663 	  else
664 	    return false;
665 	}
666       // flushnode
667       else if (out == std::string("flushnode") && iid == -1)
668 	{
669 	  if (arglength == 1 && (*argument)[0] == std::string("null"))
670 	    {
671 	      gra->updated = true;
672 	      nodes->setbuff(0);
673 		return true;
674 	    }
675 	  else
676 	    return false;
677 	}
678       // bounding box
679       else if (out == std::string("bbox") && iid == -1)
680 	{
681 	  if (arglength == 1)
682 	    {
683 	      if ((*argument)[0] == std::string("null"))
684 		{
685 		  getBBbox(&bbox);
686 		  outvalue->value->setbuff(0);
687 		  sprintf(stemp, "%d", bbox.left);
688 		  outvalue->value->add(stemp);
689 		  sprintf(stemp, "%d", bbox.top);
690 		  outvalue->value->add(stemp);
691 		  sprintf(stemp, "%d", bbox.right);
692 		  outvalue->value->add(stemp);
693 		  sprintf(stemp, "%d", bbox.bottom);
694 		  outvalue->value->add(stemp);
695 		  return true;
696 		}
697 	      else
698 		return false;
699 	    }
700 	  else
701 	    return false;
702 	}
703       else
704 	return false;
705     }
706   else
707     return false;
708 
709   return true;
710 }
711 
getBBbox(intrect * r)712 void parts::getBBbox(intrect *r)
713 {
714   int maxx, minx, maxy, miny;
715 
716 //  intpoint temp[50];
717   int i, no, interporatedno;
718   doublearray *InX = 0, *InY = 0, *OutX = 0, *OutY = 0;
719 
720   frame *fr = (frame *)parent;
721 
722   minx =  MAXINT;  maxx = -MAXINT;
723   miny =  MAXINT;  maxy = -MAXINT;
724 
725   switch(type)
726     {
727     case PARTS_TEXT:
728       drawtext(false, 0, r, 0);
729       break;
730     case PARTS_LINE:
731     case PARTS_RECTANGLE:
732     case PARTS_ELLIPSE:
733     case PARTS_CUT:
734       minx = min(p1.x, p2.x); maxx = max(p1.x, p2.x);
735       miny = min(p1.y, p2.y); maxy = max(p1.y, p2.y);
736       r->left = fr->wtov_x(minx); r->right  = fr->wtov_x(maxx);
737       r->top  = fr->wtov_y(miny); r->bottom = fr->wtov_y(maxy);
738       break;
739     case PARTS_POLYLINE:
740       no = nodes->getarraylength() - 1;
741       if (no >= 1)
742 	{
743 	  if (interpolate == PARTS_INTER_POLYLINE || interpolate == PARTS_INTER_CLOSEDPOLYLINE)
744 	    {
745 	      for (i = 0; i <= no; i++)
746 		{
747 		  minx = min(minx, fr->wtov_x((*nodes)[i].x + p1.x));
748 		  maxx = max(maxx, fr->wtov_x((*nodes)[i].x + p1.x));
749 		  miny = min(miny, fr->wtov_y((*nodes)[i].y + p1.y));
750 		  maxy = max(maxy, fr->wtov_y((*nodes)[i].y + p1.y));
751 		}
752 
753 	      r->left = minx; r->right = maxx;
754 	      r->top  = miny; r->bottom = maxy;
755 	    }
756 	  else if (interpolate == PARTS_INTER_PSPLINE || interpolate == PARTS_INTER_CLOSEDPSPLINE)
757 	    {
758 	      InX = new doublearray;
759 	      if (InX == 0)
760 		{
761 		  InX = 0;
762 		  goto j1;
763 		}
764 
765 	      InY = new doublearray;
766 	      if (InY == 0)
767 		{
768 		  InY = 0;
769 		  goto j1;
770 		}
771 
772  	      OutX = new doublearray;
773 	      if (OutX == 0)
774 		{
775 		  OutX = 0;
776 		  goto j1;
777 		}
778 
779  	      OutY = new doublearray;
780 	      if (OutY == 0)
781 		{
782 		  OutY = 0;
783 		  goto j1;
784 		}
785 
786 	      for (i = 0; i <= no; i++)
787 		{
788 		  InX->add((*nodes)[i].x + p1.x);
789 		  InY->add((*nodes)[i].y + p1.y);
790 		}
791 
792 	      if (interpolate ==  PARTS_INTER_PSPLINE)
793 		CalcPSpline(InX, InY, OutX, OutY, 1, interpolatediv);
794 	      else
795 		CalcPSpline(InX, InY, OutX, OutY, 2, interpolatediv);
796 
797 	      interporatedno = OutX->getarraylength() - 1;
798 
799 	      for (i = 0; i <= interporatedno; i++)
800 		{
801 		  minx = min(minx, fr->wtov_x((int)(*OutX)[i]));
802 		  maxx = max(maxx, fr->wtov_x((int)(*OutX)[i]));
803 		  miny = min(miny, fr->wtov_y((int)(*OutY)[i]));
804 		  maxy = max(maxy, fr->wtov_y((int)(*OutY)[i]));
805 		}
806 	    j1:
807 	      if (InX != 0)
808 		delete InX;
809 	      if (InY != 0)
810 		delete InY;
811 	      if (OutX != 0)
812 		delete OutX;
813 	      if (OutY != 0)
814 		delete OutY;
815 
816 	      r->left = minx; r->right  = maxx;
817 	      r->top  = miny; r->bottom = maxy;
818 	    }
819 	}
820       else
821 	{
822 	  r->left = 0; r->right  = 0;
823 	  r->top  = 0; r->bottom = 0;
824 	}
825       break;
826     }
827 }
828 
829 
paint(bool flag,FILE * f)830 bool parts::paint(bool flag, FILE* f)
831 {
832   switch(type)
833     {
834     case PARTS_TEXT:
835       drawtext(flag, f, 0, 0);
836       break;
837     case PARTS_LINE:
838     case PARTS_POLYLINE:
839     case PARTS_RECTANGLE:
840     case PARTS_ELLIPSE:
841     case PARTS_CUT:
842       drawparts(flag, f);
843       break;
844     }
845 
846   return true;
847 }
848 
getpartsname(int id,std::string * out)849 bool getpartsname(int id, std::string *out)
850 {
851   switch(id)
852     {
853     case PARTS_TEXT:
854       *out = std::string("text");
855       break;
856     case PARTS_LINE:
857       *out = std::string("line");
858       break;
859     case PARTS_POLYLINE:
860       *out = std::string("polyline");
861       break;
862     case PARTS_RECTANGLE:
863       *out = std::string("rectangle");
864       break;
865     case PARTS_ELLIPSE:
866       *out = std::string("ellipse");
867       break;
868     case PARTS_CUT:
869       *out = std::string("cutline");
870       break;
871     default:
872       *out = std::string("");
873       return false;
874     }
875   return true;
876 }
877 
gettextfacename(int id,std::string * out)878 bool gettextfacename(int id, std::string *out)
879 {
880   switch(id)
881     {
882     case FONT_TIMESROMAN:
883       *out = std::string("Times-Roman");
884       break;
885     case FONT_TIMESBOLD:
886       *out = std::string("Times-Bold");
887       break;
888     case FONT_TIMESITALIC:
889       *out = std::string("Times-Italic");
890       break;
891     case FONT_TIMESBOLDITALIC:
892       *out = std::string("Times-BoldItalic");
893       break;
894     case FONT_HELVETICA:
895       *out = std::string("Helvetica");
896       break;
897     case FONT_HELVETICABOLD:
898       *out = std::string("Helvetica-Bold");
899       break;
900     case FONT_HELVETICAOBLIQUE:
901       *out = std::string("Helvetica-Oblique");
902       break;
903     case FONT_HELVETICABOLDOBLIQUE:
904       *out = std::string("Helvetica-BoldOblique");
905       break;
906     case FONT_COURIER:
907       *out = std::string("Courier");
908       break;
909     case FONT_COURIERBOLD:
910       *out = std::string("Courier-Bold");
911       break;
912     case FONT_COURIEROBLIQUE:
913       *out = std::string("Courier-Oblique");
914       break;
915     case FONT_COURIERBOLDOBLIQUE:
916       *out = std::string("Courier-BoldOblique");
917       break;
918     case FONT_SYMBOL:
919       *out = std::string("Symbol");
920       break;
921     default:
922       *out = std::string("");
923       return false;
924     }
925   return true;
926 }
927 
gettextjpfacename(int id,std::string * out)928 bool gettextjpfacename(int id, std::string *out)
929 {
930   switch(id)
931     {
932     case FONT_MINCHO:
933       *out = std::string("Mincho");
934       break;
935     case FONT_GOTHIC:
936       *out = std::string("Gothic");
937       break;
938     default:
939       *out = std::string("");
940       return false;
941     }
942   return true;
943 }
944 
RotatePoint(intpoint P,intpoint OrgP,double Theta)945 intpoint RotatePoint(intpoint P, intpoint OrgP, double Theta)
946 {
947   intpoint TempPoint1, TempPoint2;
948   double fx, fy, Radian;
949 
950   TempPoint1.x = P.x - OrgP.x;
951   TempPoint1.y = P.y - OrgP.y;
952   Radian = Theta / 180.0 * M_PI;
953 
954   fx = cos(Radian) * (double)TempPoint1.x + sin(Radian) * (double)TempPoint1.y + (double)OrgP.x;
955   fy = -sin(Radian) * (double)TempPoint1.x + cos(Radian) * (double)TempPoint1.y + (double)OrgP.y;
956 
957   TempPoint2.x = (int)fx;
958   TempPoint2.y = (int)fy;
959 
960   return TempPoint2;
961 }
962 
963 
getcharwidth(Capfont * lf,unsigned int c,bool iskanji)964 int parts::getcharwidth(Capfont *lf, unsigned int c, bool iskanji)
965 {
966   double ftemp;
967 
968   // ascii
969   if (!iskanji)
970     {
971       switch(lf->face)
972 	{
973 	case FONT_TIMESROMAN:
974 	  ftemp = TR[c];
975 	  break;
976 	case FONT_TIMESBOLD:
977 	  ftemp = TB[c];
978 	  break;
979 	case FONT_TIMESITALIC:
980 	  ftemp = TI[c];
981 	  break;
982 	case FONT_TIMESBOLDITALIC:
983 	  ftemp = TO[c];
984 	  break;
985 	case FONT_HELVETICA:
986 	  ftemp = HR[c];
987 	  break;
988 	case FONT_HELVETICABOLD:
989 	  ftemp = HB[c];
990 	  break;
991 	case FONT_HELVETICAOBLIQUE:
992 	  ftemp = HI[c];
993 	  break;
994 	case FONT_HELVETICABOLDOBLIQUE:
995 	  ftemp = HO[c];
996 	  break;
997 	case FONT_COURIER:
998 	  ftemp = CR[c];
999 	  break;
1000 	case FONT_COURIERBOLD:
1001 	  ftemp = CB[c];
1002 	  break;
1003 	case FONT_COURIEROBLIQUE:
1004 	  ftemp = CI[c];
1005 	  break;
1006 	case FONT_COURIERBOLDOBLIQUE:
1007 	  ftemp = CO[c];
1008 	  break;
1009 	case FONT_SYMBOL:
1010 	  ftemp = SR[c];
1011 	  break;
1012 	default:
1013 	  ftemp = 0;
1014 	}
1015     }
1016   // jp
1017   else
1018     {
1019       ftemp = 10.0;
1020     }
1021   return (int)(((double)ftemp) * 20 * ((double)lf->size) / 200.0);
1022 }
1023 
getascend(Capfont * lf,bool iskanji)1024 int parts::getascend(Capfont *lf, bool iskanji)
1025 {
1026   double ftemp;
1027 
1028   if (!iskanji)
1029     {
1030       switch(lf->face)
1031 	{
1032 	case FONT_TIMESROMAN:
1033 	  ftemp = DTR;
1034 	  break;
1035 	case FONT_TIMESBOLD:
1036 	  ftemp = DTB;
1037 	  break;
1038 	case FONT_TIMESITALIC:
1039 	  ftemp = DTI;
1040 	  break;
1041 	case FONT_TIMESBOLDITALIC:
1042 	  ftemp = DTO;
1043 	  break;
1044 	case FONT_HELVETICA:
1045 	  ftemp = DHR;
1046 	  break;
1047 	case FONT_HELVETICABOLD:
1048 	  ftemp = DHB;
1049 	  break;
1050 	case FONT_HELVETICAOBLIQUE:
1051 	  ftemp = DHI;
1052 	  break;
1053 	case FONT_HELVETICABOLDOBLIQUE:
1054 	  ftemp = DHO;
1055 	  break;
1056 	case FONT_COURIER:
1057 	  ftemp = DCR;
1058 	  break;
1059 	case FONT_COURIERBOLD:
1060 	  ftemp = DCB;
1061 	  break;
1062 	case FONT_COURIEROBLIQUE:
1063 	  ftemp = DCI;
1064 	  break;
1065 	case FONT_COURIERBOLDOBLIQUE:
1066 	  ftemp = DCO;
1067 	  break;
1068 	case FONT_SYMBOL:
1069 	  ftemp = DSR;
1070 	  break;
1071 	default:
1072 	  ftemp = 0;
1073 	}
1074     }
1075   else
1076     ftemp = 1.2;
1077   return (int)((10.0 - (double)ftemp) * 20 *((double)lf->size) / 200.0);
1078 }
1079 
1080 
1081 
nextpoint(char * in)1082 char * nextpoint(char *in)
1083 {
1084   if (maykanji(*in))
1085     return (in + 2);
1086   else
1087     return (in + 1);
1088 }
1089 
1090 
drawtext(int flag,FILE * f,intrect * rect,int * textwidth)1091 void parts::drawtext(int flag, FILE* f, intrect *rect, int* textwidth)
1092 {
1093   /*
1094      Large						small
1095      A
1096      B       font bold
1097      C
1098      D       datafilename (full path)         datafilename (only filename)
1099      E
1100      F       restore font
1101      G       greek
1102      H       plots filename(full path)        plotsfilename (only filename)
1103      I       italic
1104      J
1105      K
1106      L
1107      M       date(month:day:year)			date(year/month/day)
1108      N
1109      O       bold italic
1110      P       pitch           				legend pattern
1111      Q
1112      R       roman
1113      S       font size
1114      T       Large TAB          				small tabbing
1115      U
1116      V
1117      W
1118      X       shift x-direction
1119      Y       shift y-direction
1120      Z
1121      */
1122 
1123 
1124   Capfont lf, lf0;
1125   int i;
1126   int CX,CY,CX0,CY0, maxCX;
1127   char *lpszTemp1;
1128   char temp3[10];
1129   unsigned char ustemp[10];
1130   int itemp;
1131   int dx,dy,tdx;
1132   int Tabspace, SmallTabspace;
1133   int h;
1134   int KaigyoNo = 0;
1135   char char_D[2]; char_D[0] = 13; char_D[1] = '\0';
1136   char char_A[2]; char_A[0] = 10; char_A[1] = '\0';
1137   intpoint RotatedPoint;		//position of text out after rotated
1138   std::string str1, str2;
1139   frame *fr = (frame *)parent;
1140   char *lpszTemp;
1141   int charw = 0;
1142   int lastcharwidth = 0;
1143   intrect bbrect;
1144   intpoint RotatedLeftTop, RotatedRightTop, RotatedRightBottom, RotatedLeftBottom;
1145   int MinX, MaxX, MinY, MaxY;
1146   int linewidth = 0, maxlinewidth = 0;
1147   int cascend;
1148   graph* gra = (graph *)(((frame *)parent)->parent);
1149   time_t timeval;
1150   bool iskanji = false;
1151 
1152   //pattern
1153   intrect PatternRect;
1154   int DataNo = 0;
1155   double LengthRate = 3.0 * legendlength;  //pattertn lenght / text height
1156 
1157   std::string str;
1158 
1159   dx = 0; dy = 0;
1160 
1161   // select initial font
1162   lf = fo;
1163 
1164   // save initial font
1165   lf0 = fo;
1166 
1167   // select textcolor
1168   if (rect == 0 && textwidth == 0)
1169     psetforecolor(flag, f, fontcolor.red, fontcolor.green, fontcolor.blue);
1170 
1171   // set initial font
1172   if (rect == 0 && textwidth == 0)
1173     ploadfont(flag, f, lf.face, fr->scale(lf.size), lf.angle);
1174   h = getascend(&lf0, false);
1175   cascend = h;
1176 
1177 
1178   //get text ascent
1179   h = getascend(&lf0, false);
1180   Tabspace = h * 2;
1181   SmallTabspace = h;
1182 
1183   CX = (int)fr->doubleworld_to_view_x(p1.x);
1184   CY = (int)fr->doubleworld_to_view_y(p1.y);
1185   CX0 = CX;
1186   CY0 = CY;
1187   maxCX = CX;
1188   RotatedPoint.x = CX0;
1189   RotatedPoint.y = CY0;
1190 
1191 
1192   lpszTemp = (char *)text->c_str();
1193   str = std::string("");
1194   //Insert text settings
1195   while (*lpszTemp != 0)
1196     {
1197       switch (*lpszTemp)
1198 	{
1199 	case '#':
1200 	  switch(*(lpszTemp + 1))
1201 	    {
1202 	    case 'H': // graph filename
1203 	      str1 = std::string(gra->graphname);
1204 	      toplainfilename((char *)str1.c_str(), &str2);
1205 	      str += str2;
1206 	      lpszTemp += 2;
1207 	      break;
1208 	    case 'M': // date (month:day:year)
1209 	      (void)time(&timeval);
1210 	      str += std::string(ctime(&timeval));
1211 	      lpszTemp += 2;
1212 	      break;
1213 
1214 	    default:
1215 	      lpszTemp1 = nextpoint(lpszTemp);
1216 	      if ((strlen(lpszTemp)-strlen(lpszTemp1))==2)
1217 		{
1218 		  temp3[0] = *lpszTemp;
1219 		  temp3[1] = *(lpszTemp + 1);
1220 		  temp3[2] = 0;
1221 		}
1222 	      else
1223 		{
1224 		  temp3[0] = *lpszTemp;
1225 		  temp3[1] = 0;
1226 		}
1227 	      str += std::string(temp3);
1228 	      lpszTemp = nextpoint(lpszTemp);
1229 	      break;
1230 	    }
1231 	  break;
1232 	default:
1233 	  lpszTemp1 = nextpoint(lpszTemp);
1234 	  if ((strlen(lpszTemp)-strlen(lpszTemp1))==2)
1235 	    {
1236 	      temp3[0] = *lpszTemp;
1237 	      temp3[1] = *(lpszTemp + 1);
1238 	      temp3[2] = 0;
1239 	    }
1240 	  else
1241 	    {
1242 	      temp3[0] = *lpszTemp;
1243 	      temp3[1] = 0;
1244 	    }
1245 	  str += std::string(temp3);
1246 	  lpszTemp = nextpoint(lpszTemp);
1247 	  break;
1248 	}
1249     }
1250   i = 0;
1251   lpszTemp = (char *)str.c_str();
1252   while (*lpszTemp != 0)
1253     {
1254       i++;
1255       tdx = 0;
1256 
1257       // setfont
1258       switch (*lpszTemp)
1259 	{
1260 	case '#':
1261 	  switch(*(lpszTemp + 1))
1262 	    {
1263 		case 'R':
1264 	      switch(lf.face)
1265 		{
1266 		case FONT_TIMESROMAN:
1267 		case FONT_TIMESBOLD:
1268 		case FONT_TIMESITALIC:
1269 		case FONT_TIMESBOLDITALIC:
1270 		  lf.face = FONT_TIMESROMAN;
1271 		  break;
1272 		    case FONT_HELVETICA:
1273 		case FONT_HELVETICABOLD:
1274 		case FONT_HELVETICAOBLIQUE:
1275 		case FONT_HELVETICABOLDOBLIQUE:
1276 		  lf.face = FONT_HELVETICA;
1277 		  break;
1278 		case FONT_COURIER:
1279 		case FONT_COURIERBOLD:
1280 		case FONT_COURIEROBLIQUE:
1281 		case FONT_COURIERBOLDOBLIQUE:
1282 		  lf.face = FONT_COURIER;
1283 		  break;
1284 		}
1285 	      if (rect == 0 && textwidth == 0)
1286 		ploadfont(flag, f, lf.face, fr->scale(lf.size), lf.angle);
1287 	      cascend = getascend(&lf, true);
1288 	      break;
1289 	    case 'B':
1290 	      switch(lf.face)
1291 		{
1292 		case FONT_TIMESROMAN:
1293 		case FONT_TIMESBOLD:
1294 		case FONT_TIMESITALIC:
1295 		case FONT_TIMESBOLDITALIC:
1296 		  lf.face = FONT_TIMESBOLD;
1297 		  break;
1298 		case FONT_HELVETICA:
1299 		case FONT_HELVETICABOLD:
1300 		case FONT_HELVETICAOBLIQUE:
1301 		case FONT_HELVETICABOLDOBLIQUE:
1302 		  lf.face = FONT_HELVETICABOLD;
1303 		  break;
1304 		case FONT_COURIER:
1305 		case FONT_COURIERBOLD:
1306 		case FONT_COURIEROBLIQUE:
1307 		case FONT_COURIERBOLDOBLIQUE:
1308 		  lf.face = FONT_COURIERBOLD;
1309 		  break;
1310 		}
1311 	      if (rect == 0 && textwidth == 0)
1312 		ploadfont(flag, f, lf.face, fr->scale(lf.size), lf.angle);
1313 	      cascend = getascend(&lf, true);
1314 	      break;
1315 	    case 'I':
1316 	      switch(lf.face)
1317 		{
1318 		case FONT_TIMESROMAN:
1319 		case FONT_TIMESBOLD:
1320 		case FONT_TIMESITALIC:
1321 		case FONT_TIMESBOLDITALIC:
1322 		  lf.face = FONT_TIMESITALIC;
1323 		  break;
1324 		case FONT_HELVETICA:
1325 		case FONT_HELVETICABOLD:
1326 		case FONT_HELVETICAOBLIQUE:
1327 		case FONT_HELVETICABOLDOBLIQUE:
1328 		  lf.face = FONT_HELVETICAOBLIQUE;
1329 		  break;
1330 		case FONT_COURIER:
1331 		case FONT_COURIERBOLD:
1332 		case FONT_COURIEROBLIQUE:
1333 		case FONT_COURIERBOLDOBLIQUE:
1334 		  lf.face = FONT_COURIEROBLIQUE;
1335 		  break;
1336 		}
1337 	      if (rect == 0 && textwidth == 0)
1338 		ploadfont(flag, f, lf.face, fr->scale(lf.size), lf.angle);
1339 	      cascend = getascend(&lf, true);
1340 	      break;
1341 	    case 'O':
1342 	      switch(lf.face)
1343 		{
1344 		case FONT_TIMESROMAN:
1345 		case FONT_TIMESBOLD:
1346 		case FONT_TIMESITALIC:
1347 		case FONT_TIMESBOLDITALIC:
1348 		  lf.face = FONT_TIMESBOLDITALIC;
1349 		  break;
1350 		case FONT_HELVETICA:
1351 		case FONT_HELVETICABOLD:
1352 		case FONT_HELVETICAOBLIQUE:
1353 		case FONT_HELVETICABOLDOBLIQUE:
1354 		  lf.face = FONT_HELVETICABOLDOBLIQUE;
1355 		  break;
1356 		case FONT_COURIER:
1357 		case FONT_COURIERBOLD:
1358 		case FONT_COURIEROBLIQUE:
1359 		case FONT_COURIERBOLDOBLIQUE:
1360 		  lf.face = FONT_COURIERBOLDOBLIQUE;
1361 		  break;
1362 		}
1363 	      if (rect == 0 && textwidth == 0)
1364 		ploadfont(flag, f, lf.face, fr->scale(lf.size), lf.angle);
1365 	      cascend = getascend(&lf, true);
1366 	      break;
1367 	    case 'S':
1368 	      if (isdigit(*(lpszTemp + 2)) != 0 && isdigit(*(lpszTemp+3)) != 0 && isdigit(*(lpszTemp+4)) != 0)
1369 		{
1370 		  strncpy(temp3,lpszTemp + 2,3);
1371 		  temp3[3] = 0;
1372 		  itemp = atoi(temp3);
1373 
1374 		  lf.size = (int)(((double)lf0.size) * ((double)itemp) / 100.0);
1375 
1376 		  if (rect == 0 && textwidth == 0)
1377 		    ploadfont(flag, f, lf.face, fr->scale(lf.size), lf.angle);
1378 		  cascend = getascend(&lf, true);
1379 		}
1380 	      break;
1381 	    case 'G':
1382 	      lf.face = FONT_SYMBOL;
1383 	      if (rect == 0 && textwidth == 0)
1384 		ploadfont(flag, f, lf.face, fr->scale(lf.size), lf.angle);
1385 	      cascend = getascend(&lf, true);
1386 	      break;
1387 	    case 'F':
1388 	      lf.face = lf0.face;
1389 	      if (rect == 0 && textwidth == 0)
1390 		ploadfont(flag, f, lf.face, fr->scale(lf.size), lf.angle);
1391 	      cascend = getascend(&lf, true);
1392 	      break;
1393 	      //legend
1394 	    case 'p':
1395 	      if (isdigit(*(lpszTemp + 2)) != 0 && isdigit(*(lpszTemp + 3)) != 0 && isdigit(*(lpszTemp + 4)) != 0)
1396 		{
1397 		  strncpy(temp3, lpszTemp+2, 3);
1398 		  temp3[3] = 0;
1399 		  DataNo = atoi(temp3);
1400 		}
1401 	      break;
1402 	    }
1403 	  break;
1404 	case '^':
1405 	case '_':
1406 	  lf.size = (int)(((double)lf0.size) * 2.0 / 3.0);
1407 	  if (rect == 0 && textwidth == 0)
1408 	    ploadfont(flag, f, lf.face, fr->scale(lf.size), lf.angle);
1409 	  cascend = getascend(&lf, true);
1410 	  break;
1411 	case '|':
1412 	  lf.size = lf0.size;
1413 	  if (rect == 0 && textwidth == 0)
1414 	    ploadfont(flag, f, lf.face, fr->scale(lf.size), lf.angle);
1415 	  cascend = getascend(&lf, true);
1416 	  break;
1417 	}
1418 
1419 
1420       if (maykanji(*lpszTemp))
1421 	{
1422 	  if (!iskanji)
1423 	    {
1424 	      if (rect == 0 && textwidth == 0)
1425 		ploadfont(flag, f, lf.jpface, fr->scale(lf.size), lf.angle);
1426 	      cascend = getascend(&lf, false);
1427 	      iskanji = true;
1428 	    }
1429 	}
1430       else
1431 	{
1432 	  if (iskanji)
1433 	    {
1434 	      if (rect == 0 && textwidth == 0)
1435 		ploadfont(flag, f, lf.face, fr->scale(lf.size), lf.angle);
1436 	      cascend = getascend(&lf, true);
1437 	      iskanji = false;
1438 	    }
1439 	}
1440 
1441 
1442       // set position
1443       switch (*lpszTemp)
1444 	{
1445 	case '^':
1446 	  dy = h / 2;
1447 	  break;
1448 	case '_':
1449 	  dy = -h / 4;
1450 	  break;
1451 	case '|':
1452 	  dx = 0;
1453 	  dy = 0;
1454 	  break;
1455 	case '#':
1456 	  switch(*(lpszTemp + 1))
1457 	    {
1458 	    case 'P':
1459 	      if ((*(lpszTemp + 2) == '+' || *(lpszTemp + 2) == '-')
1460 		  && isdigit(*(lpszTemp + 3))!= 0 && isdigit(*(lpszTemp + 4)) != 0)
1461 		{
1462 		  strncpy(temp3, lpszTemp + 2, 3);
1463 		  temp3[3] = '\0';
1464 		  itemp = atoi(temp3);
1465 
1466 		  dx = (int)(((double)h) * ((double)itemp) / 100.0);
1467 		}
1468 	      break;
1469 	    case 'Y':
1470 	      if ((*(lpszTemp + 2) == '+' || *(lpszTemp + 2) == '-')
1471 		  && isdigit(*(lpszTemp + 3)) != 0 && isdigit(*(lpszTemp + 4)) != 0)
1472 		{
1473 		  strncpy(temp3, lpszTemp + 2, 3);
1474 		  temp3[3] = 0;
1475 		  itemp = atoi(temp3);
1476 
1477 		  dy = (int)(((double)h) * ((double)itemp) / 100.0);
1478 		}
1479 	      break;
1480 	    case 'X':
1481 	      if ((*(lpszTemp + 2) == '+' || *(lpszTemp + 2) == '-')
1482 		  && isdigit(*(lpszTemp + 3)) != 0 && isdigit(*(lpszTemp + 4)) != 0)
1483 		{
1484 		  strncpy(temp3, lpszTemp + 2, 3);
1485 		  temp3[3] = 0;
1486 		  itemp = atoi(temp3);
1487 
1488 		  tdx = (int)(((double)h) * ((double)itemp) / 100.0);
1489 		}
1490 	      break;
1491 	    case 'T':
1492 	      CX = ((CX - CX0) / Tabspace+1) * Tabspace + CX0;
1493 	      break;
1494 	    case 't':
1495 	      CX = ((CX - CX0) / SmallTabspace + 1) * SmallTabspace + CX0;
1496 	      break;
1497 	    }
1498 	  break;
1499 	}
1500 
1501       // escape sequence
1502       if (*lpszTemp == '\\')
1503 	{
1504 	  switch(*(lpszTemp + 1))
1505 	    {
1506 	    case 'n':
1507 	      KaigyoNo++;
1508 	      CX = CX0;
1509 	      charw = 0;
1510 	      linewidth = 0;
1511 	      break;
1512 	    case 'b':
1513 	      charw = -lastcharwidth;
1514 	      linewidth -= lastcharwidth;
1515 	      break;
1516 	    }
1517 	}
1518 
1519 
1520       // draw text
1521       switch (*lpszTemp)
1522 	{
1523 	case  '#':
1524 	  switch(*(lpszTemp + 1))
1525 	    {
1526 	    case 'R':
1527 	    case 'B':
1528 	    case 'I':
1529 	    case 'O':
1530 	      lpszTemp = lpszTemp + 2;
1531 	      charw = 0;
1532 	      i++;
1533 	      break;
1534 	    case 'S':
1535 	      if (isdigit(*(lpszTemp + 2)) != 0 && isdigit(*(lpszTemp + 3)) != 0 && isdigit(*(lpszTemp + 4)) != 0)
1536 		{
1537 		  lpszTemp = lpszTemp + 5;
1538 		  i += 4;
1539 		}
1540 	      else
1541 		lpszTemp++;
1542 	      charw = 0;
1543 	      break;
1544 	    case 'G':
1545 	      lpszTemp = lpszTemp + 2;
1546 	      i++;
1547 	      charw = 0;
1548 	      break;
1549 	    case 'F':
1550 	      lpszTemp = lpszTemp + 2;
1551 	      i++;
1552 	      charw = 0;
1553 	      break;
1554 	    case 'P':
1555 	    case 'Y':
1556 	      if ((*(lpszTemp + 2) == '+' || *(lpszTemp + 2) == '-')
1557 		  && isdigit(*(lpszTemp + 3)) != 0 && isdigit(*(lpszTemp + 4)) != 0)
1558 		{
1559 		  lpszTemp = lpszTemp + 5;
1560 		  i += 4;
1561 		}
1562 	      else
1563 		lpszTemp++;
1564 	      charw = 0;
1565 	      break;
1566 	    case 'X':
1567 	      if ((*(lpszTemp + 2) == '+' || *(lpszTemp + 2) == '-')
1568 		  && isdigit(*(lpszTemp + 3)) != 0 && isdigit(*(lpszTemp + 4)) != 0)
1569 		{
1570 		  lpszTemp = lpszTemp + 5;
1571 		  i += 4;
1572 		}
1573 	      else
1574 		lpszTemp++;
1575 	      charw = 0;
1576 	      break;
1577 	    case 't':
1578 	    case 'T':
1579 	      lpszTemp = lpszTemp + 2;
1580 	      i++;
1581 	      charw = 0;
1582 	      break;
1583 	    case '#':
1584 	      charw = getcharwidth(&lf, '#', false);
1585 	      if (rect == 0 && textwidth == 0)
1586 		pdrawtext(flag, f, RotatedPoint.x, RotatedPoint.y, "#", fr->scale(lf.size), charw, lf.angle, cascend);
1587 	      lpszTemp = lpszTemp + 2;
1588 	      lastcharwidth = charw;
1589 	      linewidth += charw;
1590 	      if (maxlinewidth < linewidth)
1591 		maxlinewidth = linewidth;
1592 	      i++;
1593 	      break;
1594 	    case '|':
1595 	      charw = getcharwidth(&lf, '|', false);
1596 	      if (rect == 0 && textwidth == 0)
1597 		pdrawtext(flag, f, RotatedPoint.x, RotatedPoint.y, "|", fr->scale(lf.size), charw, lf.angle, cascend);
1598 	      lpszTemp = lpszTemp + 2;
1599 	      lastcharwidth = charw;
1600 	      linewidth += charw;
1601 	      if (maxlinewidth < linewidth)
1602 		maxlinewidth = linewidth;
1603 	      i++;
1604 	      break;
1605 	    case '^':
1606 	      charw = getcharwidth(&lf, '^', false);
1607 	      if (rect == 0 && textwidth == 0)
1608 		pdrawtext(flag, f, RotatedPoint.x, RotatedPoint.y, "^", fr->scale(lf.size), charw, lf.angle, cascend);
1609 	      lpszTemp = lpszTemp + 2;
1610 	      lastcharwidth = charw;
1611 	      linewidth += charw;
1612 	      if (maxlinewidth < linewidth)
1613 		maxlinewidth = linewidth;
1614 	      i++;
1615 	      break;
1616 	    case '_':
1617 	      if (rect == 0 && textwidth == 0)
1618 		pdrawtext(flag, f, RotatedPoint.x, RotatedPoint.y, "_", fr->scale(lf.size), charw, lf.angle, cascend);
1619 	      lpszTemp = lpszTemp + 2;
1620 	      charw = getcharwidth(&lf, '_', false);
1621 	      lastcharwidth = charw;
1622 	      linewidth += charw;
1623 	      if (maxlinewidth < linewidth)
1624 		maxlinewidth = linewidth;
1625 	      i++;
1626 	      break;
1627 	      //legend pattern
1628 	    case 'p':
1629 	      if (isdigit(*(lpszTemp + 2)) != 0 && isdigit(*(lpszTemp + 3)) != 0 && isdigit(*(lpszTemp + 4)) != 0)
1630 		{
1631 		  lpszTemp = lpszTemp + 5;
1632 		  i += 4;
1633 
1634 		  drawpattern(flag, f, CX, CY + (fr->scale(lf0.size) - h)
1635 			      , (int)(LengthRate * fr->scale(lf0.size) / 100.0), -fr->scale(lf0.size), DataNo);
1636 
1637 		  charw = (int)(LengthRate * fr->scale(lf0.size) / 100.0);
1638 		  lastcharwidth = charw;
1639 		  linewidth += charw;
1640 		  if (maxlinewidth < linewidth)
1641 		    maxlinewidth = linewidth;
1642 
1643 		}
1644 	      else
1645 		{
1646 		  lpszTemp++;
1647 		  charw = 0;
1648 		}
1649 	      break;
1650 	    default:
1651 	      lpszTemp++;
1652 	      charw = 0;
1653 	    }
1654 
1655 	  break;
1656 
1657 	case '\\':
1658 	  if (*(lpszTemp + 1) == 'n')
1659 	      lpszTemp += 2;
1660 	  else if (*(lpszTemp + 1) == 'b')
1661 	      lpszTemp += 2;
1662 	  else if (*(lpszTemp + 1) == '\\')
1663 	    {
1664 	      temp3[0] = '\\';
1665 	      temp3[1] = 0;
1666 	      charw = getcharwidth(&lf, (unsigned int)*temp3, false);
1667 	      if (rect == 0 && textwidth == 0)
1668 		pdrawtext(flag, f, RotatedPoint.x, RotatedPoint.y, temp3, fr->scale(lf.size), charw, lf.angle, cascend);
1669 	      lastcharwidth = charw;
1670 	      linewidth += charw;
1671 	      if (maxlinewidth < linewidth)
1672 		maxlinewidth = linewidth;
1673 	      lpszTemp += 2;
1674 	    }
1675 	  else if (isdigit(*(lpszTemp + 1)) != 0)
1676 	    {
1677 	      if (isdigit(*(lpszTemp + 2)) != 0)
1678 		{
1679 		  if (isdigit(*(lpszTemp + 3)) != 0)
1680 		    {
1681 		      ustemp[0] = (*(lpszTemp + 1) - '0') * 64 + (*(lpszTemp + 2) - '0') * 8 + (*(lpszTemp + 3) - '0');
1682 		      ustemp[1] = 0;
1683 		      charw = getcharwidth(&lf, (unsigned int)*ustemp, false);
1684 		      if (rect == 0 && textwidth == 0)
1685 			pdrawtext(flag, f, RotatedPoint.x, RotatedPoint.y, (const char *)ustemp, fr->scale(lf.size), charw, lf.angle, cascend);
1686 		      lastcharwidth = charw;
1687 		      linewidth += charw;
1688 		      if (maxlinewidth < linewidth)
1689 			maxlinewidth = linewidth;
1690 		      lpszTemp += 4;
1691 		    }
1692 		  else
1693 		    lpszTemp += 3;
1694 		}
1695 	      else
1696 		lpszTemp += 2;
1697 	    }
1698 	  else
1699 	    lpszTemp++;
1700 
1701 	  break;
1702 	case '^':
1703 	case '_':
1704 	case '|':
1705 	case 10 :
1706 	case 13 :
1707 	  lpszTemp = lpszTemp + 1;
1708 	  charw = 0;
1709 	  break;
1710 	default:
1711 	  // dwaw text
1712 	  lpszTemp1 = nextpoint(lpszTemp);
1713 
1714 	  if ((strlen(lpszTemp)-strlen(lpszTemp1)) == 2)
1715 	    {
1716 	      temp3[0] = *lpszTemp;
1717 	      temp3[1] = *(lpszTemp + 1);
1718 	      temp3[2] = 0;
1719 	      charw = getcharwidth(&lf, (unsigned int)*temp3, true);
1720 	    }
1721 	  else
1722 	    {
1723 	      temp3[0] = *lpszTemp;
1724 	      temp3[1] = 0;
1725 	      charw = getcharwidth(&lf, (unsigned int)*temp3, false);
1726 	    }
1727 
1728 	  if (rect == 0 && textwidth == 0)
1729 	    pdrawtext(flag, f, RotatedPoint.x, RotatedPoint.y, temp3, fr->scale(lf.size), charw, lf.angle, cascend);
1730 	  lastcharwidth = charw;
1731 	  linewidth += charw;
1732 	  if (maxlinewidth < linewidth)
1733 	    maxlinewidth = linewidth;
1734 	  lpszTemp = nextpoint(lpszTemp);
1735 	  break;
1736 	}
1737 
1738       // update character position
1739       CY = (int)fr->doubleworld_to_view_y(p1.y) - dy;
1740       CX = CX + charw + dx + tdx;
1741       CY = CY + (int)(((double)lf0.size) * ((double)KaigyoNo) * ((double)linespacing));
1742       RotatedPoint = RotatePoint(intpoint(CX, CY), intpoint(CX0, CY0), (double)lf.angle);
1743       if (CX > maxCX)
1744 	maxCX = CX;
1745     }
1746 
1747   //return bounding box
1748   if (rect != 0)
1749     {
1750       RotatedLeftTop = RotatePoint(intpoint(CX0, CY0 - h), intpoint(CX0, CY0), (double)lf.angle);
1751       RotatedRightTop = RotatePoint(intpoint(maxCX, CY0 - h), intpoint(CX0, CY0), (double)lf.angle);
1752       RotatedRightBottom = RotatePoint(intpoint(maxCX, CY + fr->scale(lf0.size) - h),intpoint(CX0, CY0), (double)lf.angle);
1753       RotatedLeftBottom = RotatePoint(intpoint(CX0, CY + fr->scale(lf0.size) - h), intpoint(CX0, CY0), (double)lf.angle);
1754 
1755       //MinX
1756       if (RotatedLeftTop.x <= RotatedRightTop.x)
1757 	MinX = RotatedLeftTop.x;
1758       else
1759 	MinX = RotatedRightTop.x;
1760 
1761       if (RotatedRightBottom.x <= MinX)
1762 	MinX = RotatedRightBottom.x;
1763 
1764       if (RotatedLeftBottom.x <= MinX)
1765 	MinX = RotatedLeftBottom.x;
1766 
1767       //MaxX
1768       if (RotatedLeftTop.x >= RotatedRightTop.x)
1769 	MaxX = RotatedLeftTop.x;
1770       else
1771 	MaxX = RotatedRightTop.x;
1772 
1773       if (RotatedRightBottom.x >= MaxX)
1774 	MaxX = RotatedRightBottom.x;
1775 
1776       if (RotatedLeftBottom.x >= MaxX)
1777 	MaxX = RotatedLeftBottom.x;
1778 
1779       //MinY
1780       if (RotatedLeftTop.y <= RotatedRightTop.y)
1781 	MinY = RotatedLeftTop.y;
1782       else
1783 	MinY = RotatedRightTop.y;
1784 
1785       if (RotatedRightBottom.y <= MinY)
1786 	MinY = RotatedRightBottom.y;
1787 
1788       if (RotatedLeftBottom.y <= MinY)
1789 	MinY = RotatedLeftBottom.y;
1790 
1791       //MaxY
1792       if (RotatedLeftTop.y >= RotatedRightTop.y)
1793 	MaxY = RotatedLeftTop.y;
1794       else
1795 	MaxY = RotatedRightTop.y;
1796 
1797       if (RotatedRightBottom.y >= MaxY)
1798 	MaxY = RotatedRightBottom.y;
1799 
1800       if (RotatedLeftBottom.y >= MaxY)
1801 	MaxY = RotatedLeftBottom.y;
1802 
1803       bbrect.left       = MinX;
1804       bbrect.right      = MaxX;
1805       bbrect.top        = MinY;
1806       bbrect.bottom     = MaxY;
1807 
1808       *rect = bbrect;
1809     }
1810   else if (textwidth != 0)
1811       *textwidth = CX - CX0;
1812 }
1813 
gettextwidth()1814 int parts::gettextwidth()
1815 {
1816   int width;
1817   drawtext(true, 0, 0, &width);
1818   return width;
1819 }
1820 
drawpattern(int flag,FILE * f,int x,int y,int w,int h,int dataid)1821 void parts::drawpattern(int flag, FILE* f, int x, int y, int w, int h, int dataid)
1822 {
1823   int rad;
1824   int recrad;
1825   int trirad;
1826   int dotrad;
1827   int datano = -1;
1828   int cx, cy;
1829   intpointarray *ia;
1830   doublepointarray *dpa;
1831 
1832   frame *fr = (frame *)parent;
1833   data *dat = 0;
1834 
1835   // search data object
1836   for (int i = 0; i < fr->darray->getarraylength(); i++)
1837     {
1838       dat = &(*fr->darray)[i];
1839       if (dat->id == dataid)
1840 	{
1841 	  datano = i;
1842 	  break;
1843 	}
1844     }
1845   if (datano == -1)
1846     return;
1847 
1848   rad = fr->scale(dat->markersize);
1849   recrad = rad * 14 / 20;
1850   trirad = rad * 17 / 20;
1851   dotrad = 8;
1852   cx = x + w / 2;
1853   cy = y + h / 2;
1854 
1855   // line
1856   dpa = new doublepointarray;
1857   dpa->add(new doublepoint(x, y + h / 2));
1858   dpa->add(new doublepoint(x + w, y + h / 2));
1859   plinestyle(flag, f, fr->scale(dat->linestyle.width), dat->linestyle.cap, dat->linestyle.join, dat->linestyle.style);
1860   psetforecolor(flag, f, dat->linecolor.red, dat->linecolor.green, dat->linecolor.blue);
1861   pbeginpath(flag, f);
1862   StyleLinePath(flag, f, dpa, dpa->getarraylength() - 1,
1863 		dat->linestyle.style, fr->scale(dat->linestyle.width),
1864 		false, 0, 0);
1865   pstroke(flag, f);
1866   delete dpa;
1867 
1868   // marker
1869   ia = new intpointarray;
1870   psetforecolor(flag, f, dat->markeredgecolor.red, dat->markeredgecolor.green, dat->markeredgecolor.blue);
1871   psetbackcolor(flag, f, dat->markerbodycolor.red, dat->markerbodycolor.green, dat->markerbodycolor.blue);
1872   plinestyle(flag, f, fr->scale(dat->markeredgestyle.width),
1873 	     dat->markeredgestyle.cap, dat->markeredgestyle.join, dat->markeredgestyle.style);
1874   pfillstyle(flag, f, dat->markerbodyfillstyle.fillrule, dat->markerbodyfillstyle.style);
1875   switch (dat->markerstyle)
1876     {
1877       //NULL
1878     case MARKER_NULL:
1879       break;
1880       //rectangle
1881     case MARKER_SQUARE:
1882       ia->add(new intpoint(cx - recrad, cy - recrad));
1883       ia->add(new intpoint(cx + recrad, cy - recrad));
1884       ia->add(new intpoint(cx + recrad, cy + recrad));
1885       ia->add(new intpoint(cx - recrad, cy + recrad));
1886       ppolygon(flag, f, ia);
1887       break;
1888       //rev.triangle
1889     case MARKER_REVTRIANGLE:
1890       ia->add(new intpoint(cx         , cy + rad));
1891       ia->add(new intpoint(cx + trirad, cy - rad / 2));
1892       ia->add(new intpoint(cx - trirad, cy - rad / 2));
1893       ppolygon(flag, f, ia);
1894       break;
1895 
1896       //triangle
1897     case MARKER_TRIANGLE:
1898       ia->add(new intpoint(cx         , cy - rad));
1899       ia->add(new intpoint(cx + trirad, cy + rad / 2));
1900       ia->add(new intpoint(cx - trirad, cy + rad / 2));
1901       ppolygon(flag, f, ia);
1902       break;
1903 
1904       //diamond
1905     case MARKER_DIAMOND:
1906       ia->add(new intpoint(cx         , cy - rad));
1907       ia->add(new intpoint(cx +    rad, cy));
1908       ia->add(new intpoint(cx         , cy + rad));
1909       ia->add(new intpoint(cx -    rad, cy));
1910       ppolygon(flag, f, ia);
1911       break;
1912 
1913       //circle
1914     case MARKER_CIRCLE:
1915       pellipse(flag, f, cx - rad, cy - rad, cx + rad, cy + rad);
1916       break;
1917       //cross
1918     case MARKER_CROSS:
1919       pbeginpath(flag, f);
1920       pmoveto(flag, f, cx - rad, cy);
1921       plineto(flag, f, cx + rad, cy),
1922       pmoveto(flag, f, cx      , cy - rad);
1923       plineto(flag, f, cx      , cy + rad);
1924       pstroke(flag, f);
1925       break;
1926       //diag. cross
1927     case MARKER_DCROSS:
1928       pbeginpath(flag, f);
1929       pmoveto(flag, f, cx - rad, cy - rad);
1930       plineto(flag, f, cx + rad, cy + rad),
1931       pmoveto(flag, f, cx - rad, cy + rad);
1932       plineto(flag, f, cx + rad, cy - rad);
1933       pstroke(flag, f);
1934       break;
1935     case MARKER_VAREA:
1936     case MARKER_HAREA:
1937     case MARKER_VBAR:
1938     case MARKER_HBAR:
1939     case MARKER_VSTEP:
1940     case MARKER_HSTEP:
1941     case MARKER_VBAR2:
1942     case MARKER_HBAR2:
1943       ia->add(new intpoint(x, y + h / 4));
1944       ia->add(new intpoint(x + w, y + h / 4));
1945       ia->add(new intpoint(x + w, y + 3* h / 4));
1946       ia->add(new intpoint(x, y + 3 * h / 4));
1947       ppolygon(flag, f, ia);
1948       break;
1949     }
1950 
1951 
1952   //dot
1953   if (dat->markercenterdot && dat->markerstyle)
1954       pellipse(flag, f, cx - dotrad, cy - dotrad, cx + dotrad, cy + dotrad);
1955 
1956   delete ia;
1957 
1958   psetforecolor(flag, f, fontcolor.red, fontcolor.green, fontcolor.blue);
1959 }
1960 
1961 
1962 
1963 
drawarrow(int flag,FILE * f,doublepoint * start,doublepoint * end)1964 void parts::drawarrow(int flag, FILE* f, doublepoint *start, doublepoint *end)
1965 {
1966   double fa,fb,fc;
1967   double sx, sy, ex, ey;
1968   intpointarray *PArray;
1969   intpoint *TempPoint;
1970   frame *fr = (frame *)parent;
1971   double alength = (double)fr->scale(arrowlength);
1972 
1973   PArray = new intpointarray;
1974 
1975   plinestyle(flag, f, 0, 0, 0, 0);
1976   pfillstyle(flag, f, 0, 0);
1977   psetforecolor(flag, f, linecolor.red, linecolor.green, linecolor.blue);
1978   psetbackcolor(flag, f, linecolor.red, linecolor.green, linecolor.blue);
1979 
1980   sx = start->x;
1981   sy = start->y;
1982   ex = end->x;
1983   ey = end->y;
1984 
1985   fa = (double)(ex - sx);
1986   fa = fa * fa;
1987   fb = (double)(ey - sy);
1988   fb = fb * fb;
1989   fa = fa + fb;
1990   fa = sqrt(fa);
1991 
1992   if ((int)fa != 0)
1993     {
1994       if((ex - sx) > 0)
1995 	fa = asin((double)(ey - sy) / fa);
1996       else
1997 	fa = M_PI - asin((double)(ey - sy) / fa);
1998 
1999       TempPoint = new intpoint;
2000       TempPoint->x = (int)sx;
2001       TempPoint->y = (int)sy;
2002       PArray->add(TempPoint);
2003 
2004       fb = alength * cos(fa + arrowhalfangle / 180.0 * M_PI);
2005       fc = alength * sin(fa + arrowhalfangle / 180.0 * M_PI);
2006 
2007       TempPoint = new intpoint;
2008       TempPoint->x = (int)(sx + fb);
2009       TempPoint->y = (int)(sy + fc);
2010       PArray->add(TempPoint);
2011 
2012       fb = alength * cos(fa - arrowhalfangle / 180.0 * M_PI);
2013       fc = alength * sin(fa - arrowhalfangle / 180.0 * M_PI);
2014 
2015       TempPoint = new intpoint;
2016       TempPoint->x = (int)(sx + fb);
2017       TempPoint->y = (int)(sy + fc);
2018       PArray->add(TempPoint);
2019 
2020       ppolygon(flag, f, PArray);
2021     }
2022   delete PArray;
2023 
2024 
2025 }
2026 
2027 
drawparts(int flag,FILE * f)2028 void parts::drawparts(int flag, FILE* f)
2029 {
2030 //  intpoint temp[50];
2031   int sx, sy, ex, ey;
2032   int asx = 0, asy = 0, aex = 0, aey = 0;
2033   double len, projected_arrowlen = 0.0, cost = 0.0, sint = 0.0;
2034   int i, no, interporatedno;
2035   doublearray *InX = 0, *InY = 0, *OutX = 0, *OutY = 0;
2036   intpointarray *parray = 0;
2037   intpoint *temppoint;
2038 
2039   doublepointarray *PArray;
2040   doublepoint *TempPoint;
2041   doublepoint tdp1, tdp2;
2042   frame *fr = (frame *)parent;
2043 
2044   sx = fr->wtov_x(p1.x);
2045   sy = fr->wtov_y(p1.y);
2046   ex = fr->wtov_x(p2.x);
2047   ey = fr->wtov_y(p2.y);
2048 
2049   plinestyle(flag, f, fr->scale(linestyle.width),
2050 	     linestyle.cap, linestyle.join, linestyle.style);
2051   pfillstyle(flag, f, bodystyle.fillrule, bodystyle.style);
2052   psetforecolor(flag, f, linecolor.red, linecolor.green, linecolor.blue);
2053   psetbackcolor(flag, f, bodycolor.red, bodycolor.green, bodycolor.blue);
2054 
2055   //draw parts
2056   switch(type)
2057     {
2058     case PARTS_LINE:
2059 
2060       len = (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y); len = sqrt(len);
2061       if (len == 0.0)
2062 	return;
2063 
2064       if (p1_arrow || p2_arrow)
2065 	{
2066 	  projected_arrowlen = arrowlength * cos(arrowhalfangle / 180.0 * M_PI);
2067 	  if (len != 0.0)
2068 	    {
2069 	      cost = (p2.x - p1.x) / len;
2070 	      sint = (p2.y - p1.y) / len;
2071 	    }
2072 	}
2073       if (len != 0.0)
2074 	{
2075 	  if (p1_arrow)
2076 	    {
2077 	      asx = (int)(p1.x + projected_arrowlen * cost);
2078 	      asy = (int)(p1.y + projected_arrowlen * sint);
2079 	      asx = fr->wtov_x(asx);
2080 	      asy = fr->wtov_y(asy);
2081 	    }
2082 	  else
2083 	    {
2084 	      asx = sx;
2085 	      asy = sy;
2086 	    }
2087 
2088 	  if (p2_arrow)
2089 	    {
2090 	      aex = (int)(p1.x + (len - projected_arrowlen) * cost);
2091 	      aey = (int)(p1.y + (len - projected_arrowlen) * sint);
2092 	      aex = fr->wtov_x(aex);
2093 	      aey = fr->wtov_y(aey);
2094 	    }
2095 	  else
2096 	    {
2097 	      aex = ex;
2098 	      aey = ey;
2099 	    }
2100 	}
2101 
2102       PArray = new doublepointarray;
2103       PArray->add(new doublepoint(asx, asy));
2104       PArray->add(new doublepoint(aex, aey));
2105 
2106       pbeginpath(flag, f);
2107       StyleLinePath(flag, f, PArray, PArray->getarraylength() - 1,
2108 		    linestyle.style, linestyle.width,
2109 		    false, 0, 0);
2110       pstroke(flag, f);
2111       delete PArray;
2112 
2113       if (len != 0)
2114 	{
2115 	  if(p1_arrow)
2116 	    {
2117 	      tdp1 = doublepoint(sx, sy);
2118 	      tdp2 = doublepoint(asx, asy);
2119 	      drawarrow(flag, f,
2120 			&tdp1,
2121 			&tdp2);
2122 	    }
2123 
2124 	  if(p2_arrow)
2125 	    {
2126 	      tdp1 = doublepoint(ex, ey);
2127 	      tdp2 = doublepoint(aex, aey);
2128 	      drawarrow(flag, f,
2129 		      &tdp1,
2130 		      &tdp2);
2131 	    }
2132 	}
2133 
2134       break;
2135 
2136     case PARTS_RECTANGLE:
2137       parray = new intpointarray;
2138       parray->add(new intpoint (sx, sy));
2139       parray->add(new intpoint (ex, sy));
2140       parray->add(new intpoint (ex, ey));
2141       parray->add(new intpoint (sx, ey));
2142       ppolygon(flag, f, parray);
2143       delete parray;
2144       break;
2145     case PARTS_ELLIPSE:
2146       pellipse(flag, f, sx, sy, ex, ey);
2147       break;
2148     case PARTS_CUT:
2149       plinestyle(flag, f, fr->scale(linestyle.width),
2150 		 linestyle.cap, linestyle.join, LINESTYLENULL);
2151       parray = new intpointarray;
2152       parray->add(new intpoint (sx, sy + (ey - sy) * 3 / 4));
2153       parray->add(new intpoint (sx + (ex - sx) * 3 / 4, sy));
2154       parray->add(new intpoint (ex, sy + (ey - sy) / 4));
2155       parray->add(new intpoint (sx + (ex - sx) / 4, ey));
2156       ppolygon(flag, f, parray);
2157       delete parray;
2158 
2159       plinestyle(flag, f, fr->scale(linestyle.width),
2160 		 linestyle.cap, linestyle.join, linestyle.style);
2161       pbeginpath(flag, f);
2162       pmoveto(flag, f, sx, sy + (ey - sy) * 3 / 4);
2163       plineto(flag, f, sx + (ex - sx) * 3 / 4, sy);
2164       pmoveto(flag, f, sx + (ex - sx) / 4, ey);
2165       plineto(flag, f, ex, sy + (ey - sy) / 4);
2166       pstroke(flag, f);
2167       break;
2168     case PARTS_POLYLINE:
2169       no = nodes->getarraylength() - 1;
2170       if (no >= 1)
2171 	{
2172 	  if (interpolate == PARTS_INTER_POLYLINE || interpolate == PARTS_INTER_CLOSEDPOLYLINE)
2173 	    {
2174 	      if (interpolate == PARTS_INTER_POLYLINE)
2175 		{
2176 		  PArray = new doublepointarray;
2177 		  for (i = 0; i <= no; i++)
2178 		    {
2179 		      TempPoint = new doublepoint;
2180 		      TempPoint->x = fr->wtov_x((*nodes)[i].x + p1.x);
2181 		      TempPoint->y = fr->wtov_y((*nodes)[i].y + p1.y);
2182 		      PArray->add(TempPoint);
2183 		    }
2184 
2185 		  pbeginpath(flag, f);
2186 		  StyleLinePath(flag, f, PArray, PArray->getarraylength() - 1,
2187 			       linestyle.style, linestyle.width,
2188 			       false, 0, 0);
2189 		  pstroke(flag, f);
2190 		  delete PArray;
2191 
2192 		}
2193 	      //closed polyline
2194 	      else
2195 		{
2196 		  parray = new intpointarray;
2197 		  for (i = 0; i <= no; i++)
2198 		    {
2199 		      temppoint = new intpoint(fr->wtov_x((*nodes)[i].x + p1.x), fr->wtov_y((*nodes)[i].y + p1.y));
2200 		      parray->add(temppoint);
2201 		    }
2202 		  temppoint = new intpoint(fr->wtov_x((*nodes)[0].x + p1.x), fr->wtov_y((*nodes)[0].y + p1.y));
2203 		  parray->add(temppoint);
2204 
2205 		  ppolygon(flag, f, parray);
2206 		  delete parray;
2207 
2208 		}
2209 	    }
2210 	  else if (interpolate == PARTS_INTER_PSPLINE || interpolate == PARTS_INTER_CLOSEDPSPLINE)
2211 	    {
2212 	      InX = new doublearray;
2213 	      if (InX == 0)
2214 		{
2215 		  InX = 0;
2216 		  goto j1;
2217 		}
2218 
2219 	      InY = new doublearray;
2220 	      if (InY == 0)
2221 		{
2222 		  InY = 0;
2223 		  goto j1;
2224 		}
2225 
2226  	      OutX = new doublearray;
2227 	      if (OutX == 0)
2228 		{
2229 		  OutX = 0;
2230 		  goto j1;
2231 		}
2232 
2233  	      OutY = new doublearray;
2234 	      if (OutY == 0)
2235 		{
2236 		  OutY = 0;
2237 		  goto j1;
2238 		}
2239 
2240 	      for (i = 0; i <= no; i++)
2241 		{
2242 		  InX->add((*nodes)[i].x + p1.x);
2243 		  InY->add((*nodes)[i].y + p1.y);
2244 		}
2245 
2246 	      if (interpolate == PARTS_INTER_PSPLINE)
2247 		CalcPSpline(InX, InY, OutX, OutY, 1, interpolatediv);
2248 	      else
2249 		CalcPSpline(InX, InY, OutX, OutY, 2, interpolatediv);
2250 
2251 	      interporatedno = OutX->getarraylength() - 1;
2252 
2253 	      if (interpolate == PARTS_INTER_PSPLINE)
2254 		{
2255 		  PArray = new doublepointarray;
2256 		  for (i = 0; i <= interporatedno; i++)
2257 		    PArray->add(new doublepoint(fr->wtov_x((int)(*OutX)[i]), fr->wtov_y((int)(*OutY)[i])));
2258 
2259 		  pbeginpath(flag, f);
2260 		  StyleLinePath(flag, f, PArray, PArray->getarraylength() - 1,
2261 				linestyle.style, linestyle.width,
2262 				false, 0, 0);
2263 		  pstroke(flag, f);
2264 		  delete PArray;
2265 		}
2266 	      //close pspline
2267 	      else
2268 		{
2269 		  parray = new intpointarray;
2270 		  for (i = 0; i <= interporatedno; i++)
2271 		    {
2272 		      temppoint = new intpoint(fr->wtov_x((int)(*OutX)[i]), fr->wtov_y((int)(*OutY)[i]));
2273 		      parray->add(temppoint);
2274 		    }
2275 		  plinestyle(flag, f, fr->scale(linestyle.width),
2276 			     linestyle.cap, linestyle.join, LINESTYLENULL);
2277 		  ppolygon(flag, f, parray);
2278 		  delete parray;
2279 
2280 		  PArray = new doublepointarray;
2281 		  for (i = 0; i <= interporatedno; i++)
2282 		    PArray->add(new doublepoint(fr->wtov_x((int)(*OutX)[i]), fr->wtov_y((int)(*OutY)[i])));
2283 
2284 		  plinestyle(flag, f, fr->scale(linestyle.width),
2285 			     linestyle.cap, linestyle.join, linestyle.style);
2286 		  pbeginpath(flag, f);
2287 		  StyleLinePath(flag, f, PArray, PArray->getarraylength() - 1,
2288 				linestyle.style, linestyle.width,
2289 				false, 0, 0);
2290 		  pstroke(flag, f);
2291 		  delete PArray;
2292 		}
2293 
2294 	    j1:
2295 	      if (InX != 0)
2296 		delete InX;
2297 	      if (InY != 0)
2298 		delete InY;
2299 	      if (OutX != 0)
2300 		delete OutX;
2301 	      if (OutY != 0)
2302 		delete OutY;
2303 	    }
2304 	}
2305       break;
2306     }
2307 }
2308 
readparts(FILE * fp)2309 bool parts::readparts(FILE *fp)
2310 {
2311   char stemp[10000];
2312   std::string str;
2313   char *p;
2314   int len, x, y;
2315   int readversion;
2316 
2317 //  virgin = false;
2318 
2319   // version
2320   if (getnextline(stemp, sizeof(stemp), fp))
2321   {
2322     if (nextitem(stemp, &str) != 0)
2323       readversion = atoi(str.c_str());
2324     else
2325       return false;
2326   }
2327   else
2328     return false;
2329 
2330   // id
2331   if (getnextline(stemp, sizeof(stemp), fp))
2332   {
2333     if (nextitem(stemp, &str) != 0)
2334       id = atoi(str.c_str());
2335     else
2336       return false;
2337   }
2338   else
2339     return false;
2340 
2341   // type
2342   if (getnextline(stemp, sizeof(stemp), fp))
2343   {
2344     if (nextitem(stemp, &str) != 0)
2345       type = atoi(str.c_str());
2346     else
2347       return false;
2348   }
2349   else
2350     return false;
2351 
2352   // text
2353   if (getnextline(stemp, sizeof(stemp), fp))
2354   {
2355     if (gettxt(stemp, &str))
2356       *text = str;
2357     else
2358       return false;
2359   }
2360 
2361   // fo
2362   if (getnextline(stemp, sizeof(stemp), fp))
2363   {
2364     p = stemp;
2365     // face
2366     p = nextitem(p, &str);
2367     if (p != 0)
2368       fo.face = atoi(str.c_str());
2369     else
2370       return false;
2371 
2372     if (readversion >= 1)
2373       {
2374 	// jpface
2375 	p = nextitem(p, &str);
2376 	if (p != 0)
2377 	  fo.jpface = atoi(str.c_str());
2378 	else
2379 	  return false;
2380       }
2381 
2382     // size
2383     p = nextitem(p, &str);
2384     if (p != 0)
2385       fo.size = atoi(str.c_str());
2386     else
2387       return false;
2388     // angle
2389     p = nextitem(p, &str);
2390     if (p != 0)
2391       fo.angle = atof(str.c_str());
2392     else
2393       return false;
2394   }
2395   else
2396     return false;
2397 
2398   // fontcolor
2399   if (getnextline(stemp, sizeof(stemp), fp))
2400   {
2401     p = stemp;
2402     // red
2403     p = nextitem(p, &str);
2404     if (p != 0)
2405       fontcolor.red = atoi(str.c_str());
2406     else
2407       return false;
2408     // green
2409     p = nextitem(p, &str);
2410     if (p != 0)
2411       fontcolor.green = atoi(str.c_str());
2412     else
2413       return false;
2414     // blue
2415     p = nextitem(p, &str);
2416     if (p != 0)
2417       fontcolor.blue = atoi(str.c_str());
2418     else
2419       return false;
2420   }
2421   else
2422     return false;
2423 
2424   if (getnextline(stemp, sizeof(stemp), fp))
2425   {
2426     p = stemp;
2427     // linespacing
2428     p = nextitem(p, &str);
2429     if (p != 0)
2430       linespacing = atof(str.c_str());
2431     else
2432       return false;
2433   }
2434   else
2435     return false;
2436 
2437   // linecolor
2438   if (getnextline(stemp, sizeof(stemp), fp))
2439   {
2440     p = stemp;
2441     // red
2442     p = nextitem(p, &str);
2443     if (p != 0)
2444       linecolor.red = atoi(str.c_str());
2445     else
2446       return false;
2447     // green
2448     p = nextitem(p, &str);
2449     if (p != 0)
2450       linecolor.green = atoi(str.c_str());
2451     else
2452       return false;
2453     // blue
2454     p = nextitem(p, &str);
2455     if (p != 0)
2456       linecolor.blue = atoi(str.c_str());
2457     else
2458       return false;
2459   }
2460   else
2461     return false;
2462 
2463   // bodycolor
2464   if (getnextline(stemp, sizeof(stemp), fp))
2465   {
2466     p = stemp;
2467     // red
2468     p = nextitem(p, &str);
2469     if (p != 0)
2470       bodycolor.red = atoi(str.c_str());
2471     else
2472       return false;
2473     // green
2474     p = nextitem(p, &str);
2475     if (p != 0)
2476       bodycolor.green = atoi(str.c_str());
2477     else
2478       return false;
2479     // blue
2480     p = nextitem(p, &str);
2481     if (p != 0)
2482       bodycolor.blue = atoi(str.c_str());
2483     else
2484       return false;
2485   }
2486   else
2487     return false;
2488 
2489   // linestyle
2490   if (getnextline(stemp, sizeof(stemp), fp))
2491   {
2492     p = stemp;
2493     // width
2494     p = nextitem(p, &str);
2495     if (p != 0)
2496       linestyle.width = atoi(str.c_str());
2497     else
2498       return false;
2499     // cap
2500     p = nextitem(p, &str);
2501     if (p != 0)
2502       linestyle.cap = atoi(str.c_str());
2503     else
2504       return false;
2505     // join
2506     p = nextitem(p, &str);
2507     if (p != 0)
2508       linestyle.join = atoi(str.c_str());
2509     else
2510       return false;
2511     // style
2512     p = nextitem(p, &str);
2513     if (p != 0)
2514       linestyle.style = atoi(str.c_str());
2515     else
2516       return false;
2517   }
2518   else
2519     return false;
2520 
2521   // bodystyle
2522   if (getnextline(stemp, sizeof(stemp), fp))
2523   {
2524     p = stemp;
2525     // fillrule
2526     p = nextitem(p, &str);
2527     if (p != 0)
2528       bodystyle.fillrule = atoi(str.c_str());
2529     else
2530       return false;
2531     // style
2532     p = nextitem(p, &str);
2533     if (p != 0)
2534       bodystyle.style = atoi(str.c_str());
2535     else
2536       return false;
2537   }
2538   else
2539     return false;
2540 
2541   if (getnextline(stemp, sizeof(stemp), fp))
2542   {
2543     p = stemp;
2544     // legendlength
2545     p = nextitem(p, &str);
2546     if (p != 0)
2547       legendlength = atoi(str.c_str());
2548     else
2549       return false;
2550     // interpolate
2551     p = nextitem(p, &str);
2552     if (p != 0)
2553       interpolate = atoi(str.c_str());
2554     else
2555       return false;
2556     // interpolatediv
2557     p = nextitem(p, &str);
2558     if (p != 0)
2559       interpolatediv = atoi(str.c_str());
2560     else
2561       return false;
2562   }
2563   else
2564     return false;
2565 
2566   if (getnextline(stemp, sizeof(stemp), fp))
2567   {
2568     p = stemp;
2569     // p1_arrow
2570     p = nextitem(p, &str);
2571     if (p != 0)
2572       p1_arrow = atoi(str.c_str());
2573     else
2574       return false;
2575     // p2_arrow
2576     p = nextitem(p, &str);
2577     if (p != 0)
2578       p2_arrow = atoi(str.c_str());
2579     else
2580       return false;
2581   }
2582   else
2583     return false;
2584 
2585   // p1, p2
2586   if (getnextline(stemp, sizeof(stemp), fp))
2587   {
2588     p = stemp;
2589     // p1.x
2590     p = nextitem(p, &str);
2591     if (p != 0)
2592       p1.x = atoi(str.c_str());
2593     else
2594       return false;
2595     // p1.y
2596     p = nextitem(p, &str);
2597     if (p != 0)
2598       p1.y = atoi(str.c_str());
2599     else
2600       return false;
2601     // p2.x
2602     p = nextitem(p, &str);
2603     if (p != 0)
2604       p2.x = atoi(str.c_str());
2605     else
2606       return false;
2607     // p2.y
2608     p = nextitem(p, &str);
2609     if (p != 0)
2610       p2.y = atoi(str.c_str());
2611     else
2612       return false;
2613   }
2614   else
2615     return false;
2616 
2617   if (getnextline(stemp, sizeof(stemp), fp))
2618   {
2619     p = stemp;
2620     // arrowlength
2621     p = nextitem(p, &str);
2622     if (p != 0)
2623       arrowlength = atoi(str.c_str());
2624     else
2625       return false;
2626     // arrowhalfangle
2627     p = nextitem(p, &str);
2628     if (p != 0)
2629       arrowhalfangle = atof(str.c_str());
2630     else
2631       return false;
2632   }
2633   else
2634     return false;
2635 
2636 
2637   // nodes
2638   if (getnextline(stemp, sizeof(stemp), fp))
2639   {
2640     p = stemp;
2641     p = nextitem(p, &str);
2642     if (p != 0)
2643       len = atoi(str.c_str());
2644     else
2645       return false;
2646   }
2647   else
2648     return false;
2649 
2650   nodes->setbuff(0);
2651   for (int i = 0; i < len; i++)
2652     {
2653       if (getnextline(stemp, sizeof(stemp), fp))
2654 	{
2655 	  // x
2656 	  p = stemp;
2657 	  p = nextitem(p, &str);
2658 	  if (p != 0)
2659 	    x = atoi(str.c_str());
2660 	  else
2661 	    return false;
2662 	  // y
2663 	  p = nextitem(p, &str);
2664 	  if (p != 0)
2665 	    y = atoi(str.c_str());
2666 	  else
2667 	    return false;
2668 	}
2669       else
2670 	return false;
2671 
2672       nodes->add(new intpoint(x ,y));
2673     }
2674 
2675   return true;
2676 }
2677 
writeparts(FILE * fp)2678 bool parts::writeparts(FILE *fp)
2679 {
2680   fprintf(fp, "[parts]\n");
2681 
2682   // text
2683   fprintf(fp, "%d\n", version);
2684   fprintf(fp, "%d\n", id);
2685   fprintf(fp, "%d\n", type);
2686   fprintf(fp, "\"%s\"\n", text->c_str());
2687   fprintf(fp, "%d %d %d %.15g\n", fo.face, fo.jpface, fo.size, fo.angle);
2688   fprintf(fp, "%u %u %u\n", fontcolor.red, fontcolor.green, fontcolor.blue);
2689   fprintf(fp, "%.15g\n", linespacing);
2690 
2691   // parts
2692   fprintf(fp, "%u %u %u\n", linecolor.red, linecolor.green, linecolor.blue);
2693   fprintf(fp, "%u %u %u\n", bodycolor.red, bodycolor.green, bodycolor.blue);
2694   fprintf(fp, "%d %d %d %d\n", linestyle.width, linestyle.cap, linestyle.join, linestyle.style);
2695   fprintf(fp, "%d %d\n", bodystyle.fillrule, bodystyle.style);
2696   fprintf(fp, "%d %d %d\n", legendlength, interpolate, interpolatediv);
2697   fprintf(fp, "%d %d\n", p1_arrow, p2_arrow);
2698   fprintf(fp, "%d %d %d %d\n", p1.x, p1.y, p2.x, p2.y);
2699   fprintf(fp, "%d %.15g\n", arrowlength, arrowhalfangle);
2700   fprintf(fp, "%d\n", nodes->getarraylength());
2701   for (int i = 0; i < nodes->getarraylength(); i++)
2702     fprintf(fp, "%d %d\n", (*nodes)[i].x, (*nodes)[i].y);
2703 
2704   return true;
2705 }
2706 
2707 
2708 
2709 
2710