EDA_RECT SCH_FIELD::GetBoundingBox() const { SCH_COMPONENT* parentComponent = (SCH_COMPONENT*) m_Parent; int linewidth = ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness; // We must pass the effective text thickness to GetTextBox // when calculating the bounding box linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold ); // Calculate the text bounding box: EDA_RECT rect; // set USE_TEXT_JUSTIFY_INITIAL_BEHAVIOR to 0 to use // a justification relative to the text itself // i.e. justification relative to an horizontal text // or to 1 to keep the initial behavior #if (USE_TEXT_JUSTIFY_INITIAL_BEHAVIOR == 1 ) if( m_Orient == TEXT_ORIENT_VERT ) { // For vertical texts, exchange the horizontal and the vertical justification // The idea is to keep the justification always left or top for instance, // no matter the text orientation SCH_FIELD text( *this ); // Make a local copy to swap justifications // because GetBoundingBox() is const int tmp = (int)text.m_VJustify; NEGATE( tmp ); text.m_VJustify = (EDA_TEXT_VJUSTIFY_T)text.m_HJustify; text.m_HJustify = (EDA_TEXT_HJUSTIFY_T)tmp; rect = text.GetTextBox( -1, linewidth ); } else #endif rect = GetTextBox( -1, linewidth ); // Calculate the bounding box position relative to the component: wxPoint origin = parentComponent->GetPosition(); wxPoint pos = m_Pos - origin; wxPoint begin = rect.GetOrigin() - origin; wxPoint end = rect.GetEnd() - origin; RotatePoint( &begin, pos, m_Orient ); RotatePoint( &end, pos, m_Orient ); // Due to the Y axis direction, we must mirror the bounding box, // relative to the text position: begin.y -= pos.y; end.y -= pos.y; NEGATE( begin.y ); NEGATE( end.y ); begin.y += pos.y; end.y += pos.y; // Now, apply the component transform (mirror/rot) begin = parentComponent->GetTransform().TransformCoordinate( begin ); end = parentComponent->GetTransform().TransformCoordinate( end ); rect.SetOrigin( begin); rect.SetEnd( end); rect.Move( origin ); rect.Normalize(); return rect; }
const EDA_RECT SCH_TEXT::GetBoundingBox() const { // We must pass the effective text thickness to GetTextBox // when calculating the bounding box int linewidth = GetThickness() == 0 ? GetDefaultLineThickness() : GetThickness(); linewidth = Clamp_Text_PenSize( linewidth, GetTextSize(), IsBold() ); EDA_RECT rect = GetTextBox( -1, linewidth ); if( GetTextAngle() != 0 ) // Rotate rect { wxPoint pos = rect.GetOrigin(); wxPoint end = rect.GetEnd(); RotatePoint( &pos, GetTextPos(), GetTextAngle() ); RotatePoint( &end, GetTextPos(), GetTextAngle() ); rect.SetOrigin( pos ); rect.SetEnd( end ); } rect.Normalize(); return rect; }
EDA_RECT ZONE_CONTAINER::CalculateSubAreaBoundaryBox( int aIndexStart, int aIndexEnd ) { CPolyPt start_point, end_point; EDA_RECT bbox; start_point = m_FilledPolysList[aIndexStart]; end_point = start_point; for( int ii = aIndexStart; ii <= aIndexEnd; ii++ ) { CPolyPt ptst = m_FilledPolysList[ii]; if( start_point.x > ptst.x ) start_point.x = ptst.x; if( start_point.y > ptst.y ) start_point.y = ptst.y; if( end_point.x < ptst.x ) end_point.x = ptst.x; if( end_point.y < ptst.y ) end_point.y = ptst.y; } bbox.SetOrigin( start_point.x, start_point.y ); bbox.SetEnd( wxPoint( end_point.x, end_point.y ) ); return bbox; }
/* Calculate the bounding box of this, when rotated */ const EDA_RECT EDA_RECT::GetBoundingBoxRotated( wxPoint aRotCenter, double aAngle ) { wxPoint corners[4]; // Build the corners list corners[0] = GetOrigin(); corners[2] = GetEnd(); corners[1].x = corners[0].x; corners[1].y = corners[2].y; corners[3].x = corners[2].x; corners[3].y = corners[0].y; // Rotate all corners, to find the bounding box for( int ii = 0; ii < 4; ii ++ ) RotatePoint( &corners[ii], aRotCenter, aAngle ); // Find the corners bounding box wxPoint start = corners[0]; wxPoint end = corners[0]; for( int ii = 1; ii < 4; ii ++ ) { start.x = std::min( start.x, corners[ii].x); start.y = std::min( start.y, corners[ii].y); end.x = std::max( end.x, corners[ii].x); end.y = std::max( end.y, corners[ii].y); } EDA_RECT bbox; bbox.SetOrigin( start ); bbox.SetEnd( end ); return bbox; }
const EDA_RECT LIB_BEZIER::GetBoundingBox() const { EDA_RECT rect; int xmin, xmax, ymin, ymax; if( !GetCornerCount() ) return rect; xmin = xmax = m_PolyPoints[0].x; ymin = ymax = m_PolyPoints[0].y; for( unsigned ii = 1; ii < GetCornerCount(); ii++ ) { xmin = std::min( xmin, m_PolyPoints[ii].x ); xmax = std::max( xmax, m_PolyPoints[ii].x ); ymin = std::min( ymin, m_PolyPoints[ii].y ); ymax = std::max( ymax, m_PolyPoints[ii].y ); } rect.SetOrigin( xmin, ymin ); rect.SetEnd( xmax, ymax ); rect.Inflate( ( GetPenSize()+1 ) / 2 ); rect.RevertYAxis(); return rect; }
EDA_RECT LIB_RECTANGLE::GetBoundingBox() const { EDA_RECT rect; rect.SetOrigin( m_Pos.x, m_Pos.y * -1 ); rect.SetEnd( m_End.x, m_End.y * -1 ); rect.Inflate( (GetPenSize() / 2) + 1 ); return rect; }
bool ZONE_CONTAINER::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { EDA_RECT arect = aRect; arect.Inflate( aAccuracy ); CRect rect = m_Poly->GetBoundingBox(); EDA_RECT bbox; bbox.SetOrigin( rect.left, rect.bottom ); bbox.SetEnd( rect.right, rect.top ); if( aContained ) return arect.Contains( bbox ); else // Test for intersection between aRect and the polygon // For a polygon, using its bounding box has no sense here { // Fast test: if aRect is outside the polygon bounding box, // rectangles cannot intersect if( ! bbox.Intersects( arect ) ) return false; // aRect is inside the polygon bounding box, // and can intersect the polygon: use a fine test. // aRect intersects the polygon if at least one aRect corner // is inside the polygon wxPoint corner = arect.GetOrigin(); if( HitTestInsideZone( corner ) ) return true; corner.x = arect.GetEnd().x; if( HitTestInsideZone( corner ) ) return true; corner = arect.GetEnd(); if( HitTestInsideZone( corner ) ) return true; corner.x = arect.GetOrigin().x; if( HitTestInsideZone( corner ) ) return true; // No corner inside arect, but outlines can intersect arect // if one of outline corners is inside arect int count = m_Poly->GetCornersCount(); for( int ii =0; ii < count; ii++ ) { if( arect.Contains( m_Poly->GetPos( ii ) ) ) return true; } return false; } }
const EDA_RECT LIB_CIRCLE::GetBoundingBox() const { EDA_RECT rect; rect.SetOrigin( m_Pos.x - m_Radius, ( m_Pos.y - m_Radius ) * -1 ); rect.SetEnd( m_Pos.x + m_Radius, ( m_Pos.y + m_Radius ) * -1 ); rect.Inflate( m_Width / 2, m_Width / 2 ); return rect; }
void LIB_FIELD::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData, const TRANSFORM& aTransform ) { wxPoint text_pos; int color; int linewidth = GetPenSize(); if( m_Bold ) linewidth = GetPenSizeForBold( m_Size.x ); else linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold ); if( ( m_Attributs & TEXT_NO_VISIBLE ) && ( aColor < 0 ) ) { color = GetInvisibleItemColor(); } else if( IsSelected() && ( aColor < 0 ) ) { color = GetItemSelectedColor(); } else { color = aColor; } if( color < 0 ) color = GetDefaultColor(); text_pos = aTransform.TransformCoordinate( m_Pos ) + aOffset; wxString text; if( aData ) text = *(wxString*)aData; else text = m_Text; GRSetDrawMode( aDC, aDrawMode ); EDA_RECT* clipbox = aPanel? aPanel->GetClipBox() : NULL; DrawGraphicText( clipbox, aDC, text_pos, (EDA_COLOR_T) color, text, m_Orient, m_Size, m_HJustify, m_VJustify, linewidth, m_Italic, m_Bold ); /* Set to one (1) to draw bounding box around field text to validate * bounding box calculation. */ #if 0 EDA_RECT bBox = GetBoundingBox(); EDA_RECT grBox; grBox.SetOrigin( aTransform.TransformCoordinate( bBox.GetOrigin() ) ); grBox.SetEnd( aTransform.TransformCoordinate( bBox.GetEnd() ) ); grBox.Move( aOffset ); GRRect( clipbox, aDC, grBox, 0, LIGHTMAGENTA ); #endif }
const EDA_RECT LIB_RECTANGLE::GetBoundingBox() const { EDA_RECT rect; rect.SetOrigin( m_Pos ); rect.SetEnd( m_End ); rect.Inflate( ( GetPenSize()+1 ) / 2 ); rect.RevertYAxis(); return rect; }
const EDA_RECT SCH_BUS_ENTRY_BASE::GetBoundingBox() const { EDA_RECT box; box.SetOrigin( m_pos ); box.SetEnd( m_End() ); box.Normalize(); box.Inflate( GetPenSize() / 2 ); return box; }
const EDA_RECT LIB_CIRCLE::GetBoundingBox() const { EDA_RECT rect; rect.SetOrigin( m_Pos.x - m_Radius, m_Pos.y - m_Radius ); rect.SetEnd( m_Pos.x + m_Radius, m_Pos.y + m_Radius ); rect.Inflate( ( GetPenSize()+1 ) / 2 ); rect.RevertYAxis(); return rect; }
EDA_RECT SCH_BUS_ENTRY::GetBoundingBox() const { EDA_RECT box; box.SetOrigin( m_pos ); box.SetEnd( m_End() ); box.Normalize(); int width = ( m_width == 0 ) ? GetDefaultLineThickness() : m_width; box.Inflate( width / 2 ); return box; }
EDA_RECT PCB_BASE_FRAME::GetBoardBoundingBox( bool aBoardEdgesOnly ) const { wxASSERT( m_Pcb ); EDA_RECT area = m_Pcb->ComputeBoundingBox( aBoardEdgesOnly ); if( area.GetWidth() == 0 && area.GetHeight() == 0 ) { wxSize pageSize = GetPageSizeIU(); if( m_showBorderAndTitleBlock ) { area.SetOrigin( 0, 0 ); area.SetEnd( pageSize.x, pageSize.y ); } else { area.SetOrigin( -pageSize.x / 2, -pageSize.y / 2 ); area.SetEnd( pageSize.x / 2, pageSize.y / 2 ); } } return area; }
const EDA_RECT SCH_FIELD::GetBoundingBox() const { SCH_COMPONENT* parentComponent = (SCH_COMPONENT*) m_Parent; int linewidth = ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness; // We must pass the effective text thickness to GetTextBox // when calculating the bounding box linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold ); // Calculate the text bounding box: EDA_RECT rect; if( m_id == REFERENCE ) // multi units have one letter or more added to reference { SCH_FIELD text( *this ); // Make a local copy to change text // because GetBoundingBox() is const text.SetText( GetFullyQualifiedText() ); rect = text.GetTextBox( -1, linewidth ); } else rect = GetTextBox( -1, linewidth ); // Calculate the bounding box position relative to the component: wxPoint origin = parentComponent->GetPosition(); wxPoint pos = m_Pos - origin; wxPoint begin = rect.GetOrigin() - origin; wxPoint end = rect.GetEnd() - origin; RotatePoint( &begin, pos, m_Orient ); RotatePoint( &end, pos, m_Orient ); // Due to the Y axis direction, we must mirror the bounding box, // relative to the text position: begin.y -= pos.y; end.y -= pos.y; NEGATE( begin.y ); NEGATE( end.y ); begin.y += pos.y; end.y += pos.y; // Now, apply the component transform (mirror/rot) begin = parentComponent->GetTransform().TransformCoordinate( begin ); end = parentComponent->GetTransform().TransformCoordinate( end ); rect.SetOrigin( begin); rect.SetEnd( end); rect.Move( origin ); rect.Normalize(); return rect; }
EDA_RECT LIB_TEXT::GetBoundingBox() const { /* Y coordinates for LIB_ITEMS are bottom to top, so we must invert the Y position when * calling GetTextBox() that works using top to bottom Y axis orientation. */ EDA_RECT rect = GetTextBox( -1, -1, true ); wxPoint orig = rect.GetOrigin(); wxPoint end = rect.GetEnd(); NEGATE( orig.y); NEGATE( end.y); RotatePoint( &orig, m_Pos, -m_Orient ); RotatePoint( &end, m_Pos, -m_Orient ); rect.SetOrigin( orig ); rect.SetEnd( end ); rect.Normalize(); return rect; }
EDA_RECT MODULE::GetFootprintRect() const { EDA_RECT area; area.SetOrigin( m_Pos ); area.SetEnd( m_Pos ); area.Inflate( Millimeter2iu( 0.25 ) ); // Give a min size to the area for( const BOARD_ITEM* item = m_Drawings.GetFirst(); item; item = item->Next() ) { const EDGE_MODULE *edge = dynamic_cast<const EDGE_MODULE*>( item ); if( edge ) area.Merge( edge->GetBoundingBox() ); } for( D_PAD* pad = m_Pads; pad; pad = pad->Next() ) area.Merge( pad->GetBoundingBox() ); return area; }
const EDA_RECT CPolyLine::GetBoundingBox() { int xmin = INT_MAX; int ymin = INT_MAX; int xmax = INT_MIN; int ymax = INT_MIN; for( unsigned i = 0; i< m_CornersList.GetCornersCount(); i++ ) { xmin = std::min( xmin, m_CornersList[i].x ); xmax = std::max( xmax, m_CornersList[i].x ); ymin = std::min( ymin, m_CornersList[i].y ); ymax = std::max( ymax, m_CornersList[i].y ); } EDA_RECT r; r.SetOrigin( wxPoint( xmin, ymin ) ); r.SetEnd( wxPoint( xmax, ymax ) ); return r; }
EDA_RECT EDA_RECT::Common( const EDA_RECT& aRect ) const { EDA_RECT r; if( Intersects( aRect ) ) { wxPoint originA( std::min( GetOrigin().x, GetEnd().x ), std::min( GetOrigin().y, GetEnd().y ) ); wxPoint originB( std::min( aRect.GetOrigin().x, aRect.GetEnd().x ), std::min( aRect.GetOrigin().y, aRect.GetEnd().y ) ); wxPoint endA( std::max( GetOrigin().x, GetEnd().x ), std::max( GetOrigin().y, GetEnd().y ) ); wxPoint endB( std::max( aRect.GetOrigin().x, aRect.GetEnd().x ), std::max( aRect.GetOrigin().y, aRect.GetEnd().y ) ); r.SetOrigin( wxPoint( std::max( originA.x, originB.x ), std::max( originA.y, originB.y ) ) ); r.SetEnd ( wxPoint( std::min( endA.x, endB.x ), std::min( endA.y, endB.y ) ) ); } return r; }
const EDA_RECT LIB_POLYLINE::GetBoundingBox() const { EDA_RECT rect; int xmin, xmax, ymin, ymax; xmin = xmax = m_PolyPoints[0].x; ymin = ymax = m_PolyPoints[0].y; for( unsigned ii = 1; ii < GetCornerCount(); ii++ ) { xmin = std::min( xmin, m_PolyPoints[ii].x ); xmax = std::max( xmax, m_PolyPoints[ii].x ); ymin = std::min( ymin, m_PolyPoints[ii].y ); ymax = std::max( ymax, m_PolyPoints[ii].y ); } rect.SetOrigin( xmin, ymin * -1 ); rect.SetEnd( xmax, ymax * -1 ); rect.Inflate( m_Width / 2, m_Width / 2 ); return rect; }
const EDA_RECT SCH_LABEL::GetBoundingBox() const { int linewidth = GetThickness() == 0 ? GetDefaultLineThickness() : GetThickness(); EDA_RECT rect = GetTextBox( -1, linewidth ); if( GetTextAngle() != 0.0 ) { // Rotate rect wxPoint pos = rect.GetOrigin(); wxPoint end = rect.GetEnd(); RotatePoint( &pos, GetTextPos(), GetTextAngle() ); RotatePoint( &end, GetTextPos(), GetTextAngle() ); rect.SetOrigin( pos ); rect.SetEnd( end ); rect.Normalize(); } return rect; }
EDA_RECT SCH_TEXT::GetBoundingBox() const { // We must pass the effective text thickness to GetTextBox // when calculating the bounding box int linewidth = ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness; linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold ); EDA_RECT rect = GetTextBox( -1, linewidth ); if( m_Orient ) // Rotate rect { wxPoint pos = rect.GetOrigin(); wxPoint end = rect.GetEnd(); RotatePoint( &pos, m_Pos, m_Orient ); RotatePoint( &end, m_Pos, m_Orient ); rect.SetOrigin( pos ); rect.SetEnd( end ); } rect.Normalize(); return rect; }
const EDA_RECT LIB_TEXT::GetBoundingBox() const { /* Y coordinates for LIB_ITEMS are bottom to top, so we must invert the Y position when * calling GetTextBox() that works using top to bottom Y axis orientation. */ EDA_RECT rect = GetTextBox( -1, -1, true ); rect.RevertYAxis(); // We are using now a bottom to top Y axis. wxPoint orig = rect.GetOrigin(); wxPoint end = rect.GetEnd(); RotatePoint( &orig, GetTextPos(), -GetTextAngle() ); RotatePoint( &end, GetTextPos(), -GetTextAngle() ); rect.SetOrigin( orig ); rect.SetEnd( end ); // We are using now a top to bottom Y axis: rect.RevertYAxis(); return rect; }
const EDA_RECT CPolyLine::GetBoundingBox( int icont ) { int xmin = INT_MAX; int ymin = INT_MAX; int xmax = INT_MIN; int ymax = INT_MIN; int istart = GetContourStart( icont ); int iend = GetContourEnd( icont ); for( int i = istart; i<=iend; i++ ) { xmin = std::min( xmin, m_CornersList[i].x ); xmax = std::max( xmax, m_CornersList[i].x ); ymin = std::min( ymin, m_CornersList[i].y ); ymax = std::max( ymax, m_CornersList[i].y ); } EDA_RECT r; r.SetOrigin( wxPoint( xmin, ymin ) ); r.SetEnd( wxPoint( xmax, ymax ) ); return r; }
const EDA_RECT D_PAD::GetBoundingBox() const { EDA_RECT area; wxPoint quadrant1, quadrant2, quadrant3, quadrant4; int x, y, r, dx, dy; wxPoint center = ShapePos(); wxPoint endPoint; EDA_RECT endRect; switch( GetShape() ) { case PAD_SHAPE_CIRCLE: area.SetOrigin( center ); area.Inflate( m_Size.x / 2 ); break; case PAD_SHAPE_OVAL: /* To get the BoundingBox of an oval pad: * a) If the pad is ROUND, see method for PAD_SHAPE_CIRCLE above * OTHERWISE: * b) Construct EDA_RECT for portion between circular ends * c) Rotate that EDA_RECT * d) Add the circular ends to the EDA_RECT */ // Test if the shape is circular if( m_Size.x == m_Size.y ) { area.SetOrigin( center ); area.Inflate( m_Size.x / 2 ); break; } if( m_Size.x > m_Size.y ) { // Pad is horizontal dx = ( m_Size.x - m_Size.y ) / 2; dy = m_Size.y / 2; // Location of end-points x = dx; y = 0; r = dy; } else { // Pad is vertical dx = m_Size.x / 2; dy = ( m_Size.y - m_Size.x ) / 2; x = 0; y = dy; r = dx; } // Construct the center rectangle and rotate area.SetOrigin( center ); area.Inflate( dx, dy ); area = area.GetBoundingBoxRotated( center, m_Orient ); endPoint = wxPoint( x, y ); RotatePoint( &endPoint, m_Orient ); // Add points at each quadrant of circular regions endRect.SetOrigin( center + endPoint ); endRect.Inflate( r ); area.Merge( endRect ); endRect.SetSize( 0, 0 ); endRect.SetOrigin( center - endPoint ); endRect.Inflate( r ); area.Merge( endRect ); break; case PAD_SHAPE_RECT: case PAD_SHAPE_ROUNDRECT: // Use two opposite corners and track their rotation // (use symmetry for other points) quadrant1.x = m_Size.x/2; quadrant1.y = m_Size.y/2; quadrant2.x = -m_Size.x/2; quadrant2.y = m_Size.y/2; RotatePoint( &quadrant1, m_Orient ); RotatePoint( &quadrant2, m_Orient ); dx = std::max( std::abs( quadrant1.x ) , std::abs( quadrant2.x ) ); dy = std::max( std::abs( quadrant1.y ) , std::abs( quadrant2.y ) ); // Set the bbox area.SetOrigin( ShapePos() ); area.Inflate( dx, dy ); break; case PAD_SHAPE_TRAPEZOID: // Use the four corners and track their rotation // (Trapezoids will not be symmetric) quadrant1.x = (m_Size.x + m_DeltaSize.y)/2; quadrant1.y = (m_Size.y - m_DeltaSize.x)/2; quadrant2.x = -(m_Size.x + m_DeltaSize.y)/2; quadrant2.y = (m_Size.y + m_DeltaSize.x)/2; quadrant3.x = -(m_Size.x - m_DeltaSize.y)/2; quadrant3.y = -(m_Size.y + m_DeltaSize.x)/2; quadrant4.x = (m_Size.x - m_DeltaSize.y)/2; quadrant4.y = -(m_Size.y - m_DeltaSize.x)/2; RotatePoint( &quadrant1, m_Orient ); RotatePoint( &quadrant2, m_Orient ); RotatePoint( &quadrant3, m_Orient ); RotatePoint( &quadrant4, m_Orient ); x = std::min( quadrant1.x, std::min( quadrant2.x, std::min( quadrant3.x, quadrant4.x) ) ); y = std::min( quadrant1.y, std::min( quadrant2.y, std::min( quadrant3.y, quadrant4.y) ) ); dx = std::max( quadrant1.x, std::max( quadrant2.x, std::max( quadrant3.x, quadrant4.x) ) ); dy = std::max( quadrant1.y, std::max( quadrant2.y, std::max( quadrant3.y, quadrant4.y) ) ); area.SetOrigin( ShapePos().x + x, ShapePos().y + y ); area.SetSize( dx-x, dy-y ); break; case PAD_SHAPE_CUSTOM: { SHAPE_POLY_SET polySet( m_customShapeAsPolygon ); // Move shape to actual position CustomShapeAsPolygonToBoardPosition( &polySet, GetPosition(), GetOrientation() ); quadrant1 = m_Pos; quadrant2 = m_Pos; for( int cnt = 0; cnt < polySet.OutlineCount(); ++cnt ) { const SHAPE_LINE_CHAIN& poly = polySet.COutline( cnt ); for( int ii = 0; ii < poly.PointCount(); ++ii ) { quadrant1.x = std::min( quadrant1.x, poly.CPoint( ii ).x ); quadrant1.y = std::min( quadrant1.y, poly.CPoint( ii ).y ); quadrant2.x = std::max( quadrant2.x, poly.CPoint( ii ).x ); quadrant2.y = std::max( quadrant2.y, poly.CPoint( ii ).y ); } } area.SetOrigin( quadrant1 ); area.SetEnd( quadrant2 ); } break; default: break; } return area; }
void LIB_TEXT::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform ) { int color = GetDefaultColor(); if( aColor < 0 ) // Used normal color or selected color { if( IsSelected() ) color = g_ItemSelectetColor; } else { color = aColor; } GRSetDrawMode( aDC, aDrawMode ); /* Calculate the text orientation, according to the component * orientation/mirror (needed when draw text in schematic) */ int orient = m_Orient; if( aTransform.y1 ) // Rotate component 90 degrees. { if( orient == TEXT_ORIENT_HORIZ ) orient = TEXT_ORIENT_VERT; else orient = TEXT_ORIENT_HORIZ; } /* Calculate the text justification, according to the component * orientation/mirror this is a bit complicated due to cumulative * calculations: * - numerous cases (mirrored or not, rotation) * - the DrawGraphicText function recalculate also H and H justifications * according to the text orientation. * - When a component is mirrored, the text is not mirrored and * justifications are complicated to calculate * so the more easily way is to use no justifications ( Centered text ) * and use GetBoundaryBox to know the text coordinate considered as centered */ EDA_RECT bBox = GetBoundingBox(); wxPoint txtpos = bBox.Centre(); // Calculate pos accordint to mirror/rotation. txtpos = aTransform.TransformCoordinate( txtpos ) + aOffset; DrawGraphicText( aPanel, aDC, txtpos, (EDA_Colors) color, m_Text, orient, m_Size, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, GetPenSize(), m_Italic, m_Bold ); /* Enable this to draw the bounding box around the text field to validate * the bounding box calculations. */ #if 0 EDA_RECT grBox; grBox.SetOrigin( aTransform.TransformCoordinate( bBox.GetOrigin() ) ); grBox.SetEnd( aTransform.TransformCoordinate( bBox.GetEnd() ) ); grBox.Move( aOffset ); GRRect( aPanel->GetClipBox(), aDC, grBox, 0, LIGHTMAGENTA ); #endif }
const EDA_RECT DRAWSEGMENT::GetBoundingBox() const { EDA_RECT bbox; bbox.SetOrigin( m_Start ); switch( m_Shape ) { case S_SEGMENT: bbox.SetEnd( m_End ); break; case S_CIRCLE: bbox.Inflate( GetRadius() ); break; case S_ARC: { bbox.Merge( m_End ); wxPoint end = m_End; RotatePoint( &end, m_Start, -m_Angle ); bbox.Merge( end ); } break; case S_POLYGON: { wxPoint p_end; MODULE* module = GetParentModule(); for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ ) { wxPoint pt = m_PolyPoints[ii]; if( module ) // Transform, if we belong to a module { RotatePoint( &pt, module->GetOrientation() ); pt += module->GetPosition(); } if( ii == 0 ) p_end = pt; bbox.SetX( std::min( bbox.GetX(), pt.x ) ); bbox.SetY( std::min( bbox.GetY(), pt.y ) ); p_end.x = std::max( p_end.x, pt.x ); p_end.y = std::max( p_end.y, pt.y ); } bbox.SetEnd( p_end ); } break; default: ; } bbox.Inflate( ((m_Width+1) / 2) + 1 ); bbox.Normalize(); return bbox; }
const EDA_RECT DRAWSEGMENT::GetBoundingBox() const { EDA_RECT bbox; bbox.SetOrigin( m_Start ); switch( m_Shape ) { case S_SEGMENT: bbox.SetEnd( m_End ); break; case S_CIRCLE: bbox.Inflate( GetRadius() ); break; case S_ARC: { bbox.Merge( m_End ); wxPoint end = m_End; RotatePoint( &end, m_Start, -m_Angle ); bbox.Merge( end ); // Determine the starting quarter // 0 right-bottom // 1 left-bottom // 2 left-top // 3 right-top unsigned int quarter = 0; // assume right-bottom if( m_End.y < m_Start.y ) // change to left-top quarter |= 3; if( m_End.x < m_Start.x ) // for left side, the LSB is 2nd bit negated quarter ^= 1; int radius = GetRadius(); int angle = (int) GetArcAngleStart() % 900 + m_Angle; bool directionCW = ( m_Angle > 0 ); // Is the direction of arc clockwise? if( !directionCW ) { angle = 900 - angle; quarter = ( quarter + 3 ) % 4; // -1 modulo arithmetic } while( angle > 900 ) { switch( quarter ) { case 0: bbox.Merge( wxPoint( m_Start.x, m_Start.y + radius ) ); // down break; case 1: bbox.Merge( wxPoint( m_Start.x - radius, m_Start.y ) ); // left break; case 2: bbox.Merge( wxPoint( m_Start.x, m_Start.y - radius ) ); // up break; case 3: bbox.Merge( wxPoint( m_Start.x + radius, m_Start.y ) ); // right break; } if( directionCW ) ++quarter; else quarter += 3; // -1 modulo arithmetic quarter %= 4; angle -= 900; } } break; case S_POLYGON: { wxPoint p_end; MODULE* module = GetParentModule(); for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ ) { wxPoint pt = m_PolyPoints[ii]; if( module ) // Transform, if we belong to a module { RotatePoint( &pt, module->GetOrientation() ); pt += module->GetPosition(); } if( ii == 0 ) p_end = pt; bbox.SetX( std::min( bbox.GetX(), pt.x ) ); bbox.SetY( std::min( bbox.GetY(), pt.y ) ); p_end.x = std::max( p_end.x, pt.x ); p_end.y = std::max( p_end.y, pt.y ); } bbox.SetEnd( p_end ); } break; default: ; } bbox.Inflate( ((m_Width+1) / 2) + 1 ); bbox.Normalize(); return bbox; }