mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
103 lines
3.6 KiB
C++
103 lines
3.6 KiB
C++
#pragma once
|
|
|
|
//
|
|
// This file is distributed under the MIT License. See LICENSE.md for details.
|
|
//
|
|
|
|
#include "revng/Yield/ControlFlow/Configuration.h"
|
|
#include "revng/Yield/Graph.h"
|
|
|
|
namespace yield::sugiyama {
|
|
|
|
/// Lists possible ranking strategies the layouter implements.
|
|
enum class RankingStrategy {
|
|
BreadthFirstSearch,
|
|
DepthFirstSearch,
|
|
Topological,
|
|
DisjointDepthFirstSearch
|
|
};
|
|
|
|
/// List graph orientation options the layouter implements.
|
|
enum class LayoutOrientation {
|
|
LeftToRight,
|
|
RightToLeft,
|
|
TopToBottom,
|
|
BottomToTop
|
|
};
|
|
|
|
struct Configuration {
|
|
public:
|
|
/// Specifies the way the layers of the graph are decided
|
|
RankingStrategy Ranking;
|
|
|
|
/// Specifies the orientation of the layout, (e.g. left-to-right):
|
|
/// The layers with lower ranks are closer to the first direction (e.g. left)
|
|
/// while those with higher ranks - to the second one (e.g. right).
|
|
LayoutOrientation Orientation;
|
|
|
|
/// Specifies whether orthogonal bending rules should be used, if not each
|
|
/// edge is just two points: its start and end.
|
|
bool UseOrthogonalBends;
|
|
|
|
/// Specifies whether linear segment preservation should be done.
|
|
///
|
|
/// This causes nodes any pair of nodes (A and B) such that A has only one
|
|
/// successor - B and B has only one predecessor - A to be always be routed
|
|
/// with a straight line (they both have the same horizontal position).
|
|
bool PreserveLinearSegments;
|
|
|
|
/// Specifies whether simple tree optimizations should be used.
|
|
///
|
|
/// A simple tree expects every single node to only have one predecessor and
|
|
/// to not have any back-edges.
|
|
bool UseSimpleTreeOptimization;
|
|
|
|
/// Specifies the "weight" of virtual nodes as opposed to the real ones.
|
|
///
|
|
/// Virtual nodes represent long edges (both forwards and backwards facing).
|
|
///
|
|
/// If weight is equal to 1, the placing of virtual nodes is identical to that
|
|
/// of the real ones.
|
|
///
|
|
/// If weight is bigger than 1 (e.g. 10), the virtual nodes are more likely
|
|
/// to be placed to the right of the layout (the bigger the weight, the more
|
|
/// noticeable its effect is).
|
|
///
|
|
/// If weight is smaller than 1 (e.g. 0.1), the virtual nodes are more likely
|
|
/// to be placed to the left of the layout (the smaller the weight, the more
|
|
/// noticeable its effect is).
|
|
///
|
|
/// \note: the layouts will be unnaturally skewed if this value is negative.
|
|
float VirtualNodeWeight;
|
|
|
|
/// Specifies the minimum possible distance between two nodes.
|
|
Graph::Dimension NodeMarginSize;
|
|
|
|
/// Specifies the minimum possible distance between two edges.
|
|
Graph::Dimension EdgeMarginSize;
|
|
};
|
|
|
|
/// A custom graph layering algorithm designed for pre-calculating majority of
|
|
/// the expensive stuff needed for graph rendering.
|
|
bool layout(Graph &Graph, const Configuration &Configuration);
|
|
|
|
inline bool
|
|
layout(Graph &Graph,
|
|
const cfg::Configuration &CFG,
|
|
LayoutOrientation Orientation = LayoutOrientation::TopToBottom,
|
|
RankingStrategy Ranking = RankingStrategy::DisjointDepthFirstSearch,
|
|
bool UseSimpleTreeOptimization = false) {
|
|
return layout(Graph,
|
|
Configuration{
|
|
.Ranking = Ranking,
|
|
.Orientation = Orientation,
|
|
.UseOrthogonalBends = CFG.UseOrthogonalBends,
|
|
.PreserveLinearSegments = CFG.PreserveLinearSegments,
|
|
.UseSimpleTreeOptimization = UseSimpleTreeOptimization,
|
|
.VirtualNodeWeight = CFG.VirtualNodeWeight,
|
|
.NodeMarginSize = CFG.ExternalNodeMarginSize,
|
|
.EdgeMarginSize = CFG.EdgeMarginSize });
|
|
}
|
|
|
|
} // namespace yield::sugiyama
|