private void AddAllWaitingNextPageRenderers() { bool marginsCollapsingEnabled = true.Equals(GetPropertyAsBoolean(Property.COLLAPSING_MARGINS)); while (!waitingNextPageRenderers.IsEmpty()) { if (marginsCollapsingEnabled) { marginsCollapseHandler = new MarginsCollapseHandler(this, null); } UpdateCurrentAndInitialArea(null); } }
internal static void ApplyClearance(Rectangle layoutBox, MarginsCollapseHandler marginsCollapseHandler, float clearHeightAdjustment, bool isFloat) { if (clearHeightAdjustment <= 0) { return; } if (marginsCollapseHandler == null || isFloat) { layoutBox.DecreaseHeight(clearHeightAdjustment); } else { marginsCollapseHandler.ApplyClearance(clearHeightAdjustment); } }
public override void AddChild(IRenderer renderer) { LayoutTaggingHelper taggingHelper = this.GetProperty <LayoutTaggingHelper>(Property.TAGGING_HELPER); if (taggingHelper != null) { LayoutTaggingHelper.AddTreeHints(taggingHelper, renderer); } // Some positioned renderers might have been fetched from non-positioned child and added to this renderer, // so we use this generic mechanism of determining which renderers have been just added. int numberOfChildRenderers = childRenderers.Count; int numberOfPositionedChildRenderers = positionedRenderers.Count; base.AddChild(renderer); IList <IRenderer> addedRenderers = new List <IRenderer>(1); IList <IRenderer> addedPositionedRenderers = new List <IRenderer>(1); while (childRenderers.Count > numberOfChildRenderers) { addedRenderers.Add(childRenderers[numberOfChildRenderers]); childRenderers.JRemoveAt(numberOfChildRenderers); } while (positionedRenderers.Count > numberOfPositionedChildRenderers) { addedPositionedRenderers.Add(positionedRenderers[numberOfPositionedChildRenderers]); positionedRenderers.JRemoveAt(numberOfPositionedChildRenderers); } bool marginsCollapsingEnabled = true.Equals(GetPropertyAsBoolean(Property.COLLAPSING_MARGINS)); if (currentArea == null) { UpdateCurrentAndInitialArea(null); if (marginsCollapsingEnabled) { marginsCollapseHandler = new MarginsCollapseHandler(this, null); } } // Static layout for (int i = 0; currentArea != null && i < addedRenderers.Count; i++) { renderer = addedRenderers[i]; bool rendererIsFloat = FloatingHelper.IsRendererFloating(renderer); bool clearanceOverflowsToNextPage = FloatingHelper.IsClearanceApplied(waitingNextPageRenderers, renderer.GetProperty <ClearPropertyValue?>(Property.CLEAR)); if (rendererIsFloat && (floatOverflowedCompletely || clearanceOverflowsToNextPage)) { waitingNextPageRenderers.Add(renderer); floatOverflowedCompletely = true; continue; } ProcessWaitingKeepWithNextElement(renderer); IList <IRenderer> resultRenderers = new List <IRenderer>(); LayoutResult result = null; RootLayoutArea storedArea = null; RootLayoutArea nextStoredArea = null; MarginsCollapseInfo childMarginsInfo = null; if (marginsCollapsingEnabled && currentArea != null && renderer != null) { childMarginsInfo = marginsCollapseHandler.StartChildMarginsHandling(renderer, currentArea.GetBBox()); } while (clearanceOverflowsToNextPage || currentArea != null && renderer != null && (result = renderer.SetParent (this).Layout(new LayoutContext(currentArea.Clone(), childMarginsInfo, floatRendererAreas))).GetStatus () != LayoutResult.FULL) { bool currentAreaNeedsToBeUpdated = false; if (clearanceOverflowsToNextPage) { result = new LayoutResult(LayoutResult.NOTHING, null, null, renderer); currentAreaNeedsToBeUpdated = true; } if (result.GetStatus() == LayoutResult.PARTIAL) { if (rendererIsFloat) { waitingNextPageRenderers.Add(result.GetOverflowRenderer()); break; } else { ProcessRenderer(result.GetSplitRenderer(), resultRenderers); if (nextStoredArea != null) { currentArea = nextStoredArea; currentPageNumber = nextStoredArea.GetPageNumber(); nextStoredArea = null; } else { currentAreaNeedsToBeUpdated = true; } } } else { if (result.GetStatus() == LayoutResult.NOTHING && !clearanceOverflowsToNextPage) { if (result.GetOverflowRenderer() is ImageRenderer) { float imgHeight = ((ImageRenderer)result.GetOverflowRenderer()).GetOccupiedArea().GetBBox().GetHeight(); if (!floatRendererAreas.IsEmpty() || currentArea.GetBBox().GetHeight() < imgHeight && !currentArea.IsEmptyArea ()) { if (rendererIsFloat) { waitingNextPageRenderers.Add(result.GetOverflowRenderer()); floatOverflowedCompletely = true; break; } currentAreaNeedsToBeUpdated = true; } else { ((ImageRenderer)result.GetOverflowRenderer()).AutoScale(currentArea); result.GetOverflowRenderer().SetProperty(Property.FORCED_PLACEMENT, true); ILog logger = LogManager.GetLogger(typeof(RootRenderer)); logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "")); } } else { if (currentArea.IsEmptyArea() && result.GetAreaBreak() == null) { if (true.Equals(result.GetOverflowRenderer().GetModelElement().GetProperty <bool?>(Property.KEEP_TOGETHER)) ) { result.GetOverflowRenderer().GetModelElement().SetProperty(Property.KEEP_TOGETHER, false); ILog logger = LogManager.GetLogger(typeof(RootRenderer)); logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "KeepTogether property will be ignored." )); if (storedArea != null) { nextStoredArea = currentArea; currentArea = storedArea; currentPageNumber = storedArea.GetPageNumber(); } storedArea = currentArea; } else { if (null != result.GetCauseOfNothing() && true.Equals(result.GetCauseOfNothing().GetProperty <bool?>(Property .KEEP_TOGETHER))) { // set KEEP_TOGETHER false on the deepest parent (maybe the element itself) to have KEEP_TOGETHER == true IRenderer theDeepestKeptTogether = result.GetCauseOfNothing(); IRenderer parent; while (null == theDeepestKeptTogether.GetModelElement() || null == theDeepestKeptTogether.GetModelElement( ).GetOwnProperty <bool?>(Property.KEEP_TOGETHER)) { parent = ((AbstractRenderer)theDeepestKeptTogether).parent; if (parent == null) { break; } theDeepestKeptTogether = parent; } theDeepestKeptTogether.GetModelElement().SetProperty(Property.KEEP_TOGETHER, false); ILog logger = LogManager.GetLogger(typeof(RootRenderer)); logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "KeepTogether property of inner element will be ignored." )); } else { if (!true.Equals(renderer.GetProperty <bool?>(Property.FORCED_PLACEMENT))) { result.GetOverflowRenderer().SetProperty(Property.FORCED_PLACEMENT, true); ILog logger = LogManager.GetLogger(typeof(RootRenderer)); logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "")); } else { // FORCED_PLACEMENT was already set to the renderer and // LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA message was logged. // This else-clause should never be hit, otherwise there is a bug in FORCED_PLACEMENT implementation. System.Diagnostics.Debug.Assert(false); // Still handling this case in order to avoid nasty infinite loops. break; } } } } else { storedArea = currentArea; if (nextStoredArea != null) { currentArea = nextStoredArea; currentPageNumber = nextStoredArea.GetPageNumber(); nextStoredArea = null; } else { if (rendererIsFloat) { waitingNextPageRenderers.Add(result.GetOverflowRenderer()); floatOverflowedCompletely = true; break; } currentAreaNeedsToBeUpdated = true; } } } } } renderer = result.GetOverflowRenderer(); if (marginsCollapsingEnabled) { marginsCollapseHandler.EndChildMarginsHandling(currentArea.GetBBox()); } if (currentAreaNeedsToBeUpdated) { UpdateCurrentAndInitialArea(result); } if (marginsCollapsingEnabled) { marginsCollapseHandler = new MarginsCollapseHandler(this, null); childMarginsInfo = marginsCollapseHandler.StartChildMarginsHandling(renderer, currentArea.GetBBox()); } clearanceOverflowsToNextPage = clearanceOverflowsToNextPage && FloatingHelper.IsClearanceApplied(waitingNextPageRenderers , renderer.GetProperty <ClearPropertyValue?>(Property.CLEAR)); } if (marginsCollapsingEnabled) { marginsCollapseHandler.EndChildMarginsHandling(currentArea.GetBBox()); } if (null != result && null != result.GetSplitRenderer()) { renderer = result.GetSplitRenderer(); } // Keep renderer until next element is added for future keep with next adjustments if (renderer != null && result != null) { if (true.Equals(renderer.GetProperty <bool?>(Property.KEEP_WITH_NEXT))) { if (true.Equals(renderer.GetProperty <bool?>(Property.FORCED_PLACEMENT))) { ILog logger = LogManager.GetLogger(typeof(RootRenderer)); logger.Warn(iText.IO.LogMessageConstant.ELEMENT_WAS_FORCE_PLACED_KEEP_WITH_NEXT_WILL_BE_IGNORED); ShrinkCurrentAreaAndProcessRenderer(renderer, resultRenderers, result); } else { keepWithNextHangingRenderer = renderer; keepWithNextHangingRendererLayoutResult = result; } } else { if (result.GetStatus() != LayoutResult.NOTHING) { ShrinkCurrentAreaAndProcessRenderer(renderer, resultRenderers, result); } } } } for (int i = 0; i < addedPositionedRenderers.Count; i++) { positionedRenderers.Add(addedPositionedRenderers[i]); renderer = positionedRenderers[positionedRenderers.Count - 1]; int?positionedPageNumber = renderer.GetProperty <int?>(Property.PAGE_NUMBER); if (positionedPageNumber == null) { positionedPageNumber = currentPageNumber; } LayoutArea layoutArea; // For position=absolute, if none of the top, bottom, left, right properties are provided, // the content should be displayed in the flow of the current content, not overlapping it. // The behavior is just if it would be statically positioned except it does not affect other elements if (Convert.ToInt32(LayoutPosition.ABSOLUTE).Equals(renderer.GetProperty <int?>(Property.POSITION)) && AbstractRenderer .NoAbsolutePositionInfo(renderer)) { layoutArea = new LayoutArea((int)positionedPageNumber, currentArea.GetBBox().Clone()); } else { layoutArea = new LayoutArea((int)positionedPageNumber, initialCurrentArea.GetBBox().Clone()); } Rectangle fullBbox = layoutArea.GetBBox().Clone(); PreparePositionedRendererAndAreaForLayout(renderer, fullBbox, layoutArea.GetBBox()); renderer.Layout(new PositionedLayoutContext(new LayoutArea(layoutArea.GetPageNumber(), fullBbox), layoutArea )); if (immediateFlush) { FlushSingleRenderer(renderer); positionedRenderers.JRemoveAt(positionedRenderers.Count - 1); } } }
protected internal virtual LayoutResult DirectLayout(LayoutContext layoutContext) { bool wasHeightClipped = false; bool wasParentsHeightClipped = layoutContext.IsClippedHeight(); int pageNumber = layoutContext.GetArea().GetPageNumber(); bool anythingPlaced = false; bool firstLineInBox = true; LineRenderer currentRenderer = (LineRenderer) new LineRenderer().SetParent(this); Rectangle parentBBox = layoutContext.GetArea().GetBBox().Clone(); MarginsCollapseHandler marginsCollapseHandler = null; bool marginsCollapsingEnabled = true.Equals(GetPropertyAsBoolean(Property.COLLAPSING_MARGINS)); if (marginsCollapsingEnabled) { marginsCollapseHandler = new MarginsCollapseHandler(this, layoutContext.GetMarginsCollapseInfo()); } OverflowPropertyValue?overflowX = this.GetProperty <OverflowPropertyValue?>(Property.OVERFLOW_X); bool?nowrapProp = this.GetPropertyAsBoolean(Property.NO_SOFT_WRAP_INLINE); currentRenderer.SetProperty(Property.NO_SOFT_WRAP_INLINE, nowrapProp); bool notAllKidsAreFloats = false; IList <Rectangle> floatRendererAreas = layoutContext.GetFloatRendererAreas(); FloatPropertyValue?floatPropertyValue = this.GetProperty <FloatPropertyValue?>(Property.FLOAT); float clearHeightCorrection = FloatingHelper.CalculateClearHeightCorrection(this, floatRendererAreas, parentBBox ); FloatingHelper.ApplyClearance(parentBBox, marginsCollapseHandler, clearHeightCorrection, FloatingHelper.IsRendererFloating (this)); float?blockWidth = RetrieveWidth(parentBBox.GetWidth()); if (FloatingHelper.IsRendererFloating(this, floatPropertyValue)) { blockWidth = FloatingHelper.AdjustFloatedBlockLayoutBox(this, parentBBox, blockWidth, floatRendererAreas, floatPropertyValue, overflowX); floatRendererAreas = new List <Rectangle>(); } if (0 == childRenderers.Count) { anythingPlaced = true; currentRenderer = null; } bool isPositioned = IsPositioned(); float?rotation = this.GetPropertyAsFloat(Property.ROTATION_ANGLE); float?blockMaxHeight = RetrieveMaxHeight(); OverflowPropertyValue?overflowY = (null == blockMaxHeight || blockMaxHeight > parentBBox.GetHeight()) && !wasParentsHeightClipped ? OverflowPropertyValue.FIT : this.GetProperty <OverflowPropertyValue?>(Property .OVERFLOW_Y); if (rotation != null || IsFixedLayout()) { parentBBox.MoveDown(AbstractRenderer.INF - parentBBox.GetHeight()).SetHeight(AbstractRenderer.INF); } if (rotation != null && !FloatingHelper.IsRendererFloating(this)) { blockWidth = RotationUtils.RetrieveRotatedLayoutWidth(parentBBox.GetWidth(), this); } if (marginsCollapsingEnabled) { marginsCollapseHandler.StartMarginsCollapse(parentBBox); } Border[] borders = GetBorders(); UnitValue[] paddings = GetPaddings(); float additionalWidth = ApplyBordersPaddingsMargins(parentBBox, borders, paddings); ApplyWidth(parentBBox, blockWidth, overflowX); wasHeightClipped = ApplyMaxHeight(parentBBox, blockMaxHeight, marginsCollapseHandler, false, wasParentsHeightClipped , overflowY); MinMaxWidth minMaxWidth = new MinMaxWidth(additionalWidth); AbstractWidthHandler widthHandler = new MaxMaxWidthHandler(minMaxWidth); 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)); ShrinkOccupiedAreaForAbsolutePosition(); int currentAreaPos = 0; Rectangle layoutBox = areas[0].Clone(); lines = new List <LineRenderer>(); foreach (IRenderer child in childRenderers) { notAllKidsAreFloats = notAllKidsAreFloats || !FloatingHelper.IsRendererFloating(child); currentRenderer.AddChild(child); } float lastYLine = layoutBox.GetY() + layoutBox.GetHeight(); float previousDescent = 0; float lastLineBottomLeadingIndent = 0; bool onlyOverflowedFloatsLeft = false; IList <IRenderer> inlineFloatsOverflowedToNextPage = new List <IRenderer>(); bool floatOverflowedToNextPageWithNothing = false; // rectangles are compared by instances ICollection <Rectangle> nonChildFloatingRendererAreas = new HashSet <Rectangle>(floatRendererAreas); if (marginsCollapsingEnabled && childRenderers.Count > 0) { // passing null is sufficient to notify that there is a kid, however we don't care about it and it's margins marginsCollapseHandler.StartChildMarginsHandling(null, layoutBox); } bool includeFloatsInOccupiedArea = BlockFormattingContextUtil.IsRendererCreateBfc(this); while (currentRenderer != null) { currentRenderer.SetProperty(Property.TAB_DEFAULT, this.GetPropertyAsFloat(Property.TAB_DEFAULT)); currentRenderer.SetProperty(Property.TAB_STOPS, this.GetProperty <Object>(Property.TAB_STOPS)); float lineIndent = anythingPlaced ? 0 : (float)this.GetPropertyAsFloat(Property.FIRST_LINE_INDENT); Rectangle childLayoutBox = new Rectangle(layoutBox.GetX(), layoutBox.GetY(), layoutBox.GetWidth(), layoutBox .GetHeight()); currentRenderer.SetProperty(Property.OVERFLOW_X, overflowX); currentRenderer.SetProperty(Property.OVERFLOW_Y, overflowY); LineLayoutContext lineLayoutContext = new LineLayoutContext(new LayoutArea(pageNumber, childLayoutBox), null , floatRendererAreas, wasHeightClipped || wasParentsHeightClipped).SetTextIndent(lineIndent).SetFloatOverflowedToNextPageWithNothing (floatOverflowedToNextPageWithNothing); LineLayoutResult result = (LineLayoutResult)((LineRenderer)currentRenderer.SetParent(this)).Layout(lineLayoutContext ); if (result.GetStatus() == LayoutResult.NOTHING) { float?lineShiftUnderFloats = FloatingHelper.CalculateLineShiftUnderFloats(floatRendererAreas, layoutBox); if (lineShiftUnderFloats != null) { layoutBox.DecreaseHeight((float)lineShiftUnderFloats); firstLineInBox = true; continue; } bool allRemainingKidsAreFloats = !currentRenderer.childRenderers.IsEmpty(); foreach (IRenderer renderer in currentRenderer.childRenderers) { allRemainingKidsAreFloats = allRemainingKidsAreFloats && FloatingHelper.IsRendererFloating(renderer); } if (allRemainingKidsAreFloats) { onlyOverflowedFloatsLeft = true; } } floatOverflowedToNextPageWithNothing = lineLayoutContext.IsFloatOverflowedToNextPageWithNothing(); if (result.GetFloatsOverflowedToNextPage() != null) { inlineFloatsOverflowedToNextPage.AddAll(result.GetFloatsOverflowedToNextPage()); } float minChildWidth = 0; float maxChildWidth = 0; if (result is MinMaxWidthLayoutResult) { minChildWidth = ((MinMaxWidthLayoutResult)result).GetMinMaxWidth().GetMinWidth(); maxChildWidth = ((MinMaxWidthLayoutResult)result).GetMinMaxWidth().GetMaxWidth(); } widthHandler.UpdateMinChildWidth(minChildWidth); widthHandler.UpdateMaxChildWidth(maxChildWidth); LineRenderer processedRenderer = null; if (result.GetStatus() == LayoutResult.FULL) { processedRenderer = currentRenderer; } else { if (result.GetStatus() == LayoutResult.PARTIAL) { processedRenderer = (LineRenderer)result.GetSplitRenderer(); } } if (onlyOverflowedFloatsLeft) { // This is done to trick ParagraphRenderer to break rendering and to overflow to the next page. // The `onlyOverflowedFloatsLeft` is set to true only when no other content is left except // overflowed floating elements. processedRenderer = null; } TextAlignment?textAlignment = (TextAlignment?)this.GetProperty <TextAlignment?>(Property.TEXT_ALIGNMENT, TextAlignment .LEFT); ApplyTextAlignment(textAlignment, result, processedRenderer, layoutBox, floatRendererAreas, onlyOverflowedFloatsLeft , lineIndent); Leading leading = RenderingMode.HTML_MODE.Equals(this.GetProperty <RenderingMode?>(Property.RENDERING_MODE) ) ? null : this.GetProperty <Leading>(Property.LEADING); // could be false if e.g. line contains only floats bool lineHasContent = processedRenderer != null && processedRenderer.GetOccupiedArea().GetBBox().GetHeight () > 0; bool isFit = processedRenderer != null; float deltaY = 0; if (isFit && !RenderingMode.HTML_MODE.Equals(this.GetProperty <RenderingMode?>(Property.RENDERING_MODE))) { if (lineHasContent) { float indentFromLastLine = previousDescent - lastLineBottomLeadingIndent - (leading != null ? processedRenderer .GetTopLeadingIndent(leading) : 0) - processedRenderer.GetMaxAscent(); // TODO this is a workaround. To be refactored if (processedRenderer != null && processedRenderer.ContainsImage()) { indentFromLastLine += previousDescent; } deltaY = lastYLine + indentFromLastLine - processedRenderer.GetYLine(); lastLineBottomLeadingIndent = leading != null?processedRenderer.GetBottomLeadingIndent(leading) : 0; // TODO this is a workaround. To be refactored if (lastLineBottomLeadingIndent < 0 && processedRenderer.ContainsImage()) { lastLineBottomLeadingIndent = 0; } } // for the first and last line in a paragraph, leading is smaller if (firstLineInBox) { deltaY = processedRenderer != null && leading != null ? -processedRenderer.GetTopLeadingIndent(leading) : 0; } isFit = leading == null || processedRenderer.GetOccupiedArea().GetBBox().GetY() + deltaY >= layoutBox.GetY (); } if (!isFit && (null == processedRenderer || IsOverflowFit(overflowY))) { if (currentAreaPos + 1 < areas.Count) { layoutBox = areas[++currentAreaPos].Clone(); lastYLine = layoutBox.GetY() + layoutBox.GetHeight(); firstLineInBox = true; } else { bool keepTogether = IsKeepTogether(); if (keepTogether) { floatRendererAreas.RetainAll(nonChildFloatingRendererAreas); return(new MinMaxWidthLayoutResult(LayoutResult.NOTHING, null, null, this, null == result.GetCauseOfNothing () ? this : result.GetCauseOfNothing())); } else { if (marginsCollapsingEnabled) { if (anythingPlaced && notAllKidsAreFloats) { marginsCollapseHandler.EndChildMarginsHandling(layoutBox); } } // On page split, if not only overflowed floats left, content will be drawn on next page, i.e. under all floats on this page bool includeFloatsInOccupiedAreaOnSplit = !onlyOverflowedFloatsLeft || includeFloatsInOccupiedArea; if (includeFloatsInOccupiedAreaOnSplit) { FloatingHelper.IncludeChildFloatsInOccupiedArea(floatRendererAreas, this, nonChildFloatingRendererAreas); FixOccupiedAreaIfOverflowedX(overflowX, layoutBox); } if (marginsCollapsingEnabled) { marginsCollapseHandler.EndMarginsCollapse(layoutBox); } bool minHeightOverflowed = false; if (!includeFloatsInOccupiedAreaOnSplit) { AbstractRenderer minHeightOverflow = ApplyMinHeight(overflowY, layoutBox); minHeightOverflowed = minHeightOverflow != null; ApplyVerticalAlignment(); } iText.Layout.Renderer.ParagraphRenderer[] split = Split(); split[0].lines = lines; foreach (LineRenderer line in lines) { split[0].childRenderers.AddAll(line.GetChildRenderers()); } split[1].childRenderers.AddAll(inlineFloatsOverflowedToNextPage); if (processedRenderer != null) { split[1].childRenderers.AddAll(processedRenderer.GetChildRenderers()); } if (result.GetOverflowRenderer() != null) { split[1].childRenderers.AddAll(result.GetOverflowRenderer().GetChildRenderers()); } if (onlyOverflowedFloatsLeft && !includeFloatsInOccupiedArea && !minHeightOverflowed) { FloatingHelper.RemoveParentArtifactsOnPageSplitIfOnlyFloatsOverflow(split[1]); } float usedHeight = occupiedArea.GetBBox().GetHeight(); if (!includeFloatsInOccupiedAreaOnSplit) { Rectangle commonRectangle = Rectangle.GetCommonRectangle(layoutBox, occupiedArea.GetBBox()); usedHeight = commonRectangle.GetHeight(); } UpdateHeightsOnSplit(usedHeight, wasHeightClipped, this, split[1], includeFloatsInOccupiedAreaOnSplit); CorrectFixedLayout(layoutBox); ApplyPaddings(occupiedArea.GetBBox(), paddings, true); ApplyBorderBox(occupiedArea.GetBBox(), borders, true); ApplyMargins(occupiedArea.GetBBox(), true); ApplyAbsolutePositionIfNeeded(layoutContext); LayoutArea editedArea = FloatingHelper.AdjustResultOccupiedAreaForFloatAndClear(this, layoutContext.GetFloatRendererAreas (), layoutContext.GetArea().GetBBox(), clearHeightCorrection, marginsCollapsingEnabled); if (wasHeightClipped) { return(new MinMaxWidthLayoutResult(LayoutResult.FULL, editedArea, split[0], null).SetMinMaxWidth(minMaxWidth )); } else { if (anythingPlaced) { return(new MinMaxWidthLayoutResult(LayoutResult.PARTIAL, editedArea, split[0], split[1]).SetMinMaxWidth(minMaxWidth )); } else { if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT))) { occupiedArea.SetBBox(Rectangle.GetCommonRectangle(occupiedArea.GetBBox(), currentRenderer.GetOccupiedArea( ).GetBBox())); FixOccupiedAreaIfOverflowedX(overflowX, layoutBox); parent.SetProperty(Property.FULL, true); lines.Add(currentRenderer); // Force placement of children we have and do not force placement of the others if (LayoutResult.PARTIAL == result.GetStatus()) { IRenderer childNotRendered = result.GetCauseOfNothing(); int firstNotRendered = currentRenderer.childRenderers.IndexOf(childNotRendered); currentRenderer.childRenderers.RetainAll(currentRenderer.childRenderers.SubList(0, firstNotRendered)); split[1].childRenderers.RemoveAll(split[1].childRenderers.SubList(0, firstNotRendered)); return(new MinMaxWidthLayoutResult(LayoutResult.PARTIAL, editedArea, this, split[1], null).SetMinMaxWidth( minMaxWidth)); } else { return(new MinMaxWidthLayoutResult(LayoutResult.FULL, editedArea, null, null, this).SetMinMaxWidth(minMaxWidth )); } } else { floatRendererAreas.RetainAll(nonChildFloatingRendererAreas); return(new MinMaxWidthLayoutResult(LayoutResult.NOTHING, null, null, this, null == result.GetCauseOfNothing () ? this : result.GetCauseOfNothing())); } } } } } } else { if (leading != null) { processedRenderer.ApplyLeading(deltaY); if (lineHasContent) { lastYLine = processedRenderer.GetYLine(); } } if (lineHasContent) { occupiedArea.SetBBox(Rectangle.GetCommonRectangle(occupiedArea.GetBBox(), processedRenderer.GetOccupiedArea ().GetBBox())); FixOccupiedAreaIfOverflowedX(overflowX, layoutBox); } firstLineInBox = false; layoutBox.SetHeight(processedRenderer.GetOccupiedArea().GetBBox().GetY() - layoutBox.GetY()); lines.Add(processedRenderer); anythingPlaced = true; currentRenderer = (LineRenderer)result.GetOverflowRenderer(); previousDescent = processedRenderer.GetMaxDescent(); if (!inlineFloatsOverflowedToNextPage.IsEmpty() && result.GetOverflowRenderer() == null) { onlyOverflowedFloatsLeft = true; // dummy renderer to trick paragraph renderer to continue kids loop currentRenderer = new LineRenderer(); } } } if (!RenderingMode.HTML_MODE.Equals(this.GetProperty <RenderingMode?>(Property.RENDERING_MODE))) { float moveDown = lastLineBottomLeadingIndent; if (IsOverflowFit(overflowY) && moveDown > occupiedArea.GetBBox().GetY() - layoutBox.GetY()) { moveDown = occupiedArea.GetBBox().GetY() - layoutBox.GetY(); } occupiedArea.GetBBox().MoveDown(moveDown); occupiedArea.GetBBox().SetHeight(occupiedArea.GetBBox().GetHeight() + moveDown); } if (marginsCollapsingEnabled) { if (childRenderers.Count > 0 && notAllKidsAreFloats) { marginsCollapseHandler.EndChildMarginsHandling(layoutBox); } } if (includeFloatsInOccupiedArea) { FloatingHelper.IncludeChildFloatsInOccupiedArea(floatRendererAreas, this, nonChildFloatingRendererAreas); FixOccupiedAreaIfOverflowedX(overflowX, layoutBox); } if (wasHeightClipped) { FixOccupiedAreaIfOverflowedY(overflowY, layoutBox); } if (marginsCollapsingEnabled) { marginsCollapseHandler.EndMarginsCollapse(layoutBox); } AbstractRenderer overflowRenderer = ApplyMinHeight(overflowY, layoutBox); if (overflowRenderer != null && IsKeepTogether()) { floatRendererAreas.RetainAll(nonChildFloatingRendererAreas); return(new LayoutResult(LayoutResult.NOTHING, null, null, this, this)); } CorrectFixedLayout(layoutBox); ApplyPaddings(occupiedArea.GetBBox(), paddings, true); ApplyBorderBox(occupiedArea.GetBBox(), borders, true); ApplyMargins(occupiedArea.GetBBox(), true); ApplyAbsolutePositionIfNeeded(layoutContext); if (rotation != null) { ApplyRotationLayout(layoutContext.GetArea().GetBBox().Clone()); if (IsNotFittingLayoutArea(layoutContext.GetArea())) { if (IsNotFittingWidth(layoutContext.GetArea()) && !IsNotFittingHeight(layoutContext.GetArea())) { LogManager.GetLogger(GetType()).Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA , "It fits by height so it will be forced placed")); } else { if (!true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT))) { floatRendererAreas.RetainAll(nonChildFloatingRendererAreas); return(new MinMaxWidthLayoutResult(LayoutResult.NOTHING, null, null, this, this)); } } } } ApplyVerticalAlignment(); FloatingHelper.RemoveFloatsAboveRendererBottom(floatRendererAreas, this); LayoutArea editedArea_1 = FloatingHelper.AdjustResultOccupiedAreaForFloatAndClear(this, layoutContext.GetFloatRendererAreas (), layoutContext.GetArea().GetBBox(), clearHeightCorrection, marginsCollapsingEnabled); if (null == overflowRenderer) { return(new MinMaxWidthLayoutResult(LayoutResult.FULL, editedArea_1, null, null, null).SetMinMaxWidth(minMaxWidth )); } else { return(new MinMaxWidthLayoutResult(LayoutResult.PARTIAL, editedArea_1, this, overflowRenderer, null).SetMinMaxWidth (minMaxWidth)); } }
internal static float AdjustLayoutBoxAccordingToFloats(IList <Rectangle> floatRendererAreas, Rectangle layoutBox , float?boxWidth, float clearHeightCorrection, MarginsCollapseHandler marginsCollapseHandler) { float topShift = clearHeightCorrection; float left; float right; Rectangle[] lastLeftAndRightBoxes = null; do { if (lastLeftAndRightBoxes != null) { float bottomLeft = lastLeftAndRightBoxes[0] != null ? lastLeftAndRightBoxes[0].GetBottom() : float.MaxValue; float bottomRight = lastLeftAndRightBoxes[1] != null ? lastLeftAndRightBoxes[1].GetBottom() : float.MaxValue; float updatedHeight = Math.Min(bottomLeft, bottomRight) - layoutBox.GetY(); topShift = layoutBox.GetHeight() - updatedHeight; } IList <Rectangle> boxesAtYLevel = GetBoxesAtYLevel(floatRendererAreas, layoutBox.GetTop() - topShift); if (boxesAtYLevel.IsEmpty()) { ApplyClearance(layoutBox, marginsCollapseHandler, topShift, false); return(topShift); } lastLeftAndRightBoxes = FindLastLeftAndRightBoxes(layoutBox, boxesAtYLevel); left = lastLeftAndRightBoxes[0] != null ? lastLeftAndRightBoxes[0].GetRight() : float.MinValue; right = lastLeftAndRightBoxes[1] != null ? lastLeftAndRightBoxes[1].GetLeft() : float.MaxValue; if (left > right || left > layoutBox.GetRight() || right < layoutBox.GetLeft()) { left = layoutBox.GetLeft(); right = left; } else { if (right > layoutBox.GetRight()) { right = layoutBox.GetRight(); } if (left < layoutBox.GetLeft()) { left = layoutBox.GetLeft(); } } }while (boxWidth != null && boxWidth > right - left); if (layoutBox.GetWidth() > right - left) { layoutBox.SetX(left).SetWidth(right - left); } ApplyClearance(layoutBox, marginsCollapseHandler, topShift, false); return(topShift); }