home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Troubleshooting Netware Systems
/
CSTRIAL0196.BIN
/
attach
/
msj
/
v10n08
/
sketchsc.exe
/
STROKE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-01
|
9KB
|
286 lines
//-----------------------------------------------------------------------
// STROKE.CPP: Drawing objects: drawing_element, stroke, line
//-----------------------------------------------------------------------
#include "stdafx.h"
#include "stroke.h"
#include "mywin.h"
//======================================================================
drawing_element::drawing_element( unsigned pen_width )
: width( pen_width )
{}
/*virtual*/
drawing_element::~drawing_element(){}
//----------------------------------------------------------------------
void drawing_element::draw_line( device *echo_dc, const CPoint &start, const CPoint &end ) const
{
CPen new_pen( PS_SOLID, width, RGB(0,0,0) );
CPen *old_pen = echo_dc->SelectObject( &new_pen );
echo_dc->MoveTo( start );
echo_dc->LineTo( end );
echo_dc->SelectObject( old_pen );
}
//----------------------------------------------------------------------
void drawing_element::erase_line( device *echo_dc, const CPoint &start, const CPoint &end ) const
{
CPen new_pen( PS_SOLID, width, RGB(255,255,255) );
CPen *old_pen = echo_dc->SelectObject( &new_pen );
echo_dc->MoveTo( start );
echo_dc->LineTo( end );
echo_dc->SelectObject( old_pen );
}
//----------------------------------------------------------------------
void drawing_element::adjust_rect_for_pen_width( CRect *bound ) const
{
bound->InflateRect( width, width );
}
//----------------------------------------------------------------------
/*virtual*/ void drawing_element::Serialize(CArchive& ar)
{
CObject::Serialize( ar );
if (ar.IsStoring())
{
ar << (unsigned short) width;
}
else
{
unsigned short tmp;
ar >> tmp;
width = tmp;
}
}
//======================================================================
// Stroke
//======================================================================
IMPLEMENT_SERIAL( stroke, CObject, stroke::version );
/*virtual*/ stroke::~stroke( void ) {}
stroke::stroke( unsigned pen_width )
: drawing_element( pen_width )
, bounding ( 0, 0, 0, 0 )
{}
//----------------------------------------------------------------------
// Load functions. The incomming dc should have been ajusted for
// scrolling (origen offset), mapping modes, etc.
/*virtual*/ void stroke::start_load( const CPoint &first_point, device *echo_dc )
{
points.Add( prev_point = first_point );
}
/*virtual*/ void stroke::mouse_has_moved( const CPoint &new_point, device *echo_dc )
{
drawing_element::draw_line( echo_dc, prev_point, new_point );
points.Add( prev_point = new_point );
}
/*virtual*/ int stroke::end_load( const CPoint &new_point, device *echo_dc )
{
// End the loading process. Return true if an invalidate is
// needed.
drawing_element::draw_line( echo_dc, prev_point, new_point );
points.Add( new_point );
return 0;
}
//----------------------------------------------------------------------
void stroke::draw( device *dc ) const
{
int npoints = points.GetSize();
CPoint start = points[0];
for(int i = 1; i < npoints; ++i )
{
drawing_element::draw_line( dc, start, points[i] );
start = points[i];
}
}
/*virtual*/ void stroke::render_as_text( device *dc) const
{
int npoints = points.GetSize();
CPoint start = points[0];
CString output = "Stroke=";
CString current;
for(int i = 1; i < npoints; ++i )
{
current.Format( "(%d,%d)", start, points[i] );
output += current;
start = points[i];
}
dc->puts(output);
}
//----------------------------------------------------------------------
/*virtual*/ void stroke::invalidate( CWnd *window ) const
{
// InvalidateRect is in device units, so we need to translate
device dc( window );
dc.invalidate_rect( bounding );
}
//----------------------------------------------------------------------
/*virtual*/ unsigned stroke::is_in( CRect region ) const
{
// Return true if any part of the drawing object intersects
// the indicated region. This function is an example of one
// that is "const" from the user's perspective, but not
// internally.
if( bounding.IsRectNull() )
{
// Compute the bounding rectangle. This is done in the
// finish_stroke() function in Scribble, but it's better
// done here. This way it's impossible to forget to call
// it. The IsRectEmpty() overhead is insignificant.
int npoints = points.GetSize();
if( npoints > 0 )
{
CRect &bound = ((stroke *)this)->bounding;
CPoint pt = points[0];
bound.left = bound.right = pt.x;
bound.bottom = bound.top = pt.y;
for( int i = 1; i < npoints; ++i )
{
pt = points[i];
bound.left = min( bounding.left, pt.x );
bound.top = min( bounding.top, pt.y );
bound.right = max( bounding.right, pt.x );
bound.bottom = max( bounding.bottom, pt.y );
ASSERT( (bounding.top <= bounding.bottom) && (bounding.left <= bounding.right) );
}
// Add the pen width
drawing_element::adjust_rect_for_pen_width( &bound );
}
}
CRect intersection;
return intersection.IntersectRect( bounding, region );
}
//----------------------------------------------------------------------
/*virtual*/ void stroke::Serialize( CArchive &ar )
{
drawing_element::Serialize( ar );
points.Serialize( ar );
if (ar.IsStoring())
{
ar << bounding;
}
else
{
ar >> bounding;
}
}
//======================================================================
// Line
//======================================================================
IMPLEMENT_SERIAL( line, CObject, line::version );
/*virtual*/ line::~line( void ) {}
line::line( unsigned pen_width )
: drawing_element( pen_width )
, first( 0, 0 )
, last ( 0, 0 )
{}
//----------------------------------------------------------------------
// Load functions. The incomming dc should have been ajusted for
// scrolling (origen offset), mapping modes, etc.
/*virtual*/ void line::start_load( const CPoint &first_point, device *echo_dc )
{
first = first_point;
last = first_point;
}
/*virtual*/ void line::mouse_has_moved( const CPoint &new_point, device *echo_dc )
{
drawing_element::erase_line( echo_dc, first, last );
drawing_element::draw_line ( echo_dc, first, last = new_point );
}
/*virtual*/ int line::end_load( const CPoint &new_point, device *echo_dc )
{
drawing_element::erase_line( echo_dc, first, last );
drawing_element::draw_line ( echo_dc, first, last = new_point );
return 1;
}
//----------------------------------------------------------------------
void line::draw( device *dc ) const
{
drawing_element::draw_line( dc, first, last );
}
//----------------------------------------------------------------------
void line::render_as_text( device *dc ) const
{
CString s;
s.Format( "Line=(%d,%d)(%d,%d)",
first.x, first.y, last.x, last.y );
dc->puts(s);
}
//----------------------------------------------------------------------
/*virtual*/ void line::invalidate( CWnd *window ) const
{
CRect bounding ( min( first.x, last.x ),
min( first.y, last.y ),
max( first.x, last.x ),
max( first.y, last.y ) );
drawing_element::adjust_rect_for_pen_width( &bounding );
ASSERT( (bounding.top <= bounding.bottom) && (bounding.left <= bounding.right) );
device dc( window );
dc.invalidate_rect( bounding );
}
//----------------------------------------------------------------------
/*virtual*/ unsigned line::is_in( CRect region ) const
{
CRect bounding ( min( first.x, last.x ),
min( first.y, last.y ),
max( first.x, last.x ),
max( first.y, last.y ) );
drawing_element::adjust_rect_for_pen_width( &bounding );
ASSERT( (bounding.top <= bounding.bottom) && (bounding.left <= bounding.right) );
CRect intersection;
int intersects = intersection.IntersectRect( bounding, region );
//
// TRACE( "\n" );
// TRACE( "%-16s (LTRB)(%03d,%03d)(%03d,%03d) region\n", "line::is_in", region.left, region.top, region.right, region.bottom );
// TRACE( "%-16s (LTRB)(%03d,%03d)(%03d,%03d) LINE \n", "line::is_in", bounding.left, bounding.top, bounding.right, bounding.bottom );
// TRACE( "In line:: Rectangles %s intersect\n", intersects ? "DO" : "DO NOT" );
//
return intersects;
}
//----------------------------------------------------------------------
/*virtual*/ void line::Serialize( CArchive &ar )
{
drawing_element::Serialize( ar );
if (ar.IsStoring())
{
ar << first;
ar << last;
}
else
{
ar >> first;
ar >> last;
}
}