Commit 4ca6c4fb authored by jean-pierre charras's avatar jean-pierre charras

Eeschema:

* fix incorrect bounding box size calculation of schematic components.
* fix incorrect bounding box position and size used when schematic components are not found in lib (dummy lib componen used).
Pcbnew:
* Fix issues in block selection for arcs in modedit. Minor code cleaning.
CopyToClipboard: fix incorrect call to PrintPage (bad parameters)
parent 38b69092
......@@ -15,9 +15,6 @@
#include "confirm.h"
#include "wxstruct.h"
static const bool s_PlotBlackAndWhite = FALSE;
static const bool Print_Sheet_Ref = TRUE;
static bool DrawPage( EDA_DRAW_FRAME* aFrame );
......@@ -77,11 +74,12 @@ bool DrawPage( EDA_DRAW_FRAME* aFrame )
screen->SetZoom( 1 );
wxMetafileDC dc /*(wxT(""), DrawArea.GetWidth(), DrawArea.GetHeight())*/;
wxMetafileDC dc;
EDA_Rect tmp = aFrame->DrawPanel->m_ClipBox;
GRResetPenAndBrush( &dc );
GRForceBlackPen( s_PlotBlackAndWhite );
const bool plotBlackAndWhite = FALSE;
GRForceBlackPen( plotBlackAndWhite );
screen->m_IsPrinting = true;
dc.SetUserScale( scale, scale );
ClipboardSizeX = dc.MaxX() + 10;
......@@ -96,7 +94,8 @@ bool DrawPage( EDA_DRAW_FRAME* aFrame )
dc.SetClippingRegion( DrawArea );
}
aFrame->PrintPage( &dc, Print_Sheet_Ref, -1, false );
const int maskLayer = 0xFFFFFFFF;
aFrame->PrintPage( &dc, maskLayer, false );
screen->m_IsPrinting = false;
aFrame->DrawPanel->m_ClipBox = tmp;
wxMetafile* mf = dc.Close();
......
......@@ -959,15 +959,13 @@ bool LIB_COMPONENT::LoadFootprints( FILE* aFile, char* aLine,
return true;
}
/**********************************************************************/
/* Return the component boundary box ( in user coordinates )
* The unit aUnit, and the shape aConvert are considered.
* aUnit = unit selection = 0, or 1..n
* aConvert = 0, 1 or 2
* If aUnit == 0, unit is not used
* if aConvert == 0 Convert is non used
* Invisible fields are not take in account
* Invisible fields are not taken in account
**/
/**********************************************************************/
EDA_Rect LIB_COMPONENT::GetBoundingBox( int aUnit, int aConvert ) const
{
EDA_Rect bBox( wxPoint( 0, 0 ), wxSize( 0, 0 ) );
......@@ -991,6 +989,36 @@ EDA_Rect LIB_COMPONENT::GetBoundingBox( int aUnit, int aConvert ) const
}
/* Return the component boundary box ( in user coordinates )
* aUnit = unit selection = 0, or 1..n
* aConvert = 0, 1 or 2
* If aUnit == 0, unit is not used
* if aConvert == 0 Convert is non used
* Fields are not take in account
**/
EDA_Rect LIB_COMPONENT::GetBodyBoundingBox( int aUnit, int aConvert ) const
{
EDA_Rect bBox( wxPoint( 0, 0 ), wxSize( 0, 0 ) );
BOOST_FOREACH( const LIB_DRAW_ITEM& item, drawings )
{
if( ( item.m_Unit > 0 ) && ( ( m_unitCount > 1 ) && ( aUnit > 0 )
&& ( aUnit != item.m_Unit ) ) )
continue;
if( item.m_Convert > 0 && ( ( aConvert > 0 ) && ( aConvert != item.m_Convert ) ) )
continue;
if ( item.Type() == LIB_FIELD_T )
continue;
bBox.Merge( item.GetBoundingBox() );
}
return bBox;
}
void LIB_COMPONENT::deleteAllFields()
{
LIB_DRAW_ITEM_LIST::iterator it;
......
......@@ -233,8 +233,28 @@ public:
wxArrayString& GetFootPrints() { return m_FootprintList; }
/**
* Function GetBoundingBox
* @return the component boundary box ( in user coordinates )
* @param aUnit = unit selection = 0, or 1..n
* @param aConvert = 0, 1 or 2
* If aUnit == 0, unit is not used
* if aConvert == 0 Convert is non used
* Invisible fields are not taken in account
**/
EDA_Rect GetBoundingBox( int aUnit, int aConvert ) const;
/**
* Function GetBodyBoundingBox
* @return the component boundary box ( in user coordinates ) without fields
* @param aUnit = unit selection = 0, or 1..n
* @param aConvert = 0, 1 or 2
* If aUnit == 0, unit is not used
* if aConvert == 0 Convert is non used
* Fields are not taken in account
**/
EDA_Rect GetBodyBoundingBox( int aUnit, int aConvert ) const;
bool SaveDateAndTime( FILE* aFile );
bool LoadDateAndTime( char* aLine );
......
......@@ -1360,10 +1360,14 @@ EDA_Rect SCH_COMPONENT::GetBodyBoundingBox() const
int x0, xm, y0, ym;
if( Entry == NULL )
return EDA_Rect( wxPoint( 0, 0 ), wxSize( 0, 0 ) );
{
if( DummyCmp == NULL )
CreateDummyCmp();
Entry = DummyCmp;
}
/* Get the basic Boundary box */
bBox = Entry->GetBoundingBox( m_unit, m_convert );
bBox = Entry->GetBodyBoundingBox( m_unit, m_convert );
x0 = bBox.GetX();
xm = bBox.GetRight();
......
......@@ -667,14 +667,7 @@ int MarkItemsInBloc( MODULE* module, EDA_Rect& Rect )
switch( item->Type() )
{
case TYPE_EDGE_MODULE:
pos = ( (EDGE_MODULE*) item )->m_Start;
if( Rect.Contains( pos ) )
{
item->m_Selected = IS_SELECTED;
ItemsCount++;
}
pos = ( (EDGE_MODULE*) item )->m_End;
if( Rect.Contains( pos ) )
if( ((EDGE_MODULE*)item )->HitTest( Rect ) )
{
item->m_Selected = IS_SELECTED;
ItemsCount++;
......
......@@ -204,19 +204,17 @@ wxPoint DRAWSEGMENT::GetStart() const
wxPoint DRAWSEGMENT::GetEnd() const
{
wxPoint center; // center point of the arc
wxPoint start; // start of arc
wxPoint endPoint; // start of arc
switch( m_Shape )
{
case S_ARC:
// rotate the starting point of the arc, given by m_End, through the
// angle m_Angle to get the ending point of the arc.
center = m_Start; // center point of the arc
start = m_End; // start of arc
RotatePoint( &start.x, &start.y, center.x, center.y, -m_Angle );
return start; // after rotation, the end of the arc.
// m_Start is the arc centre
endPoint = m_End; // m_End = start point of arc
RotatePoint( &endPoint, m_Start, -m_Angle );
return endPoint; // after rotation, the end of the arc.
break;
case S_SEGMENT:
......@@ -417,33 +415,25 @@ void DRAWSEGMENT::DisplayInfo( EDA_DRAW_FRAME* frame )
*/
bool DRAWSEGMENT::HitTest( const wxPoint& aRefPos )
{
int ux0 = m_Start.x;
int uy0 = m_Start.y;
/* Calculate coordinates with ux0, uy0 = origin. */
int dx = m_End.x - ux0;
int dy = m_End.y - uy0;
int spot_cX = aRefPos.x - ux0;
int spot_cY = aRefPos.y - uy0;
/* Calculate coordinates to test relative to segment origin. */
wxPoint relPos = aRefPos - m_Start;
switch(m_Shape){
switch(m_Shape)
{
case S_CIRCLE:
case S_ARC:
int rayon, dist, stAngle, endAngle, mouseAngle;
rayon = (int) hypot( (double) (dx), (double) (dy) );
dist = (int) hypot( (double) (spot_cX), (double) (spot_cY) );
{
int rayon = GetRadius();
int dist = (int) hypot( (double) relPos.x, (double) relPos.y );
if( abs( rayon - dist ) <= ( m_Width / 2 ) )
{
if( m_Shape == S_CIRCLE )
return true;
mouseAngle = (int) ArcTangente( spot_cY, spot_cX );
stAngle = (int) ArcTangente( dy, dx );
endAngle = stAngle + m_Angle;
int mouseAngle = ArcTangente( relPos.y, relPos.x );
int stAngle = ArcTangente( m_End.y - m_Start.y, m_End.x - m_Start.x );
int endAngle = stAngle + m_Angle;
if( endAngle > 3600 )
{
......@@ -454,6 +444,7 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aRefPos )
if( mouseAngle >= stAngle && mouseAngle <= endAngle )
return true;
}
}
break;
case S_CURVE:
......@@ -464,8 +455,9 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aRefPos )
return true;
}
break;
default:
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
if( TestSegmentHit( aRefPos, m_Start, m_End, m_Width / 2 ) )
return true;
}
return false;
......@@ -475,16 +467,33 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aRefPos )
/**
* Function HitTest (overlayed)
* tests if the given EDA_Rect intersect this object.
* For now, an ending point must be inside this rect.
* For now, for arcs and segments, an ending point must be inside this rect.
* @param refArea : the given EDA_Rect
* @return bool - true if a hit, else false
*/
bool DRAWSEGMENT::HitTest( EDA_Rect& refArea )
{
if( refArea.Contains( m_Start ) )
return true;
if( refArea.Contains( m_End ) )
return true;
switch(m_Shape)
{
case S_CIRCLE:
{
int radius = GetRadius();
// Text if area intersects the circle:
EDA_Rect area = refArea;
area.Inflate(radius);
if( area.Contains(m_Start) )
return true;
}
break;
case S_ARC:
case S_SEGMENT:
if( refArea.Contains( GetStart() ) )
return true;
if( refArea.Contains( GetEnd() ) )
return true;
break;
}
return false;
}
......
......@@ -52,6 +52,17 @@ public:
*/
wxPoint GetEnd() const;
/**
* Function GetRadius
* returns the radius of this item
* Has meaning only for arc and circle
*/
int GetRadius() const
{
double radius = hypot( (double) (m_End.x - m_Start.x), (double) (m_End.y - m_Start.y) );
return wxRound(radius);
}
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
......
......@@ -26,7 +26,6 @@
EDGE_MODULE::EDGE_MODULE( MODULE* parent ) :
BOARD_ITEM( parent, TYPE_EDGE_MODULE )
{
m_Width = 0;
m_Shape = S_SEGMENT;
m_Angle = 0;
m_Width = 120;
......@@ -77,16 +76,12 @@ EDA_Rect EDGE_MODULE::GetBoundingBox() const
break;
case S_CIRCLE:
{
int rayon = (int) hypot( (double) (m_End.x - m_Start.x), (double) (m_End.y - m_Start.y) );
bbox.Inflate( rayon + 1 );
}
break;
bbox.Inflate( GetRadius() + 1 );
break;
case S_ARC:
{
int rayon = (int) hypot( (double) (m_End.x - m_Start.x), (double) (m_End.y - m_Start.y) );
bbox.Inflate( rayon + 1 );
bbox.Inflate( GetRadius() + 1 );
}
break;
......@@ -489,6 +484,42 @@ int EDGE_MODULE::ReadDescr( LINE_READER* aReader )
}
wxPoint EDGE_MODULE::GetStart() const
{
switch( m_Shape )
{
case S_ARC:
return m_End; // the start of the arc is held in field m_End, center point is in m_Start.
case S_SEGMENT:
default:
return m_Start;
}
}
wxPoint EDGE_MODULE::GetEnd() const
{
wxPoint endPoint; // start of arc
switch( m_Shape )
{
case S_ARC:
// rotate the starting point of the arc, given by m_End, through the
// angle m_Angle to get the ending point of the arc.
// m_Start is the arc centre
endPoint = m_End; // m_End = start point of arc
RotatePoint( &endPoint, m_Start, -m_Angle );
return endPoint; // after rotation, the end of the arc.
break;
case S_SEGMENT:
default:
return m_End;
}
}
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
......@@ -497,47 +528,31 @@ int EDGE_MODULE::ReadDescr( LINE_READER* aReader )
*/
bool EDGE_MODULE::HitTest( const wxPoint& refPos )
{
int uxf, uyf;
int rayon, dist;
int dx, dy, spot_cX, spot_cY;
int ux0, uy0;
ux0 = m_Start.x;
uy0 = m_Start.y;
uxf = m_End.x;
uyf = m_End.y;
switch( m_Shape )
{
case S_SEGMENT:
spot_cX = refPos.x - ux0;
spot_cY = refPos.y - uy0;
dx = uxf - ux0;
dy = uyf - uy0;
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
if( TestSegmentHit( refPos, m_Start, m_End, m_Width / 2 ) )
return true;
break;
case S_CIRCLE:
rayon = (int) hypot( (double) (uxf - ux0), (double) (uyf - uy0) );
dist = (int) hypot( (double) (refPos.x - ux0),
(double) (refPos.y - uy0) );
if( abs( rayon - dist ) <= m_Width )
rayon = GetRadius();
dist = (int) hypot( (double) (refPos.x - m_Start.x), (double) (refPos.y - m_Start.y) );
if( abs( rayon - dist ) <= (m_Width/2) )
return true;
break;
case S_ARC:
rayon = (int) hypot( (double) (uxf - ux0), (double) (uyf - uy0) );
dist = (int) hypot( (double) (refPos.x - ux0),
(double) (refPos.y - uy0) );
rayon = GetRadius();
dist = (int) hypot( (double) (refPos.x - m_Start.x), (double) (refPos.y - m_Start.y) );
if( abs( rayon - dist ) > m_Width )
if( abs( rayon - dist ) > (m_Width/2) )
break;
int mouseAngle = (int) ArcTangente( refPos.y - uy0, refPos.x - ux0 );
int stAngle = (int) ArcTangente( uyf - uy0, uxf - ux0 );
int mouseAngle = ArcTangente( refPos.y - m_Start.y, refPos.x - m_Start.x );
int stAngle = ArcTangente( m_End.y - m_Start.y, m_End.x - m_Start.x );
int endAngle = stAngle + m_Angle;
if( endAngle > 3600 )
......@@ -556,6 +571,39 @@ bool EDGE_MODULE::HitTest( const wxPoint& refPos )
}
/**
* Function HitTest (overlayed)
* tests if the given EDA_Rect intersect this object.
* For now, for arcs and segments, an ending point must be inside this rect.
* @param refArea : the given EDA_Rect
* @return bool - true if a hit, else false
*/
bool EDGE_MODULE::HitTest( EDA_Rect& refArea )
{
switch(m_Shape)
{
case S_CIRCLE:
{
int radius = GetRadius();
// Test if area intersects the circle:
EDA_Rect area = refArea;
area.Inflate(radius);
if( area.Contains(m_Start) )
return true;
}
break;
case S_ARC:
case S_SEGMENT:
if( refArea.Contains( GetStart() ) )
return true;
if( refArea.Contains( GetEnd() ) )
return true;
break;
}
return false;
}
#if defined(DEBUG)
......
......@@ -11,8 +11,8 @@ class EDGE_MODULE : public BOARD_ITEM
{
public:
int m_Width; // 0 = line, > 0 = tracks, bus ...
wxPoint m_Start; // Line start point / circle and arc center
wxPoint m_End; // Line end point / circle and arc starting point
wxPoint m_Start; // Line start point and circle and arc center
wxPoint m_End; // Line end point and circle and arc starting point
int m_Shape; // enum Track_Shapes
wxPoint m_Start0; // Start point or centre, relative to module origin, orient 0.
......@@ -44,6 +44,28 @@ public:
return m_Start;
}
/**
* Function GetStart
* returns the starting point of the graphic
*/
wxPoint GetStart() const;
/**
* Function GetEnd
* returns the ending point of the graphic
*/
wxPoint GetEnd() const;
/**
* Function GetRadius
* returns the radius of this item
* Has meaning only for arc and circle
*/
int GetRadius() const
{
double radius = hypot( (double) (m_End.x - m_Start.x), (double) (m_End.y - m_Start.y) );
return wxRound(radius);
}
void Copy( EDGE_MODULE* source ); // copy structure
......@@ -92,6 +114,15 @@ public:
*/
bool HitTest( const wxPoint& refPos );
/**
* Function HitTest (overlayed)
* tests if the given EDA_Rect intersect this object.
* For now, for segments and arcs, an ending point must be inside this rect.
* @param refArea the given EDA_Rect to test
* @return bool - true if a hit, else false
*/
bool HitTest( EDA_Rect& refArea );
/**
* Function GetClass
* returns the class name.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment