private static LayoutResult HandleAttemptAsSuccessful(OrphansWidowsLayoutHelper.OrphansWidowsLayoutAttempt
                                                       attemptResult, LayoutContext originalContext)
 {
     originalContext.GetFloatRendererAreas().Clear();
     originalContext.GetFloatRendererAreas().AddAll(attemptResult.attemptContext.GetFloatRendererAreas());
     if (originalContext.GetMarginsCollapseInfo() != null)
     {
         MarginsCollapseInfo.UpdateFromCopy(originalContext.GetMarginsCollapseInfo(), attemptResult.attemptContext.
                                            GetMarginsCollapseInfo());
     }
     return(attemptResult.attemptResult);
 }
        private static OrphansWidowsLayoutHelper.OrphansWidowsLayoutAttempt AttemptLayout(ParagraphRenderer renderer
                                                                                          , LayoutContext originalContext, LayoutArea attemptArea)
        {
            OrphansWidowsLayoutHelper.OrphansWidowsLayoutAttempt attemptResult = new OrphansWidowsLayoutHelper.OrphansWidowsLayoutAttempt
                                                                                     ();
            MarginsCollapseInfo copiedMarginsCollapseInfo = null;

            if (originalContext.GetMarginsCollapseInfo() != null)
            {
                copiedMarginsCollapseInfo = MarginsCollapseInfo.CreateDeepCopy(originalContext.GetMarginsCollapseInfo());
            }
            List <Rectangle> attemptFloatRectsList = new List <Rectangle>(originalContext.GetFloatRendererAreas());
            LayoutContext    attemptContext        = new LayoutContext(attemptArea, copiedMarginsCollapseInfo, attemptFloatRectsList
                                                                       , originalContext.IsClippedHeight());

            attemptResult.attemptContext = attemptContext;
            attemptResult.attemptResult  = renderer.DirectLayout(attemptContext);
            return(attemptResult);
        }
        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));
            }
        }
        public override LayoutResult Layout(LayoutContext layoutContext)
        {
            LayoutArea      area         = layoutContext.GetArea().Clone();
            Rectangle       layoutBox    = area.GetBBox().Clone();
            AffineTransform t            = new AffineTransform();
            Image           modelElement = (Image)(GetModelElement());
            PdfXObject      xObject      = modelElement.GetXObject();

            imageWidth  = modelElement.GetImageWidth();
            imageHeight = modelElement.GetImageHeight();
            CalculateImageDimensions(layoutBox, t, xObject);
            OverflowPropertyValue?overflowX = null != parent?parent.GetProperty <OverflowPropertyValue?>(Property.OVERFLOW_X
                                                                                                         ) : OverflowPropertyValue.FIT;

            bool nowrap = false;

            if (parent is LineRenderer)
            {
                nowrap = true.Equals(this.parent.GetOwnProperty <bool?>(Property.NO_SOFT_WRAP_INLINE));
            }
            IList <Rectangle> floatRendererAreas    = layoutContext.GetFloatRendererAreas();
            float             clearHeightCorrection = FloatingHelper.CalculateClearHeightCorrection(this, floatRendererAreas, layoutBox
                                                                                                    );
            FloatPropertyValue?floatPropertyValue = this.GetProperty <FloatPropertyValue?>(Property.FLOAT);

            if (FloatingHelper.IsRendererFloating(this, floatPropertyValue))
            {
                layoutBox.DecreaseHeight(clearHeightCorrection);
                FloatingHelper.AdjustFloatedBlockLayoutBox(this, layoutBox, width, floatRendererAreas, floatPropertyValue,
                                                           overflowX);
            }
            else
            {
                clearHeightCorrection = FloatingHelper.AdjustLayoutBoxAccordingToFloats(floatRendererAreas, layoutBox, width
                                                                                        , clearHeightCorrection, null);
            }
            ApplyMargins(layoutBox, false);
            Border[] borders = GetBorders();
            ApplyBorderBox(layoutBox, borders, false);
            float?declaredMaxHeight         = RetrieveMaxHeight();
            OverflowPropertyValue?overflowY = null == parent || ((null == declaredMaxHeight || declaredMaxHeight > layoutBox
                                                                  .GetHeight()) && !layoutContext.IsClippedHeight()) ? OverflowPropertyValue.FIT : parent.GetProperty <OverflowPropertyValue?
                                                                                                                                                                       >(Property.OVERFLOW_Y);
            bool processOverflowX = !IsOverflowFit(overflowX) || nowrap;
            bool processOverflowY = !IsOverflowFit(overflowY);

            if (IsAbsolutePosition())
            {
                ApplyAbsolutePosition(layoutBox);
            }
            occupiedArea = new LayoutArea(area.GetPageNumber(), new Rectangle(layoutBox.GetX(), layoutBox.GetY() + layoutBox
                                                                              .GetHeight(), 0, 0));
            float imageItselfScaledWidth  = (float)width;
            float imageItselfScaledHeight = (float)height;

            if (IsFixedLayout())
            {
                fixedXPosition = this.GetPropertyAsFloat(Property.LEFT);
                fixedYPosition = this.GetPropertyAsFloat(Property.BOTTOM);
            }
            float?angle = this.GetPropertyAsFloat(Property.ROTATION_ANGLE);

            // See in adjustPositionAfterRotation why angle = 0 is necessary
            if (null == angle)
            {
                angle = 0f;
            }
            t.Rotate((float)angle);
            initialOccupiedAreaBBox = GetOccupiedAreaBBox().Clone();
            float scaleCoef = AdjustPositionAfterRotation((float)angle, layoutBox.GetWidth(), layoutBox.GetHeight());

            imageItselfScaledHeight *= scaleCoef;
            imageItselfScaledWidth  *= scaleCoef;
            initialOccupiedAreaBBox.MoveDown(imageItselfScaledHeight);
            initialOccupiedAreaBBox.SetHeight(imageItselfScaledHeight);
            initialOccupiedAreaBBox.SetWidth(imageItselfScaledWidth);
            if (xObject is PdfFormXObject)
            {
                t.Scale(scaleCoef, scaleCoef);
            }
            GetMatrix(t, imageItselfScaledWidth, imageItselfScaledHeight);
            // indicates whether the placement is forced
            bool isPlacingForced = false;

            if (width > layoutBox.GetWidth() || height > layoutBox.GetHeight())
            {
                if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT)) || (width > layoutBox.GetWidth() && processOverflowX
                                                                                     ) || (height > layoutBox.GetHeight() && processOverflowY))
                {
                    isPlacingForced = true;
                }
                else
                {
                    ApplyMargins(initialOccupiedAreaBBox, true);
                    ApplyBorderBox(initialOccupiedAreaBBox, true);
                    occupiedArea.GetBBox().SetHeight(initialOccupiedAreaBBox.GetHeight());
                    return(new MinMaxWidthLayoutResult(LayoutResult.NOTHING, occupiedArea, null, this, this));
                }
            }
            occupiedArea.GetBBox().MoveDown((float)height);
            if (borders[3] != null)
            {
                height += (float)Math.Sin((float)angle) * borders[3].GetWidth();
            }
            occupiedArea.GetBBox().SetHeight((float)height);
            occupiedArea.GetBBox().SetWidth((float)width);
            UnitValue leftMargin = this.GetPropertyAsUnitValue(Property.MARGIN_LEFT);

            if (!leftMargin.IsPointValue())
            {
                ILog logger = LogManager.GetLogger(typeof(iText.Layout.Renderer.ImageRenderer));
                logger.Error(MessageFormatUtil.Format(iText.IO.LogMessageConstant.PROPERTY_IN_PERCENTS_NOT_SUPPORTED, Property
                                                      .MARGIN_LEFT));
            }
            UnitValue topMargin = this.GetPropertyAsUnitValue(Property.MARGIN_TOP);

            if (!topMargin.IsPointValue())
            {
                ILog logger = LogManager.GetLogger(typeof(iText.Layout.Renderer.ImageRenderer));
                logger.Error(MessageFormatUtil.Format(iText.IO.LogMessageConstant.PROPERTY_IN_PERCENTS_NOT_SUPPORTED, Property
                                                      .MARGIN_TOP));
            }
            if (0 != leftMargin.GetValue() || 0 != topMargin.GetValue())
            {
                TranslateImage(leftMargin.GetValue(), topMargin.GetValue(), t);
                GetMatrix(t, imageItselfScaledWidth, imageItselfScaledHeight);
            }
            ApplyBorderBox(occupiedArea.GetBBox(), borders, true);
            ApplyMargins(occupiedArea.GetBBox(), true);
            if (angle != 0)
            {
                ApplyRotationLayout((float)angle);
            }
            float       unscaledWidth = occupiedArea.GetBBox().GetWidth() / scaleCoef;
            MinMaxWidth minMaxWidth   = new MinMaxWidth(unscaledWidth, unscaledWidth, 0);
            UnitValue   rendererWidth = this.GetProperty <UnitValue>(Property.WIDTH);

            if (rendererWidth != null && rendererWidth.IsPercentValue())
            {
                minMaxWidth.SetChildrenMinWidth(0);
                float coeff = imageWidth / (float)RetrieveWidth(area.GetBBox().GetWidth());
                minMaxWidth.SetChildrenMaxWidth(unscaledWidth * coeff);
            }
            else
            {
                bool autoScale      = HasProperty(Property.AUTO_SCALE) && (bool)this.GetProperty <bool?>(Property.AUTO_SCALE);
                bool autoScaleWidth = HasProperty(Property.AUTO_SCALE_WIDTH) && (bool)this.GetProperty <bool?>(Property.AUTO_SCALE_WIDTH
                                                                                                               );
                if (autoScale || autoScaleWidth)
                {
                    minMaxWidth.SetChildrenMinWidth(0);
                }
            }
            FloatingHelper.RemoveFloatsAboveRendererBottom(floatRendererAreas, this);
            LayoutArea editedArea = FloatingHelper.AdjustResultOccupiedAreaForFloatAndClear(this, floatRendererAreas,
                                                                                            layoutContext.GetArea().GetBBox(), clearHeightCorrection, false);

            ApplyAbsolutePositionIfNeeded(layoutContext);
            return(new MinMaxWidthLayoutResult(LayoutResult.FULL, editedArea, null, null, isPlacingForced ? this : null
                                               ).SetMinMaxWidth(minMaxWidth));
        }
