diff --git a/Ghidra/Features/FunctionGraph/src/main/help/help/topics/FunctionGraphPlugin/Function_Graph.html b/Ghidra/Features/FunctionGraph/src/main/help/help/topics/FunctionGraphPlugin/Function_Graph.html index 9e5de3196f..b66dce8c8f 100644 --- a/Ghidra/Features/FunctionGraph/src/main/help/help/topics/FunctionGraphPlugin/Function_Graph.html +++ b/Ghidra/Features/FunctionGraph/src/main/help/help/topics/FunctionGraphPlugin/Function_Graph.html @@ -840,6 +840,22 @@ location when zooming from the middle-mouse. The default for this option is off, which triggers zoom to work from the center of the graph, regardless of the mouse location.

+

The View Settings option describes how the graph will be zoomed when it is first + loaded. The values are:

+ + +
+
+

There are various edge color and highlight color options available to change. The highlight colors are those to be used when the flow animations take place.

diff --git a/Ghidra/Features/FunctionGraph/src/main/help/help/topics/FunctionGraphPlugin/Function_Graph_Layouts.html b/Ghidra/Features/FunctionGraph/src/main/help/help/topics/FunctionGraphPlugin/Function_Graph_Layouts.html index 2f2eab68a8..6e71260598 100644 --- a/Ghidra/Features/FunctionGraph/src/main/help/help/topics/FunctionGraphPlugin/Function_Graph_Layouts.html +++ b/Ghidra/Features/FunctionGraph/src/main/help/help/topics/FunctionGraphPlugin/Function_Graph_Layouts.html @@ -49,6 +49,13 @@ notes on how edges are routed for this layout.)

+ +
+

The Use Dim Return Edges option makes default code block return flow edges + lighter than conditional edges. This makes it easier for users to scan the + graph and ignore return flows. +

