apportion method

Node apportion(
  1. Graph graph,
  2. Node node,
  3. Node defaultAncestor
)

Implementation

Node apportion(Graph graph, Node node, Node defaultAncestor) {
  var ancestor = defaultAncestor;
  if (hasLeftSibling(graph, node)) {
    var leftSibling = getLeftSibling(graph, node);
    Node? vop = node;
    Node? vom = getLeftMostChild(graph, graph.predecessorsOf(node).first);
    var sip = getModifier(node);

    var sop = getModifier(node);

    var sim = getModifier(leftSibling);

    var som = getModifier(vom);
    var nextRight = this.nextRight(graph, leftSibling);

    Node? nextLeft;
    for (nextLeft = this.nextLeft(graph, node);
        nextRight != null && nextLeft != null;
        nextLeft = this.nextLeft(graph, nextLeft)) {
      vom = this.nextLeft(graph, vom);
      vop = this.nextRight(graph, vop);

      setAncestor(vop, node);
      var shift = getPrelim(nextRight) + sim - (getPrelim(nextLeft) + sip) + getSpacing(graph, nextRight, node);
      if (shift > 0) {
        moveSubtree(this.ancestor(graph, nextRight, node, ancestor), node, shift);
        sip += shift;
        sop += shift;
      }

      sim += getModifier(nextRight);
      sip += getModifier(nextLeft);

      som += getModifier(vom);
      sop += getModifier(vop);
      nextRight = this.nextRight(graph, nextRight);
    }

    if (nextRight != null && this.nextRight(graph, vop) == null) {
      setThread(vop, nextRight);
      setModifier(vop, getModifier(vop) + sim - sop);
    }

    if (nextLeft != null && this.nextLeft(graph, vom) == null) {
      setThread(vom, nextLeft);
      setModifier(vom, getModifier(vom) + sip - som);
      ancestor = node;
    }
  }

  return ancestor;
}