void EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( SHAPE_POLY_SET* aCornerBuffer, int aClearanceValue ) const { // Oh dear. When in UTF-8 mode, wxString puts string iterators in a linked list, and // that linked list is not thread-safe. std::lock_guard<std::mutex> guard( m_mutex ); if( GetText().Length() == 0 ) return; wxPoint corners[4]; // Buffer of polygon corners EDA_RECT rect = GetTextBox( -1 ); rect.Inflate( aClearanceValue ); corners[0].x = rect.GetOrigin().x; corners[0].y = rect.GetOrigin().y; corners[1].y = corners[0].y; corners[1].x = rect.GetRight(); corners[2].x = corners[1].x; corners[2].y = rect.GetBottom(); corners[3].y = corners[2].y; corners[3].x = corners[0].x; aCornerBuffer->NewOutline(); for( int ii = 0; ii < 4; ii++ ) { // Rotate polygon RotatePoint( &corners[ii].x, &corners[ii].y, GetTextPos().x, GetTextPos().y, GetTextAngle() ); aCornerBuffer->Append( corners[ii].x, corners[ii].y ); } }
void SCH_TEXT::Rotate( wxPoint aPosition ) { int dy; wxPoint pt = GetTextPos(); RotatePoint( &pt, aPosition, 900 ); SetTextPos( pt ); int spin = GetLabelSpinStyle(); // Global and hierarchical labels spin backwards. Fix here because // changing SetLabelSpinStyle would break existing designs. if( this->Type() == SCH_GLOBAL_LABEL_T || this->Type() == SCH_HIERARCHICAL_LABEL_T ) SetLabelSpinStyle( ( spin - 1 >= 0 ? ( spin - 1 ) : 3 ) ); else SetLabelSpinStyle( ( spin + 1 ) % 4 ); if( this->Type() == SCH_TEXT_T ) { switch( GetLabelSpinStyle() ) { case 0: dy = GetTextHeight(); break; // horizontal text case 1: dy = 0; break; // Vert Orientation UP case 2: dy = GetTextHeight(); break; // invert horizontal text case 3: dy = 0; break; // Vert Orientation BOTTOM default: dy = 0; break; } SetTextY( GetTextPos().y + dy ); } }
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; }
int LIB_TEXT::compare( const LIB_ITEM& other ) const { wxASSERT( other.Type() == LIB_TEXT_T ); const LIB_TEXT* tmp = ( LIB_TEXT* ) &other; int result = m_Text.CmpNoCase( tmp->m_Text ); if( result != 0 ) return result; if( GetTextPos().x != tmp->GetTextPos().x ) return GetTextPos().x - tmp->GetTextPos().x; if( GetTextPos().y != tmp->GetTextPos().y ) return GetTextPos().y - tmp->GetTextPos().y; if( GetTextWidth() != tmp->GetTextWidth() ) return GetTextWidth() - tmp->GetTextWidth(); if( GetTextHeight() != tmp->GetTextHeight() ) return GetTextHeight() - tmp->GetTextHeight(); return 0; }
void TEXTE_MODULE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis ) { // Used in modedit, to transform the footprint // the mirror is around the Y axis or X axis if aMirrorAroundXAxis = true // the position is mirrored, but the text itself is not mirrored if( aMirrorAroundXAxis ) SetTextY( ::Mirror( GetTextPos().y, aCentre.y ) ); else SetTextX( ::Mirror( GetTextPos().x, aCentre.x ) ); SetLocalCoord(); }
const EDA_RECT SCH_GLOBALLABEL::GetBoundingBox() const { int x, y, dx, dy, length, height; x = GetTextPos().x; y = GetTextPos().y; dx = dy = 0; int width = GetThickness() == 0 ? GetDefaultLineThickness() : GetThickness(); height = ( (GetTextHeight() * 15) / 10 ) + width + 2 * TXT_MARGIN; // text X size add height for triangular shapes(bidirectional) length = LenSize( GetShownText(), width ) + height + DANGLING_SYMBOL_SIZE; switch( GetLabelSpinStyle() ) // respect orientation { default: case 0: // Horiz Normal Orientation (left justified) dx = -length; dy = height; x += DANGLING_SYMBOL_SIZE; y -= height / 2; break; case 1: // Vert Orientation UP dx = height; dy = -length; x -= height / 2; y += DANGLING_SYMBOL_SIZE; break; case 2: // Horiz Orientation - Right justified dx = length; dy = height; x -= DANGLING_SYMBOL_SIZE; y -= height / 2; break; case 3: // Vert Orientation BOTTOM dx = height; dy = length; x -= height / 2; y -= DANGLING_SYMBOL_SIZE; break; } EDA_RECT box( wxPoint( x, y ), wxSize( dx, dy ) ); box.Normalize(); return box; }
void SCH_TEXT::Plot( PLOTTER* aPlotter ) { static std::vector <wxPoint> Poly; COLOR4D color = GetLayerColor( GetLayer() ); int tmp = GetThickness(); int thickness = GetPenSize(); // Two thicknesses are set here: // The first is for EDA_TEXT, which controls the interline spacing based on text thickness // The second is for the output that sets the actual stroke size SetThickness( thickness ); aPlotter->SetCurrentLineWidth( thickness ); if( IsMultilineAllowed() ) { std::vector<wxPoint> positions; wxArrayString strings_list; wxStringSplit( GetShownText(), strings_list, '\n' ); positions.reserve( strings_list.Count() ); GetPositionsOfLinesOfMultilineText(positions, (int) strings_list.Count() ); for( unsigned ii = 0; ii < strings_list.Count(); ii++ ) { wxPoint textpos = positions[ii] + GetSchematicTextOffset(); wxString& txt = strings_list.Item( ii ); aPlotter->Text( textpos, color, txt, GetTextAngle(), GetTextSize(), GetHorizJustify(), GetVertJustify(), thickness, IsItalic(), IsBold() ); } } else { wxPoint textpos = GetTextPos() + GetSchematicTextOffset(); aPlotter->Text( textpos, color, GetShownText(), GetTextAngle(), GetTextSize(), GetHorizJustify(), GetVertJustify(), thickness, IsItalic(), IsBold() ); } // Draw graphic symbol for global or hierarchical labels CreateGraphicShape( Poly, GetTextPos() ); aPlotter->SetCurrentLineWidth( GetPenSize() ); if( Poly.size() ) aPlotter->PlotPoly( Poly, NO_FILL ); SetThickness( tmp ); }
void SCH_SHEET_PIN::ConstrainOnEdge( wxPoint Pos ) { SCH_SHEET* sheet = GetParent(); if( sheet == NULL ) return; wxPoint center = sheet->m_pos + ( sheet->m_size / 2 ); if( m_edge == SHEET_LEFT_SIDE || m_edge == SHEET_RIGHT_SIDE ) { if( Pos.x > center.x ) { SetEdge( SHEET_RIGHT_SIDE ); } else { SetEdge( SHEET_LEFT_SIDE ); } SetTextY( Pos.y ); if( GetTextPos().y < sheet->m_pos.y ) SetTextY( sheet->m_pos.y ); if( GetTextPos().y > (sheet->m_pos.y + sheet->m_size.y) ) SetTextY( sheet->m_pos.y + sheet->m_size.y ); } else { if( Pos.y > center.y ) { SetEdge( SHEET_BOTTOM_SIDE ); } else { SetEdge( SHEET_TOP_SIDE ); } SetTextX( Pos.x ); if( GetTextPos().x < sheet->m_pos.x ) SetTextX( sheet->m_pos.x ); if( GetTextPos().x > (sheet->m_pos.x + sheet->m_size.x) ) SetTextX( sheet->m_pos.x + sheet->m_size.x ); } }
void SCH_TEXT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems, SCH_SHEET_PATH* aSheetPath ) { if( GetLayer() == LAYER_NOTES || GetLayer() == LAYER_SHEETLABEL ) return; NETLIST_OBJECT* item = new NETLIST_OBJECT(); item->m_SheetPath = *aSheetPath; item->m_SheetPathInclude = *aSheetPath; item->m_Comp = (SCH_ITEM*) this; item->m_Type = NET_LABEL; if( GetLayer() == LAYER_GLOBLABEL ) item->m_Type = NET_GLOBLABEL; else if( GetLayer() == LAYER_HIERLABEL ) item->m_Type = NET_HIERLABEL; item->m_Label = m_Text; item->m_Start = item->m_End = GetTextPos(); aNetListItems.push_back( item ); // If a bus connects to label if( Connection( *aSheetPath )->IsBusLabel( m_Text ) ) { item->ConvertBusToNetListItems( aNetListItems ); } }
void SCH_SHEET_PIN::Rotate( wxPoint aPosition ) { wxPoint pt = GetTextPos(); RotatePoint( &pt, aPosition, 900 ); SetTextPos( pt ); switch( m_edge ) { case SHEET_LEFT_SIDE: //pin on left side SetEdge( SHEET_BOTTOM_SIDE ); break; case SHEET_RIGHT_SIDE: //pin on right side SetEdge( SHEET_TOP_SIDE ); break; case SHEET_TOP_SIDE: //pin on top side SetEdge( SHEET_LEFT_SIDE ); break; case SHEET_BOTTOM_SIDE: //pin on bottom side SetEdge( SHEET_RIGHT_SIDE ); break; default: break; } }
bool LIB_FIELD::HitTest( const wxPoint& aPosition, int aAccuracy ) const { // Because HitTest is mainly used to select the field return false if it is void if( IsVoid() ) return false; // Build a temporary copy of the text for hit testing EDA_TEXT tmp_text( *this ); // Reference designator text has one or 2 additional character (displays // U? or U?A) if( m_id == REFERENCE ) { wxString extended_text = tmp_text.GetText(); extended_text.Append('?'); const LIB_PART* parent = static_cast<const LIB_PART*>( m_Parent ); if ( parent && ( parent->GetUnitCount() > 1 ) ) extended_text.Append('A'); tmp_text.SetText( extended_text ); } tmp_text.SetTextPos( DefaultTransform.TransformCoordinate( GetTextPos() ) ); /* The text orientation may need to be flipped if the * transformation matrix causes xy axes to be flipped. * this simple algo works only for schematic matrix (rot 90 or/and mirror) */ bool t1 = ( DefaultTransform.x1 != 0 ) ^ ( GetTextAngle() != 0 ); tmp_text.SetTextAngle( t1 ? TEXT_ANGLE_HORIZ : TEXT_ANGLE_VERT ); return tmp_text.TextHitTest( aPosition, aAccuracy ); }
void TEXTE_MODULE::SetLocalCoord() { const MODULE* module = static_cast<const MODULE*>( m_Parent ); if( module ) { m_Pos0 = GetTextPos() - module->GetPosition(); double angle = module->GetOrientation(); RotatePoint( &m_Pos0.x, &m_Pos0.y, -angle ); } else { m_Pos0 = GetTextPos(); } }
bool SCH_FIELD::Save( FILE* aFile ) const { char hjustify = 'C'; if( GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT ) hjustify = 'L'; else if( GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT ) hjustify = 'R'; char vjustify = 'C'; if( GetVertJustify() == GR_TEXT_VJUSTIFY_BOTTOM ) vjustify = 'B'; else if( GetVertJustify() == GR_TEXT_VJUSTIFY_TOP ) vjustify = 'T'; if( fprintf( aFile, "F %d %s %c %-3d %-3d %-3d %4.4X %c %c%c%c", m_id, EscapedUTF8( m_Text ).c_str(), // wraps in quotes too GetTextAngle() == TEXT_ANGLE_HORIZ ? 'H' : 'V', GetTextPos().x, GetTextPos().y, GetTextWidth(), !IsVisible(), hjustify, vjustify, IsItalic() ? 'I' : 'N', IsBold() ? 'B' : 'N' ) == EOF ) { return false; } // Save field name, if the name is user definable if( m_id >= FIELD1 ) { if( fprintf( aFile, " %s", EscapedUTF8( m_name ).c_str() ) == EOF ) { return false; } } if( fprintf( aFile, "\n" ) == EOF ) { return false; } return true; }
void TEXTE_PCB::Rotate( const wxPoint& aRotCentre, double aAngle ) { wxPoint pt = GetTextPos(); RotatePoint( &pt, aRotCentre, aAngle ); SetTextPos( pt ); SetTextAngle( GetTextAngle() + aAngle ); }
wxPoint SCH_FIELD::GetPosition() const { SCH_COMPONENT* component = (SCH_COMPONENT*) GetParent(); wxPoint pos = GetTextPos() - component->GetPosition(); return component->GetTransform().TransformCoordinate( pos ) + component->GetPosition(); }
void SCH_TEXT::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const { // Normal text labels do not have connection points. All others do. if( Type() == SCH_TEXT_T ) return; aPoints.push_back( GetTextPos() ); }
const EDA_RECT TEXTE_PCB::GetBoundingBox() const { EDA_RECT rect = GetTextBox( -1, -1 ); if( GetTextAngle() ) rect = rect.GetBoundingBoxRotated( GetTextPos(), GetTextAngle() ); return rect; }
void SCH_TEXT::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList ) { // Normal text labels cannot be tested for dangling ends. if( Type() == SCH_TEXT_T ) return; DANGLING_END_ITEM item( LABEL_END, this, GetTextPos() ); aItemList.push_back( item ); }
void TEXTE_PCB::Flip( const wxPoint& aCentre ) { SetTextY( aCentre.y - ( GetTextPos().y - aCentre.y ) ); int copperLayerCount = GetBoard()->GetCopperLayerCount(); SetLayer( FlipLayer( GetLayer(), copperLayerCount ) ); SetMirrored( !IsMirrored() ); }
void LIB_TEXT::MirrorVertical( const wxPoint& center ) { int y = GetTextPos().y; y -= center.y; y *= -1; y += center.y; SetTextY( y ); }
void LIB_TEXT::Rotate( const wxPoint& center, bool aRotateCCW ) { int rot_angle = aRotateCCW ? -900 : 900; wxPoint pt = GetTextPos(); RotatePoint( &pt, center, rot_angle ); SetTextPos( pt ); SetTextAngle( GetTextAngle() != 0.0 ? 0 : 900 ); }
const BOX2I TEXTE_MODULE::ViewBBox() const { double angle = GetDrawRotation(); EDA_RECT text_area = GetTextBox( -1, -1 ); if( angle ) text_area = text_area.GetBoundingBoxRotated( GetTextPos(), angle ); return BOX2I( text_area.GetPosition(), text_area.GetSize() ); }
void LIB_TEXT::MirrorHorizontal( const wxPoint& center ) { int x = GetTextPos().x; x -= center.x; x *= -1; x += center.x; SetTextX( x ); }
const EDA_RECT TEXTE_MODULE::GetBoundingBox() const { double angle = GetDrawRotation(); EDA_RECT text_area = GetTextBox( -1, -1 ); if( angle ) text_area = text_area.GetBoundingBoxRotated( GetTextPos(), angle ); return text_area; }
bool SCH_TEXT::IsSelectStateChanged( const wxRect& aRect ) { bool previousState = IsSelected(); if( aRect.Contains( GetTextPos() ) ) SetFlags( SELECTED ); else ClearFlags( SELECTED ); return previousState != IsSelected(); }
bool TEXTE_MODULE::TextHitTest( const wxPoint& aPoint, int aAccuracy ) const { EDA_RECT rect = GetTextBox( -1 ); wxPoint location = aPoint; rect.Inflate( aAccuracy ); RotatePoint( &location, GetTextPos(), -GetDrawRotation() ); return rect.Contains( location ); }
void TEXTE_MODULE::Flip( const wxPoint& aCentre ) { // flipping the footprint is relative to the X axis SetTextY( ::Mirror( GetTextPos().y, aCentre.y ) ); SetTextAngle( -GetTextAngle() ); SetLayer( FlipLayer( GetLayer() ) ); SetMirrored( IsBackLayer( GetLayer() ) ); SetLocalCoord(); }
void TEXTE_MODULE::Rotate( const wxPoint& aRotCentre, double aAngle ) { // Used in footprint edition // Note also in module editor, m_Pos0 = m_Pos wxPoint pt = GetTextPos(); RotatePoint( &pt, aRotCentre, aAngle ); SetTextPos( pt ); SetTextAngle( GetTextAngle() + aAngle ); SetLocalCoord(); }
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; }
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; }