home *** CD-ROM | disk | FTP | other *** search
/ Troubleshooting Netware Systems / CSTRIAL0196.BIN / attach / msj / v10n08 / sketchsc.exe / STROKE.CPP < prev    next >
C/C++ Source or Header  |  1995-08-01  |  9KB  |  286 lines

  1. //-----------------------------------------------------------------------
  2. // STROKE.CPP:    Drawing objects:    drawing_element, stroke, line
  3. //-----------------------------------------------------------------------
  4. #include "stdafx.h"
  5. #include "stroke.h"
  6. #include "mywin.h"
  7.  
  8. //======================================================================
  9. drawing_element::drawing_element( unsigned pen_width )
  10.                                 : width( pen_width )
  11. {}
  12.  
  13. /*virtual*/
  14. drawing_element::~drawing_element(){}
  15. //----------------------------------------------------------------------
  16. void drawing_element::draw_line( device *echo_dc, const CPoint &start, const CPoint &end ) const
  17. {
  18.     CPen new_pen( PS_SOLID, width, RGB(0,0,0) );
  19.  
  20.     CPen *old_pen = echo_dc->SelectObject( &new_pen );
  21.     echo_dc->MoveTo( start );                        
  22.     echo_dc->LineTo( end   );
  23.     echo_dc->SelectObject( old_pen );
  24. }
  25. //----------------------------------------------------------------------
  26. void drawing_element::erase_line( device *echo_dc, const CPoint &start, const CPoint &end ) const
  27. {
  28.     CPen new_pen( PS_SOLID, width, RGB(255,255,255) );
  29.  
  30.     CPen *old_pen = echo_dc->SelectObject( &new_pen );
  31.     echo_dc->MoveTo( start );                        
  32.     echo_dc->LineTo( end   );
  33.     echo_dc->SelectObject( old_pen );
  34. }
  35. //----------------------------------------------------------------------
  36. void drawing_element::adjust_rect_for_pen_width( CRect *bound ) const
  37. {
  38.     bound->InflateRect( width, width );
  39. }
  40. //----------------------------------------------------------------------
  41. /*virtual*/ void drawing_element::Serialize(CArchive& ar)
  42. {
  43.     CObject::Serialize( ar );
  44.  
  45.     if (ar.IsStoring())
  46.     {
  47.         ar << (unsigned short) width;
  48.     }
  49.     else
  50.     {
  51.         unsigned short tmp;
  52.         ar >> tmp;
  53.         width = tmp;
  54.     }
  55. }
  56. //======================================================================
  57. // Stroke
  58. //======================================================================
  59. IMPLEMENT_SERIAL( stroke, CObject, stroke::version );
  60.  
  61. /*virtual*/ stroke::~stroke( void ) {}
  62.  
  63. stroke::stroke( unsigned pen_width )
  64.                             : drawing_element( pen_width    )
  65.                             , bounding         ( 0, 0, 0, 0    )
  66. {}
  67.  
  68. //----------------------------------------------------------------------
  69. // Load functions. The incomming dc should have been ajusted for
  70. // scrolling (origen offset), mapping modes, etc.
  71.  
  72. /*virtual*/ void stroke::start_load( const CPoint &first_point, device *echo_dc )
  73. {
  74.     points.Add( prev_point = first_point );
  75. }
  76.  
  77. /*virtual*/ void stroke::mouse_has_moved( const CPoint &new_point, device *echo_dc )
  78. {
  79.     drawing_element::draw_line( echo_dc, prev_point, new_point );
  80.     points.Add( prev_point = new_point );
  81. }
  82.  
  83. /*virtual*/ int stroke::end_load( const CPoint &new_point, device *echo_dc )
  84. {
  85.     // End the loading process. Return true if an invalidate is
  86.     // needed.
  87.  
  88.     drawing_element::draw_line( echo_dc, prev_point, new_point );
  89.     points.Add( new_point );
  90.     return 0;
  91. }
  92. //----------------------------------------------------------------------
  93. void stroke::draw( device *dc ) const
  94. {
  95.     int npoints  = points.GetSize();
  96.     CPoint start = points[0];
  97.  
  98.     for(int i = 1; i < npoints; ++i )
  99.     {
  100.         drawing_element::draw_line( dc, start, points[i] );
  101.         start = points[i];
  102.     }
  103. }
  104. /*virtual*/ void stroke::render_as_text( device *dc) const
  105. {
  106.     int npoints    = points.GetSize();
  107.     CPoint start   = points[0];
  108.     CString output = "Stroke=";
  109.     CString current;
  110.  
  111.     for(int i = 1; i < npoints; ++i )
  112.     {
  113.         current.Format( "(%d,%d)", start, points[i] );
  114.         output += current;
  115.         start = points[i];
  116.     }
  117.     dc->puts(output);
  118. }
  119. //----------------------------------------------------------------------
  120. /*virtual*/ void stroke::invalidate( CWnd *window ) const
  121. {
  122.     // InvalidateRect is in device units, so we need to translate
  123.  
  124.     device dc( window );
  125.     dc.invalidate_rect( bounding );
  126. }
  127. //----------------------------------------------------------------------
  128. /*virtual*/ unsigned stroke::is_in( CRect region ) const
  129. {
  130.     // Return true if any part of the drawing object intersects
  131.     // the indicated region. This function is an example of one
  132.     // that is "const" from the user's perspective, but not
  133.     // internally.
  134.  
  135.     if( bounding.IsRectNull() )
  136.     {
  137.         // Compute the bounding rectangle. This is done in the
  138.         // finish_stroke() function in Scribble, but it's better
  139.         // done here. This way it's impossible to forget to call
  140.         // it. The IsRectEmpty() overhead is insignificant.
  141.  
  142.         int npoints = points.GetSize();
  143.         
  144.         if( npoints > 0 )
  145.         {
  146.             CRect &bound = ((stroke *)this)->bounding;
  147.             CPoint pt     = points[0];
  148.  
  149.             bound.left      = bound.right = pt.x;
  150.             bound.bottom = bound.top   = pt.y;
  151.  
  152.             for( int i = 1; i < npoints; ++i )
  153.             {
  154.                 pt = points[i];
  155.                 bound.left     = min( bounding.left,     pt.x );
  156.                 bound.top     = min( bounding.top,     pt.y );
  157.                 bound.right     = max( bounding.right,     pt.x );
  158.                 bound.bottom = max( bounding.bottom, pt.y );
  159.  
  160.                 ASSERT( (bounding.top <= bounding.bottom) && (bounding.left <= bounding.right) );
  161.             }
  162.             // Add the pen width
  163.             drawing_element::adjust_rect_for_pen_width( &bound );
  164.         }
  165.     }
  166.     CRect  intersection;
  167.     return intersection.IntersectRect( bounding, region );
  168. }
  169. //----------------------------------------------------------------------
  170. /*virtual*/ void stroke::Serialize( CArchive &ar )
  171. {
  172.     drawing_element::Serialize( ar );
  173.  
  174.     points.Serialize( ar );
  175.     if (ar.IsStoring())
  176.     {
  177.         ar << bounding;
  178.     }
  179.     else
  180.     { 
  181.         ar >> bounding;
  182.     }
  183. }
  184.  
  185. //======================================================================
  186. // Line
  187. //======================================================================
  188. IMPLEMENT_SERIAL( line, CObject, line::version );
  189.  
  190. /*virtual*/ line::~line( void ) {}
  191.  
  192. line::line( unsigned pen_width )
  193.                             : drawing_element( pen_width    )
  194.                             , first( 0, 0 )
  195.                             , last ( 0, 0 )
  196. {}
  197.  
  198. //----------------------------------------------------------------------
  199. // Load functions. The incomming dc should have been ajusted for
  200. // scrolling (origen offset), mapping modes, etc.
  201.  
  202. /*virtual*/ void line::start_load( const CPoint &first_point, device *echo_dc )
  203. {
  204.     first = first_point;
  205.     last  = first_point;
  206. }
  207.  
  208. /*virtual*/ void line::mouse_has_moved( const CPoint &new_point, device *echo_dc )
  209. {
  210.     drawing_element::erase_line( echo_dc, first, last );
  211.     drawing_element::draw_line ( echo_dc, first, last = new_point );
  212. }
  213.  
  214. /*virtual*/ int line::end_load( const CPoint &new_point, device *echo_dc )
  215. {
  216.     drawing_element::erase_line( echo_dc, first, last );
  217.     drawing_element::draw_line ( echo_dc, first, last = new_point );
  218.     return 1;
  219. }
  220. //----------------------------------------------------------------------
  221. void line::draw( device *dc ) const
  222. {
  223.     drawing_element::draw_line( dc, first, last );
  224. }
  225. //----------------------------------------------------------------------
  226. void line::render_as_text( device *dc ) const
  227. {
  228.     CString s;
  229.     s.Format( "Line=(%d,%d)(%d,%d)",
  230.                 first.x, first.y, last.x, last.y );
  231.     dc->puts(s);
  232. }
  233. //----------------------------------------------------------------------
  234. /*virtual*/ void line::invalidate( CWnd *window ) const
  235. {
  236.     CRect bounding ( min( first.x, last.x ),
  237.                      min( first.y, last.y ),
  238.                      max( first.x, last.x ),
  239.                      max( first.y, last.y ) );
  240.  
  241.     drawing_element::adjust_rect_for_pen_width( &bounding );
  242.  
  243.     ASSERT( (bounding.top <= bounding.bottom) && (bounding.left <= bounding.right) );
  244.     
  245.     device dc( window );
  246.     dc.invalidate_rect( bounding );
  247. }
  248. //----------------------------------------------------------------------
  249. /*virtual*/ unsigned line::is_in( CRect region ) const
  250. {
  251.     CRect bounding ( min( first.x, last.x ),
  252.                      min( first.y, last.y ),
  253.                      max( first.x, last.x ),
  254.                      max( first.y, last.y ) );
  255.  
  256.     drawing_element::adjust_rect_for_pen_width( &bounding );
  257.  
  258.     ASSERT( (bounding.top <= bounding.bottom) && (bounding.left <= bounding.right) );
  259.  
  260.     CRect intersection;
  261.     int intersects = intersection.IntersectRect( bounding, region );
  262. //
  263. //    TRACE( "\n" );
  264. //    TRACE( "%-16s (LTRB)(%03d,%03d)(%03d,%03d) region\n", "line::is_in", region.left, region.top, region.right, region.bottom );
  265. //    TRACE( "%-16s (LTRB)(%03d,%03d)(%03d,%03d) LINE  \n", "line::is_in", bounding.left, bounding.top, bounding.right, bounding.bottom );
  266. //    TRACE( "In line:: Rectangles %s intersect\n",      intersects ? "DO" : "DO NOT" );
  267. //
  268.     return intersects;
  269. }
  270. //----------------------------------------------------------------------
  271. /*virtual*/ void line::Serialize( CArchive &ar )
  272. {
  273.     drawing_element::Serialize( ar );
  274.  
  275.     if (ar.IsStoring())
  276.     {
  277.         ar << first;
  278.         ar << last;
  279.     }
  280.     else
  281.     { 
  282.         ar >> first;
  283.         ar >> last;
  284.     }
  285. }
  286.