diff --git a/eeschema/lib_symbol.cpp b/eeschema/lib_symbol.cpp index 5b8945780e..3472bf0c87 100644 --- a/eeschema/lib_symbol.cpp +++ b/eeschema/lib_symbol.cpp @@ -1697,16 +1697,35 @@ int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags, REPORTER* aR if( !aReporter ) return retv; } - else if( int tmp = aField->SCH_ITEM::compare( *bField, aCompareFlags ) ) + else { - retv = tmp; - REPORT( wxString::Format( _( "Field '%s' differs: %s; %s." ), - aField->GetName( false ), - ITEM_DESC( aField ), - ITEM_DESC( bField ) ) ); + int tmp = 0; - if( !aReporter ) - return retv; + // For EQUALITY comparison, we need to compare field content directly + // since SCH_ITEM::compare() returns 0 for EQUALITY flag + if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY ) + { + // Compare field text content + tmp = aField->GetText().CmpNoCase( bField->GetText() ); + } + + if( tmp == 0 ) + { + // Fall back to base class comparison for other properties + tmp = aField->SCH_ITEM::compare( *bField, aCompareFlags ); + } + + if( tmp != 0 ) + { + retv = tmp; + REPORT( wxString::Format( _( "Field '%s' differs: %s; %s." ), + aField->GetName( false ), + ITEM_DESC( aField ), + ITEM_DESC( bField ) ) ); + + if( !aReporter ) + return retv; + } } } diff --git a/eeschema/pin_layout_cache.cpp b/eeschema/pin_layout_cache.cpp index 026f44f942..6e6a780cd5 100644 --- a/eeschema/pin_layout_cache.cpp +++ b/eeschema/pin_layout_cache.cpp @@ -750,7 +750,9 @@ std::optional PIN_LAYOUT_CACHE::GetPinNameInfo( int info->m_Thickness = m_nameThickness; info->m_Angle = ANGLE_HORIZONTAL; - if( m_pin.GetParentSymbol()->GetPinNameOffset() > 0 ) + bool nameInside = m_pin.GetParentSymbol()->GetPinNameOffset() > 0; + + if( nameInside ) { // This means name inside the pin VECTOR2I pos = { m_pin.GetLength() + m_pin.GetParentSymbol()->GetPinNameOffset(), 0 }; @@ -760,6 +762,7 @@ std::optional PIN_LAYOUT_CACHE::GetPinNameInfo( int info->m_TextPosition = pos + VECTOR2I{ thickOffset, 0 }; info->m_HAlign = GR_TEXT_H_ALIGN_LEFT; info->m_VAlign = GR_TEXT_V_ALIGN_CENTER; + transformTextForPin( *info ); } else { @@ -769,42 +772,44 @@ std::optional PIN_LAYOUT_CACHE::GetPinNameInfo( int info->m_TextPosition = pos; info->m_HAlign = GR_TEXT_H_ALIGN_CENTER; info->m_VAlign = GR_TEXT_V_ALIGN_BOTTOM; - } - // New policy: names follow same positioning semantics as numbers. - const SYMBOL* parentSym = m_pin.GetParentSymbol(); - if( parentSym ) - { - int maxHalfHeight = 0; - for( const SCH_PIN* p : parentSym->GetPins() ) + // New policy: names follow same positioning semantics as numbers except when + // specified as inside. When names are inside, they should not overlap with the + // number position. + const SYMBOL* parentSym = m_pin.GetParentSymbol(); + if( parentSym ) { - wxString n = p->GetShownName(); - if( n.IsEmpty() ) - continue; - maxHalfHeight = std::max( maxHalfHeight, p->GetNameTextSize() / 2 ); - } - int clearance = getPinTextOffset() + schIUScale.MilsToIU( PIN_TEXT_MARGIN ); - VECTOR2I pinPos = m_pin.GetPosition(); - PIN_ORIENTATION orient = m_pin.PinDrawOrient( DefaultTransform ); - bool verticalOrient = ( orient == PIN_ORIENTATION::PIN_UP || orient == PIN_ORIENTATION::PIN_DOWN ); + int maxHalfHeight = 0; + for( const SCH_PIN* p : parentSym->GetPins() ) + { + wxString n = p->GetShownName(); + if( n.IsEmpty() ) + continue; + maxHalfHeight = std::max( maxHalfHeight, p->GetNameTextSize() / 2 ); + } + int clearance = getPinTextOffset() + schIUScale.MilsToIU( PIN_TEXT_MARGIN ); + VECTOR2I pinPos = m_pin.GetPosition(); + PIN_ORIENTATION orient = m_pin.PinDrawOrient( DefaultTransform ); + bool verticalOrient = ( orient == PIN_ORIENTATION::PIN_UP || orient == PIN_ORIENTATION::PIN_DOWN ); - if( verticalOrient ) - { - // Vertical pins: name mirrors number placement (left + rotated) for visual consistency. - int boxWidth = info->m_TextSize * (int) info->m_Text.Length() * 0.6; // heuristic width - int centerX = pinPos.x - clearance - boxWidth / 2; - info->m_TextPosition = { centerX, pinPos.y }; - info->m_Angle = ANGLE_VERTICAL; - info->m_HAlign = GR_TEXT_H_ALIGN_CENTER; - info->m_VAlign = GR_TEXT_V_ALIGN_CENTER; - } - else - { - // Horizontal pins: name above (negative Y) aligned to same Y offset logic as numbers. - info->m_TextPosition = { pinPos.x, pinPos.y - ( maxHalfHeight + clearance ) }; - info->m_Angle = ANGLE_HORIZONTAL; - info->m_HAlign = GR_TEXT_H_ALIGN_CENTER; - info->m_VAlign = GR_TEXT_V_ALIGN_CENTER; + if( verticalOrient ) + { + // Vertical pins: name mirrors number placement (left + rotated) for visual consistency. + int boxWidth = info->m_TextSize * (int) info->m_Text.Length() * 0.6; // heuristic width + int centerX = pinPos.x - clearance - boxWidth / 2; + info->m_TextPosition = { centerX, pinPos.y }; + info->m_Angle = ANGLE_VERTICAL; + info->m_HAlign = GR_TEXT_H_ALIGN_CENTER; + info->m_VAlign = GR_TEXT_V_ALIGN_CENTER; + } + else + { + // Horizontal pins: name above (negative Y) aligned to same Y offset logic as numbers. + info->m_TextPosition = { pinPos.x, pinPos.y - ( maxHalfHeight + clearance ) }; + info->m_Angle = ANGLE_HORIZONTAL; + info->m_HAlign = GR_TEXT_H_ALIGN_CENTER; + info->m_VAlign = GR_TEXT_V_ALIGN_CENTER; + } } } return info; diff --git a/qa/tests/eeschema/test_pin_stacked_layout.cpp b/qa/tests/eeschema/test_pin_stacked_layout.cpp index a2b71364d7..d4bbe984a2 100644 --- a/qa/tests/eeschema/test_pin_stacked_layout.cpp +++ b/qa/tests/eeschema/test_pin_stacked_layout.cpp @@ -46,6 +46,9 @@ static std::unique_ptr createTestResistorSymbol() { auto symbol = std::make_unique( wxT( "TestResistor" ) ); + // Set pin name offset to 0 so names are positioned outside (like numbers) + symbol->SetPinNameOffset( 0 ); + // Create first pin with stacked numbers [1-5] auto pin1 = std::make_unique( symbol.get() ); pin1->SetPosition( VECTOR2I( 0, schIUScale.MilsToIU( 250 ) ) ); // top pin