]>
git.siccegge.de Git - frida/frida.git/blob - src/gui/widgets/CFGScene.cxx
1 #include "CFGScene.hxx"
3 void CFGScene::drawBackground(QPainter
* painter
, const QRectF
& rect
) {
4 QGraphicsScene::drawBackground(painter
, rect
);
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));
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);
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);
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);
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
39 void CFGScene::drawLine(QPainter
* painter
, BasicBlockWidget
* from
, BasicBlockWidget
* to
, int8_t side
) {
40 QPointF from_p
= from
->getExits()[side
+1] + QPointF(0, 20);
41 QPointF to_p
= to
->getEntry() - QPointF(0, 20);
42 if ((to_p
- from_p
).y() > 0) {
44 QPointF
angle1(from_p
+ QPointF(0, (to_p
- from_p
).y()));
45 painter
->drawLine(from_p
, angle1
);
46 painter
->drawLine(angle1
, to_p
);
49 QRectF
from_r(from
->boundingRect()), to_r(to
->boundingRect());
50 from_r
.moveTo(from
->scenePos());
51 to_r
.moveTo(to
->scenePos());
52 QRectF bound
= from_r
| to_r
;
53 if (std::abs(bound
.right() - from_p
.x()) > std::abs(bound
.left() - to_p
.x())) {
55 QPointF middle1
= from_p
+ QPointF(bound
.left() - from_p
.x() - 20, 0);
56 QPointF middle2
= to_p
+ QPointF(bound
.left() - to_p
.x() - 20, 0);
58 painter
->drawLine(from_p
, middle1
);
59 painter
->drawLine(middle1
, middle2
);
60 painter
->drawLine(middle2
, to_p
);
63 QPointF middle1
= from_p
- QPointF(from_p
.x() - bound
.right() - 20, 0);
64 QPointF middle2
= to_p
- QPointF(to_p
.x() - bound
.right() - 20, 0);
66 painter
->drawLine(from_p
, middle1
);
67 painter
->drawLine(middle1
, middle2
);
68 painter
->drawLine(middle2
, to_p
);
73 void CFGScene::spaceWidgets() {
76 /* While some BasicBlockWidget overlaps with a direct predecessor,
77 * move that widget down one step. Move each widget at most once
78 * per iteration so that widgets with severall incoming edges
79 * don't outrun these with less -- preserving order by address
84 for (BasicBlockWidget
* widget
: widgets
) {
85 QPointF
out(std::get
<0>(widget
->getExits()));
86 BasicBlockWidget
** next
= widget
->getNext();
89 && (next
[0]->getEntry() - widget
->getEntry()).y() > 0
90 && (next
[0]->getEntry() - out
).y() < 50) {
91 widget
->moveBy(0, -3);
93 } else if (NULL
!= next
[1]
94 && (next
[1]->getEntry() - widget
->getEntry()).y() > 0
95 && (next
[1]->getEntry() - out
).y() < 50) {
96 widget
->moveBy(0, -3);
102 /* If there are still BasicBlockWidgets overlapping (BasicBlocks
103 * that don't have a direct edge) spread them sideways.
105 for (BasicBlockWidget
* widget
: widgets
) {
106 QRectF relevantRect
= widget
->boundingRect();
107 relevantRect
.moveTo(widget
->scenePos());
108 relevantRect
.adjust(-20, -20, 20, 20);
109 for (QGraphicsItem
* item
: items(relevantRect
)) {
110 if (item
== widget
) continue;
111 if (std::find(widgets
.begin(), widgets
.end(), item
) == widgets
.end()) continue;
112 QRectF itemrect
= item
->boundingRect();
113 itemrect
.moveTo(item
->scenePos());
114 while (relevantRect
.intersects(itemrect
)) {
115 if (widget
->scenePos().x() > item
->scenePos().x()) {
116 widget
->moveBy(3, 0);
117 relevantRect
.moveTo(widget
->scenePos());
120 itemrect
.moveTo(item
->scenePos());
127 void CFGScene::highlightBlock(BasicBlockWidget
* block
) {
128 QGraphicsView
* view
= *(views().begin());
129 if (highlightedBlock
) {
130 highlightedBlock
->setColor(highlightedBlock
->defaultColor
);
131 update(highlightedBlock
->boundingRect());
133 highlightedBlock
= block
;
134 view
->centerOn(block
);
135 block
->setColor(block
->highlightColor
);
136 update(block
->boundingRect());