+
diff --git a/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/mvc/FunctionGraphOptions.java b/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/mvc/FunctionGraphOptions.java index 51b6773a9a..ea22f1cf44 100644 --- a/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/mvc/FunctionGraphOptions.java +++ b/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/mvc/FunctionGraphOptions.java @@ -42,7 +42,7 @@ public class FunctionGraphOptions extends VisualGraphOptions { private static final String EDGE_COLOR_CONDITIONAL_JUMP_KEY = "Edge Color - Conditional Jump "; //@formatter:off - private static final String NAVIGATION_HISTORY_KEY = "Navigation History"; + private static final String NAVIGATION_HISTORY_KEY = "Navigation History"; private static final String NAVIGATION_HISTORY_DESCRIPTION = "Determines how the navigation history will be updated when using the Function Graph. " + "The basic options are:" + @@ -185,8 +185,8 @@ public class FunctionGraphOptions extends VisualGraphOptions { options.registerOption(SCROLL_WHEEL_PANS_KEY, getScrollWheelPans(), help, SCROLL_WHEEL_PANS_DESCRIPTION); - options.registerOption(GRAPH_BACKGROUND_COLOR_KEY, DEFAULT_GRAPH_BACKGROUND_COLOR, - help, GRAPH_BACKGROUND_COLOR_DESCRPTION); + options.registerOption(GRAPH_BACKGROUND_COLOR_KEY, DEFAULT_GRAPH_BACKGROUND_COLOR, help, + GRAPH_BACKGROUND_COLOR_DESCRPTION); options.registerOption(DEFAULT_VERTEX_BACKGROUND_COLOR_KEY, DEFAULT_VERTEX_BACKGROUND_COLOR, help, DEFAULT_VERTEX_BACKGROUND_COLOR_DESCRPTION); diff --git a/Ghidra/Features/FunctionGraphDecompilerExtension/src/main/java/ghidra/app/plugin/core/functiongraph/graph/layout/DNLayoutOptions.java b/Ghidra/Features/FunctionGraphDecompilerExtension/src/main/java/ghidra/app/plugin/core/functiongraph/graph/layout/DNLayoutOptions.java index 1467a84781..1549c2cd9a 100644 --- a/Ghidra/Features/FunctionGraphDecompilerExtension/src/main/java/ghidra/app/plugin/core/functiongraph/graph/layout/DNLayoutOptions.java +++ b/Ghidra/Features/FunctionGraphDecompilerExtension/src/main/java/ghidra/app/plugin/core/functiongraph/graph/layout/DNLayoutOptions.java @@ -31,7 +31,12 @@ public class DNLayoutOptions implements FGLayoutOptions { "edges should be routed around any intersecting vertex. When toggled off, edges will " + "pass through any intersecting vertices."; + private static final String DIM_RETURN_EDGES_KEY = "Use Dim Return Edges"; + private static final String DIM_RETURN_EDGES_DESCRIPTION = + "Signals to lighten the default return edges."; + private boolean useEdgeRoutingAroundVertices; + private boolean useDimmedReturnEdges = true; @Override public void registerOptions(Options options) { @@ -40,21 +45,32 @@ public class DNLayoutOptions implements FGLayoutOptions { options.registerOption(USE_EDGE_ROUTING_AROUND_VERTICES_KEY, useEdgeRoutingAroundVertices, help, USE_EDGE_ROUTING_AROUND_VERTICES_DESCRIPTION); + + options.registerOption(DIM_RETURN_EDGES_KEY, useDimmedReturnEdges, help, + DIM_RETURN_EDGES_DESCRIPTION); } @Override public void loadOptions(Options options) { useEdgeRoutingAroundVertices = options.getBoolean(USE_EDGE_ROUTING_AROUND_VERTICES_KEY, useEdgeRoutingAroundVertices); + + useDimmedReturnEdges = options.getBoolean(DIM_RETURN_EDGES_KEY, useDimmedReturnEdges); + } public boolean useEdgeRoutingAroundVertices() { return useEdgeRoutingAroundVertices; } + public boolean useDimmedReturnEdges() { + return useDimmedReturnEdges; + } + @Override public boolean optionChangeRequiresRelayout(String optionName) { // format: 'Nested Code Layout.Route Edges....' - return optionName.endsWith(USE_EDGE_ROUTING_AROUND_VERTICES_KEY); + return optionName.endsWith(USE_EDGE_ROUTING_AROUND_VERTICES_KEY) || + optionName.endsWith(DIM_RETURN_EDGES_KEY); } } diff --git a/Ghidra/Features/FunctionGraphDecompilerExtension/src/main/java/ghidra/app/plugin/core/functiongraph/graph/layout/DecompilerNestedLayout.java b/Ghidra/Features/FunctionGraphDecompilerExtension/src/main/java/ghidra/app/plugin/core/functiongraph/graph/layout/DecompilerNestedLayout.java index e3a40d8ff3..660257ed51 100644 --- a/Ghidra/Features/FunctionGraphDecompilerExtension/src/main/java/ghidra/app/plugin/core/functiongraph/graph/layout/DecompilerNestedLayout.java +++ b/Ghidra/Features/FunctionGraphDecompilerExtension/src/main/java/ghidra/app/plugin/core/functiongraph/graph/layout/DecompilerNestedLayout.java @@ -412,6 +412,13 @@ public class DecompilerNestedLayout extends AbstractFGLayout { // Condensing is when the graph will pull nodes closer together on the x axis to // reduce whitespace and make the entire graph easier to see. In this case, update // the offset to avoid running into the moved vertices. + + // Condensing Note: we have guilty knowledge that our parent class my condense the + // vertices and edges towards the center of the graph after we calculate positions. + // To prevent the edges from moving to far behind the vertices, we will compensate a + // bit for that effect using this offset value. The getEdgeOffset() method is + // updated for the condense factor. + int exaggerationFactor = 1; if (isCondensedLayout()) { exaggerationFactor = 2; // determined by trial-and-error; can be made into an option @@ -675,6 +682,13 @@ public class DecompilerNestedLayout extends AbstractFGLayout { // Condensing is when the graph will pull nodes closer together on the x axis to // reduce whitespace and make the entire graph easier to see. In this case, update // the offset to avoid running into the moved vertices. + + // Condensing Note: we have guilty knowledge that our parent class my condense the + // vertices and edges towards the center of the graph after we calculate positions. + // To prevent the edges from moving to far behind the vertices, we will compensate a + // bit for that effect using this offset value. The getEdgeOffset() method is + // updated for the condense factor. + int vertexToEdgeOffset = otherVertex.getEdgeOffset(); int exaggerationFactor = 1; if (isCondensedLayout()) { @@ -700,7 +714,7 @@ public class DecompilerNestedLayout extends AbstractFGLayout { -p2 - just past the left edge -p3 - just past the bottom of the vertex -p4 - back at the original x value - + | .___| | .-----. @@ -794,6 +808,10 @@ public class DecompilerNestedLayout extends AbstractFGLayout { private void lighten(FGEdge e) { + if (!getLayoutOptions().useDimmedReturnEdges()) { + return; + } + // assumption: edges that move to the left in this layout are return flows that happen // after the code block has been executed. We dim those a bit so that they // produce less clutter.