]>
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
,
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) {
45 QPointF
angle1(from_p
+ QPointF(0, (to_p
- from_p
).y()));
46 painter
->drawLine(from_p
, angle1
);
47 painter
->drawLine(angle1
, to_p
);
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())) {
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);
59 painter
->drawLine(from_p
, middle1
);
60 painter
->drawLine(middle1
, middle2
);
61 painter
->drawLine(middle2
, to_p
);
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);
67 painter
->drawLine(from_p
, middle1
);
68 painter
->drawLine(middle1
, middle2
);
69 painter
->drawLine(middle2
, to_p
);
74 void CFGScene::spaceWidgets() {
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
85 for (BasicBlockWidget
* widget
: widgets
) {
86 QPointF
out(std::get
<0>(widget
->getExits()));
87 BasicBlockWidget
** next
= widget
->getNext();
90 && (next
[0]->getEntry() - widget
->getEntry()).y() > 0
91 && (next
[0]->getEntry() - out
).y() < 50) {
92 widget
->moveBy(0, -3);
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);
103 /* If there are still BasicBlockWidgets overlapping (BasicBlocks
104 * that don't have a direct edge) spread them sideways.
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
)) {
113 if (std::find(widgets
.begin(), widgets
.end(), item
) == widgets
.end())
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());
123 itemrect
.moveTo(item
->scenePos());
130 void CFGScene::highlightBlock(BasicBlockWidget
* block
) {
131 QGraphicsView
* view
= *(views().begin());
132 if (highlightedBlock
) {
133 highlightedBlock
->setColor(highlightedBlock
->defaultColor
);
134 update(highlightedBlock
->boundingRect());
136 highlightedBlock
= block
;
137 view
->centerOn(block
);
138 block
->setColor(block
->highlightColor
);
139 update(block
->boundingRect());