mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-940 - Function Graph - fixed caching satellite view not showing
primary view lens; fixed occasional bad vertex clipping
This commit is contained in:
parent
2466f85ea8
commit
76569d3ca9
3 changed files with 55 additions and 28 deletions
|
@ -112,6 +112,12 @@ public class DecompilerNestedLayout extends AbstractFGLayout {
|
||||||
return new DNLEdgeLabelRenderer<>(getCondenseFactor());
|
return new DNLEdgeLabelRenderer<>(getCondenseFactor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void condenseEdges(List<Row<FGVertex>> rows,
|
||||||
|
Map<FGEdge, List<Point2D>> newEdgeArticulations, double centerX, double centerY) {
|
||||||
|
// do not condense, as we route our edges at the preferred positions
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double getCondenseFactor() {
|
protected double getCondenseFactor() {
|
||||||
// our layout needs more spacing because we have custom edge routing that we want to
|
// our layout needs more spacing because we have custom edge routing that we want to
|
||||||
|
|
|
@ -313,20 +313,27 @@ public abstract class AbstractVisualGraphLayout<V extends VisualVertex,
|
||||||
Map<V, Point2D> vertexLayoutLocations =
|
Map<V, Point2D> vertexLayoutLocations =
|
||||||
positionVerticesInLayoutSpace(transformer, vertices, layoutLocations);
|
positionVerticesInLayoutSpace(transformer, vertices, layoutLocations);
|
||||||
|
|
||||||
Map<E, List<Point2D>> edgeLayoutArticulationLocations = new HashMap<>();
|
Rectangle graphBounds = getTotalGraphSize(vertexLayoutLocations, transformer);
|
||||||
Rectangle graphBounds =
|
|
||||||
getTotalGraphSize(vertexLayoutLocations, edgeLayoutArticulationLocations, transformer);
|
|
||||||
double centerX = graphBounds.getCenterX();
|
double centerX = graphBounds.getCenterX();
|
||||||
double centerY = graphBounds.getCenterY();
|
double centerY = graphBounds.getCenterY();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Condense vertices before placing edges. This allows layouts to perform custom routing
|
||||||
|
// of edges around vertices *after* condensing.
|
||||||
|
//
|
||||||
if (isCondensed) {
|
if (isCondensed) {
|
||||||
List<Row<V>> rows = gridLocations.rows();
|
List<Row<V>> rows = gridLocations.rows();
|
||||||
condense(rows, vertexLayoutLocations, edgeLayoutArticulationLocations, transformer,
|
condenseVertices(rows, vertexLayoutLocations, transformer, centerX, centerY);
|
||||||
centerX, centerY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
edgeLayoutArticulationLocations = positionEdgeArticulationsInLayoutSpace(transformer,
|
Map<E, List<Point2D>> edgeLayoutArticulations = positionEdgeArticulationsInLayoutSpace(
|
||||||
vertexLayoutLocations, edges, layoutLocations);
|
transformer, vertexLayoutLocations, edges, layoutLocations);
|
||||||
|
|
||||||
|
if (isCondensed) {
|
||||||
|
// note: some layouts will not condense the edges, as they perform custom routing
|
||||||
|
List<Row<V>> rows = gridLocations.rows();
|
||||||
|
condenseEdges(rows, edgeLayoutArticulations, centerX, centerY);
|
||||||
|
}
|
||||||
|
|
||||||
// DEGUG triggers grid lines to be printed; useful for debugging
|
// DEGUG triggers grid lines to be printed; useful for debugging
|
||||||
// VisualGraphRenderer.DEBUG_ROW_COL_MAP.put(this, layoutLocations.copy());
|
// VisualGraphRenderer.DEBUG_ROW_COL_MAP.put(this, layoutLocations.copy());
|
||||||
|
@ -334,8 +341,7 @@ public abstract class AbstractVisualGraphLayout<V extends VisualVertex,
|
||||||
layoutLocations.dispose();
|
layoutLocations.dispose();
|
||||||
gridLocations.dispose();
|
gridLocations.dispose();
|
||||||
|
|
||||||
return LayoutPositions.createNewPositions(vertexLayoutLocations,
|
return LayoutPositions.createNewPositions(vertexLayoutLocations, edgeLayoutArticulations);
|
||||||
edgeLayoutArticulationLocations);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<V, Point2D> positionVerticesInLayoutSpace(
|
private Map<V, Point2D> positionVerticesInLayoutSpace(
|
||||||
|
@ -430,11 +436,12 @@ public abstract class AbstractVisualGraphLayout<V extends VisualVertex,
|
||||||
}
|
}
|
||||||
|
|
||||||
private Rectangle getTotalGraphSize(Map<V, Point2D> vertexLocationMap,
|
private Rectangle getTotalGraphSize(Map<V, Point2D> vertexLocationMap,
|
||||||
Map<E, List<Point2D>> edgeArticulations,
|
|
||||||
com.google.common.base.Function<V, Shape> vertexShapeTransformer) {
|
com.google.common.base.Function<V, Shape> vertexShapeTransformer) {
|
||||||
|
|
||||||
|
// note: do not include edges in the size of the graph at this point, as some layouts use
|
||||||
|
// custom edge routing after this method is called
|
||||||
Set<V> vertices = vertexLocationMap.keySet();
|
Set<V> vertices = vertexLocationMap.keySet();
|
||||||
Set<E> edges = edgeArticulations.keySet();
|
Set<E> edges = Collections.emptySet();
|
||||||
|
|
||||||
Function<V, Rectangle> vertexToBounds = v -> {
|
Function<V, Rectangle> vertexToBounds = v -> {
|
||||||
|
|
||||||
|
@ -452,14 +459,13 @@ public abstract class AbstractVisualGraphLayout<V extends VisualVertex,
|
||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
Function<E, List<Point2D>> edgeToArticulations = e -> edgeArticulations.get(e);
|
Function<E, List<Point2D>> edgeToArticulations = e -> Collections.emptyList();
|
||||||
Rectangle bounds = GraphViewerUtils.getTotalGraphSizeInLayoutSpace(vertices, edges,
|
Rectangle bounds = GraphViewerUtils.getTotalGraphSizeInLayoutSpace(vertices, edges,
|
||||||
vertexToBounds, edgeToArticulations);
|
vertexToBounds, edgeToArticulations);
|
||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void condense(List<Row<V>> rows, Map<V, Point2D> newLocations,
|
protected void condenseVertices(List<Row<V>> rows, Map<V, Point2D> newLocations,
|
||||||
Map<E, List<Point2D>> newEdgeArticulations,
|
|
||||||
VisualGraphVertexShapeTransformer<V> transformer, double centerX, double centerY) {
|
VisualGraphVertexShapeTransformer<V> transformer, double centerX, double centerY) {
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -480,6 +486,22 @@ public abstract class AbstractVisualGraphLayout<V extends VisualVertex,
|
||||||
point.setLocation(offsetX, currentY);
|
point.setLocation(offsetX, currentY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// The above aggressive condensing may lead to neighboring node overlapping for
|
||||||
|
// nodes in the same row. Check to see if we need to move the nodes to avoid this case.
|
||||||
|
//
|
||||||
|
unclip(rows, newLocations, transformer);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void condenseEdges(List<Row<V>> rows, Map<E, List<Point2D>> newEdgeArticulations,
|
||||||
|
double centerX, double centerY) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Note: we move the articulations and vertices closer together on the x-axis. We do
|
||||||
|
// not move the y-axis, as that is already as close together as we would like at
|
||||||
|
// this point.
|
||||||
|
//
|
||||||
|
double condenseFactor = getCondenseFactor();
|
||||||
Collection<List<Point2D>> edgeArticulations = newEdgeArticulations.values();
|
Collection<List<Point2D>> edgeArticulations = newEdgeArticulations.values();
|
||||||
for (List<Point2D> edgePoints : edgeArticulations) {
|
for (List<Point2D> edgePoints : edgeArticulations) {
|
||||||
for (Point2D point : edgePoints) {
|
for (Point2D point : edgePoints) {
|
||||||
|
@ -493,12 +515,6 @@ public abstract class AbstractVisualGraphLayout<V extends VisualVertex,
|
||||||
point.setLocation(offsetX, currentY);
|
point.setLocation(offsetX, currentY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// The above aggressive condensing may lead to neighboring node overlapping for
|
|
||||||
// nodes in the same row. Check to see if we need to move the nodes to avoid this case.
|
|
||||||
//
|
|
||||||
unclip(rows, newLocations, transformer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -527,7 +543,7 @@ public abstract class AbstractVisualGraphLayout<V extends VisualVertex,
|
||||||
private void moveLeft(Row<V> row, int moveLeftStartIndex, Map<V, Point2D> vertexLocations,
|
private void moveLeft(Row<V> row, int moveLeftStartIndex, Map<V, Point2D> vertexLocations,
|
||||||
VisualGraphVertexShapeTransformer<V> transformer) {
|
VisualGraphVertexShapeTransformer<V> transformer) {
|
||||||
|
|
||||||
for (int i = moveLeftStartIndex; i >= 0; i--) {
|
for (int i = moveLeftStartIndex; i >= row.getStartColumn(); i--) {
|
||||||
V vertex = row.getVertex(i);
|
V vertex = row.getVertex(i);
|
||||||
V rightVertex = getRightVertex(row, i);
|
V rightVertex = getRightVertex(row, i);
|
||||||
moveLeftIfOverlaps(vertexLocations, transformer, vertex, rightVertex);
|
moveLeftIfOverlaps(vertexLocations, transformer, vertex, rightVertex);
|
||||||
|
@ -537,7 +553,7 @@ public abstract class AbstractVisualGraphLayout<V extends VisualVertex,
|
||||||
private void moveRight(Row<V> row, int moveRightStartIndex, Map<V, Point2D> vertexLocations,
|
private void moveRight(Row<V> row, int moveRightStartIndex, Map<V, Point2D> vertexLocations,
|
||||||
VisualGraphVertexShapeTransformer<V> transformer) {
|
VisualGraphVertexShapeTransformer<V> transformer) {
|
||||||
|
|
||||||
for (int i = moveRightStartIndex; i < row.getColumnCount(); i++) {
|
for (int i = moveRightStartIndex; i <= row.getEndColumn(); i++) {
|
||||||
V vertex = row.getVertex(i);
|
V vertex = row.getVertex(i);
|
||||||
V leftVertex = getLeftVertex(row, i);
|
V leftVertex = getLeftVertex(row, i);
|
||||||
moveRightIfOverlaps(vertexLocations, transformer, vertex, leftVertex);
|
moveRightIfOverlaps(vertexLocations, transformer, vertex, leftVertex);
|
||||||
|
|
|
@ -39,6 +39,8 @@ public class CachingSatelliteGraphViewer<V extends VisualVertex, E extends Visua
|
||||||
private BufferedImage bufferedBackgroundImage = null;
|
private BufferedImage bufferedBackgroundImage = null;
|
||||||
private BufferedImage bufferedOverlayImage = null;
|
private BufferedImage bufferedOverlayImage = null;
|
||||||
|
|
||||||
|
private Color backgroundColor;
|
||||||
|
|
||||||
private VisualVertexSatelliteRenderer<V, E> highlightRenderer =
|
private VisualVertexSatelliteRenderer<V, E> highlightRenderer =
|
||||||
new VisualVertexSatelliteRenderer<>();
|
new VisualVertexSatelliteRenderer<>();
|
||||||
|
|
||||||
|
@ -53,7 +55,10 @@ public class CachingSatelliteGraphViewer<V extends VisualVertex, E extends Visua
|
||||||
super(masterViewer, preferredSize);
|
super(masterViewer, preferredSize);
|
||||||
|
|
||||||
preRenderers.clear(); // remove default lens painter
|
preRenderers.clear(); // remove default lens painter
|
||||||
setBackground(masterViewer.getBackground().darker()); // same behavior as default ViewLens
|
|
||||||
|
// same behavior as default ViewLens
|
||||||
|
backgroundColor = masterViewer.getBackground().darker();
|
||||||
|
setBackground(backgroundColor);
|
||||||
|
|
||||||
Layout<V, E> layout = masterViewer.getGraphLayout();
|
Layout<V, E> layout = masterViewer.getGraphLayout();
|
||||||
if (layout instanceof ObservableCachingLayout<?, ?>) {
|
if (layout instanceof ObservableCachingLayout<?, ?>) {
|
||||||
|
@ -95,16 +100,16 @@ public class CachingSatelliteGraphViewer<V extends VisualVertex, E extends Visua
|
||||||
bufferedBackgroundImage =
|
bufferedBackgroundImage =
|
||||||
new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
|
new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||||
Graphics2D graphics = (Graphics2D) bufferedBackgroundImage.getGraphics();
|
Graphics2D graphics = (Graphics2D) bufferedBackgroundImage.getGraphics();
|
||||||
|
setBackground(backgroundColor);
|
||||||
renderGraph(graphics);
|
renderGraph(graphics);
|
||||||
graphics.dispose();
|
graphics.dispose();
|
||||||
|
|
||||||
bufferedOverlayImage =
|
bufferedOverlayImage =
|
||||||
new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
|
new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||||
graphics = (Graphics2D) bufferedOverlayImage.getGraphics();
|
graphics = (Graphics2D) bufferedOverlayImage.getGraphics();
|
||||||
Color originalBackground = getBackground();
|
|
||||||
setBackground(Color.WHITE);
|
setBackground(Color.WHITE);
|
||||||
renderGraph(graphics);
|
renderGraph(graphics);
|
||||||
setBackground(originalBackground);
|
setBackground(backgroundColor);
|
||||||
graphics.dispose();
|
graphics.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue