#include "CFGScene.hxx"
void CFGScene::drawBackground(QPainter* painter, const QRectF & rect) {
- QGraphicsScene::drawBackground(painter, rect);
-
- spaceWidgets();
-
- 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));
- }
- }
- }
+ QGraphicsScene::drawBackground(painter, rect);
+
+ spaceWidgets();
+
+ 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, 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();
-
- 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);
+ 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);
+
+ 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;
+ if (std::find(widgets.begin(), widgets.end(), item) == widgets.end()) 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());
+ }
+ }
+ }
+ }
}