const EDA_RECT PCB_TARGET::GetBoundingBox() const { EDA_RECT bBox; bBox.SetX( m_Pos.x - m_Size/2 ); bBox.SetY( m_Pos.y - m_Size/2 ); bBox.SetWidth( m_Size ); bBox.SetHeight( m_Size ); return bBox; }
const EDA_RECT DIMENSION::GetBoundingBox() const { EDA_RECT bBox; int xmin, xmax, ymin, ymax; bBox = m_Text.GetTextBox( -1 ); xmin = bBox.GetX(); xmax = bBox.GetRight(); ymin = bBox.GetY(); ymax = bBox.GetBottom(); xmin = std::min( xmin, m_crossBarO.x ); xmin = std::min( xmin, m_crossBarF.x ); ymin = std::min( ymin, m_crossBarO.y ); ymin = std::min( ymin, m_crossBarF.y ); xmax = std::max( xmax, m_crossBarO.x ); xmax = std::max( xmax, m_crossBarF.x ); ymax = std::max( ymax, m_crossBarO.y ); ymax = std::max( ymax, m_crossBarF.y ); xmin = std::min( xmin, m_featureLineGO.x ); xmin = std::min( xmin, m_featureLineGF.x ); ymin = std::min( ymin, m_featureLineGO.y ); ymin = std::min( ymin, m_featureLineGF.y ); xmax = std::max( xmax, m_featureLineGO.x ); xmax = std::max( xmax, m_featureLineGF.x ); ymax = std::max( ymax, m_featureLineGO.y ); ymax = std::max( ymax, m_featureLineGF.y ); xmin = std::min( xmin, m_featureLineDO.x ); xmin = std::min( xmin, m_featureLineDF.x ); ymin = std::min( ymin, m_featureLineDO.y ); ymin = std::min( ymin, m_featureLineDF.y ); xmax = std::max( xmax, m_featureLineDO.x ); xmax = std::max( xmax, m_featureLineDF.x ); ymax = std::max( ymax, m_featureLineDO.y ); ymax = std::max( ymax, m_featureLineDF.y ); bBox.SetX( xmin ); bBox.SetY( ymin ); bBox.SetWidth( xmax - xmin + 1 ); bBox.SetHeight( ymax - ymin + 1 ); bBox.Normalize(); return bBox; }
EDA_RECT EDA_TEXT::GetTextBox( int aLine, int aThickness, bool aInvertY ) const { EDA_RECT rect; wxPoint pos; wxArrayString strings; wxString text = GetShownText(); int thickness = ( aThickness < 0 ) ? m_Thickness : aThickness; int linecount = 1; if( m_MultilineAllowed ) { wxStringSplit( text, strings, '\n' ); if ( strings.GetCount() ) // GetCount() == 0 for void strings { if( aLine >= 0 && (aLine < (int)strings.GetCount()) ) text = strings.Item( aLine ); else text = strings.Item( 0 ); linecount = strings.GetCount(); } } // calculate the H and V size int dx = LenSize( text ); int dy = GetInterline( aThickness ); // Creates bounding box (rectangle) for an horizontal text wxSize textsize = wxSize( dx, dy ); if( aInvertY ) rect.SetOrigin( m_Pos.x, -m_Pos.y ); else rect.SetOrigin( m_Pos ); // extra dy interval for letters like j and y and ] int extra_dy = dy - m_Size.y; rect.Move( wxPoint( 0, -extra_dy / 2 ) ); // move origin by the half extra interval // for multiline texts and aLine < 0, merge all rectangles if( m_MultilineAllowed && aLine < 0 ) { for( unsigned ii = 1; ii < strings.GetCount(); ii++ ) { text = strings.Item( ii ); dx = LenSize( text ); textsize.x = std::max( textsize.x, dx ); textsize.y += dy; } } rect.SetSize( textsize ); /* Now, calculate the rect origin, according to text justification * At this point the rectangle origin is the text origin (m_Pos). * This is true only for left and top text justified texts (using top to bottom Y axis * orientation). and must be recalculated for others justifications * also, note the V justification is relative to the first line */ switch( m_HJustify ) { case GR_TEXT_HJUSTIFY_LEFT: if( m_Mirror ) rect.SetX( rect.GetX() - rect.GetWidth() ); break; case GR_TEXT_HJUSTIFY_CENTER: rect.SetX( rect.GetX() - (rect.GetWidth() / 2) ); break; case GR_TEXT_HJUSTIFY_RIGHT: if( !m_Mirror ) rect.SetX( rect.GetX() - rect.GetWidth() ); break; } dy = m_Size.y + thickness; switch( m_VJustify ) { case GR_TEXT_VJUSTIFY_TOP: break; case GR_TEXT_VJUSTIFY_CENTER: rect.SetY( rect.GetY() - ( dy / 2) ); break; case GR_TEXT_VJUSTIFY_BOTTOM: rect.SetY( rect.GetY() - dy ); break; } if( linecount > 1 ) { int yoffset; linecount -= 1; switch( m_VJustify ) { case GR_TEXT_VJUSTIFY_TOP: break; case GR_TEXT_VJUSTIFY_CENTER: yoffset = linecount * GetInterline() / 2; rect.SetY( rect.GetY() - yoffset ); break; case GR_TEXT_VJUSTIFY_BOTTOM: yoffset = linecount * GetInterline( aThickness ); rect.SetY( rect.GetY() - yoffset ); break; } } rect.Inflate( thickness / 2 ); rect.Normalize(); // Make h and v sizes always >= 0 return rect; }
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; }