internal static MinMaxWidth CalculateMinMaxWidthForFloat(AbstractRenderer renderer, FloatPropertyValue?floatPropertyVal ) { bool floatPropIsRendererOwn = renderer.HasOwnProperty(Property.FLOAT); renderer.SetProperty(Property.FLOAT, FloatPropertyValue.NONE); MinMaxWidth kidMinMaxWidth = renderer.GetMinMaxWidth(); if (floatPropIsRendererOwn) { renderer.SetProperty(Property.FLOAT, floatPropertyVal); } else { renderer.DeleteOwnProperty(Property.FLOAT); } return(kidMinMaxWidth); }
public override LayoutResult Layout(LayoutContext layoutContext) { int pageNumber = layoutContext.GetArea().GetPageNumber(); bool isPositioned = IsPositioned(); Rectangle parentBBox = layoutContext.GetArea().GetBBox().Clone(); if (this.GetProperty <float?>(Property.ROTATION_ANGLE) != null || isPositioned) { parentBBox.MoveDown(AbstractRenderer.INF - parentBBox.GetHeight()).SetHeight(AbstractRenderer.INF); } float?blockHeight = RetrieveHeight(); if (!IsFixedLayout() && blockHeight != null && blockHeight > parentBBox.GetHeight() && !true.Equals(GetPropertyAsBoolean (Property.FORCED_PLACEMENT))) { return(new LayoutResult(LayoutResult.NOTHING, null, null, this, this)); } float[] margins = GetMargins(); ApplyMargins(parentBBox, margins, false); Border[] borders = GetBorders(); ApplyBorderBox(parentBBox, borders, false); if (isPositioned) { float x = (float)this.GetPropertyAsFloat(Property.X); float relativeX = IsFixedLayout() ? 0 : parentBBox.GetX(); parentBBox.SetX(relativeX + x); } float?blockWidth = RetrieveWidth(parentBBox.GetWidth()); if (blockWidth != null && (blockWidth < parentBBox.GetWidth() || isPositioned)) { parentBBox.SetWidth((float)blockWidth); } float[] paddings = GetPaddings(); ApplyPaddings(parentBBox, paddings, false); IList <Rectangle> areas; if (isPositioned) { areas = JavaCollectionsUtil.SingletonList(parentBBox); } else { areas = InitElementAreas(new LayoutArea(pageNumber, parentBBox)); } occupiedArea = new LayoutArea(pageNumber, new Rectangle(parentBBox.GetX(), parentBBox.GetY() + parentBBox. GetHeight(), parentBBox.GetWidth(), 0)); int currentAreaPos = 0; Rectangle layoutBox = areas[0].Clone(); // the first renderer (one of childRenderers or their children) to produce LayoutResult.NOTHING IRenderer causeOfNothing = null; bool anythingPlaced = false; for (int childPos = 0; childPos < childRenderers.Count; childPos++) { IRenderer childRenderer = childRenderers[childPos]; LayoutResult result; childRenderer.SetParent(this); while ((result = childRenderer.SetParent(this).Layout(new LayoutContext(new LayoutArea(pageNumber, layoutBox )))).GetStatus() != LayoutResult.FULL) { if (result.GetOccupiedArea() != null) { occupiedArea.SetBBox(Rectangle.GetCommonRectangle(occupiedArea.GetBBox(), result.GetOccupiedArea().GetBBox ())); layoutBox.SetHeight(layoutBox.GetHeight() - result.GetOccupiedArea().GetBBox().GetHeight()); } if (childRenderer.GetOccupiedArea() != null) { AlignChildHorizontally(childRenderer, layoutBox.GetWidth()); } // Save the first renderer to produce LayoutResult.NOTHING if (null == causeOfNothing && null != result.GetCauseOfNothing()) { causeOfNothing = result.GetCauseOfNothing(); } // have more areas if (currentAreaPos + 1 < areas.Count) { if (result.GetStatus() == LayoutResult.PARTIAL) { childRenderers[childPos] = result.GetSplitRenderer(); // TODO linkedList would make it faster childRenderers.Add(childPos + 1, result.GetOverflowRenderer()); } else { childRenderers[childPos] = result.GetOverflowRenderer(); childPos--; } layoutBox = areas[++currentAreaPos].Clone(); break; } else { if (result.GetStatus() == LayoutResult.PARTIAL) { layoutBox.SetHeight(layoutBox.GetHeight() - result.GetOccupiedArea().GetBBox().GetHeight()); if (currentAreaPos + 1 == areas.Count) { AbstractRenderer splitRenderer = CreateSplitRenderer(LayoutResult.PARTIAL); splitRenderer.childRenderers = new List <IRenderer>(childRenderers.SubList(0, childPos)); splitRenderer.childRenderers.Add(result.GetSplitRenderer()); splitRenderer.occupiedArea = occupiedArea; AbstractRenderer overflowRenderer = CreateOverflowRenderer(LayoutResult.PARTIAL); // Apply forced placement only on split renderer overflowRenderer.DeleteOwnProperty(Property.FORCED_PLACEMENT); IList <IRenderer> overflowRendererChildren = new List <IRenderer>(); overflowRendererChildren.Add(result.GetOverflowRenderer()); overflowRendererChildren.AddAll(childRenderers.SubList(childPos + 1, childRenderers.Count)); overflowRenderer.childRenderers = overflowRendererChildren; ApplyPaddings(occupiedArea.GetBBox(), paddings, true); ApplyBorderBox(occupiedArea.GetBBox(), borders, true); ApplyMargins(occupiedArea.GetBBox(), margins, true); return(new LayoutResult(LayoutResult.PARTIAL, occupiedArea, splitRenderer, overflowRenderer, causeOfNothing )); } else { childRenderers[childPos] = result.GetSplitRenderer(); childRenderers.Add(childPos + 1, result.GetOverflowRenderer()); layoutBox = areas[++currentAreaPos].Clone(); break; } } else { if (result.GetStatus() == LayoutResult.NOTHING) { bool keepTogether = IsKeepTogether(); int layoutResult = anythingPlaced && !keepTogether ? LayoutResult.PARTIAL : LayoutResult.NOTHING; AbstractRenderer splitRenderer = CreateSplitRenderer(layoutResult); splitRenderer.childRenderers = new List <IRenderer>(childRenderers.SubList(0, childPos)); foreach (IRenderer renderer in splitRenderer.childRenderers) { renderer.SetParent(splitRenderer); } AbstractRenderer overflowRenderer = CreateOverflowRenderer(layoutResult); IList <IRenderer> overflowRendererChildren = new List <IRenderer>(); overflowRendererChildren.Add(result.GetOverflowRenderer()); overflowRendererChildren.AddAll(childRenderers.SubList(childPos + 1, childRenderers.Count)); overflowRenderer.childRenderers = overflowRendererChildren; if (keepTogether) { splitRenderer = null; overflowRenderer.childRenderers.Clear(); overflowRenderer.childRenderers = new List <IRenderer>(childRenderers); } ApplyPaddings(occupiedArea.GetBBox(), paddings, true); ApplyBorderBox(occupiedArea.GetBBox(), borders, true); ApplyMargins(occupiedArea.GetBBox(), margins, true); if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT))) { return(new LayoutResult(LayoutResult.FULL, occupiedArea, null, null)); } else { return(new LayoutResult(layoutResult, occupiedArea, splitRenderer, overflowRenderer, LayoutResult.NOTHING == layoutResult ? result.GetCauseOfNothing() : null)); } } } } } anythingPlaced = true; occupiedArea.SetBBox(Rectangle.GetCommonRectangle(occupiedArea.GetBBox(), result.GetOccupiedArea().GetBBox ())); if (result.GetStatus() == LayoutResult.FULL) { layoutBox.SetHeight(layoutBox.GetHeight() - result.GetOccupiedArea().GetBBox().GetHeight()); if (childRenderer.GetOccupiedArea() != null) { AlignChildHorizontally(childRenderer, layoutBox.GetWidth()); } } // Save the first renderer to produce LayoutResult.NOTHING if (null == causeOfNothing && null != result.GetCauseOfNothing()) { causeOfNothing = result.GetCauseOfNothing(); } } ApplyPaddings(occupiedArea.GetBBox(), paddings, true); if (blockHeight != null && blockHeight > occupiedArea.GetBBox().GetHeight()) { occupiedArea.GetBBox().MoveDown((float)blockHeight - occupiedArea.GetBBox().GetHeight()).SetHeight((float) blockHeight); } if (isPositioned) { float y = (float)this.GetPropertyAsFloat(Property.Y); float relativeY = IsFixedLayout() ? 0 : layoutBox.GetY(); Move(0, relativeY + y - occupiedArea.GetBBox().GetY()); } ApplyBorderBox(occupiedArea.GetBBox(), borders, true); ApplyMargins(occupiedArea.GetBBox(), margins, true); if (this.GetProperty <float?>(Property.ROTATION_ANGLE) != null) { ApplyRotationLayout(layoutContext.GetArea().GetBBox().Clone()); if (IsNotFittingLayoutArea(layoutContext.GetArea())) { if (!true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT))) { return(new LayoutResult(LayoutResult.NOTHING, occupiedArea, null, this, this)); } } } ApplyVerticalAlignment(); return(new LayoutResult(LayoutResult.FULL, occupiedArea, null, null, causeOfNothing)); }