@@ -1265,7 +1265,7 @@ void RenderThread::drawChip(QPainter* painter,
12651265
12661266 utl::Timer inst_access_points;
12671267 if (viewer_->options_ ->areAccessPointsVisible ()) {
1268- drawAccessPoints (gui_painter, insts);
1268+ drawAccessPoints (gui_painter, block, bounds, insts);
12691269 }
12701270 debugPrint (logger_, GUI, " draw" , 1 , " access points {}" , inst_access_points);
12711271
@@ -1438,6 +1438,8 @@ void RenderThread::drawNetTracks(Painter& painter, odb::dbTechLayer* layer)
14381438}
14391439
14401440void RenderThread::drawAccessPoints (Painter& painter,
1441+ odb::dbBlock* block,
1442+ const odb::Rect& bounds,
14411443 const std::vector<odb::dbInst*>& insts)
14421444{
14431445 const int shape_limit = viewer_->shapeSizeLimit ();
@@ -1481,11 +1483,18 @@ void RenderThread::drawAccessPoints(Painter& painter,
14811483 }
14821484 }
14831485 }
1484- for (auto term : viewer_->getBlock ()->getBTerms ()) {
1485- if (restart_) {
1486- break ;
1487- }
1488- for (auto pin : term->getBPins ()) {
1486+
1487+ odb::dbTech* tech = block->getTech ();
1488+ for (odb::dbTechLayer* layer : tech->getLayers ()) {
1489+ for (const auto & [box, pin] : viewer_->search_ .searchBPins (block,
1490+ layer,
1491+ bounds.xMin (),
1492+ bounds.yMin (),
1493+ bounds.xMax (),
1494+ bounds.yMax ())) {
1495+ if (restart_) {
1496+ break ;
1497+ }
14891498 for (auto ap : pin->getAccessPoints ()) {
14901499 draw (ap, {});
14911500 }
@@ -1531,16 +1540,17 @@ void RenderThread::drawModuleView(QPainter* painter,
15311540
15321541void RenderThread::setupIOPins (odb::dbBlock* block, const odb::Rect& bounds)
15331542{
1534- pins_.clear ();
15351543 if (!viewer_->options_ ->areIOPinsVisible ()) {
1544+ pin_draw_names_ = false ;
15361545 return ;
15371546 }
15381547
15391548 const auto die_area = block->getDieArea ();
15401549 const auto die_width = die_area.dx ();
15411550 const auto die_height = die_area.dy ();
15421551
1543- if (viewer_->options_ ->areIOPinNamesVisible ()) {
1552+ pin_draw_names_ = viewer_->options_ ->areIOPinNamesVisible ();
1553+ if (pin_draw_names_) {
15441554 const double scale_factor
15451555 = 0.02 ; // 4 Percent of bounds is used to draw pin-markers
15461556 const int die_max_dim
@@ -1551,15 +1561,6 @@ void RenderThread::setupIOPins(odb::dbBlock* block, const odb::Rect& bounds)
15511561 pin_font_ = viewer_->options_ ->ioPinMarkersFont ();
15521562 const QFontMetrics font_metrics (pin_font_);
15531563
1554- QString largest_text;
1555- for (auto pin : block->getBTerms ()) {
1556- QString current_text = QString::fromStdString (pin->getName ());
1557- if (font_metrics.boundingRect (current_text).width ()
1558- > font_metrics.boundingRect (largest_text).width ()) {
1559- largest_text = std::move (current_text);
1560- }
1561- }
1562-
15631564 const int vertical_gap
15641565 = (viewer_->geometry ().height ()
15651566 - viewer_->getBounds ().dy () * viewer_->pixels_per_dbu_ )
@@ -1574,59 +1575,73 @@ void RenderThread::setupIOPins(odb::dbBlock* block, const odb::Rect& bounds)
15741575 - std::ceil (pin_max_size_) * viewer_->pixels_per_dbu_ ; // in pixels
15751576
15761577 int font_size = pin_font_.pointSize ();
1577- int largest_text_width = font_metrics.boundingRect (largest_text).width ();
15781578 const int drawing_font_size = 6 ; // in points
15791579
15801580 // when the size is minimum the text won't be drawn
15811581 const int minimum_font_size = drawing_font_size - 1 ;
15821582
1583- while (largest_text_width > available_space) {
1584- if (font_size == minimum_font_size) {
1583+ int largest_text_width = 0 ;
1584+ std::set<odb::dbBTerm*> checked;
1585+ odb::dbTech* tech = block->getTech ();
1586+ for (odb::dbTechLayer* layer : tech->getLayers ()) {
1587+ if (restart_) {
1588+ return ;
1589+ }
1590+ if (font_size <= minimum_font_size) {
15851591 break ;
15861592 }
1587- font_size -= 1 ;
1588- pin_font_.setPointSize (font_size);
1589- QFontMetrics current_font_metrics (pin_font_);
1590- largest_text_width
1591- = current_font_metrics.boundingRect (largest_text).width ();
1593+ for (const auto & [box, pin] :
1594+ viewer_->search_ .searchBPins (block,
1595+ layer,
1596+ bounds.xMin (),
1597+ bounds.yMin (),
1598+ bounds.xMax (),
1599+ bounds.yMax ())) {
1600+ if (restart_) {
1601+ return ;
1602+ }
1603+ odb::dbBTerm* bterm = pin->getBTerm ();
1604+ if (checked.find (bterm) != checked.end ()) {
1605+ continue ;
1606+ }
1607+ checked.insert (bterm);
1608+
1609+ QString current_text = QString::fromStdString (pin->getName ());
1610+ int text_width = font_metrics.boundingRect (current_text).width ();
1611+ if (text_width > largest_text_width) {
1612+ largest_text_width = text_width;
1613+ }
1614+ while (largest_text_width > available_space) {
1615+ if (font_size <= minimum_font_size) {
1616+ break ;
1617+ }
1618+ font_size -= 1 ;
1619+ pin_font_.setPointSize (font_size);
1620+ QFontMetrics current_font_metrics (pin_font_);
1621+ largest_text_width
1622+ = current_font_metrics.boundingRect (current_text).width ();
1623+ }
1624+
1625+ if (font_size <= minimum_font_size) {
1626+ break ;
1627+ }
1628+ }
15921629 }
15931630
15941631 // draw names of pins when text height is at least 6 pts
15951632 pin_draw_names_ = font_size >= drawing_font_size;
15961633 } else {
15971634 pin_draw_names_ = false ;
15981635 }
1599-
1600- for (odb::dbBTerm* term : block->getBTerms ()) {
1601- if (restart_) {
1602- break ;
1603- }
1604- if (!viewer_->isNetVisible (term->getNet ())) {
1605- continue ;
1606- }
1607- for (odb::dbBPin* pin : term->getBPins ()) {
1608- odb::dbPlacementStatus status = pin->getPlacementStatus ();
1609- if (!status.isPlaced ()) {
1610- continue ;
1611- }
1612- for (odb::dbBox* box : pin->getBoxes ()) {
1613- if (!box) {
1614- continue ;
1615- }
1616-
1617- pins_[box->getTechLayer ()].emplace_back (term, box);
1618- }
1619- }
1620- }
16211636}
16221637
16231638void RenderThread::drawIOPins (Painter& painter,
16241639 odb::dbBlock* block,
16251640 const odb::Rect& bounds,
16261641 odb::dbTechLayer* layer)
16271642{
1628- const auto & pins = pins_[layer];
1629- if (pins. empty ()) {
1643+ if (!viewer_-> options_ -> areIOPinsVisible ()
1644+ || !viewer_-> options_ -> areIOPinNamesVisible ()) {
16301645 return ;
16311646 }
16321647
@@ -1659,10 +1674,11 @@ void RenderThread::drawIOPins(Painter& painter,
16591674
16601675 // RTree used to search for overlapping shapes and decide if rotation of
16611676 // text is needed.
1662- bgi::rtree<odb::Rect, bgi::quadratic<16 >> pin_text_spec_shapes;
1677+ using PinShapeTree = bgi::rtree<odb::Rect, bgi::quadratic<16 >>;
1678+ PinShapeTree pin_text_spec_shapes;
16631679 struct PinText
16641680 {
1665- odb::Rect rect;
1681+ std::optional< odb::Rect> rect;
16661682 bool can_rotate;
16671683 std::string text;
16681684 odb::Point pt;
@@ -1673,11 +1689,21 @@ void RenderThread::drawIOPins(Painter& painter,
16731689 painter.setPen (layer);
16741690 painter.setBrush (layer);
16751691
1676- for (const auto & [term, box] : pins) {
1692+ std::vector<odb::Rect> pin_text_spec_shape_rects;
1693+ for (const auto & [box, pin] : viewer_->search_ .searchBPins (block,
1694+ layer,
1695+ bounds.xMin (),
1696+ bounds.yMin (),
1697+ bounds.xMax (),
1698+ bounds.yMax ())) {
16771699 if (restart_) {
16781700 break ;
16791701 }
1680- const auto pin_dir = term->getIoType ();
1702+
1703+ odb::dbBTerm* term = pin->getBTerm ();
1704+ if (!viewer_->options_ ->isNetVisible (term->getNet ())) {
1705+ continue ;
1706+ }
16811707
16821708 Point pin_center ((box->xMin () + box->xMax ()) / 2 ,
16831709 (box->yMin () + box->yMax ()) / 2 );
@@ -1716,6 +1742,7 @@ void RenderThread::drawIOPins(Painter& painter,
17161742
17171743 // select marker
17181744 const std::vector<Point>* template_points = &bi_marker;
1745+ const auto pin_dir = term->getIoType ();
17191746 if (pin_dir == odb::dbIoType::INPUT) {
17201747 template_points = &in_marker;
17211748 } else if (pin_dir == odb::dbIoType::OUTPUT) {
@@ -1724,6 +1751,7 @@ void RenderThread::drawIOPins(Painter& painter,
17241751
17251752 // make new marker based on pin location
17261753 std::vector<Point> marker;
1754+ marker.reserve (template_points->size ());
17271755 for (const auto & pt : *template_points) {
17281756 Point new_pt = pt;
17291757 xfm.apply (new_pt);
@@ -1766,13 +1794,15 @@ void RenderThread::drawIOPins(Painter& painter,
17661794 pin_specs.text );
17671795 text_rect.bloat (text_margin, text_rect);
17681796 pin_specs.rect = text_rect;
1769- pin_text_spec_shapes.insert (pin_specs.rect );
1770- } else {
1771- pin_specs.rect = odb::Rect ();
1797+ pin_text_spec_shape_rects.push_back (text_rect);
17721798 }
17731799 pin_text_spec.push_back (std::move (pin_specs));
17741800 }
17751801 }
1802+ if (!pin_text_spec_shape_rects.empty ()) {
1803+ pin_text_spec_shapes = PinShapeTree (pin_text_spec_shape_rects.begin (),
1804+ pin_text_spec_shape_rects.end ());
1805+ }
17761806
17771807 painter.setPen (layer);
17781808 auto color = painter.getPenColor ();
@@ -1788,9 +1818,9 @@ void RenderThread::drawIOPins(Painter& painter,
17881818 bool do_rotate = false ;
17891819 auto anchor = pin.anchor ;
17901820 if (pin.can_rotate ) {
1791- if (pin_text_spec_shapes.qbegin (bgi::intersects (pin.rect )
1821+ if (pin_text_spec_shapes.qbegin (bgi::intersects (* pin.rect )
17921822 && bgi::satisfies ([&](const auto & other) {
1793- return !bg::equals (other, pin.rect );
1823+ return !bg::equals (other, * pin.rect );
17941824 }))
17951825 != pin_text_spec_shapes.qend ()) {
17961826 // adjust anchor
0 commit comments