]> git.siccegge.de Git - frida/frida.git/blob - src/gui/widgets/CFGScene.cxx
Wrap long lines
[frida/frida.git] / src / gui / widgets / CFGScene.cxx
1 #include "CFGScene.hxx"
2
3 void CFGScene::drawBackground(QPainter* painter, const QRectF & rect) {
4 QGraphicsScene::drawBackground(painter, rect);
5
6 spaceWidgets();
7
8 for (BasicBlockWidget * widget : widgets) {
9 QPointF kopf = widget->getEntry();
10 painter->setPen(QColor(0x00, 0xff, 0x00, 0xff));
11 painter->drawLine(kopf, kopf - QPointF(0, 20));
12
13 auto tails = widget->getExits();
14 auto next = widget->getNext();
15 if (NULL != next[0]) {
16 if (NULL != next[1]) {
17 painter->setPen(QColor(0xff, 0x00, 0x00, 0xff));
18 painter->drawLine(std::get<0>(tails), std::get<0>(tails) + QPointF(0, 20));
19 drawLine(painter, widget, next[1], -1);
20
21 painter->setPen(QColor(0x00, 0xff, 0x00, 0xff));
22 painter->drawLine(std::get<2>(tails), std::get<2>(tails) + QPointF(0, 20));
23 drawLine(painter, widget, next[0], 1);
24 } else {
25 painter->setPen(QColor(0x00, 0x00, 0x00, 0xff));
26 painter->drawLine(std::get<1>(tails), std::get<1>(tails) + QPointF(0, 20));
27 drawLine(painter, widget, next[0], 0);
28 }
29 }
30 }
31 }
32
33 /* Forward edges: Forward (downward) edges are just drawn straight
34 * down and then to the right side
35 * Backward edges: Consider the smallest rectangle that contains both,
36 * source and destination block. Draw the edge along
37 * the shorter side of that rectangle
38 */
39 void CFGScene::drawLine(QPainter* painter, BasicBlockWidget * from, BasicBlockWidget * to,
40 int8_t side) {
41 QPointF from_p = from->getExits()[side+1] + QPointF(0, 20);
42 QPointF to_p = to->getEntry() - QPointF(0, 20);
43 if ((to_p - from_p).y() > 0) {
44 /* Forward Edge */
45 QPointF angle1(from_p + QPointF(0, (to_p - from_p).y()));
46 painter->drawLine(from_p, angle1);
47 painter->drawLine(angle1, to_p);
48 } else {
49 /* Backward Edge */
50 QRectF from_r(from->boundingRect()), to_r(to->boundingRect());
51 from_r.moveTo(from->scenePos());
52 to_r.moveTo(to->scenePos());
53 QRectF bound = from_r | to_r;
54 if (std::abs(bound.right() - from_p.x()) > std::abs(bound.left() - to_p.x())) {
55 /* we go left */
56 QPointF middle1 = from_p + QPointF(bound.left() - from_p.x() - 20, 0);
57 QPointF middle2 = to_p + QPointF(bound.left() - to_p.x() - 20, 0);
58
59 painter->drawLine(from_p, middle1);
60 painter->drawLine(middle1, middle2);
61 painter->drawLine(middle2, to_p);
62 } else {
63 /* we go right */
64 QPointF middle1 = from_p - QPointF(from_p.x() - bound.right() - 20, 0);
65 QPointF middle2 = to_p - QPointF(to_p.x() - bound.right() - 20, 0);
66
67 painter->drawLine(from_p, middle1);
68 painter->drawLine(middle1, middle2);
69 painter->drawLine(middle2, to_p);
70 }
71 }
72 }
73
74 void CFGScene::spaceWidgets() {
75 bool changed = false;
76
77 /* While some BasicBlockWidget overlaps with a direct predecessor,
78 * move that widget down one step. Move each widget at most once
79 * per iteration so that widgets with severall incoming edges
80 * don't outrun these with less -- preserving order by address
81 * where appropriate.
82 */
83 do {
84 changed = false;
85 for (BasicBlockWidget * widget : widgets) {
86 QPointF out(std::get<0>(widget->getExits()));
87 BasicBlockWidget ** next = widget->getNext();
88
89 if (NULL != next[0]
90 && (next[0]->getEntry() - widget->getEntry()).y() > 0
91 && (next[0]->getEntry() - out).y() < 50) {
92 widget->moveBy(0, -3);
93 changed = true;
94 } else if (NULL != next[1]
95 && (next[1]->getEntry() - widget->getEntry()).y() > 0
96 && (next[1]->getEntry() - out).y() < 50) {
97 widget->moveBy(0, -3);
98 changed = true;
99 }
100 }
101 } while (changed);
102
103 /* If there are still BasicBlockWidgets overlapping (BasicBlocks
104 * that don't have a direct edge) spread them sideways.
105 */
106 for (BasicBlockWidget * widget : widgets) {
107 QRectF relevantRect = widget->boundingRect();
108 relevantRect.moveTo(widget->scenePos());
109 relevantRect.adjust(-20, -20, 20, 20);
110 for (QGraphicsItem * item : items(relevantRect)) {
111 if (item == widget)
112 continue;
113 if (std::find(widgets.begin(), widgets.end(), item) == widgets.end())
114 continue;
115 QRectF itemrect = item->boundingRect();
116 itemrect.moveTo(item->scenePos());
117 while (relevantRect.intersects(itemrect)) {
118 if (widget->scenePos().x() > item->scenePos().x()) {
119 widget->moveBy(3, 0);
120 relevantRect.moveTo(widget->scenePos());
121 } else {
122 item->moveBy(3, 0);
123 itemrect.moveTo(item->scenePos());
124 }
125 }
126 }
127 }
128 }
129
130 void CFGScene::highlightBlock(BasicBlockWidget* block) {
131 QGraphicsView* view = *(views().begin());
132 if (highlightedBlock) {
133 highlightedBlock->setColor(highlightedBlock->defaultColor);
134 update(highlightedBlock->boundingRect());
135 }
136 highlightedBlock = block;
137 view->centerOn(block);
138 block->setColor(block->highlightColor);
139 update(block->boundingRect());
140 }