X-Git-Url: https://git.siccegge.de//index.cgi?p=frida%2Ffrida.git;a=blobdiff_plain;f=src%2Fgui%2Fwidgets%2FCFGScene.cxx;h=ec33463c835c5c1a3ee8856e1bf8dc445bb55835;hp=a297c856f3dd7dc8aa91e5a29e8d3c9da59cb7dc;hb=9e283567ac56a6433e832d0fa38cf534a0cb8f9f;hpb=fae0fc8f1d90f5f36cfc336a92aa9d488471332d diff --git a/src/gui/widgets/CFGScene.cxx b/src/gui/widgets/CFGScene.cxx index a297c85..ec33463 100644 --- a/src/gui/widgets/CFGScene.cxx +++ b/src/gui/widgets/CFGScene.cxx @@ -1,73 +1,109 @@ #include "CFGScene.hxx" void CFGScene::drawBackground(QPainter* painter, const QRectF & rect) { - QGraphicsScene::drawBackground(painter, rect); + QGraphicsScene::drawBackground(painter, rect); - spaceWidgets(); + spaceWidgets(); - for (BasicBlockWidget * widget : widgets) { - QPointF kopf = widget->getEntry(); - painter->setPen(QColor(0x00, 0xff, 0x00, 0xff)); - painter->drawLine(kopf, kopf - QPointF(0, 20)); + for (BasicBlockWidget * widget : widgets) { + QPointF kopf = widget->getEntry(); + painter->setPen(QColor(0x00, 0xff, 0x00, 0xff)); + painter->drawLine(kopf, kopf - QPointF(0, 20)); - auto tails = widget->getExits(); - auto next = widget->getNext(); - if (NULL != next[0]) { - if (NULL != next[1]) { - painter->setPen(QColor(0xff, 0x00, 0x00, 0xff)); - painter->drawLine(std::get<0>(tails), std::get<0>(tails) + QPointF(0, 20)); - drawLine(painter, std::get<0>(tails) + QPointF(0, 20), next[1]->getEntry() - QPointF(0, 20)); - painter->setPen(QColor(0x00, 0xff, 0x00, 0xff)); - painter->drawLine(std::get<2>(tails), std::get<2>(tails) + QPointF(0, 20)); - drawLine(painter, std::get<2>(tails) + QPointF(0, 20), next[0]->getEntry() - QPointF(0, 20)); - } else { - painter->setPen(QColor(0x00, 0x00, 0x00, 0xff)); - painter->drawLine(std::get<1>(tails), std::get<1>(tails) + QPointF(0, 20)); - drawLine(painter, std::get<1>(tails) + QPointF(0, 20), next[0]->getEntry() - QPointF(0, 20)); - } - } - } + auto tails = widget->getExits(); + auto next = widget->getNext(); + if (NULL != next[0]) { + if (NULL != next[1]) { + painter->setPen(QColor(0xff, 0x00, 0x00, 0xff)); + painter->drawLine(std::get<0>(tails), std::get<0>(tails) + QPointF(0, 20)); + drawLine(painter, widget, next[1], -1); + + painter->setPen(QColor(0x00, 0xff, 0x00, 0xff)); + painter->drawLine(std::get<2>(tails), std::get<2>(tails) + QPointF(0, 20)); + drawLine(painter, widget, next[0], 1); + } else { + painter->setPen(QColor(0x00, 0x00, 0x00, 0xff)); + painter->drawLine(std::get<1>(tails), std::get<1>(tails) + QPointF(0, 20)); + drawLine(painter, widget, next[0], 0); + } + } + } } -void CFGScene::drawLine(QPainter* painter, QPointF from, QPointF to, bool left) { - if ((to - from).y() > 0) { - QPointF angle1(from + QPointF(0, (to - from).y())), angle2(to - QPointF(0, (to - from).y() / 2)); - painter->drawLine(from, angle1); - painter->drawLine(angle1, to); - } +void CFGScene::drawLine(QPainter* painter, BasicBlockWidget * from, BasicBlockWidget * to, int8_t side) { + QPointF from_p = from->getExits()[side+1] + QPointF(0, 20); + QPointF to_p = to->getEntry() - QPointF(0, 20); + if ((to_p - from_p).y() > 0) { + /* Forward Edge */ + QPointF angle1(from_p + QPointF(0, (to_p - from_p).y())); + painter->drawLine(from_p, angle1); + painter->drawLine(angle1, to_p); + } else { + /* Backward Edge */ + QRectF from_r(from->boundingRect()), to_r(to->boundingRect()); + from_r.moveTo(from->scenePos()); + to_r.moveTo(to->scenePos()); + QRectF bound = from_r | to_r; + if (std::abs(bound.right() - from_p.x()) > std::abs(bound.left() - to_p.x())) { + /* we go left */ + QPointF middle1 = from_p + QPointF(bound.left() - from_p.x() - 20, 0); + QPointF middle2 = to_p + QPointF(bound.left() - to_p.x() - 20, 0); + + painter->drawLine(from_p, middle1); + painter->drawLine(middle1, middle2); + painter->drawLine(middle2, to_p); + } else { + /* we go right */ + QPointF middle1 = from_p - QPointF(from_p.x() - bound.right() - 20, 0); + QPointF middle2 = to_p - QPointF(to_p.x() - bound.right() - 20, 0); + + painter->drawLine(from_p, middle1); + painter->drawLine(middle1, middle2); + painter->drawLine(middle2, to_p); + } + } } void CFGScene::spaceWidgets() { - bool changed = false; - do { - changed = false; - for (BasicBlockWidget * widget : widgets) { - QPointF out(std::get<0>(widget->getExits())); - BasicBlockWidget ** next = widget->getNext(); + bool changed = false; + do { + changed = false; + for (BasicBlockWidget * widget : widgets) { + QPointF out(std::get<0>(widget->getExits())); + BasicBlockWidget ** next = widget->getNext(); - if (NULL != next[0] - && (next[0]->getEntry() - widget->getEntry()).y() > 0 - && (next[0]->getEntry() - out).y() < 50) { - next[0]->moveBy(0, 1); - changed = true; - } - if (NULL != next[1] - && (next[1]->getEntry() - widget->getEntry()).y() > 0 - && (next[1]->getEntry() - out).y() < 50) { - next[1]->moveBy(0, 1); - changed = true; - } - } - } while (changed); + if (NULL != next[0] + && (next[0]->getEntry() - widget->getEntry()).y() > 0 + && (next[0]->getEntry() - out).y() < 50) { + next[0]->moveBy(0, 1); + changed = true; + } + if (NULL != next[1] + && (next[1]->getEntry() - widget->getEntry()).y() > 0 + && (next[1]->getEntry() - out).y() < 50) { + next[1]->moveBy(0, 1); + changed = true; + } + } + } while (changed); - for (BasicBlockWidget * widget : widgets) { - for (QGraphicsItem * item : widget->collidingItems()) { - while (widget->collidesWithItem(item)) { - if (widget->scenePos().x() > item->scenePos().x()) - widget->moveBy(1, 0); - else - item->moveBy(1, 0); - } - } - } + for (BasicBlockWidget * widget : widgets) { + QRectF relevantRect = widget->boundingRect(); + relevantRect.moveTo(widget->scenePos()); + relevantRect.adjust(-20, -20, 20, 20); + for (QGraphicsItem * item : items(relevantRect)) { + if (item == widget) continue; + QRectF itemrect = item->boundingRect(); + itemrect.moveTo(item->scenePos()); + while (relevantRect.intersects(itemrect)) { + if (widget->scenePos().x() > item->scenePos().x()) { + widget->moveBy(1, 0); + relevantRect.moveTo(widget->scenePos()); + } else { + item->moveBy(1, 0); + itemrect.moveTo(item->scenePos()); + } + } + } + } }