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 <<
")" );