private void PrepareBoxForLayoutAttempt(Rectangle layoutBox, int childIndex, bool childIsBlockElement) { if (prevChildMarginInfo != null) { bool prevChildHasAppliedCollapseAfter = !prevChildMarginInfo.IsIgnoreOwnMarginBottom() && (!prevChildMarginInfo .IsSelfCollapsing() || !prevChildMarginInfo.IsIgnoreOwnMarginTop()); if (prevChildHasAppliedCollapseAfter) { layoutBox.SetHeight(layoutBox.GetHeight() + prevChildMarginInfo.GetCollapseAfter().GetCollapsedMarginsSize ()); } bool prevChildCanApplyCollapseAfter = !prevChildMarginInfo.IsSelfCollapsing() || !prevChildMarginInfo.IsIgnoreOwnMarginTop (); if (!childIsBlockElement && prevChildCanApplyCollapseAfter) { MarginsCollapse ownCollapseAfter = prevChildMarginInfo.GetOwnCollapseAfter(); float ownCollapsedMargins = ownCollapseAfter == null ? 0 : ownCollapseAfter.GetCollapsedMarginsSize(); layoutBox.SetHeight(layoutBox.GetHeight() - ownCollapsedMargins); } } else { if (childIndex > firstNotEmptyKidIndex) { if (LastChildMarginAdjoinedToParent(renderer)) { // restore layout box after inline element float bottomIndent = collapseInfo.GetCollapseAfter().GetCollapsedMarginsSize() - collapseInfo.GetUsedBufferSpaceOnBottom (); // used space shall be always less or equal to collapsedMarginAfter size collapseInfo.SetBufferSpaceOnBottom(collapseInfo.GetBufferSpaceOnBottom() + collapseInfo.GetUsedBufferSpaceOnBottom ()); collapseInfo.SetUsedBufferSpaceOnBottom(0); layoutBox.SetY(layoutBox.GetY() - bottomIndent); layoutBox.SetHeight(layoutBox.GetHeight() + bottomIndent); } } } if (!childIsBlockElement) { if (childIndex == firstNotEmptyKidIndex && FirstChildMarginAdjoinedToParent(renderer)) { float topIndent = collapseInfo.GetCollapseBefore().GetCollapsedMarginsSize(); ApplyTopMargin(layoutBox, topIndent); } if (LastChildMarginAdjoinedToParent(renderer)) { // if not adjoined - bottom margin have been already applied on startMarginsCollapse float bottomIndent = collapseInfo.GetCollapseAfter().GetCollapsedMarginsSize(); ApplyBottomMargin(layoutBox, bottomIndent); } } }
public virtual void EndMarginsCollapse(Rectangle layoutBox) { if (backupLayoutBox != null) { RestoreLayoutBoxAfterFailedLayoutAttempt(layoutBox); } if (prevChildMarginInfo != null) { UpdateCollapseBeforeIfPrevKidIsFirstAndSelfCollapsed(prevChildMarginInfo.GetCollapseAfter()); } bool couldBeSelfCollapsing = iText.Layout.Margincollapse.MarginsCollapseHandler.MarginsCouldBeSelfCollapsing (renderer) && !lastKidCollapsedAfterHasClearanceApplied; bool blockHasNoKidsWithContent = collapseInfo.IsSelfCollapsing(); if (FirstChildMarginAdjoinedToParent(renderer)) { if (blockHasNoKidsWithContent && !couldBeSelfCollapsing) { AddNotYetAppliedTopMargin(layoutBox); } } collapseInfo.SetSelfCollapsing(collapseInfo.IsSelfCollapsing() && couldBeSelfCollapsing); if (!blockHasNoKidsWithContent && lastKidCollapsedAfterHasClearanceApplied) { ApplySelfCollapsedKidMarginWithClearance(layoutBox); } MarginsCollapse ownCollapseAfter; bool lastChildMarginJoinedToParent = prevChildMarginInfo != null && prevChildMarginInfo.IsIgnoreOwnMarginBottom () && !lastKidCollapsedAfterHasClearanceApplied; if (lastChildMarginJoinedToParent) { ownCollapseAfter = prevChildMarginInfo.GetOwnCollapseAfter(); } else { ownCollapseAfter = new MarginsCollapse(); } ownCollapseAfter.JoinMargin(GetModelBottomMargin(renderer)); collapseInfo.SetOwnCollapseAfter(ownCollapseAfter); if (collapseInfo.IsSelfCollapsing()) { if (prevChildMarginInfo != null) { collapseInfo.SetCollapseAfter(prevChildMarginInfo.GetCollapseAfter()); } else { collapseInfo.GetCollapseAfter().JoinMargin(collapseInfo.GetCollapseBefore()); collapseInfo.GetOwnCollapseAfter().JoinMargin(collapseInfo.GetCollapseBefore()); } if (!collapseInfo.IsIgnoreOwnMarginBottom() && !collapseInfo.IsIgnoreOwnMarginTop()) { float collapsedMargins = collapseInfo.GetCollapseAfter().GetCollapsedMarginsSize(); OverrideModelBottomMargin(renderer, collapsedMargins); } } else { MarginsCollapse marginsCollapseBefore = collapseInfo.GetCollapseBefore(); if (!collapseInfo.IsIgnoreOwnMarginTop()) { float collapsedMargins = marginsCollapseBefore.GetCollapsedMarginsSize(); OverrideModelTopMargin(renderer, collapsedMargins); } if (lastChildMarginJoinedToParent) { collapseInfo.SetCollapseAfter(prevChildMarginInfo.GetCollapseAfter()); } if (!collapseInfo.IsIgnoreOwnMarginBottom()) { float collapsedMargins = collapseInfo.GetCollapseAfter().GetCollapsedMarginsSize(); OverrideModelBottomMargin(renderer, collapsedMargins); } } if (LastChildMarginAdjoinedToParent(renderer) && (prevChildMarginInfo != null || blockHasNoKidsWithContent )) { // Adjust layout box here in order to make it represent the available area left. float collapsedMargins = collapseInfo.GetCollapseAfter().GetCollapsedMarginsSize(); // May be in case of self-collapsed margins it would make more sense to apply this value to topMargin, // because that way the layout box would represent the area left after the empty self-collapsed block, not // before it. However at the same time any considerations about the layout (i.e. content) area in case // of the self-collapsed block seem to be invalid, because self-collapsed block shall have content area // of zero height. ApplyBottomMargin(layoutBox, collapsedMargins); } }