home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 mARCH / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / ArcBox.C < prev    next >
C/C++ Source or Header  |  1998-11-23  |  10KB  |  473 lines

  1. // $Id: ArcBox.C,v 1.12 1998/11/23 15:00:14 zeller Exp $
  2. // Arc boxes
  3.  
  4. // Copyright (C) 1995 Technische Universitaet Braunschweig, Germany.
  5. // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  6. // 
  7. // This file is part of DDD.
  8. // 
  9. // DDD is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. // 
  14. // DDD is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. // See the GNU General Public License for more details.
  18. // 
  19. // You should have received a copy of the GNU General Public
  20. // License along with DDD -- see the file COPYING.
  21. // If not, write to the Free Software Foundation, Inc.,
  22. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. // 
  24. // DDD is the data display debugger.
  25. // For details, see the DDD World-Wide-Web page, 
  26. // `http://www.cs.tu-bs.de/softech/ddd/',
  27. // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
  28.  
  29. char ArcBox_rcsid[] = 
  30.     "$Id: ArcBox.C,v 1.12 1998/11/23 15:00:14 zeller Exp $";
  31.  
  32. #ifdef __GNUG__
  33. #pragma implementation
  34. #endif
  35.  
  36. #include "ArcBox.h"
  37. #include "printBox.h"
  38.  
  39. #include <X11/Xlib.h>
  40. #include <X11/Intrinsic.h>
  41.  
  42. // Some systems define these values in <values.h> and re-define them 
  43. // DIFFERENTLY in <math.h>.  Prefer the <math.h> definitions.
  44. #undef M_LN2
  45. #undef M_PI
  46. #undef M_SQRT2
  47. #include <math.h>
  48.  
  49. DEFINE_TYPE_INFO_1(ArcBox, LineBox)
  50.  
  51. // ArcBox
  52.  
  53. // Draw
  54. void ArcBox::__draw(Widget w, 
  55.             const BoxRegion& r, 
  56.             const BoxRegion& , GC gc, 
  57.             bool) const
  58. {
  59.     BoxSize space   = r.space();
  60.     BoxPoint origin = r.origin();
  61.  
  62.     // Adapt coordinates for partial arcs
  63.  
  64.     // Only the most common cases (i.e. multiples of 90) are handled
  65.     // here.
  66.  
  67.     switch (_length) {
  68.     case 360:   // do nothing
  69.         break;
  70.  
  71.     case 180:   // Double space
  72.         switch (_start) {
  73.         case 0:
  74.             space[Y] *= 2;
  75.             break;
  76.         case 90:
  77.             space[X] *= 2;
  78.             break;
  79.         case 180:
  80.             origin[Y] -= space[Y];
  81.             space[Y] *= 2;
  82.             break;
  83.         case 270:
  84.             origin[X] -= space[X];
  85.             space[X] *= 2;
  86.             break;
  87.         default:
  88.             cerr << "ArcBox::_draw(): illegal start\n";
  89.         }
  90.         break;
  91.  
  92.     case 90:    // Quadruple space
  93.         switch (_start) {
  94.         case 0:
  95.             origin[X] -= space[X];
  96.             break;
  97.         case 90:
  98.             break;
  99.         case 180:
  100.             origin[Y] -= space[Y];
  101.             break;
  102.         case 270:
  103.             origin[X] -= space[X];
  104.             origin[Y] -= space[Y];
  105.             break;
  106.         default:
  107.             cerr << "ArcBox::_draw(): illegal start\n";
  108.         }
  109.         space *= BoxPoint(2,2);
  110.         break;
  111.  
  112.     default:
  113.         cerr << "ArcBox::_draw(): illegal length\n";
  114.     }
  115.  
  116.     if (space[X] > 0 && space[Y] > 0 && _length > 0)
  117.     XDrawArc(XtDisplay(w), XtWindow(w), gc, origin[X], origin[Y],
  118.          space[X], space[Y], _start * 64, _length * 64);
  119. }
  120.  
  121. void ArcBox::dump(ostream& s) const
  122. {
  123.     s << "arc(" << _start << "," << _length << ")";
  124. }
  125.  
  126.  
  127. // Print
  128.  
  129. #define POINT(i) (os << points[i][X] << " " << points[i][Y] << " ")
  130.  
  131. //
  132. // constants for drawing Arcs
  133. //
  134.  
  135. const float rad = 0.70710678118654752440;
  136.  
  137.  
  138. //
  139. // drawFigArc
  140. //
  141.  
  142. void ArcBox::_printFig(ostream& os, 
  143.                const BoxRegion& region, 
  144.                const PrintGC &) const
  145. {
  146.     BoxPoint origin = region.origin() ;
  147.     BoxPoint space = region.space();
  148.     BoxDegrees s = start();
  149.     BoxDegrees l = length() ;
  150.     BoxCoordinate thickness = linethickness() ;
  151.     BoxPoint points[12] ;
  152.     BoxCoordinate middle ;
  153.  
  154.     switch (l) {
  155.     case 0:
  156.     case 360:
  157.     case 270:
  158.     break ;
  159.     case 180:
  160.     switch (s) {
  161.     case 0:
  162.         space[Y] *= 2;
  163.         break ;
  164.     case 90:
  165.         space[X] *= 2;
  166.         break;
  167.     case 180:
  168.         origin[Y] -= space[Y] ;
  169.         space[Y] *= 2;
  170.         break ;
  171.     case 270:
  172.         origin[X] -= space[X] ;
  173.         space[X] *= 2;
  174.         break;
  175.     default:
  176.         cerr << "illegal start" ;
  177.     }
  178.     
  179.     break ;
  180.     case 90:
  181.     switch (s) {
  182.     case 0:
  183.         origin[X] -= space[X] ;
  184.         break ;
  185.     case 90:
  186.         break ;
  187.     case 180:
  188.         origin[Y] -= space[Y] ;
  189.         break ;
  190.     case 270:
  191.         origin[X] -= space[X] ;
  192.         origin[Y] -= space[Y] ;
  193.         break ;
  194.     default:
  195.         cerr << "illegal start" ;
  196.     }
  197.     space[X] *= 2;
  198.     space[Y] *= 2;
  199.     break ;
  200.     default:
  201.     cerr << "illegal length" ;
  202.     }
  203.     
  204.  
  205.     if (space[X] < space[Y]) {
  206.     middle = (int) ((float)space[X]/2 * rad) ;
  207.     
  208.     points[0][X] = origin[X] + space[X]/2 ;
  209.     points[0][Y] = origin[Y] ;
  210.     points[1][X] = origin[X] + space[X]/2 + middle ;
  211.     points[1][Y] = origin[Y] + space[X]/2 - middle ;
  212.     points[2][X] = origin[X] + space[X] ;
  213.     points[2][Y] = origin[Y] + space[X]/2 ;
  214.     points[3][X] = origin[X] + space[X] ;
  215.     points[3][Y] = origin[Y] + space[Y]/2 ;
  216.     
  217.     points[4][X] = origin[X] + space[X] ;
  218.     points[4][Y] = origin[Y] + space[Y] - space[X]/2;
  219.     points[5][X] = origin[X] + space[X]/2 + middle ;
  220.     points[5][Y] = origin[Y] + space[Y] - space[X]/2 + middle ;
  221.     points[6][X] = origin[X] + space[X]/2 ;
  222.     points[6][Y] = origin[Y] + space[Y]  ;
  223.     points[7][X] = origin[X] + space[X]/2 - middle ;
  224.     points[7][Y] = origin[Y] + space[Y] - space[X]/2 + middle;
  225.     
  226.     points[8][X] = origin[X] ;
  227.     points[8][Y] = origin[Y] + space[Y] - space[X]/2;
  228.     points[9][X] = origin[X] ;
  229.     points[9][Y] = origin[Y] + space[Y]/2 ;
  230.     points[10][X] = origin[X] ;
  231.     points[10][Y] = origin[Y] + space[X]/2 ;
  232.     points[11][X] = origin[X] + space[X]/2 - middle ;
  233.     points[11][Y] = origin[Y] + space[X]/2 - middle ;
  234.     
  235.     while (l) {
  236.         switch (s) {
  237.         case 360:
  238.         case 0:
  239.         os << LINEHEAD1 ;
  240.         os << thickness ;
  241.         os << LINEHEAD2 ;
  242.         POINT(0) ;
  243.         POINT(1) ;
  244.         POINT(2) ;
  245.         POINT(3) ;
  246.         os << "9999 9999\n" ;
  247.         
  248.         break;
  249.         case 270:
  250.         os << LINEHEAD1 ;
  251.         os << thickness ;
  252.         os << LINEHEAD2 ;
  253.         POINT(3) ;
  254.         POINT(4) ;
  255.         POINT(5) ;
  256.         POINT(6) ;
  257.         os << "9999 9999\n" ;
  258.         
  259.         break;
  260.         case 180:
  261.         os << LINEHEAD1 ;
  262.         os << thickness ;
  263.         os << LINEHEAD2 ;
  264.         POINT(6) ;
  265.         POINT(7) ;
  266.         POINT(8) ;
  267.         POINT(9) ;
  268.         os << "9999 9999\n" ;
  269.         
  270.         break;
  271.         case 90:
  272.         os << LINEHEAD1 ;
  273.         os << thickness ;
  274.         os << LINEHEAD2 ;
  275.         POINT(9) ;
  276.         POINT(10) ;
  277.         POINT(11) ;
  278.         POINT(0) ;
  279.         os << "9999 9999\n" ;
  280.         
  281.         break;
  282.         
  283.         default:
  284.         cerr << "drawArc: illegal start\n";
  285.         }
  286.         l -= 90 ;
  287.         s = (s + 90) % 360 ;
  288.     }
  289.     } else  {
  290.     middle = (int) ((float)space[Y]/2 * rad) ;
  291.     int equal = (space[X] == space[Y]) ;
  292.     
  293.     points[0][Y] = origin[Y] + space[Y]/2 ;
  294.     points[0][X] = origin[X] ;
  295.     points[1][Y] = origin[Y] + space[Y]/2 + middle ;
  296.     points[1][X] = origin[X] + space[Y]/2 - middle ;
  297.     points[2][Y] = origin[Y] + space[Y] ;
  298.     points[2][X] = origin[X] + space[Y]/2 ;
  299.     points[3][Y] = origin[Y] + space[Y] ;
  300.     points[3][X] = origin[X] + space[X]/2 ;
  301.     
  302.     points[4][Y] = origin[Y] + space[Y] ;
  303.     points[4][X] = origin[X] + space[X] - space[Y]/2;
  304.     points[5][Y] = origin[Y] + space[Y]/2 + middle ;
  305.     points[5][X] = origin[X] + space[X] - space[Y]/2 + middle ;
  306.     points[6][Y] = origin[Y] + space[Y]/2 ;
  307.     points[6][X] = origin[X] + space[X]  ;
  308.     points[7][Y] = origin[Y] + space[Y]/2 - middle ;
  309.     points[7][X] = origin[X] + space[X] - space[Y]/2 + middle;
  310.     
  311.     points[8][Y] = origin[Y] ;
  312.     points[8][X] = origin[X] + space[X] - space[Y]/2;
  313.     points[9][Y] = origin[Y] ;
  314.     points[9][X] = origin[X] + space[X]/2 ;
  315.     points[10][Y] = origin[Y] ;
  316.     points[10][X] = origin[X] + space[Y]/2 ;
  317.     points[11][Y] = origin[Y] + space[Y]/2 - middle ;
  318.     points[11][X] = origin[X] + space[Y]/2 - middle ;
  319.  
  320.     while (l) {
  321.         switch (s) {
  322.         case 180:
  323.         os << LINEHEAD1 ;
  324.         os << thickness ;
  325.         os << LINEHEAD2 ;
  326.         POINT(0) ;
  327.         POINT(1) ;
  328.         POINT(2) ;
  329.         if (!equal)
  330.             POINT(3) ;
  331.         os << "9999 9999\n" ;
  332.         
  333.         break;
  334.         case 270:
  335.         os << LINEHEAD1 ;
  336.         os << thickness ;
  337.         os << LINEHEAD2 ;
  338.         if (!equal)
  339.             POINT(3) ;
  340.         POINT(4) ;
  341.         POINT(5) ;
  342.         POINT(6) ;
  343.         os << "9999 9999\n" ;
  344.         
  345.         break;
  346.         case 360:
  347.         case 0:
  348.         os << LINEHEAD1 ;
  349.         os << thickness ;
  350.         os << LINEHEAD2 ;
  351.         POINT(6) ;
  352.         POINT(7) ;
  353.         POINT(8) ;
  354.         if (!equal)
  355.             POINT(9) ;
  356.         os << "9999 9999\n" ;
  357.         
  358.         break;
  359.         case 90:
  360.         os << LINEHEAD1 ;
  361.         os << thickness ;
  362.         os << LINEHEAD2 ;
  363.         if (!equal)
  364.             POINT(9) ;
  365.         POINT(10) ;
  366.         POINT(11) ;
  367.         POINT(0) ;
  368.         os << "9999 9999\n" ;
  369.         
  370.         break;
  371.         
  372.         default:
  373.         cerr << "drawArc: illegal start\n";
  374.         }
  375.         l -= 90 ;
  376.         s = (s + 90) % 360 ;
  377.     }
  378.     }
  379. }
  380.  
  381.  
  382. //
  383. // drawPSArc
  384. //
  385.  
  386. void ArcBox::_printPS(ostream& os, 
  387.               const BoxRegion& region, 
  388.               const PrintGC &) const
  389. {
  390.     BoxPoint origin = region.origin() ;
  391.     BoxPoint space = region.space();
  392.     BoxDegrees s = start();
  393.     BoxDegrees end;
  394.     BoxDegrees l = length() ;
  395.     BoxCoordinate thickness = linethickness() ;
  396.     
  397.     switch (l) {
  398.     case 0:
  399.     case 360:
  400.     case 270:
  401.     break ;
  402.     case 180:
  403.     switch (s) {
  404.     case 0:
  405.         space[Y] *= 2;
  406.         break ;
  407.     case 90:
  408.         space[X] *= 2;
  409.         break;
  410.     case 180:
  411.         origin[Y] -= space[Y] ;
  412.         space[Y] *= 2;
  413.         break ;
  414.     case 270:
  415.         origin[X] -= space[X] ;
  416.         space[X] *= 2;
  417.         break;
  418.     default:
  419.         cerr << "illegal start" ;
  420.     }
  421.     
  422.     break ;
  423.     case 90:
  424.     switch (s) {
  425.     case 0:
  426.         origin[X] -= space[X] ;
  427.         break ;
  428.     case 90:
  429.         break ;
  430.     case 180:
  431.         origin[Y] -= space[Y] ;
  432.         break ;
  433.     case 270:
  434.         origin[X] -= space[X] ;
  435.         origin[Y] -= space[Y] ;
  436.         break ;
  437.     default:
  438.         cerr << "illegal start" ;
  439.     }
  440.     space[X] *= 2;
  441.     space[Y] *= 2;
  442.     break ;
  443.     default:
  444.     cerr << "illegal length" ;
  445.     }
  446.     
  447.     end = (720 - s) % 360 ;
  448.     s   = (720 - s - l) % 360 ;
  449.     
  450.     
  451.     os << s << " " << end << " " ;
  452.     os << space[X]/2 << " " << space[Y]/2 << " ";
  453.     os << origin[X] + space[X]/2 << " " << origin[Y] + space[Y]/2;
  454.     os << " " << thickness << " arc*\n";
  455.     
  456. }
  457.  
  458. //
  459. // drawArc
  460. //
  461.  
  462. void ArcBox::_print(ostream& os, 
  463.             const BoxRegion& region, 
  464.             const PrintGC& gc) const
  465. {
  466.     if (gc.isFig()) {
  467.     _printFig(os, region, gc);
  468.     } else if (gc.isPostScript()) {
  469.     _printPS(os, region, gc);
  470.     }
  471.  
  472. }
  473.