155    std::vector<SCH_PIN*> pins;
 
  157    for( 
SCH_ITEM& item : symbol->GetDrawItems() )
 
  160            pins.push_back( 
static_cast<SCH_PIN*
>( &item ) );
 
  163    BOOST_REQUIRE_EQUAL( pins.size(), 2 );
 
  166    std::vector<TRANSFORM> rotations = {
 
  173    std::vector<wxString> rotationNames = { wxT(
"0°"), wxT(
"90°"), wxT(
"180°"), wxT(
"270°") };
 
  175    for( 
size_t r = 0; r < rotations.size(); r++ )
 
  177        const TRANSFORM& transform = rotations[r];
 
  178        const wxString& rotName = rotationNames[r];
 
  184        for( 
size_t p = 0; p < pins.size(); p++ )
 
  192            std::optional<PIN_LAYOUT_CACHE::TEXT_INFO> numberInfoOpt = cache.
GetPinNumberInfo( 0 );
 
  194            if( !numberInfoOpt.has_value() )
 
  199            if( numberInfo.
m_Text.IsEmpty() )
 
  212            if( numberInfo.
m_Text.Contains( 
'\n' ) )
 
  220                    int lineSpacing = textHeight * 1.3;
 
  221                    textWidth = lines.size() * lineSpacing;
 
  225                    for( 
const wxString& line : lines )
 
  226                        maxLen = std::max( maxLen, line.Length() );
 
  228                    textHeight = maxLen * textHeight * 0.6;
 
  233                    int lineSpacing = textHeight * 1.3;
 
  234                    textHeight = lines.size() * lineSpacing;
 
  238                    for( 
const wxString& line : lines )
 
  239                        maxLen = std::max( maxLen, line.Length() );
 
  241                    textWidth = maxLen * textHeight * 0.6;
 
  249            textBbox.
SetSize( textWidth, textHeight );
 
  255            wxLogTrace( 
"KICAD_PINS", wxT(
"Rotation %s, Pin %s: pos=(%d,%d) textPos=(%d,%d) pinLine=(%d,%d)-(%d,%d) textBox=(%d,%d,%dx%d) overlap=%s"),
 
  256                          rotName, 
pin->GetNumber(),
 
  257                          pinStart.
x, pinStart.
y,
 
  259                          pinStart.
x, pinStart.
y, pinEnd.
x, pinEnd.
y,
 
  261                          overlaps ? wxT(
"YES") : wxT(
"NO") );
 
  264            BOOST_CHECK_MESSAGE( !overlaps,
 
  265                                 "Pin number '" << 
pin->GetNumber() << 
"' overlaps with pin geometry at rotation " << rotName );
 
 
  284    std::vector<SCH_PIN*> pins;
 
  286    for( 
SCH_ITEM& item : symbol->GetDrawItems() )
 
  289            pins.push_back( 
static_cast<SCH_PIN*
>( &item ) );
 
  292    BOOST_REQUIRE_EQUAL( pins.size(), 2 );
 
  295    std::vector<TRANSFORM> rotations = {
 
  302    std::vector<wxString> rotationNames = { wxT(
"0°"), wxT(
"90°"), wxT(
"180°"), wxT(
"270°") };
 
  304    for( 
size_t r = 0; r < rotations.size(); r++ )
 
  306        const TRANSFORM& transform = rotations[r];
 
  307        const wxString& rotName = rotationNames[r];
 
  322        std::vector<PinTextInfo> pinInfos;
 
  327            info.pinPos = 
pin->GetPosition();
 
  328            info.pinNumber = 
pin->GetNumber();
 
  334            std::optional<PIN_LAYOUT_CACHE::TEXT_INFO> numberInfoOpt = cache.
GetPinNumberInfo( 0 );
 
  336            if( numberInfoOpt.has_value() )
 
  340                info.isMultiline = numberInfo.
m_Text.Contains( 
'\n' );
 
  344            std::optional<PIN_LAYOUT_CACHE::TEXT_INFO> nameInfoOpt = cache.
GetPinNameInfo( 0 );
 
  346            if( nameInfoOpt.has_value() )
 
  352            pinInfos.push_back( 
info );
 
  354            wxLogTrace( 
"KICAD_PINS", 
"Rotation %s, Pin %s: pos=(%d,%d) numberPos=(%d,%d) namePos=(%d,%d) multiline=%s",
 
  355                        rotName, 
info.pinNumber,
 
  359                        info.isMultiline ? wxT(
"YES") : wxT(
"NO") );
 
  362        BOOST_REQUIRE_EQUAL( pinInfos.size(), 2 );
 
  371            for( 
const PinTextInfo& inf : pinInfos )
 
  373                BOOST_CHECK_MESSAGE( inf.numberPos.x > inf.pinPos.x,
 
  374                    "At rotation " << rotName << 
", number for pin " << inf.pinNumber << 
" not right of vertical pin." );
 
  375                BOOST_CHECK_MESSAGE( inf.namePos.x < inf.pinPos.x,
 
  376                    "At rotation " << rotName << 
", name for pin " << inf.pinNumber << 
" not left of vertical pin." );
 
  381            for( 
const PinTextInfo& inf : pinInfos )
 
  383                BOOST_CHECK_MESSAGE( inf.numberPos.y > inf.pinPos.y,
 
  384                    "At rotation " << rotName << 
", number for pin " << inf.pinNumber << 
" not below horizontal pin." );
 
  385                BOOST_CHECK_MESSAGE( inf.namePos.y < inf.pinPos.y,
 
  386                    "At rotation " << rotName << 
", name for pin " << inf.pinNumber << 
" not above horizontal pin." );
 
 
  406    std::vector<SCH_PIN*> pins;
 
  408    for( 
SCH_ITEM& item : symbol->GetDrawItems() )
 
  411            pins.push_back( 
static_cast<SCH_PIN*
>( &item ) );
 
  414    BOOST_REQUIRE_EQUAL( pins.size(), 2 );
 
  417    std::vector<TRANSFORM> rotations = {
 
  424    std::vector<wxString> rotationNames = { wxT(
"0°"), wxT(
"90°"), wxT(
"180°"), wxT(
"270°") };
 
  426    for( 
size_t r = 0; r < rotations.size(); r++ )
 
  428        const TRANSFORM& transform = rotations[r];
 
  429        const wxString& rotName = rotationNames[r];
 
  442            int numberBottomDistance;
 
  443            int nameBottomDistance;
 
  446        std::vector<PinTextData> pinData;
 
  451            data.pinPos = 
pin->GetPosition();
 
  452            data.pinNumber = 
pin->GetNumber();
 
  458            std::optional<PIN_LAYOUT_CACHE::TEXT_INFO> numberInfoOpt = cache.
GetPinNumberInfo( 0 );
 
  461            if( numberInfoOpt.has_value() )
 
  463                numberInfo = numberInfoOpt.value();
 
  465                data.isMultiline = numberInfo.
m_Text.Contains( 
'\n' );
 
  469                BOOST_FAIL( 
"Expected pin number text info" );
 
  473            std::optional<PIN_LAYOUT_CACHE::TEXT_INFO> nameInfoOpt = cache.
GetPinNameInfo( 0 );
 
  476            if( nameInfoOpt.has_value() )
 
  478                nameInfo = nameInfoOpt.value();
 
  483                BOOST_FAIL( 
"Expected pin name text info" );
 
  493                int textWidth = data.isMultiline ? 0 : (int)( data.pinNumber.Length() * numberInfo.
m_TextSize * 0.6 );
 
  496                if( data.isMultiline )
 
  499                    int lineSpacing = numberInfo.
m_TextSize * 1.3;
 
  500                    textWidth = lines.size() * lineSpacing; 
 
  504                int leftEdge = data.numberPos.x - textWidth / 2;
 
  505                data.numberBottomDistance = leftEdge - data.pinPos.x; 
 
  508                int nameWidth = (int)( nameInfo.
m_Text.Length() * nameInfo.
m_TextSize * 0.6 );
 
  509                int nameRightEdge = data.namePos.x + nameWidth / 2;
 
  510                data.nameBottomDistance = data.pinPos.x - nameRightEdge; 
 
  516                int textHeight = data.isMultiline ? 0 : numberInfo.
m_TextSize;
 
  518                if( data.isMultiline )
 
  522                    int lineSpacing = numberInfo.
m_TextSize * 1.3;
 
  523                    textHeight = lines.size() * lineSpacing;
 
  527                int topEdge = data.numberPos.y - textHeight / 2;
 
  528                data.numberBottomDistance = topEdge - data.pinPos.y; 
 
  532                int nameBottomEdge = data.namePos.y + nameHeight / 2;
 
  533                data.nameBottomDistance = data.pinPos.y - nameBottomEdge; 
 
  536            pinData.push_back( data );
 
  538            wxLogTrace( 
"KICAD_PINS", 
"Rotation %s, Pin %s: pos=(%d,%d) numberPos=(%d,%d) namePos=(%d,%d) multiline=%s numberBottomDist=%d nameBottomDist=%d",
 
  539                        rotName, data.pinNumber,
 
  540                        data.pinPos.x, data.pinPos.y,
 
  541                        data.numberPos.x, data.numberPos.y,
 
  542                        data.namePos.x, data.namePos.y,
 
  543                        data.isMultiline ? wxT(
"YES") : wxT(
"NO"),
 
  544                        data.numberBottomDistance, data.nameBottomDistance );
 
  547        BOOST_REQUIRE_EQUAL( pinData.size(), 2 );
 
  551        const int tolerance = 100; 
 
  553        int bottomDist1 = pinData[0].numberBottomDistance;
 
  554        int bottomDist2 = pinData[1].numberBottomDistance;
 
  555        int distanceDiff = abs( bottomDist1 - bottomDist2 );
 
  557        BOOST_CHECK_MESSAGE( distanceDiff <= tolerance,
 
  558                           "At rotation " << rotName << 
", pin numbers have different bottom distances from pin. " 
  559                           << 
"Pin " << pinData[0].pinNumber << 
" distance=" << bottomDist1
 
  560                           << 
", Pin " << pinData[1].pinNumber << 
" distance=" << bottomDist2
 
  561                           << 
", difference=" << distanceDiff << 
" (tolerance=" << tolerance << 
")" );
 
  564        int nameBottomDist1 = pinData[0].nameBottomDistance;
 
  565        int nameBottomDist2 = pinData[1].nameBottomDistance;
 
  566        int nameDistanceDiff = abs( nameBottomDist1 - nameBottomDist2 );
 
  568        BOOST_CHECK_MESSAGE( nameDistanceDiff <= tolerance,
 
  569                           "At rotation " << rotName << 
", pin names have different bottom distances from pin. " 
  570                           << 
"Pin " << pinData[0].pinNumber << 
" name distance=" << nameBottomDist1
 
  571                           << 
", Pin " << pinData[1].pinNumber << 
" name distance=" << nameBottomDist2
 
  572                           << 
", difference=" << nameDistanceDiff << 
" (tolerance=" << tolerance << 
")" );