Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ private void compileNode(PreparedNode<DocumentNode> prepared,
}

if (definition.paginationPolicy(node) == PaginationPolicy.SPLITTABLE) {
compileSplittableLeaf(prepared, definition, path, semanticName, parentPath, childIndex, depth, regionX,
SplittableLeafCompiler.compile(prepared, definition, path, semanticName, parentPath, childIndex, depth, regionX,
availableWidth, state, prepareContext, fragmentContext, nodes, fragments);
return;
}
Expand Down Expand Up @@ -859,171 +859,6 @@ private void placeStackLayer(DocumentNode child,
layerCtx);
}

private void compileSplittableLeaf(PreparedNode<DocumentNode> prepared,
NodeDefinition<DocumentNode> definition,
String path,
String semanticName,
String parentPath,
int childIndex,
int depth,
double regionX,
double availableWidth,
CompilerState state,
PrepareContext prepareContext,
FragmentContext fragmentContext,
List<PlacedNode> nodes,
List<PlacedFragment> fragments) {
Margin originalMargin = toMargin(prepared.node().margin());
Padding originalPadding = toPadding(prepared.node().padding());

PreparedNode<DocumentNode> current = prepared;
double firstPlacementX = Double.NaN;
double firstPlacementY = Double.NaN;
int startPage = -1;
int endPage = -1;

while (current != null) {
DocumentNode currentNode = current.node();
Margin currentMargin = toMargin(currentNode.margin());
Padding currentPadding = toPadding(currentNode.padding());
MeasureResult pieceMeasure = current.measureResult();
double pieceOuterHeight = pieceMeasure.height() + currentMargin.vertical();
double fullPageOuterHeight = state.activeInnerHeight();

if (pieceOuterHeight <= state.remainingHeight() + EPS) {
state.touchPage();
if (startPage < 0) {
startPage = state.pageIndex;
}
double placementX = regionX + currentMargin.left();
double placementY = state.pageTop() - state.usedHeight - currentMargin.top() - pieceMeasure.height();
FragmentPlacement placement = new FragmentPlacement(
path,
parentPath,
childIndex,
depth,
state.pageIndex,
placementX,
placementY,
pieceMeasure.width(),
pieceMeasure.height(),
startPage,
state.pageIndex,
currentMargin,
currentPadding);
addPlacedFragments(definition.emitFragments(current, fragmentContext, placement), placement, fragments);

if (Double.isNaN(firstPlacementX)) {
firstPlacementX = placementX;
firstPlacementY = placementY;
}
endPage = state.pageIndex;
state.usedHeight += pieceOuterHeight;
current = null;
continue;
}

double remainingBoxHeight = Math.max(0.0, state.remainingHeight() - currentMargin.vertical());
if (remainingBoxHeight <= EPS && state.usedHeight > EPS) {
state.newPage();
continue;
}

SplitRequest splitRequest = new SplitRequest(
new BoxConstraints(availableWidth, remainingBoxHeight),
remainingBoxHeight,
Math.max(0.0, fullPageOuterHeight - currentMargin.vertical()),
prepareContext);
PreparedSplitResult<DocumentNode> splitResult = definition.split(current, splitRequest);
PreparedNode<DocumentNode> head = splitResult.head();
PreparedNode<DocumentNode> tail = splitResult.tail();

if (head == null) {
if (state.usedHeight > EPS) {
state.newPage();
continue;
}
throw AtomicNodeTooLargeException.forNode(path, pieceOuterHeight, fullPageOuterHeight);
}
if (tail != null && tail.equals(current)) {
throw new IllegalStateException("Split did not make progress for node '" + path
+ "'. The node's NodeDefinition.split() returned the original input as the tail — "
+ "check the definition for an infinite split loop and ensure each split advances.");
}

DocumentNode headNode = head.node();
Margin headMargin = toMargin(headNode.margin());
Padding headPadding = toPadding(headNode.padding());
MeasureResult headMeasure = head.measureResult();
double headOuterHeight = headMeasure.height() + headMargin.vertical();

if (headOuterHeight > state.remainingHeight() + EPS) {
if (state.usedHeight > EPS) {
state.newPage();
continue;
}
throw AtomicNodeTooLargeException.forNode(path, headOuterHeight, fullPageOuterHeight);
}

state.touchPage();
if (startPage < 0) {
startPage = state.pageIndex;
}

double placementX = regionX + headMargin.left();
double placementY = state.pageTop() - state.usedHeight - headMargin.top() - headMeasure.height();
FragmentPlacement placement = new FragmentPlacement(
path,
parentPath,
childIndex,
depth,
state.pageIndex,
placementX,
placementY,
headMeasure.width(),
headMeasure.height(),
startPage,
state.pageIndex,
headMargin,
headPadding);
addPlacedFragments(definition.emitFragments(head, fragmentContext, placement), placement, fragments);

if (Double.isNaN(firstPlacementX)) {
firstPlacementX = placementX;
firstPlacementY = placementY;
}
endPage = state.pageIndex;
state.usedHeight += headOuterHeight;

current = tail;
if (current != null) {
state.newPage();
}
}

MeasureResult originalMeasure = prepared.measureResult();
nodes.add(new PlacedNode(
path,
semanticName,
prepared.node().nodeKind(),
parentPath,
childIndex,
depth,
depth,
firstPlacementX,
firstPlacementY,
firstPlacementX,
firstPlacementY,
originalMeasure.width(),
originalMeasure.height(),
startPage,
endPage,
originalMeasure.width(),
originalMeasure.height(),
originalMargin,
originalPadding));
}

/**
* Compiles a composite or leaf node inside a fixed slot.
*
Expand Down
Loading
Loading