private void UpdateCollapseBeforeIfPrevKidIsFirstAndSelfCollapsed(MarginsCollapse collapseAfter)
 {
     if (prevChildMarginInfo.IsSelfCollapsing() && prevChildMarginInfo.IsIgnoreOwnMarginTop())
     {
         // prevChildMarginInfo.isIgnoreOwnMarginTop() is true only if it's the first kid and is adjoined to parent margin
         collapseInfo.GetCollapseBefore().JoinMargin(collapseAfter);
     }
 }
 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);
         }
     }
 }
        private MarginsCollapseInfo CreateMarginsInfoForBlockChild(int childIndex)
        {
            bool ignoreChildTopMargin = false;
            // always assume that current child might be the last on this area
            bool ignoreChildBottomMargin = LastChildMarginAdjoinedToParent(renderer);

            if (childIndex == firstNotEmptyKidIndex)
            {
                ignoreChildTopMargin = FirstChildMarginAdjoinedToParent(renderer);
            }
            MarginsCollapse childCollapseBefore;

            if (childIndex == 0)
            {
                MarginsCollapse parentCollapseBefore = collapseInfo.GetCollapseBefore();
                childCollapseBefore = ignoreChildTopMargin ? parentCollapseBefore : new MarginsCollapse();
            }
            else
            {
                MarginsCollapse prevChildCollapseAfter = prevChildMarginInfo != null?prevChildMarginInfo.GetOwnCollapseAfter
                                                             () : null;

                childCollapseBefore = prevChildCollapseAfter != null ? prevChildCollapseAfter : new MarginsCollapse();
            }
            MarginsCollapse     parentCollapseAfter = collapseInfo.GetCollapseAfter().Clone();
            MarginsCollapse     childCollapseAfter  = ignoreChildBottomMargin ? parentCollapseAfter : new MarginsCollapse();
            MarginsCollapseInfo childMarginsInfo    = new MarginsCollapseInfo(ignoreChildTopMargin, ignoreChildBottomMargin
                                                                              , childCollapseBefore, childCollapseAfter);

            if (ignoreChildTopMargin && childIndex == firstNotEmptyKidIndex)
            {
                childMarginsInfo.SetBufferSpaceOnTop(collapseInfo.GetBufferSpaceOnTop());
            }
            if (ignoreChildBottomMargin)
            {
                childMarginsInfo.SetBufferSpaceOnBottom(collapseInfo.GetBufferSpaceOnBottom());
            }
            return(childMarginsInfo);
        }
        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);
            }
        }