use of org.loboevolution.html.renderstate.BlockRenderState in project LoboEvolution by LoboEvolution.
the class RBlock method forceLayout.
/**
* Lays out the block without checking for prior dimensions.
*/
private RBlockLayoutInfo forceLayout(RenderState renderState, RLayoutInfo info) {
final int availWidth = info.getAvailWidth();
final int availHeight = info.getAvailHeight();
final boolean expandWidth = info.isExpandWidth();
final boolean expandHeight = info.isExpandHeight();
final boolean sizeOnly = info.isSizeOnly();
final FloatingBoundsSource blockFloatBoundsSource = info.getBlockFloatBoundsSource();
RenderState rs = renderState;
if (rs == null) {
rs = new BlockRenderState(null);
}
applyStyle(availWidth, availHeight);
final RBlockViewport bodyLayout = this.bodyLayout;
final NodeImpl node = (NodeImpl) this.modelNode;
if (node == null || bodyLayout == null) {
final Insets insets = getInsetsMarginBorder(false, false);
return RBlockLayoutInfo.builder().width(insets.left + insets.right).height(insets.bottom + insets.top).hasHScrollBar(false).hasVScrollBar(false).build();
}
Insets paddingInsets = (this.paddingInsets == null) ? RBlockViewport.ZERO_INSETS : this.paddingInsets;
final int paddingTotalWidth = paddingInsets.left + paddingInsets.right;
final int paddingTotalHeight = paddingInsets.top + paddingInsets.bottom;
int overflowX = (this.overflowX == RenderState.OVERFLOW_NONE) ? defaultOverflowX : this.overflowX;
int overflowY = (this.overflowY == RenderState.OVERFLOW_NONE) ? defaultOverflowY : this.overflowY;
final boolean vauto = overflowY == RenderState.OVERFLOW_AUTO;
boolean hscroll = overflowX == RenderState.OVERFLOW_SCROLL;
final boolean hauto = overflowX == RenderState.OVERFLOW_AUTO;
boolean vscroll = overflowY == RenderState.OVERFLOW_SCROLL;
Insets insets = getInsetsMarginBorder(hscroll, vscroll);
int insetsTotalWidth = insets.left + insets.right;
int insetsTotalHeight = insets.top + insets.bottom;
int actualAvailWidth = availWidth - paddingTotalWidth - insetsTotalWidth;
final int actualAvailHeight = availHeight - paddingTotalHeight - insetsTotalHeight;
final Integer dw = getDeclaredWidth(renderState, actualAvailWidth);
final Integer dh = getDeclaredHeight(renderState, actualAvailHeight);
int declaredWidth = dw != null ? dw : -1;
int declaredHeight = dh != null ? dh : -1;
clearGUIComponents();
int tentativeWidth;
int tentativeHeight;
if ("border-box".equals(rs.getBoxSizing())) {
tentativeWidth = declaredWidth == -1 ? availWidth : declaredWidth;
tentativeHeight = declaredHeight == -1 ? availHeight : declaredHeight;
} else {
tentativeWidth = declaredWidth == -1 ? availWidth : declaredWidth + insetsTotalWidth + paddingTotalWidth;
tentativeHeight = declaredHeight == -1 ? availHeight : declaredHeight + insetsTotalHeight + paddingTotalHeight;
}
if (declaredWidth == -1 && !expandWidth && availWidth > insetsTotalWidth + paddingTotalWidth) {
final RenderThreadState state = RenderThreadState.getState();
final boolean prevOverrideNoWrap = state.overrideNoWrap;
if (!prevOverrideNoWrap) {
state.overrideNoWrap = true;
try {
bodyLayout.layout(paddingTotalWidth, paddingTotalHeight, paddingInsets, -1, null, true);
if (bodyLayout.getWidth() + insetsTotalWidth < tentativeWidth) {
tentativeWidth = bodyLayout.getWidth() + insetsTotalWidth;
tentativeHeight = bodyLayout.getHeight() + insetsTotalHeight;
}
} finally {
state.overrideNoWrap = false;
}
}
}
FloatingBounds viewportFloatBounds = null;
FloatingBounds blockFloatBounds = null;
if (blockFloatBoundsSource != null) {
blockFloatBounds = blockFloatBoundsSource.getChildBlockFloatingBounds(tentativeWidth);
viewportFloatBounds = new ShiftedFloatingBounds(blockFloatBounds, -insets.left, -insets.right, -insets.top);
}
int desiredViewportWidth = tentativeWidth - insetsTotalWidth;
final int desiredViewportHeight = tentativeHeight - insets.top - insets.bottom;
final int maxY = vauto ? (declaredHeight == -1 ? availHeight : declaredHeight + paddingInsets.top) : -1;
try {
bodyLayout.layout(desiredViewportWidth, desiredViewportHeight, paddingInsets, maxY, viewportFloatBounds, sizeOnly);
} catch (final SizeExceededException see) {
vscroll = true;
insets = getInsetsMarginBorder(hscroll, vscroll);
insetsTotalWidth = insets.left + insets.right;
actualAvailWidth = availWidth - paddingTotalWidth - insetsTotalWidth;
Integer newdw = getDeclaredWidth(renderState, actualAvailWidth);
declaredWidth = newdw == null ? -1 : newdw;
desiredViewportWidth = tentativeWidth - insetsTotalWidth;
if (blockFloatBounds != null) {
viewportFloatBounds = new ShiftedFloatingBounds(blockFloatBounds, -insets.left, -insets.right, -insets.top);
}
bodyLayout.layout(desiredViewportWidth, desiredViewportHeight, paddingInsets, -1, viewportFloatBounds, sizeOnly);
}
final int bodyWidth = bodyLayout.getWidth();
final int bodyHeight = bodyLayout.getHeight();
final int prelimBlockWidth = bodyWidth + insetsTotalWidth;
int prelimBlockHeight = bodyHeight + insetsTotalHeight;
if ((vauto || vscroll) && ((prelimBlockHeight - insetsTotalHeight) < bodyLayout.getHeight())) {
final boolean isHtmlElem = getModelNode() instanceof HTMLHtmlElement;
if (isHtmlElem) {
prelimBlockHeight = bodyLayout.getHeight() + insetsTotalHeight;
} else {
vscroll = true;
insets = this.getInsetsMarginBorder(hscroll, vscroll);
insetsTotalWidth = insets.left + insets.right;
}
}
int adjDeclaredWidth;
int adjDeclaredHeight;
if ("border-box".equals(rs.getBoxSizing())) {
adjDeclaredWidth = declaredWidth;
adjDeclaredHeight = declaredHeight;
} else {
adjDeclaredWidth = declaredWidth == -1 ? -1 : declaredWidth + insets.left + insets.right + paddingInsets.left + paddingInsets.right;
adjDeclaredHeight = declaredHeight == -1 ? -1 : declaredHeight + insets.top + insets.bottom + paddingInsets.top + paddingInsets.bottom;
}
// Adjust insets and other dimensions base on overflow-y=auto.
if (hauto && (adjDeclaredWidth != -1 && prelimBlockWidth > adjDeclaredWidth || prelimBlockWidth > tentativeWidth)) {
hscroll = true;
insets = getInsetsMarginBorder(hscroll, vscroll);
insetsTotalHeight = insets.top + insets.bottom;
prelimBlockHeight = bodyHeight + insetsTotalHeight;
}
int resultingWidth;
int resultingHeight;
if (adjDeclaredWidth == -1) {
resultingWidth = expandWidth ? Math.max(prelimBlockWidth, tentativeWidth) : prelimBlockWidth;
if (hscroll && resultingWidth > tentativeWidth) {
resultingWidth = Math.max(tentativeWidth, SCROLL_BAR_THICKNESS);
}
} else {
resultingWidth = adjDeclaredWidth;
}
if (adjDeclaredHeight == -1) {
resultingHeight = expandHeight ? Math.max(prelimBlockHeight, tentativeHeight) : prelimBlockHeight;
if (vscroll && resultingHeight > tentativeHeight) {
resultingHeight = Math.max(tentativeHeight, SCROLL_BAR_THICKNESS);
}
} else {
resultingHeight = adjDeclaredHeight;
}
if (!sizeOnly) {
final int alignmentYPercent = rs.getAlignYPercent();
final int alignmentXPercent = rs.getAlignXPercent();
if (alignmentXPercent > 0) {
final int canvasWidth = Math.max(bodyLayout.getWidth(), resultingWidth - insets.left - insets.right);
bodyLayout.alignX(alignmentXPercent, canvasWidth, paddingInsets);
}
if (alignmentYPercent > 0) {
final int canvasHeight = Math.max(bodyLayout.getHeight(), resultingHeight - insets.top - insets.bottom);
bodyLayout.alignY(alignmentYPercent, canvasHeight, paddingInsets);
}
}
if (hscroll || vscroll) {
if (vscroll) {
addComponent(scroll.getVScrollBar());
}
if (hscroll) {
addComponent(scroll.getHScrollBar());
}
correctViewportOrigin(insets, resultingWidth, resultingHeight);
this.setWidth(resultingWidth);
this.setHeight(resultingHeight);
scroll.resetScrollBars(rs);
} else {
bodyLayout.setX(insets.left);
bodyLayout.setY(insets.top);
}
return RBlockLayoutInfo.builder().width(resultingWidth).height(resultingHeight).hasHScrollBar(hscroll).hasVScrollBar(vscroll).build();
}
Aggregations