Beispiel #5
0
        public override LayoutResult Layout(LayoutContext layoutContext)
        {
            // Resolve width here in case it's relative, while parent width is still intact.
            // If it's inline-block context, relative width is already resolved.
            float?width = RetrieveWidth(layoutContext.GetArea().GetBBox().GetWidth());

            if (width != null)
            {
                UpdateWidth(UnitValue.CreatePointValue((float)width));
            }
            float      childrenMaxWidth = GetMinMaxWidth().GetMaxWidth();
            LayoutArea area             = layoutContext.GetArea().Clone();

            area.GetBBox().MoveDown(INF - area.GetBBox().GetHeight()).SetHeight(INF).SetWidth(childrenMaxWidth + EPS);
            LayoutResult layoutResult = base.Layout(new LayoutContext(area, layoutContext.GetMarginsCollapseInfo(), layoutContext
                                                                      .GetFloatRendererAreas(), layoutContext.IsClippedHeight()));

            if (layoutResult.GetStatus() != LayoutResult.FULL)
            {
                if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT)))
                {
                    layoutResult = MakeLayoutResultFull(layoutContext.GetArea(), layoutResult);
                }
                else
                {
                    return(new LayoutResult(LayoutResult.NOTHING, null, null, this, this));
                }
            }
            float     availableHeight = layoutContext.GetArea().GetBBox().GetHeight();
            bool      isClippedHeight = layoutContext.IsClippedHeight();
            Rectangle dummy           = new Rectangle(0, 0);

            ApplyMargins(dummy, true);
            ApplyBorderBox(dummy, true);
            ApplyPaddings(dummy, true);
            float additionalHeight = dummy.GetHeight();

            availableHeight -= additionalHeight;
            availableHeight  = Math.Max(availableHeight, 0);
            float actualHeight           = GetOccupiedArea().GetBBox().GetHeight() - additionalHeight;
            float finalSelectFieldHeight = GetFinalSelectFieldHeight(availableHeight, actualHeight, isClippedHeight);

            if (finalSelectFieldHeight < 0)
            {
                return(new LayoutResult(LayoutResult.NOTHING, null, null, this, this));
            }
            float delta = finalSelectFieldHeight - actualHeight;

            if (Math.Abs(delta) > EPS)
            {
                GetOccupiedArea().GetBBox().IncreaseHeight(delta).MoveDown(delta);
            }
            return(layoutResult);
        }