Example #1
0
 public override int GetHashCode()
 {
     unchecked
     {
         var hashCode = Leading.GetHashCode();
         hashCode = (hashCode * 397) ^ Children.GetHashCode();
         hashCode = (hashCode * 397) ^ Trailing.GetHashCode();
         hashCode = (hashCode * 397) ^ Body.GetHashCode();
         return(hashCode);
     }
 }
Example #2
0
        public virtual float GetLeadingValue(Leading leading)
        {
            switch (leading.GetLeadingType())
            {
            case Leading.FIXED:
            {
                return(leading.GetValue());
            }

            case Leading.MULTIPLIED:
            {
                return(occupiedArea.GetBBox().GetHeight() * leading.GetValue());
            }

            default:
            {
                throw new InvalidOperationException();
            }
            }
        }
        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));
            }
        }
        /// <summary><inheritDoc/></summary>
        public override LayoutResult Layout(LayoutContext layoutContext)
        {
            int          pageNumber      = layoutContext.GetArea().GetPageNumber();
            bool         anythingPlaced  = false;
            bool         firstLineInBox  = true;
            LineRenderer currentRenderer = (LineRenderer) new LineRenderer().SetParent(this);
            Rectangle    parentBBox      = layoutContext.GetArea().GetBBox().Clone();

            if (0 == childRenderers.Count)
            {
                anythingPlaced  = true;
                currentRenderer = null;
                SetProperty(Property.MARGIN_TOP, 0);
                SetProperty(Property.MARGIN_RIGHT, 0);
                SetProperty(Property.MARGIN_BOTTOM, 0);
                SetProperty(Property.MARGIN_LEFT, 0);
                SetProperty(Property.PADDING_TOP, 0);
                SetProperty(Property.PADDING_RIGHT, 0);
                SetProperty(Property.PADDING_BOTTOM, 0);
                SetProperty(Property.PADDING_LEFT, 0);
                SetProperty(Property.BORDER, Border.NO_BORDER);
            }
            if (this.GetProperty <float?>(Property.ROTATION_ANGLE) != null)
            {
                parentBBox.MoveDown(AbstractRenderer.INF - parentBBox.GetHeight()).SetHeight(AbstractRenderer.INF);
            }
            float[] margins = GetMargins();
            ApplyMargins(parentBBox, margins, false);
            Border[] borders = GetBorders();
            ApplyBorderBox(parentBBox, borders, false);
            bool isPositioned = IsPositioned();

            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();

            lines = new List <LineRenderer>();
            foreach (IRenderer child in childRenderers)
            {
                currentRenderer.AddChild(child);
            }
            float   lastYLine      = layoutBox.GetY() + layoutBox.GetHeight();
            Leading leading        = this.GetProperty <Leading>(Property.LEADING);
            float   leadingValue   = 0;
            float   lastLineHeight = 0;

            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);
                float     availableWidth = layoutBox.GetWidth() - lineIndent;
                Rectangle childLayoutBox = new Rectangle(layoutBox.GetX() + lineIndent, layoutBox.GetY(), availableWidth,
                                                         layoutBox.GetHeight());
                LineLayoutResult result = ((LineLayoutResult)((LineRenderer)currentRenderer.SetParent(this)).Layout(new LayoutContext
                                                                                                                        (new LayoutArea(pageNumber, childLayoutBox))));
                LineRenderer processedRenderer = null;
                if (result.GetStatus() == LayoutResult.FULL)
                {
                    processedRenderer = currentRenderer;
                }
                else
                {
                    if (result.GetStatus() == LayoutResult.PARTIAL)
                    {
                        processedRenderer = (LineRenderer)result.GetSplitRenderer();
                    }
                }
                TextAlignment?textAlignment = (TextAlignment?)this.GetProperty <TextAlignment?>(Property.TEXT_ALIGNMENT, TextAlignment
                                                                                                .LEFT);
                if (result.GetStatus() == LayoutResult.PARTIAL && textAlignment == TextAlignment.JUSTIFIED && !result.IsSplitForcedByNewline
                        () || textAlignment == TextAlignment.JUSTIFIED_ALL)
                {
                    if (processedRenderer != null)
                    {
                        processedRenderer.Justify(layoutBox.GetWidth() - lineIndent);
                    }
                }
                else
                {
                    if (textAlignment != TextAlignment.LEFT && processedRenderer != null)
                    {
                        float deltaX = availableWidth - processedRenderer.GetOccupiedArea().GetBBox().GetWidth();
                        switch (textAlignment)
                        {
                        case TextAlignment.RIGHT: {
                            processedRenderer.Move(deltaX, 0);
                            break;
                        }

                        case TextAlignment.CENTER: {
                            processedRenderer.Move(deltaX / 2, 0);
                            break;
                        }
                        }
                    }
                }
                leadingValue = processedRenderer != null && leading != null?processedRenderer.GetLeadingValue(leading) :
                                   0;

                if (processedRenderer != null && processedRenderer.ContainsImage())
                {
                    leadingValue -= previousDescent;
                }
                bool  doesNotFit = result.GetStatus() == LayoutResult.NOTHING;
                float deltaY     = 0;
                if (!doesNotFit)
                {
                    lastLineHeight = processedRenderer.GetOccupiedArea().GetBBox().GetHeight();
                    deltaY         = lastYLine - leadingValue - processedRenderer.GetYLine();
                    // for the first and last line in a paragraph, leading is smaller
                    if (firstLineInBox)
                    {
                        deltaY = -(leadingValue - lastLineHeight) / 2;
                    }
                    doesNotFit = leading != null && processedRenderer.GetOccupiedArea().GetBBox().GetY() + deltaY < layoutBox.
                                 GetY();
                }
                if (doesNotFit)
                {
                    if (currentAreaPos + 1 < areas.Count)
                    {
                        layoutBox      = areas[++currentAreaPos].Clone();
                        lastYLine      = layoutBox.GetY() + layoutBox.GetHeight();
                        firstLineInBox = true;
                    }
                    else
                    {
                        bool keepTogether = IsKeepTogether();
                        if (keepTogether)
                        {
                            return(new LayoutResult(LayoutResult.NOTHING, occupiedArea, null, this, null == result.GetCauseOfNothing()
                                 ? this : result.GetCauseOfNothing()));
                        }
                        else
                        {
                            ApplyPaddings(occupiedArea.GetBBox(), paddings, true);
                            ApplyBorderBox(occupiedArea.GetBBox(), borders, true);
                            ApplyMargins(occupiedArea.GetBBox(), margins, true);
                            iText.Layout.Renderer.ParagraphRenderer[] split = Split();
                            split[0].lines = lines;
                            foreach (LineRenderer line in lines)
                            {
                                split[0].childRenderers.AddAll(line.GetChildRenderers());
                            }
                            if (processedRenderer != null)
                            {
                                split[1].childRenderers.AddAll(processedRenderer.GetChildRenderers());
                            }
                            if (result.GetOverflowRenderer() != null)
                            {
                                split[1].childRenderers.AddAll(result.GetOverflowRenderer().GetChildRenderers());
                            }
                            if (anythingPlaced)
                            {
                                return(new LayoutResult(LayoutResult.PARTIAL, occupiedArea, split[0], split[1]));
                            }
                            else
                            {
                                if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT)))
                                {
                                    occupiedArea.SetBBox(Rectangle.GetCommonRectangle(occupiedArea.GetBBox(), currentRenderer.GetOccupiedArea(
                                                                                          ).GetBBox()));
                                    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 LayoutResult(LayoutResult.PARTIAL, occupiedArea, this, split[1]));
                                    }
                                    else
                                    {
                                        return(new LayoutResult(LayoutResult.FULL, occupiedArea, null, null, this));
                                    }
                                }
                                else
                                {
                                    return(new LayoutResult(LayoutResult.NOTHING, occupiedArea, null, this, null == result.GetCauseOfNothing()
                                         ? this : result.GetCauseOfNothing()));
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (leading != null)
                    {
                        processedRenderer.Move(0, deltaY);
                        lastYLine = processedRenderer.GetYLine();
                    }
                    occupiedArea.SetBBox(Rectangle.GetCommonRectangle(occupiedArea.GetBBox(), processedRenderer.GetOccupiedArea
                                                                          ().GetBBox()));
                    layoutBox.SetHeight(processedRenderer.GetOccupiedArea().GetBBox().GetY() - layoutBox.GetY());
                    lines.Add(processedRenderer);
                    anythingPlaced  = true;
                    firstLineInBox  = false;
                    currentRenderer = (LineRenderer)result.GetOverflowRenderer();
                    previousDescent = processedRenderer.GetMaxDescent();
                }
            }
            if (!isPositioned)
            {
                float moveDown = Math.Min((leadingValue - lastLineHeight) / 2, occupiedArea.GetBBox().GetY() - layoutBox.GetY
                                              ());
                occupiedArea.GetBBox().MoveDown(moveDown);
                occupiedArea.GetBBox().SetHeight(occupiedArea.GetBBox().GetHeight() + moveDown);
            }
            float?blockHeight = this.GetPropertyAsFloat(Property.HEIGHT);

            ApplyPaddings(occupiedArea.GetBBox(), paddings, true);
            if (blockHeight != null && blockHeight > occupiedArea.GetBBox().GetHeight())
            {
                occupiedArea.GetBBox().MoveDown((float)blockHeight - occupiedArea.GetBBox().GetHeight()).SetHeight((float)
                                                                                                                   blockHeight);
                ApplyVerticalAlignment();
            }
            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));
                    }
                }
            }
            return(new LayoutResult(LayoutResult.FULL, occupiedArea, null, null));
        }
