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); }
/* (non-Javadoc) * @see com.itextpdf.layout.renderer.BlockRenderer#layout(com.itextpdf.layout.layout.LayoutContext) */ public override LayoutResult Layout(LayoutContext layoutContext) { childRenderers.Clear(); flatRenderer = null; float parentWidth = layoutContext.GetArea().GetBBox().GetWidth(); float parentHeight = layoutContext.GetArea().GetBBox().GetHeight(); IRenderer renderer = CreateFlatRenderer(); renderer.SetProperty(Property.OVERFLOW_X, OverflowPropertyValue.VISIBLE); renderer.SetProperty(Property.OVERFLOW_Y, OverflowPropertyValue.VISIBLE); AddChild(renderer); Rectangle bBox = layoutContext.GetArea().GetBBox().Clone().MoveDown(INF - parentHeight).SetHeight(INF); layoutContext.GetArea().SetBBox(bBox); LayoutResult result = base.Layout(layoutContext); if (!childRenderers.IsEmpty()) { flatRenderer = childRenderers[0]; ProcessLangAttribute(); childRenderers.Clear(); childRenderers.Add(flatRenderer); AdjustFieldLayout(layoutContext); if (IsLayoutBasedOnFlatRenderer()) { Rectangle fBox = flatRenderer.GetOccupiedArea().GetBBox(); occupiedArea.GetBBox().SetX(fBox.GetX()).SetY(fBox.GetY()).SetWidth(fBox.GetWidth()).SetHeight(fBox.GetHeight ()); ApplyPaddings(occupiedArea.GetBBox(), true); ApplyBorderBox(occupiedArea.GetBBox(), true); ApplyMargins(occupiedArea.GetBBox(), true); } } else { LogManager.GetLogger(GetType()).Error(iText.Html2pdf.LogMessageConstant.ERROR_WHILE_LAYOUT_OF_FORM_FIELD); occupiedArea.GetBBox().SetWidth(0).SetHeight(0); } if (!true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT)) && !IsRendererFit(parentWidth, parentHeight )) { occupiedArea.GetBBox().SetWidth(0).SetHeight(0); return(new MinMaxWidthLayoutResult(LayoutResult.NOTHING, occupiedArea, null, this, this).SetMinMaxWidth(new MinMaxWidth())); } if (result.GetStatus() != LayoutResult.FULL || !IsRendererFit(parentWidth, parentHeight)) { LogManager.GetLogger(GetType()).Warn(iText.Html2pdf.LogMessageConstant.INPUT_FIELD_DOES_NOT_FIT); } return(new MinMaxWidthLayoutResult(LayoutResult.FULL, occupiedArea, this, null).SetMinMaxWidth(new MinMaxWidth (occupiedArea.GetBBox().GetWidth(), occupiedArea.GetBBox().GetWidth(), 0))); }
public override LayoutResult Layout(LayoutContext layoutContext) { LayoutResult result = base.Layout(layoutContext); this.entry.Value = layoutContext.GetArea().GetPageNumber(); return(result); }
/* (non-Javadoc) * @see com.itextpdf.html2pdf.attach.impl.layout.form.renderer.AbstractFormFieldRenderer#adjustFieldLayout() */ protected internal override void AdjustFieldLayout(LayoutContext layoutContext) { IList <LineRenderer> flatLines = ((ParagraphRenderer)flatRenderer).GetLines(); Rectangle flatBBox = flatRenderer.GetOccupiedArea().GetBBox(); UpdatePdfFont((ParagraphRenderer)flatRenderer); if (!flatLines.IsEmpty() && font != null) { if (flatLines.Count != 1) { isSplit = true; } CropContentLines(flatLines, flatBBox); float?width = RetrieveWidth(layoutContext.GetArea().GetBBox().GetWidth()); if (width == null) { LineRenderer drawnLine = flatLines[0]; drawnLine.Move(flatBBox.GetX() - drawnLine.GetOccupiedArea().GetBBox().GetX(), 0); flatBBox.SetWidth(drawnLine.GetOccupiedArea().GetBBox().GetWidth()); } } else { LogManager.GetLogger(GetType()).Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.ERROR_WHILE_LAYOUT_OF_FORM_FIELD_WITH_TYPE , "button")); SetProperty(Html2PdfProperty.FORM_FIELD_FLATTEN, true); baseline = flatBBox.GetTop(); flatBBox.SetY(flatBBox.GetTop()).SetHeight(0); } }
/** * Method adapts content, that can't be fit into the cell, * to prevent truncation by replacing truncated part of content with '...' */ public override LayoutResult Layout(LayoutContext layoutContext) { PdfFont bf = GetPropertyAsFont(Property.FONT); int contentLength = content.Length; int leftCharIndex = 0; int rightCharIndex = contentLength - 1; Rectangle rect = layoutContext.GetArea().GetBBox().Clone(); // Cell's margins, borders and paddings should be extracted from the available width as well. // Note that this part of the sample was introduced specifically for iText7. // since in iText5 the approach of processing cells was different ApplyBordersPaddingsMargins(rect, GetBorders(), GetPaddings()); float availableWidth = rect.GetWidth(); UnitValue fontSizeUV = this.GetPropertyAsUnitValue(Property.FONT_SIZE); // Unit values can be of POINT or PERCENT type. In this particular sample // the font size value is expected to be of POINT type. float fontSize = fontSizeUV.GetValue(); availableWidth -= bf.GetWidth("...", fontSize); while (leftCharIndex < contentLength && rightCharIndex != leftCharIndex) { availableWidth -= bf.GetWidth(content[leftCharIndex], fontSize); if (availableWidth > 0) { leftCharIndex++; } else { break; } availableWidth -= bf.GetWidth(content[rightCharIndex], fontSize); if (availableWidth > 0) { rightCharIndex--; } else { break; } } // left char is the first char which should not be added // right char is the last char which should not be added String newContent = content.Substring(0, leftCharIndex) + "..." + content.Substring(rightCharIndex + 1); Paragraph p = new Paragraph(newContent); // We're operating on a Renderer level here, that's why we need to process a renderer, // created with the updated paragraph IRenderer pr = p.CreateRendererSubTree().SetParent(this); childRenderers.Add(pr); return(base.Layout(layoutContext)); }
/* (non-Javadoc) * @see com.itextpdf.layout.renderer.TextRenderer#layout(com.itextpdf.layout.layout.LayoutContext) */ public override LayoutResult Layout(LayoutContext layoutContext) { PageCountType pageCountType = (PageCountType)this.GetProperty <PageCountType?>(Html2PdfProperty.PAGE_COUNT_TYPE ); if (pageCountType == PageCountType.CURRENT_PAGE_NUMBER) { SetText(layoutContext.GetArea().GetPageNumber().ToString()); } else { if (pageCountType == PageCountType.TOTAL_PAGE_COUNT) { IRenderer rootRenderer = this; while (rootRenderer is AbstractRenderer && ((AbstractRenderer)rootRenderer).GetParent() != null) { rootRenderer = ((AbstractRenderer)rootRenderer).GetParent(); } if (rootRenderer is HtmlDocumentRenderer && ((HtmlDocumentRenderer)rootRenderer).GetEstimatedNumberOfPages () > 0) { SetText(((HtmlDocumentRenderer)rootRenderer).GetEstimatedNumberOfPages().ToString()); } else { if (rootRenderer is DocumentRenderer && rootRenderer.GetModelElement() is Document) { SetText(((Document)rootRenderer.GetModelElement()).GetPdfDocument().GetNumberOfPages().ToString()); } } } } return(base.Layout(layoutContext)); }
public virtual LayoutResult Layout(LayoutContext layoutContext) { LayoutArea occupiedArea = layoutContext.GetArea().Clone(); occupiedArea.GetBBox().SetHeight(0); occupiedArea.GetBBox().SetWidth(0); return(new LayoutResult(LayoutResult.NOTHING, occupiedArea, null, null).SetAreaBreak(areaBreak)); }
public override LayoutResult Layout(LayoutContext layoutContext) { LayoutArea area = layoutContext.GetArea(); float? width = RetrieveWidth(area.GetBBox().GetWidth()); float? height = this.GetPropertyAsFloat(Property.HEIGHT); occupiedArea = new LayoutArea(area.GetPageNumber(), new Rectangle(area.GetBBox().GetX(), area.GetBBox().GetY () + area.GetBBox().GetHeight(), (float)width, (float)height)); return(new LayoutResult(LayoutResult.FULL, occupiedArea, null, null)); }
public override LayoutResult Layout(LayoutContext layoutContext) { Rectangle area = layoutContext.GetArea().GetBBox(); LayoutContext context = new LayoutContext(new LayoutArea(layoutContext.GetArea().GetPageNumber(), new Rectangle(area.GetLeft(), area.GetTop() - (float)RetrieveHeight(), area.GetWidth(), (float)RetrieveHeight()))); LayoutResult result = base.Layout(context); // If content doesn't fit the size of a cell, // iTest will still return layout result full as if everything is OK. // As a result, the cell's content will be clipped. if (LayoutResult.FULL != result.GetStatus()) { return(new LayoutResult(LayoutResult.FULL, result.GetOccupiedArea(), null, null)); } return(result); }
/// <summary><inheritDoc/></summary> public override LayoutResult Layout(LayoutContext layoutContext) { Rectangle parentBBox = layoutContext.GetArea().GetBBox().Clone(); if (this.GetProperty <float?>(Property.ROTATION_ANGLE) != null) { parentBBox.MoveDown(AbstractRenderer.INF - parentBBox.GetHeight()).SetHeight(AbstractRenderer.INF); } ILineDrawer lineDrawer = this.GetProperty <ILineDrawer>(Property.LINE_DRAWER); float height = lineDrawer != null?lineDrawer.GetLineWidth() : 0; occupiedArea = new LayoutArea(layoutContext.GetArea().GetPageNumber(), parentBBox.Clone()); ApplyMargins(occupiedArea.GetBBox(), false); float?calculatedWidth = RetrieveWidth(layoutContext.GetArea().GetBBox().GetWidth()); if (calculatedWidth == null) { calculatedWidth = occupiedArea.GetBBox().GetWidth(); } if ((occupiedArea.GetBBox().GetHeight() < height || occupiedArea.GetBBox().GetWidth() < calculatedWidth) && !HasOwnProperty(Property.FORCED_PLACEMENT)) { return(new LayoutResult(LayoutResult.NOTHING, null, null, this, this)); } occupiedArea.GetBBox().SetWidth((float)calculatedWidth).MoveUp(occupiedArea.GetBBox().GetHeight() - height ).SetHeight(height); ApplyMargins(occupiedArea.GetBBox(), 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, null, null, this, this)); } } } return(new LayoutResult(LayoutResult.FULL, occupiedArea, this, null)); }
/* (non-Javadoc) * @see com.itextpdf.layout.renderer.TextRenderer#layout(com.itextpdf.layout.layout.LayoutContext) */ public override LayoutResult Layout(LayoutContext layoutContext) { PageCountType pageCountType = (PageCountType)this.GetProperty <PageCountType?>(Html2PdfProperty.PAGE_COUNT_TYPE ); String previousText = GetText().ToString(); // If typography is enabled and the page counter element has a non-default direction, // iText processes its content (see LineRenderer#updateBidiLevels) before layouting it. // This might result in an ArrayIndexOutOfBounds exception, because currently iText updates the page counter's content on layout. // To solve this, this workaround has been implemented: the renderer's strToBeConverted shouldn't be updated by layout. bool textHasBeenReplaced = false; if (pageCountType == PageCountType.CURRENT_PAGE_NUMBER) { SetText(layoutContext.GetArea().GetPageNumber().ToString()); textHasBeenReplaced = true; } else { if (pageCountType == PageCountType.TOTAL_PAGE_COUNT) { IRenderer rootRenderer = this; while (rootRenderer is AbstractRenderer && ((AbstractRenderer)rootRenderer).GetParent() != null) { rootRenderer = ((AbstractRenderer)rootRenderer).GetParent(); } if (rootRenderer is HtmlDocumentRenderer && ((HtmlDocumentRenderer)rootRenderer).GetEstimatedNumberOfPages () > 0) { SetText(((HtmlDocumentRenderer)rootRenderer).GetEstimatedNumberOfPages().ToString()); textHasBeenReplaced = true; } else { if (rootRenderer is DocumentRenderer && rootRenderer.GetModelElement() is Document) { SetText(((Document)rootRenderer.GetModelElement()).GetPdfDocument().GetNumberOfPages().ToString()); textHasBeenReplaced = true; } } } } LayoutResult result = base.Layout(layoutContext); if (textHasBeenReplaced) { SetText(previousText); } return(result); }
public override LayoutResult Layout(LayoutContext layoutContext) { ILineDrawer lineDrawer = this.GetProperty <ILineDrawer>(Property.LINE_DRAWER); float height = lineDrawer != null?lineDrawer.GetLineWidth() : 0; occupiedArea = layoutContext.GetArea().Clone(); ApplyMargins(occupiedArea.GetBBox(), false); if (occupiedArea.GetBBox().GetHeight() < height) { return(new LayoutResult(LayoutResult.NOTHING, null, null, this)); } occupiedArea.GetBBox().MoveUp(occupiedArea.GetBBox().GetHeight() - height).SetHeight(height); ApplyMargins(occupiedArea.GetBBox(), true); return(new LayoutResult(LayoutResult.FULL, occupiedArea, this, null)); }
/* (non-Javadoc) * @see com.itextpdf.html2pdf.attach.impl.layout.form.renderer.AbstractFormFieldRenderer#adjustFieldLayout() */ protected internal override void AdjustFieldLayout(LayoutContext layoutContext) { IList <LineRenderer> flatLines = ((ParagraphRenderer)flatRenderer).GetLines(); Rectangle flatBBox = flatRenderer.GetOccupiedArea().GetBBox(); UpdatePdfFont((ParagraphRenderer)flatRenderer); if (!flatLines.IsEmpty() && font != null) { CropContentLines(flatLines, flatBBox); } else { LogManager.GetLogger(GetType()).Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.ERROR_WHILE_LAYOUT_OF_FORM_FIELD_WITH_TYPE , "text input")); SetProperty(Html2PdfProperty.FORM_FIELD_FLATTEN, true); flatBBox.SetY(flatBBox.GetTop()).SetHeight(0); } flatBBox.SetWidth((float)RetrieveWidth(layoutContext.GetArea().GetBBox().GetWidth())); }
public override LayoutResult Layout(LayoutContext layoutContext) { LayoutArea area = layoutContext.GetArea().Clone(); Rectangle layoutBox = area.GetBBox(); ApplyMargins(layoutBox, false); occupiedArea = new LayoutArea(area.GetPageNumber(), new Rectangle(layoutBox.GetX(), layoutBox.GetY() + layoutBox .GetHeight(), 0, 0)); width = RetrieveWidth(layoutBox.GetWidth()); float? angle = this.GetPropertyAsFloat(Property.ROTATION_ANGLE); PdfXObject xObject = ((Image)(GetModelElement())).GetXObject(); imageWidth = xObject.GetWidth(); imageHeight = xObject.GetHeight(); width = width == null ? imageWidth : width; height = (float)width / imageWidth * imageHeight; fixedXPosition = this.GetPropertyAsFloat(Property.X); fixedYPosition = this.GetPropertyAsFloat(Property.Y); float? horizontalScaling = this.GetPropertyAsFloat(Property.HORIZONTAL_SCALING, 1f); float? verticalScaling = this.GetPropertyAsFloat(Property.VERTICAL_SCALING, 1f); AffineTransform t = new AffineTransform(); if (xObject is PdfFormXObject && width != imageWidth) { horizontalScaling *= width / imageWidth; verticalScaling *= height / imageHeight; } if (horizontalScaling != 1) { if (xObject is PdfFormXObject) { t.Scale((float)horizontalScaling, 1); } width *= (float)horizontalScaling; } if (verticalScaling != 1) { if (xObject is PdfFormXObject) { t.Scale(1, (float)verticalScaling); } height *= (float)verticalScaling; } float imageItselfScaledWidth = (float)width; float imageItselfScaledHeight = (float)height; // See in adjustPositionAfterRotation why angle = 0 is necessary if (null == angle) { angle = 0f; } t.Rotate((float)angle); float scaleCoef = AdjustPositionAfterRotation((float)angle, layoutBox.GetWidth(), layoutBox.GetHeight()); imageItselfScaledHeight *= scaleCoef; imageItselfScaledWidth *= scaleCoef; 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))) { isPlacingForced = true; } else { return(new LayoutResult(LayoutResult.NOTHING, occupiedArea, null, this, this)); } } occupiedArea.GetBBox().MoveDown(height); occupiedArea.GetBBox().SetHeight(height); occupiedArea.GetBBox().SetWidth((float)width); float leftMargin = (float)this.GetPropertyAsFloat(Property.MARGIN_LEFT); float topMargin = (float)this.GetPropertyAsFloat(Property.MARGIN_TOP); if (leftMargin != 0 || topMargin != 0) { TranslateImage(leftMargin, topMargin, t); GetMatrix(t, imageItselfScaledWidth, imageItselfScaledHeight); } ApplyMargins(occupiedArea.GetBBox(), true); return(new LayoutResult(LayoutResult.FULL, occupiedArea, null, null, isPlacingForced ? this : null)); }
public override LayoutResult Layout(LayoutContext layoutContext) { Rectangle layoutBox = layoutContext.GetArea().GetBBox().Clone(); occupiedArea = new LayoutArea(layoutContext.GetArea().GetPageNumber(), layoutBox. Clone().MoveDown(-layoutBox.GetHeight()).SetHeight(0)); float curWidth = 0; maxAscent = 0; maxDescent = 0; int childPos = 0; BaseDirection?baseDirection = this.GetProperty <BaseDirection?>(Property.BASE_DIRECTION, BaseDirection.NO_BIDI); foreach (IRenderer renderer in childRenderers) { if (renderer is TextRenderer) { renderer.SetParent(this); ((TextRenderer)renderer).ApplyOtf(); renderer.SetParent(null); if (baseDirection == null || baseDirection == BaseDirection.NO_BIDI) { baseDirection = renderer.GetOwnProperty <BaseDirection?>(Property.BASE_DIRECTION); } } } IList <int> unicodeIdsReorderingList = null; if (levels == null && baseDirection != null && baseDirection != BaseDirection.NO_BIDI) { unicodeIdsReorderingList = new List <int>(); bool newLineFound = false; foreach (IRenderer child in childRenderers) { if (newLineFound) { break; } if (child is TextRenderer) { GlyphLine text = ((TextRenderer)child).GetText(); for (int i = text.start; i < text.end; i++) { if (TextRenderer.IsNewLine(text, i)) { newLineFound = true; break; } // we assume all the chars will have the same bidi group // we also assume pairing symbols won't get merged with other ones unicodeIdsReorderingList.Add(text.Get(i).GetUnicode()); } } } levels = unicodeIdsReorderingList.Count > 0 ? TypographyUtils.GetBidiLevels((BaseDirection)baseDirection, ArrayUtil.ToArray(unicodeIdsReorderingList)) : null; } bool anythingPlaced = false; TabStop nextTabStop = null; LineLayoutResult result = null; while (childPos < childRenderers.Count) { IRenderer childRenderer = childRenderers[childPos]; LayoutResult childResult; Rectangle bbox = new Rectangle(layoutBox.GetX() + curWidth, layoutBox.GetY(), layoutBox .GetWidth() - curWidth, layoutBox.GetHeight()); if (childRenderer is TextRenderer) { // Delete these properties in case of relayout. We might have applied them during justify(). childRenderer.DeleteOwnProperty(Property.CHARACTER_SPACING); childRenderer.DeleteOwnProperty(Property.WORD_SPACING); } else { if (childRenderer is TabRenderer) { if (nextTabStop != null) { IRenderer tabRenderer = childRenderers[childPos - 1]; tabRenderer.Layout(new LayoutContext(new LayoutArea(layoutContext.GetArea().GetPageNumber (), bbox))); curWidth += tabRenderer.GetOccupiedArea().GetBBox().GetWidth(); } nextTabStop = CalculateTab(childRenderer, curWidth, layoutBox.GetWidth()); if (childPos == childRenderers.Count - 1) { nextTabStop = null; } if (nextTabStop != null) { ++childPos; continue; } } } if (!anythingPlaced && childRenderer is TextRenderer) { ((TextRenderer)childRenderer).TrimFirst(); } if (nextTabStop != null && nextTabStop.GetTabAlignment() == TabAlignment.ANCHOR && childRenderer is TextRenderer) { childRenderer.SetProperty(Property.TAB_ANCHOR, nextTabStop .GetTabAnchor()); } childResult = childRenderer.SetParent(this).Layout(new LayoutContext(new LayoutArea (layoutContext.GetArea().GetPageNumber(), bbox))); float childAscent = 0; float childDescent = 0; if (childRenderer is TextRenderer) { childAscent = ((TextRenderer)childRenderer).GetAscent(); childDescent = ((TextRenderer)childRenderer).GetDescent(); } else { if (childRenderer is ImageRenderer) { childAscent = childRenderer.GetOccupiedArea().GetBBox().GetHeight(); } } maxAscent = Math.Max(maxAscent, childAscent); maxDescent = Math.Min(maxDescent, childDescent); float maxHeight = maxAscent - maxDescent; if (nextTabStop != null) { IRenderer tabRenderer = childRenderers[childPos - 1]; float tabWidth = CalculateTab(layoutBox, curWidth, nextTabStop, childRenderer, childResult , tabRenderer); tabRenderer.Layout(new LayoutContext(new LayoutArea(layoutContext.GetArea().GetPageNumber (), bbox))); childResult.GetOccupiedArea().GetBBox().MoveRight(tabWidth); if (childResult.GetSplitRenderer() != null) { childResult.GetSplitRenderer().GetOccupiedArea().GetBBox().MoveRight(tabWidth); } float tabAndNextElemWidth = tabWidth + childResult.GetOccupiedArea().GetBBox().GetWidth(); if (nextTabStop.GetTabAlignment() == TabAlignment.RIGHT && curWidth + tabAndNextElemWidth < nextTabStop.GetTabPosition()) { curWidth = nextTabStop.GetTabPosition(); } else { curWidth += tabAndNextElemWidth; } nextTabStop = null; } else { curWidth += childResult.GetOccupiedArea().GetBBox().GetWidth(); } occupiedArea.SetBBox(new Rectangle(layoutBox.GetX(), layoutBox.GetY() + layoutBox .GetHeight() - maxHeight, curWidth, maxHeight)); if (childResult.GetStatus() != LayoutResult.FULL) { LineRenderer[] split = Split(); split[0].childRenderers = new List <IRenderer>(childRenderers.SubList(0, childPos) ); bool wordWasSplitAndItWillFitOntoNextLine = false; if (childResult is TextLayoutResult && ((TextLayoutResult)childResult).IsWordHasBeenSplit ()) { LayoutResult newLayoutResult = childRenderer.Layout(layoutContext); if (newLayoutResult is TextLayoutResult && !((TextLayoutResult)newLayoutResult).IsWordHasBeenSplit ()) { wordWasSplitAndItWillFitOntoNextLine = true; } } if (wordWasSplitAndItWillFitOntoNextLine) { split[1].childRenderers.Add(childRenderer); split[1].childRenderers.AddAll(childRenderers.SubList(childPos + 1, childRenderers .Count)); } else { if (childResult.GetStatus() == LayoutResult.PARTIAL) { split[0].AddChild(childResult.GetSplitRenderer()); anythingPlaced = true; } if (childResult.GetStatus() == LayoutResult.PARTIAL && childResult.GetOverflowRenderer () is ImageRenderer) { ((ImageRenderer)childResult.GetOverflowRenderer()).AutoScale(layoutContext.GetArea ()); } if (null != childResult.GetOverflowRenderer()) { split[1].childRenderers.Add(childResult.GetOverflowRenderer()); } split[1].childRenderers.AddAll(childRenderers.SubList(childPos + 1, childRenderers .Count)); // no sense to process empty renderer if (split[1].childRenderers.Count == 0) { split[1] = null; } } result = new LineLayoutResult(anythingPlaced ? LayoutResult.PARTIAL : LayoutResult.NOTHING, occupiedArea, split[0], split[1], childResult.GetStatus() == LayoutResult.NOTHING ? childResult.GetCauseOfNothing() : this); if (childResult.GetStatus() == LayoutResult.PARTIAL && childResult is TextLayoutResult && ((TextLayoutResult)childResult).IsSplitForcedByNewline()) { result.SetSplitForcedByNewline(true); } break; } else { anythingPlaced = true; childPos++; } } if (result == null) { if (anythingPlaced) { result = new LineLayoutResult(LayoutResult.FULL, occupiedArea, null, null); } else { result = new LineLayoutResult(LayoutResult.NOTHING, occupiedArea, null, this, this); } } // Consider for now that all the children have the same font, and that after reordering text pieces // can be reordered, but cannot be split. if (baseDirection != null && baseDirection != BaseDirection.NO_BIDI) { IList <IRenderer> children = null; if (result.GetStatus() == LayoutResult.PARTIAL) { children = result.GetSplitRenderer().GetChildRenderers(); } else { if (result.GetStatus() == LayoutResult.FULL) { children = GetChildRenderers(); } } if (children != null) { IList <LineRenderer.RendererGlyph> lineGlyphs = new List <LineRenderer.RendererGlyph >(); foreach (IRenderer child in children) { if (child is TextRenderer) { GlyphLine childLine = ((TextRenderer)child).line; for (int i = childLine.start; i < childLine.end; i++) { lineGlyphs.Add(new LineRenderer.RendererGlyph(childLine.Get(i), (TextRenderer)child )); } } } byte[] lineLevels = new byte[lineGlyphs.Count]; if (levels != null) { System.Array.Copy(levels, 0, lineLevels, 0, lineGlyphs.Count); } int[] reorder = TypographyUtils.ReorderLine(lineGlyphs, lineLevels, levels); if (reorder != null) { children.Clear(); int pos = 0; IList <int[]> reversedRanges = new List <int[]>(); int initialPos = 0; bool reversed = false; int offset = 0; while (pos < lineGlyphs.Count) { IRenderer renderer_1 = lineGlyphs[pos].renderer; TextRenderer newRenderer = new TextRenderer((TextRenderer)renderer_1); newRenderer.DeleteOwnProperty(Property.REVERSED); children.Add(newRenderer); ((TextRenderer)children[children.Count - 1]).line = new GlyphLine(((TextRenderer) children[children.Count - 1]).line); GlyphLine gl = ((TextRenderer)children[children.Count - 1]).line; IList <Glyph> replacementGlyphs = new List <Glyph>(); while (pos < lineGlyphs.Count && lineGlyphs[pos].renderer == renderer_1) { if (pos < lineGlyphs.Count - 1) { if (reorder[pos] == reorder[pos + 1] + 1) { reversed = true; } else { if (reversed) { IList <int[]> reversedRange = new List <int[]>(); reversedRange.Add(new int[] { initialPos - offset, pos - offset }); newRenderer.SetProperty(Property.REVERSED, reversedRange); reversedRanges.Add(new int[] { initialPos - offset, pos - offset }); reversed = false; } initialPos = pos + 1; } } replacementGlyphs.Add(lineGlyphs[pos].glyph); pos++; } if (reversed) { IList <int[]> reversedRange = new List <int[]>(); reversedRange.Add(new int[] { initialPos - offset, pos - 1 - offset }); newRenderer.SetProperty(Property.REVERSED, reversedRange ); reversedRanges.Add(new int[] { initialPos - offset, pos - 1 - offset }); reversed = false; initialPos = pos; } offset = initialPos; gl.SetGlyphs(replacementGlyphs); } if (reversed) { if (children.Count == 1) { offset = 0; } IList <int[]> reversedRange = new List <int[]>(); reversedRange.Add(new int[] { initialPos - offset, pos - offset - 1 }); lineGlyphs[pos - 1].renderer.SetProperty(Property.REVERSED , reversedRange); reversedRanges.Add(new int[] { initialPos - offset, pos - 1 - offset }); } if (!reversedRanges.IsEmpty()) { if (children.Count == 1) { lineGlyphs[0].renderer.SetProperty(Property.REVERSED, reversedRanges); } } float currentXPos = layoutContext.GetArea().GetBBox().GetLeft(); foreach (IRenderer child_1 in children) { float currentWidth = ((TextRenderer)child_1).CalculateLineWidth(); ((TextRenderer)child_1).occupiedArea.GetBBox().SetX(currentXPos).SetWidth(currentWidth ); currentXPos += currentWidth; } } if (result.GetStatus() == LayoutResult.PARTIAL) { LineRenderer overflow = (LineRenderer)result.GetOverflowRenderer(); if (levels != null) { overflow.levels = new byte[levels.Length - lineLevels.Length]; System.Array.Copy(levels, lineLevels.Length, overflow.levels, 0, overflow.levels. Length); if (overflow.levels.Length == 0) { overflow.levels = null; } } } else if (result.GetStatus() == LayoutResult.NOTHING) { if (levels != null) { ((LineRenderer)result.GetOverflowRenderer()).levels = levels; } } } } if (anythingPlaced) { LineRenderer processed = result.GetStatus() == LayoutResult.FULL ? this : (LineRenderer )result.GetSplitRenderer(); processed.AdjustChildrenYLine().TrimLast(); } return(result); }
internal static LayoutResult OrphansWidowsAwareLayout(ParagraphRenderer renderer, LayoutContext context, ParagraphOrphansControl orphansControl, ParagraphWidowsControl widowsControl) { OrphansWidowsLayoutHelper.OrphansWidowsLayoutAttempt layoutAttempt = AttemptLayout(renderer, context, context .GetArea().Clone()); if (context.IsClippedHeight() || renderer.IsPositioned() || layoutAttempt.attemptResult.GetStatus() != LayoutResult .PARTIAL || layoutAttempt.attemptResult.GetSplitRenderer() == null) { return(HandleAttemptAsSuccessful(layoutAttempt, context)); } ParagraphRenderer splitRenderer = (ParagraphRenderer)layoutAttempt.attemptResult.GetSplitRenderer(); bool orphansViolation = orphansControl != null && splitRenderer != null && splitRenderer.GetLines().Count < orphansControl.GetMinOrphans() && !renderer.IsFirstOnRootArea(); bool forcedPlacement = true.Equals(renderer.GetPropertyAsBoolean(Property.FORCED_PLACEMENT)); if (orphansViolation && forcedPlacement) { orphansControl.HandleViolatedOrphans(splitRenderer, "Ignored orphans constraint due to forced placement."); } if (orphansViolation && !forcedPlacement) { layoutAttempt = null; } else { if (widowsControl != null && splitRenderer != null && layoutAttempt.attemptResult.GetOverflowRenderer() != null) { ParagraphRenderer overflowRenderer = (ParagraphRenderer)layoutAttempt.attemptResult.GetOverflowRenderer(); // Excessively big value to check if widows constraint is violated; // Make this value less in order to improve performance if you are sure // that min number of widows will fit in this height. E.g. A4 page height is 842. int simulationHeight = 3500; LayoutArea simulationArea = new LayoutArea(context.GetArea().GetPageNumber(), context.GetArea().GetBBox(). Clone().SetHeight(simulationHeight)); // collapsingMarginsInfo might affect available space, which is redundant in case we pass arbitrary space. // floatedRendererAreas list on new area is considered empty. We don't know if there will be any, however their presence in any case will result in more widows, not less. // clippedHeight is undefined for the next area, because it is defined by overflow part of the paragraph parent. // Even if it will be set to true in actual overflow-part layouting, stealing lines approach will result in // giving bigger part of MAX-HEIGHT to the overflow part and resulting in bigger number of widows, which is better. // However for possible other approaches which change content "length" (like word/char spacing adjusts), // if in actual overflow-part layouting clippedHeight will be true, those widows fixing attempts will result in worse results. LayoutContext simulationContext = new LayoutContext(simulationArea); LayoutResult simulationResult = overflowRenderer.DirectLayout(simulationContext); if (simulationResult.GetStatus() == LayoutResult.FULL) { // simulationHeight is excessively big in order to allow to layout all of the content remaining in overflowRenderer: // this way after all of the remaining content is layouted we can check if it has led to widows violation. // To make this analysis possible, we expect to get result FULL. // if result is PARTIAL: means that simulationHeight value isn't big enough to layout all of the content remaining in overflowRenderer. // In this case we assume that widows aren't violated since the amount of the lines to fit the simulatedHeight is expected to be very large. // if result is NOTHING: unexpected result, limitation of simulation approach. Retry again with forced placement set. int extraWidows = widowsControl.GetMinWidows() - overflowRenderer.GetLines().Count; if (extraWidows > 0) { int extraLinesToMove = orphansControl != null?Math.Max(orphansControl.GetMinOrphans(), 1) : 1; if (extraWidows <= widowsControl.GetMaxLinesToMove() && splitRenderer.GetLines().Count - extraWidows >= extraLinesToMove ) { LineRenderer lastLine = splitRenderer.GetLines()[splitRenderer.GetLines().Count - 1]; LineRenderer lastLineToLeave = splitRenderer.GetLines()[splitRenderer.GetLines().Count - extraWidows - 1]; float d = lastLineToLeave.GetOccupiedArea().GetBBox().GetY() - lastLine.GetOccupiedArea().GetBBox().GetY() - AbstractRenderer.EPS; Rectangle smallerBBox = new Rectangle(context.GetArea().GetBBox()); smallerBBox.DecreaseHeight(d); smallerBBox.MoveUp(d); LayoutArea smallerAvailableArea = new LayoutArea(context.GetArea().GetPageNumber(), smallerBBox); layoutAttempt = AttemptLayout(renderer, context, smallerAvailableArea); } else { if (forcedPlacement || renderer.IsFirstOnRootArea() || !widowsControl.IsOverflowOnWidowsViolation()) { if (forcedPlacement) { widowsControl.HandleViolatedWidows(overflowRenderer, "forced placement"); } else { widowsControl.HandleViolatedWidows(overflowRenderer, "inability to fix it"); } } else { layoutAttempt = null; } } } } } } if (layoutAttempt != null) { return(HandleAttemptAsSuccessful(layoutAttempt, context)); } else { return(new LayoutResult(LayoutResult.NOTHING, null, null, renderer)); } }
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)); }
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)); }
public override LayoutResult Layout(LayoutContext layoutContext) { int pageNumber = layoutContext.GetArea().GetPageNumber(); bool isPositioned = IsPositioned(); Rectangle parentBBox = layoutContext.GetArea().GetBBox().Clone(); if (this.GetProperty <float?>(Property.ROTATION_ANGLE) != null || isPositioned) { parentBBox.MoveDown(AbstractRenderer.INF - parentBBox.GetHeight()).SetHeight(AbstractRenderer.INF); } float?blockHeight = RetrieveHeight(); if (!IsFixedLayout() && blockHeight != null && blockHeight > parentBBox.GetHeight() && !true.Equals(GetPropertyAsBoolean (Property.FORCED_PLACEMENT))) { return(new LayoutResult(LayoutResult.NOTHING, null, null, this, this)); } float[] margins = GetMargins(); ApplyMargins(parentBBox, margins, false); Border[] borders = GetBorders(); ApplyBorderBox(parentBBox, borders, false); 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(); // the first renderer (one of childRenderers or their children) to produce LayoutResult.NOTHING IRenderer causeOfNothing = null; bool anythingPlaced = false; for (int childPos = 0; childPos < childRenderers.Count; childPos++) { IRenderer childRenderer = childRenderers[childPos]; LayoutResult result; childRenderer.SetParent(this); while ((result = childRenderer.SetParent(this).Layout(new LayoutContext(new LayoutArea(pageNumber, layoutBox )))).GetStatus() != LayoutResult.FULL) { if (result.GetOccupiedArea() != null) { occupiedArea.SetBBox(Rectangle.GetCommonRectangle(occupiedArea.GetBBox(), result.GetOccupiedArea().GetBBox ())); layoutBox.SetHeight(layoutBox.GetHeight() - result.GetOccupiedArea().GetBBox().GetHeight()); } if (childRenderer.GetOccupiedArea() != null) { AlignChildHorizontally(childRenderer, layoutBox.GetWidth()); } // Save the first renderer to produce LayoutResult.NOTHING if (null == causeOfNothing && null != result.GetCauseOfNothing()) { causeOfNothing = result.GetCauseOfNothing(); } // have more areas if (currentAreaPos + 1 < areas.Count) { if (result.GetStatus() == LayoutResult.PARTIAL) { childRenderers[childPos] = result.GetSplitRenderer(); // TODO linkedList would make it faster childRenderers.Add(childPos + 1, result.GetOverflowRenderer()); } else { childRenderers[childPos] = result.GetOverflowRenderer(); childPos--; } layoutBox = areas[++currentAreaPos].Clone(); break; } else { if (result.GetStatus() == LayoutResult.PARTIAL) { layoutBox.SetHeight(layoutBox.GetHeight() - result.GetOccupiedArea().GetBBox().GetHeight()); if (currentAreaPos + 1 == areas.Count) { AbstractRenderer splitRenderer = CreateSplitRenderer(LayoutResult.PARTIAL); splitRenderer.childRenderers = new List <IRenderer>(childRenderers.SubList(0, childPos)); splitRenderer.childRenderers.Add(result.GetSplitRenderer()); splitRenderer.occupiedArea = occupiedArea; AbstractRenderer overflowRenderer = CreateOverflowRenderer(LayoutResult.PARTIAL); // Apply forced placement only on split renderer overflowRenderer.DeleteOwnProperty(Property.FORCED_PLACEMENT); IList <IRenderer> overflowRendererChildren = new List <IRenderer>(); overflowRendererChildren.Add(result.GetOverflowRenderer()); overflowRendererChildren.AddAll(childRenderers.SubList(childPos + 1, childRenderers.Count)); overflowRenderer.childRenderers = overflowRendererChildren; ApplyPaddings(occupiedArea.GetBBox(), paddings, true); ApplyBorderBox(occupiedArea.GetBBox(), borders, true); ApplyMargins(occupiedArea.GetBBox(), margins, true); return(new LayoutResult(LayoutResult.PARTIAL, occupiedArea, splitRenderer, overflowRenderer, causeOfNothing )); } else { childRenderers[childPos] = result.GetSplitRenderer(); childRenderers.Add(childPos + 1, result.GetOverflowRenderer()); layoutBox = areas[++currentAreaPos].Clone(); break; } } else { if (result.GetStatus() == LayoutResult.NOTHING) { bool keepTogether = IsKeepTogether(); int layoutResult = anythingPlaced && !keepTogether ? LayoutResult.PARTIAL : LayoutResult.NOTHING; AbstractRenderer splitRenderer = CreateSplitRenderer(layoutResult); splitRenderer.childRenderers = new List <IRenderer>(childRenderers.SubList(0, childPos)); foreach (IRenderer renderer in splitRenderer.childRenderers) { renderer.SetParent(splitRenderer); } AbstractRenderer overflowRenderer = CreateOverflowRenderer(layoutResult); IList <IRenderer> overflowRendererChildren = new List <IRenderer>(); overflowRendererChildren.Add(result.GetOverflowRenderer()); overflowRendererChildren.AddAll(childRenderers.SubList(childPos + 1, childRenderers.Count)); overflowRenderer.childRenderers = overflowRendererChildren; if (keepTogether) { splitRenderer = null; overflowRenderer.childRenderers.Clear(); overflowRenderer.childRenderers = new List <IRenderer>(childRenderers); } ApplyPaddings(occupiedArea.GetBBox(), paddings, true); ApplyBorderBox(occupiedArea.GetBBox(), borders, true); ApplyMargins(occupiedArea.GetBBox(), margins, true); if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT))) { return(new LayoutResult(LayoutResult.FULL, occupiedArea, null, null)); } else { return(new LayoutResult(layoutResult, occupiedArea, splitRenderer, overflowRenderer, LayoutResult.NOTHING == layoutResult ? result.GetCauseOfNothing() : null)); } } } } } anythingPlaced = true; occupiedArea.SetBBox(Rectangle.GetCommonRectangle(occupiedArea.GetBBox(), result.GetOccupiedArea().GetBBox ())); if (result.GetStatus() == LayoutResult.FULL) { layoutBox.SetHeight(layoutBox.GetHeight() - result.GetOccupiedArea().GetBBox().GetHeight()); if (childRenderer.GetOccupiedArea() != null) { AlignChildHorizontally(childRenderer, layoutBox.GetWidth()); } } // Save the first renderer to produce LayoutResult.NOTHING if (null == causeOfNothing && null != result.GetCauseOfNothing()) { causeOfNothing = result.GetCauseOfNothing(); } } ApplyPaddings(occupiedArea.GetBBox(), paddings, true); if (blockHeight != null && blockHeight > occupiedArea.GetBBox().GetHeight()) { occupiedArea.GetBBox().MoveDown((float)blockHeight - occupiedArea.GetBBox().GetHeight()).SetHeight((float) blockHeight); } 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)); } } } ApplyVerticalAlignment(); return(new LayoutResult(LayoutResult.FULL, occupiedArea, null, null, causeOfNothing)); }
public override LayoutResult Layout(LayoutContext layoutContext) { return(base.Layout(new LayoutContext(new LayoutArea(layoutContext.GetArea().GetPageNumber(), rect)))); }