Example #5
0
        protected bool Equals(InstructionNode other)
        {
            var eq = Equals(Body, other.Body);

            return(Leading.Equals(other.Leading) && Equals(Children, other.Children) && Trailing.Equals(other.Trailing) && eq);
        }
Example #6
0
 public override int GetHashCode()
 {
     return(Top.GetHashCode() ^ Leading.GetHashCode() ^ Trailing.GetHashCode() ^ Bottom.GetHashCode());
 }
            public override void Draw(DrawContext drawContext)
            {
                base.Draw(drawContext);

                Rectangle area = GetOccupiedAreaBBox();

                img.ScaleToFit(area.GetWidth(), area.GetHeight());

                drawContext.GetCanvas().AddXObjectFittedIntoRectangle(img.GetXObject(), new Rectangle(
                                                                          area.GetX() + (area.GetWidth() - img.GetImageWidth() *
                                                                                         img.GetProperty <float>(Property.HORIZONTAL_SCALING)) / 2,
                                                                          area.GetY() + (area.GetHeight() - img.GetImageHeight() *
                                                                                         img.GetProperty <float>(Property.VERTICAL_SCALING)) / 2,
                                                                          img.GetImageWidth() * img.GetProperty <float>(Property.HORIZONTAL_SCALING),
                                                                          img.GetImageHeight() * img.GetProperty <float>(Property.VERTICAL_SCALING)));

                drawContext.GetCanvas().Stroke();

                Paragraph p       = new Paragraph(content);
                Leading   leading = p.GetDefaultProperty <Leading>(Property.LEADING);

                UnitValue defaultFontSizeUv = new DocumentRenderer(new Document(drawContext.GetDocument()))
                                              .GetPropertyAsUnitValue(Property.FONT_SIZE);

                float         defaultFontSize = defaultFontSizeUv.IsPointValue() ? defaultFontSizeUv.GetValue() : 12f;
                float         x;
                float         y;
                TextAlignment?alignment;

                switch (position)
                {
                case POSITION.TOP_LEFT:
                {
                    x         = area.GetLeft() + 3;
                    y         = area.GetTop() - defaultFontSize * leading.GetValue();
                    alignment = TextAlignment.LEFT;
                    break;
                }

                case POSITION.TOP_RIGHT:
                {
                    x         = area.GetRight() - 3;
                    y         = area.GetTop() - defaultFontSize * leading.GetValue();
                    alignment = TextAlignment.RIGHT;
                    break;
                }

                case POSITION.BOTTOM_LEFT:
                {
                    x         = area.GetLeft() + 3;
                    y         = area.GetBottom() + 3;
                    alignment = TextAlignment.LEFT;
                    break;
                }

                case POSITION.BOTTOM_RIGHT:
                {
                    x         = area.GetRight() - 3;
                    y         = area.GetBottom() + 3;
                    alignment = TextAlignment.RIGHT;
                    break;
                }

                default:
                {
                    x         = 0;
                    y         = 0;
                    alignment = TextAlignment.CENTER;
                    break;
                }
                }

                new Canvas(drawContext.GetCanvas(), area).ShowTextAligned(p, x, y, alignment);
            }
Example #8
0
        public override IEnumerable <SvgAttribute> GetAttributes()
        {
            var baseAttributes = base.GetAttributes();

            if (baseAttributes != null)
            {
                foreach (var attr in baseAttributes)
                {
                    yield return(attr);
                }
            }

            yield return
                (new SvgAttribute("alignment", TextAlignment.Left.ToString().ToLowerInvariant(), XmlNamespace.AurigmaVectorObjects,
                                  () => Alignment.ToString().ToLowerInvariant(),
                                  v => Alignment = SvgAttribute.ParseEnumAttribute <TextAlignment>(v)));

            yield return
                (new SvgAttribute("text-color", "", XmlNamespace.AurigmaVectorObjects,
                                  () => _textColor,
                                  v => _textColor = v));

            yield return
                (new SvgAttribute("font-postscript-name", "", XmlNamespace.AurigmaVectorObjects,
                                  () => _font.PostScriptName,
                                  v =>
            {
                if (_font == null)
                {
                    _font = new FontSettings();
                }
                _font.PostScriptName = v;
            }));

            yield return
                (new SvgAttribute("font-fauxbold", bool.FalseString, XmlNamespace.AurigmaVectorObjects,
                                  () => _font.FauxBold.ToString(CultureInfo.InvariantCulture),
                                  v =>
            {
                if (_font == null)
                {
                    _font = new FontSettings();
                }
                _font.FauxBold = SvgAttribute.ParseBooleanAttribute(v);
            }));

            yield return
                (new SvgAttribute("font-fauxitalic", bool.FalseString, XmlNamespace.AurigmaVectorObjects,
                                  () => _font.FauxItalic.ToString(CultureInfo.InvariantCulture),
                                  v =>
            {
                if (_font == null)
                {
                    _font = new FontSettings();
                }
                _font.FauxItalic = SvgAttribute.ParseBooleanAttribute(v);
            }));

            yield return
                (new SvgAttribute("tracking", "0",
                                  () => Tracking.ToString(CultureInfo.InvariantCulture),
                                  v => Tracking = SvgAttribute.ParseFloatAttribute(v)));

            yield return
                (new SvgAttribute("leading", "0",
                                  () => Leading.ToString(CultureInfo.InvariantCulture),
                                  v => Leading = SvgAttribute.ParseFloatAttribute(v)));

            yield return
                (new SvgAttribute("is-rich-text", bool.FalseString,
                                  () => IsRichText.ToString(),
                                  v => IsRichText = SvgAttribute.ParseBooleanAttribute(v)));

            yield return
                (new SvgAttribute("vertical-scale", "0",
                                  () => VerticalScale.ToString(CultureInfo.InvariantCulture),
                                  v => VerticalScale = SvgAttribute.ParseFloatAttribute(v)));

            yield return
                (new SvgAttribute("horizontal-scale", "0",
                                  () => HorizontalScale.ToString(CultureInfo.InvariantCulture),
                                  v => HorizontalScale = SvgAttribute.ParseFloatAttribute(v)));

            yield return
                (new SvgAttribute("italic", bool.FalseString,
                                  null,
                                  v => _oldItalic = SvgAttribute.ParseBooleanAttribute(v)));
        }