public override LayoutResult Layout(LayoutContext layoutContext) { LayoutResult errorResult = InitializeListSymbols(layoutContext); if (errorResult != null) { return(errorResult); } LayoutResult result = base.Layout(layoutContext); // cannot place even the first ListItemRenderer if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT)) && null != result.GetCauseOfNothing()) { if (LayoutResult.FULL == result.GetStatus()) { result = CorrectListSplitting(this, null, result.GetCauseOfNothing(), result.GetOccupiedArea()); } else { if (LayoutResult.PARTIAL == result.GetStatus()) { result = CorrectListSplitting(result.GetSplitRenderer(), result.GetOverflowRenderer(), result.GetCauseOfNothing (), result.GetOccupiedArea()); } } } return(result); }
internal HeightDimensionContainer(CssContextNode pmbcNode, float width, float maxHeight, IRenderer renderer , float additionalWidthFix) { String height = pmbcNode.GetStyles().Get(CssConstants.HEIGHT); if (height != null && !CssConstants.AUTO.Equals(height)) { dimension = ParseDimension(pmbcNode, height, maxHeight, additionalWidthFix); } minDimension = GetMinHeight(pmbcNode, maxHeight, additionalWidthFix); maxDimension = GetMaxHeight(pmbcNode, maxHeight, additionalWidthFix); if (!IsAutoDimension()) { maxContentDimension = dimension; maxContentDimension = dimension; } else { LayoutArea layoutArea = new LayoutArea(1, new Rectangle(0, 0, width, infHeight)); LayoutContext minimalContext = new LayoutContext(layoutArea); LayoutResult quickLayout = renderer.Layout(minimalContext); if (quickLayout.GetStatus() != LayoutResult.NOTHING) { maxContentDimension = quickLayout.GetOccupiedArea().GetBBox().GetHeight(); minContentDimension = maxContentDimension; } } }
private void ApplyCopyFittingFontSize(Paragraph paragraph, Rectangle rect, IRenderer parentRenderer) { IRenderer renderer = paragraph.CreateRendererSubTree().SetParent(parentRenderer); LayoutContext layoutContext = new LayoutContext(new LayoutArea(1, rect)); float lFontSize = 0.1f; float rFontSize = 100; int numberOfIterations = 15; // 15 iterations with lFontSize = 0.1 and rFontSize = 100 should result in ~0.003 precision for (int i = 0; i < numberOfIterations; i++) { float mFontSize = (lFontSize + rFontSize) / 2; paragraph.SetFontSize(mFontSize); LayoutResult result = renderer.Layout(layoutContext); if (result.GetStatus() == LayoutResult.FULL) { lFontSize = mFontSize; } else { rFontSize = mFontSize; } } paragraph.SetFontSize(lFontSize); }
public override LayoutResult Layout(LayoutContext layoutContext) { LayoutResult result = base.Layout(layoutContext); CustomTableRenderer split = (CustomTableRenderer)result.GetSplitRenderer(); CustomTableRenderer overflow = (CustomTableRenderer)result.GetOverflowRenderer(); // Page split happened if (result.GetStatus() == LayoutResult.PARTIAL) { Table.RowRange splitRange = split.rowRange; Table.RowRange overflowRange = overflow.rowRange; // The table split happened if (splitRange.GetFinishRow() == overflowRange.GetStartRow()) { if (null != overflow.rows[0]) { // Change cell contents on the new page CellRenderer customContentCellRenderer = (CellRenderer) new Cell() .Add(new Paragraph("Custom content")) .CreateRendererSubTree() .SetParent(this); overflow.rows[0][CUSTOM_CONTENT_COLUMN_NUMBER] = customContentCellRenderer; } } } return(result); }
public static MinMaxWidth CountDefaultMinMaxWidth(IRenderer renderer) { LayoutResult result = renderer.Layout(new LayoutContext(new LayoutArea(1, new Rectangle(GetInfWidth(), GetInfHeight ())))); return(result.GetStatus() == LayoutResult.NOTHING ? new MinMaxWidth() : new MinMaxWidth(0, result.GetOccupiedArea ().GetBBox().GetWidth(), 0)); }
public override LayoutResult Layout(LayoutContext layoutContext) { // Resolve width here in case it's relative, while parent width is still intact. // If it's inline-block context, relative width is already resolved. float?width = RetrieveWidth(layoutContext.GetArea().GetBBox().GetWidth()); if (width != null) { UpdateWidth(UnitValue.CreatePointValue((float)width)); } float childrenMaxWidth = GetMinMaxWidth().GetMaxWidth(); LayoutArea area = layoutContext.GetArea().Clone(); area.GetBBox().MoveDown(INF - area.GetBBox().GetHeight()).SetHeight(INF).SetWidth(childrenMaxWidth + EPS); LayoutResult layoutResult = base.Layout(new LayoutContext(area, layoutContext.GetMarginsCollapseInfo(), layoutContext .GetFloatRendererAreas(), layoutContext.IsClippedHeight())); if (layoutResult.GetStatus() != LayoutResult.FULL) { if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT))) { layoutResult = MakeLayoutResultFull(layoutContext.GetArea(), layoutResult); } else { return(new LayoutResult(LayoutResult.NOTHING, null, null, this, this)); } } float availableHeight = layoutContext.GetArea().GetBBox().GetHeight(); bool isClippedHeight = layoutContext.IsClippedHeight(); Rectangle dummy = new Rectangle(0, 0); ApplyMargins(dummy, true); ApplyBorderBox(dummy, true); ApplyPaddings(dummy, true); float additionalHeight = dummy.GetHeight(); availableHeight -= additionalHeight; availableHeight = Math.Max(availableHeight, 0); float actualHeight = GetOccupiedArea().GetBBox().GetHeight() - additionalHeight; float finalSelectFieldHeight = GetFinalSelectFieldHeight(availableHeight, actualHeight, isClippedHeight); if (finalSelectFieldHeight < 0) { return(new LayoutResult(LayoutResult.NOTHING, null, null, this, this)); } float delta = finalSelectFieldHeight - actualHeight; if (Math.Abs(delta) > EPS) { GetOccupiedArea().GetBBox().IncreaseHeight(delta).MoveDown(delta); } return(layoutResult); }
/// <summary>Draws margin boxes.</summary> /// <param name="pageNumber">the page</param> /// <param name="pdfDocument"> /// the /// <see cref="iText.Kernel.Pdf.PdfDocument"/> /// to which content is written /// </param> /// <param name="documentRenderer">the document renderer</param> private void DrawMarginBoxes(int pageNumber, PdfDocument pdfDocument, DocumentRenderer documentRenderer) { if (properties.GetResolvedPageMarginBoxes().IsEmpty()) { return; } PdfPage page = pdfDocument.GetPage(pageNumber); foreach (PageMarginBoxContextNode marginBoxContentNode in properties.GetResolvedPageMarginBoxes()) { IElement curBoxElement = ProcessMarginBoxContent(marginBoxContentNode, pageNumber, context); IRenderer renderer = curBoxElement.CreateRendererSubTree(); RemoveAreaBreaks(renderer); renderer.SetParent(documentRenderer); bool isTagged = pdfDocument.IsTagged(); if (isTagged) { LayoutTaggingHelper taggingHelper = renderer.GetProperty <LayoutTaggingHelper>(Property.TAGGING_HELPER); LayoutTaggingHelper.AddTreeHints(taggingHelper, renderer); } LayoutResult result = renderer.Layout(new LayoutContext(new LayoutArea(pageNumber, marginBoxContentNode.GetPageMarginBoxRectangle ()))); IRenderer rendererToDraw = result.GetStatus() == LayoutResult.FULL ? renderer : result.GetSplitRenderer(); if (rendererToDraw != null) { TagTreePointer tagPointer = null; TagTreePointer backupPointer = null; PdfPage backupPage = null; if (isTagged) { tagPointer = pdfDocument.GetTagStructureContext().GetAutoTaggingPointer(); backupPage = tagPointer.GetCurrentPage(); backupPointer = new TagTreePointer(tagPointer); tagPointer.MoveToRoot(); tagPointer.SetPageForTagging(page); } rendererToDraw.SetParent(documentRenderer).Draw(new DrawContext(page.GetDocument(), new PdfCanvas(page), isTagged )); if (isTagged) { tagPointer.SetPageForTagging(backupPage); tagPointer.MoveToPointer(backupPointer); } } else { // marginBoxElements have overflow property set to HIDDEN, therefore it is not expected to neither get // LayoutResult other than FULL nor get no split renderer (result NOTHING) even if result is not FULL ILog logger = LogManager.GetLogger(typeof(iText.Html2pdf.Attach.Impl.Layout.PageContextProcessor)); logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.PAGE_MARGIN_BOX_CONTENT_CANNOT_BE_DRAWN , marginBoxContentNode.GetMarginBoxName())); } } }
public virtual void LayoutTest() { AreaBreakRenderer areaBreakRenderer = new AreaBreakRenderer(new AreaBreak()); LayoutResult layoutResult = areaBreakRenderer.Layout(new LayoutContext(null)); NUnit.Framework.Assert.AreEqual(LayoutResult.NOTHING, layoutResult.GetStatus()); NUnit.Framework.Assert.IsNull(layoutResult.GetOccupiedArea()); NUnit.Framework.Assert.IsNull(layoutResult.GetSplitRenderer()); NUnit.Framework.Assert.IsNull(layoutResult.GetOverflowRenderer()); NUnit.Framework.Assert.AreEqual(areaBreakRenderer, layoutResult.GetCauseOfNothing()); NUnit.Framework.Assert.AreEqual(areaBreakRenderer.areaBreak, layoutResult.GetAreaBreak()); }
/* (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 virtual void NoNeedToSplitTextRendererOnLineSplit() { PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new MemoryStream())); Document document = new Document(pdfDocument); PdfFont pdfFont = PdfFontFactory.CreateFont(REGULAR_FONT, PdfEncodings.IDENTITY_H); // หากอากาศอากาศ - first 3 glyphs are an unbreakable placeholder in the first renderer so that text.start != 0; // the next 5 glyphs are an unbreakable part of first renderer that're supposed to fully fit on the first line, // the last 5 glyphs are an unbreakable part of the second renderer that could fit only partially, hence fully overflowed String thai = "\u0E2B\u0E32\u0E01" + THAI_WORD + THAI_WORD; TextRenderer textRendererFirst = new TextRenderer(new Text("")); textRendererFirst.SetProperty(Property.FONT, pdfFont); textRendererFirst.SetText(thai.JSubstring(0, 8)); textRendererFirst.text.start = 3; textRendererFirst.SetSpecialScriptsWordBreakPoints(new List <int>(JavaUtil.ArraysAsList(3, 8))); textRendererFirst.SetParent(document.GetRenderer()); float longestWordLength = textRendererFirst.GetMinMaxWidth().GetMaxWidth(); TextRenderer textRendererSecond = new TextRenderer(new Text(thai.Substring(8))); textRendererSecond.SetProperty(Property.FONT, pdfFont); textRendererSecond.SetSpecialScriptsWordBreakPoints(new List <int>(JavaUtil.ArraysAsList(5))); LayoutArea layoutArea = new LayoutArea(1, new Rectangle(longestWordLength * 1.5f, AbstractRenderer.INF)); LineRenderer lineRenderer = new LineRenderer(); lineRenderer.SetParent(document.GetRenderer()); lineRenderer.AddChild(textRendererFirst); lineRenderer.AddChild(textRendererSecond); LayoutResult result = lineRenderer.Layout(new LayoutContext(layoutArea)); NUnit.Framework.Assert.AreEqual(LayoutResult.PARTIAL, result.GetStatus()); IRenderer splitRenderer = result.GetSplitRenderer(); NUnit.Framework.Assert.IsNotNull(splitRenderer); IList <IRenderer> splitChildren = splitRenderer.GetChildRenderers(); NUnit.Framework.Assert.IsNotNull(splitChildren); NUnit.Framework.Assert.AreEqual(1, splitChildren.Count); IRenderer overflowRenderer = result.GetOverflowRenderer(); NUnit.Framework.Assert.IsNotNull(overflowRenderer); IList <IRenderer> overflowChildren = overflowRenderer.GetChildRenderers(); NUnit.Framework.Assert.IsNotNull(overflowChildren); NUnit.Framework.Assert.AreEqual(1, overflowChildren.Count); TextRenderer splitChild = (TextRenderer)splitChildren[0]; TextRenderer overflowChild = (TextRenderer)overflowChildren[0]; NUnit.Framework.Assert.AreEqual(splitChild.text, overflowChild.text); }
public virtual void InlineBlockWithBigMinWidth01() { Document dummyDocument = CreateDocument(); LineRenderer lineRenderer = (LineRenderer) new LineRenderer().SetParent(dummyDocument.GetRenderer()); Div div = new Div().SetMinWidth(2000).SetHeight(100); DivRenderer inlineBlockRenderer = (DivRenderer)div.CreateRendererSubTree(); lineRenderer.AddChild(inlineBlockRenderer); LayoutResult result = lineRenderer.Layout(new LayoutContext(CreateLayoutArea(1000, 1000))); // In case there is an inline block child with large min-width, the inline block child will be force placed (not layouted properly) NUnit.Framework.Assert.AreEqual(LayoutResult.FULL, result.GetStatus()); NUnit.Framework.Assert.AreEqual(0, result.GetOccupiedArea().GetBBox().GetHeight(), EPS); NUnit.Framework.Assert.AreEqual(true, inlineBlockRenderer.GetPropertyAsBoolean(Property.FORCED_PLACEMENT)); }
private static void AddSection(PdfDocument pdfDoc, Paragraph paragraph, int pageNumber, int sectionNumber) { Document doc = new Document(pdfDoc); ParagraphRenderer renderer = (ParagraphRenderer)paragraph.CreateRendererSubTree(); renderer.SetParent(new DocumentRenderer(doc)); float pageHeight = pdfDoc.GetDefaultPageSize().GetHeight(); float pageWidth = pdfDoc.GetDefaultPageSize().GetWidth(); Rectangle textSectionRectangle = new Rectangle( doc.GetLeftMargin(), doc.GetBottomMargin() + ((pageHeight - doc.GetTopMargin() - doc.GetBottomMargin()) / 3) * sectionNumber, pageWidth - doc.GetLeftMargin() - doc.GetRightMargin(), (pageHeight - doc.GetTopMargin() - doc.GetBottomMargin()) / 3); // Simulate the positioning of the renderer to find out how much space the text section will occupy. LayoutResult layoutResult = renderer .Layout(new LayoutContext(new LayoutArea(pageNumber, textSectionRectangle))); /* Fill the current page section with the content. * If the content isn't fully placed in the current page section, * it will be split and drawn in the next page section. */ while (layoutResult.GetStatus() != LayoutResult.FULL) { if (pdfDoc.GetNumberOfPages() < pageNumber) { pdfDoc.AddNewPage(); } pageNumber++; layoutResult.GetSplitRenderer().Draw(new DrawContext(pdfDoc, new PdfCanvas(pdfDoc.GetPage(pageNumber - 1)), false)); renderer = (ParagraphRenderer)layoutResult.GetOverflowRenderer(); layoutResult = renderer .Layout(new LayoutContext(new LayoutArea(pageNumber, textSectionRectangle))); } if (pdfDoc.GetNumberOfPages() < pageNumber) { pdfDoc.AddNewPage(); } renderer.Draw(new DrawContext(pdfDoc, new PdfCanvas(pdfDoc.GetPage(pageNumber)), false)); }
public virtual void ForcedSplitOnTooNarrowArea() { PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new MemoryStream())); Document document = new Document(pdfDocument); TextRenderer textRenderer = new TextRenderer(new Text(THAI_WORD)); textRenderer.SetProperty(Property.FONT, PdfFontFactory.CreateFont(THAI_FONT, PdfEncodings.IDENTITY_H)); textRenderer.SetSpecialScriptsWordBreakPoints(new List <int>(JavaUtil.ArraysAsList(5))); LineRenderer lineRenderer = new LineRenderer(); lineRenderer.SetParent(document.GetRenderer()); lineRenderer.AddChild(textRenderer); float minWidth = lineRenderer.GetMinMaxWidth().GetMinWidth(); LayoutArea layoutArea = new LayoutArea(1, new Rectangle(minWidth / 2, 100)); LayoutResult layoutResult = lineRenderer.Layout(new LayoutContext(layoutArea)); NUnit.Framework.Assert.IsTrue(layoutResult.GetStatus() == LayoutResult.PARTIAL); }
// TODO underlying should not be applied // https://jira.itextsupport.com/browse/SUP-952 public override LayoutResult Layout(LayoutContext layoutContext) { if (!HasOwnProperty(Property.LIST_SYMBOLS_INITIALIZED)) { IList <IRenderer> symbolRenderers = new List <IRenderer>(); int listItemNum = (int)this.GetProperty <int?>(Property.LIST_START, 1); for (int i = 0; i < childRenderers.Count; i++) { if (childRenderers[i].GetModelElement() is ListItem) { childRenderers[i].SetParent(this); IRenderer currentSymbolRenderer = MakeListSymbolRenderer(listItemNum++, childRenderers[i]); childRenderers[i].SetParent(null); symbolRenderers.Add(currentSymbolRenderer); LayoutResult listSymbolLayoutResult = currentSymbolRenderer.SetParent(this).Layout(layoutContext); currentSymbolRenderer.SetParent(null); if (listSymbolLayoutResult.GetStatus() != LayoutResult.FULL) { return(new LayoutResult(LayoutResult.NOTHING, null, null, this)); } } } float maxSymbolWidth = 0; foreach (IRenderer symbolRenderer in symbolRenderers) { maxSymbolWidth = Math.Max(maxSymbolWidth, symbolRenderer.GetOccupiedArea().GetBBox().GetWidth()); } float?symbolIndent = modelElement.GetProperty <float?>(Property.LIST_SYMBOL_INDENT); listItemNum = 0; foreach (IRenderer childRenderer in childRenderers) { childRenderer.DeleteOwnProperty(Property.MARGIN_LEFT); childRenderer.SetProperty(Property.MARGIN_LEFT, childRenderer.GetProperty(Property.MARGIN_LEFT, (float?)0f ) + maxSymbolWidth + (symbolIndent != null ? symbolIndent : 0f)); if (childRenderer.GetModelElement() is ListItem) { IRenderer symbolRenderer_1 = symbolRenderers[listItemNum++]; ((ListItemRenderer)childRenderer).AddSymbolRenderer(symbolRenderer_1, maxSymbolWidth); } } } return(base.Layout(layoutContext)); }
public override LayoutResult Layout(LayoutContext layoutContext) { if (symbolRenderer != null && this.GetProperty <Object>(Property.HEIGHT) == null && !IsListSymbolEmpty(symbolRenderer )) { float[] ascenderDescender = CalculateAscenderDescender(); float minHeight = Math.Max(symbolRenderer.GetOccupiedArea().GetBBox().GetHeight(), ascenderDescender[0] - ascenderDescender[1]); UpdateMinHeight(UnitValue.CreatePointValue(minHeight)); } ApplyListSymbolPosition(); LayoutResult result = base.Layout(layoutContext); if (LayoutResult.PARTIAL == result.GetStatus()) { result.GetOverflowRenderer().DeleteOwnProperty(Property.MIN_HEIGHT); } return(result); }
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); }
private static Rectangle ResolveTableRect(Document doc, Table table) { Rectangle pageDimension = new Rectangle(36, 36, 523, 770); IRenderer tableRenderer = table.CreateRendererSubTree().SetParent(doc.GetRenderer()); LayoutResult tableLayoutResult = tableRenderer.Layout(new LayoutContext(new LayoutArea(0, pageDimension))); Rectangle resultRect; if (LayoutResult.PARTIAL == tableLayoutResult.GetStatus()) { resultRect = pageDimension; } else { Rectangle tableBBox = tableLayoutResult.GetOccupiedArea().GetBBox(); resultRect = new Rectangle(pageDimension.GetX(), ((tableBBox.GetBottom() + pageDimension.GetX()) / 2), pageDimension.GetWidth(), tableBBox.GetHeight()); } return(resultRect); }
public virtual void NothingLayoutResult() { PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new MemoryStream())); Document document = new Document(pdfDocument); TextRenderer textRenderer = new TextRenderer(new iText.Layout.Element.Text(THAI_TEXT)); textRenderer.SetSpecialScriptsWordBreakPoints(new List <int>(JavaUtil.ArraysAsList(3, 8, 10, 12, 15, 20, 23 , 26, 28, 30, 36))); textRenderer.SetProperty(Property.FONT, PdfFontFactory.CreateFont(THAI_FONT, PdfEncodings.IDENTITY_H)); LineRenderer lineRenderer = new LineRenderer(); lineRenderer.SetParent(document.GetRenderer()); lineRenderer.AddChild(textRenderer); LayoutArea layoutArea = new LayoutArea(1, new Rectangle(MinMaxWidthUtils.GetInfWidth(), 10000)); Rectangle occupiedArea = lineRenderer.Layout(new LayoutContext(layoutArea)).GetOccupiedArea().GetBBox(); LayoutArea decreasedHeightLayoutArea = new LayoutArea(1, new Rectangle(occupiedArea.GetWidth(), occupiedArea .GetHeight() - 1)); LayoutResult nothingExpected = lineRenderer.Layout(new LayoutContext(decreasedHeightLayoutArea)); NUnit.Framework.Assert.AreEqual(LayoutResult.NOTHING, nothingExpected.GetStatus()); }
public override LayoutResult Layout(LayoutContext layoutContext) { LayoutResult layoutResult = base.Layout(layoutContext); // options container is the only kid of the select field renderer by design IRenderer optionsContainer = childRenderers.Count == 1 ? childRenderers[0] : null; if (!IsFlatten() || layoutResult.GetStatus() != LayoutResult.FULL || optionsContainer == null || optionsContainer .GetOccupiedArea() == null) { return(layoutResult); } if (IsOverflowProperty(OverflowPropertyValue.HIDDEN, this, Property.OVERFLOW_Y)) { IList <IRenderer> selectedOptions = GetSelectedOptions(this); IRenderer firstSelectedOption; if (!selectedOptions.IsEmpty() && (firstSelectedOption = selectedOptions[0]).GetOccupiedArea() != null) { Rectangle borderAreaBBox = GetBorderAreaBBox(); Rectangle optionBBox = firstSelectedOption.GetOccupiedArea().GetBBox().Clone(); if (firstSelectedOption is AbstractRenderer) { ((AbstractRenderer)firstSelectedOption).ApplyMargins(optionBBox, false); } if (optionBBox.GetHeight() < borderAreaBBox.GetHeight()) { float selectedBottom = optionBBox.GetBottom(); float borderAreaBBoxBottom = borderAreaBBox.GetBottom(); if (selectedBottom < borderAreaBBoxBottom) { optionsContainer.Move(0, borderAreaBBoxBottom - selectedBottom); } } else { optionsContainer.Move(0, borderAreaBBox.GetTop() - optionBBox.GetTop()); } } } return(layoutResult); }
private void Draw(IRenderer renderer, PageMarginBoxContextNode node, PdfDocument pdfDocument, PdfPage page , DocumentRenderer documentRenderer, int pageNumber) { LayoutResult result = renderer.Layout(new LayoutContext(new LayoutArea(pageNumber, node.GetPageMarginBoxRectangle ()))); IRenderer rendererToDraw = result.GetStatus() == LayoutResult.FULL ? renderer : result.GetSplitRenderer(); if (rendererToDraw != null) { TagTreePointer tagPointer = null; TagTreePointer backupPointer = null; PdfPage backupPage = null; if (pdfDocument.IsTagged()) { tagPointer = pdfDocument.GetTagStructureContext().GetAutoTaggingPointer(); backupPage = tagPointer.GetCurrentPage(); backupPointer = new TagTreePointer(tagPointer); tagPointer.MoveToRoot(); tagPointer.SetPageForTagging(page); } rendererToDraw.SetParent(documentRenderer).Draw(new DrawContext(page.GetDocument(), new PdfCanvas(page), pdfDocument .IsTagged())); if (pdfDocument.IsTagged()) { tagPointer.SetPageForTagging(backupPage); tagPointer.MoveToPointer(backupPointer); } } else { // marginBoxElements have overflow property set to HIDDEN, therefore it is not expected to neither get // LayoutResult other than FULL nor get no split renderer (result NOTHING) even if result is not FULL LOGGER.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.PAGE_MARGIN_BOX_CONTENT_CANNOT_BE_DRAWN , node.GetMarginBoxName())); } }
public override void AddChild(IRenderer renderer) { base.AddChild(renderer); if (currentArea == null) { UpdateCurrentArea(null); } // Static layout if (currentArea != null && !childRenderers.IsEmpty() && childRenderers[childRenderers.Count - 1] == renderer ) { childRenderers.JRemoveAt(childRenderers.Count - 1); IList <IRenderer> resultRenderers = new List <IRenderer>(); LayoutResult result = null; LayoutArea storedArea = null; LayoutArea nextStoredArea = null; while (currentArea != null && renderer != null && (result = renderer.SetParent(this).Layout(new LayoutContext (currentArea.Clone()))).GetStatus() != LayoutResult.FULL) { if (result.GetStatus() == LayoutResult.PARTIAL) { if (result.GetOverflowRenderer() is ImageRenderer) { ((ImageRenderer)result.GetOverflowRenderer()).AutoScale(currentArea); } else { ProcessRenderer(result.GetSplitRenderer(), resultRenderers); if (nextStoredArea != null) { currentArea = nextStoredArea; currentPageNumber = nextStoredArea.GetPageNumber(); nextStoredArea = null; } else { UpdateCurrentArea(result); } } } else { if (result.GetStatus() == LayoutResult.NOTHING) { if (result.GetOverflowRenderer() is ImageRenderer) { if (currentArea.GetBBox().GetHeight() < ((ImageRenderer)result.GetOverflowRenderer()).imageHeight && !currentArea .IsEmptyArea()) { UpdateCurrentArea(result); } ((ImageRenderer)result.GetOverflowRenderer()).AutoScale(currentArea); } else { if (currentArea.IsEmptyArea() && !(renderer is AreaBreakRenderer)) { if (true.Equals(result.GetOverflowRenderer().GetModelElement().GetProperty <bool?>(Property.KEEP_TOGETHER)) ) { result.GetOverflowRenderer().GetModelElement().SetProperty(Property.KEEP_TOGETHER, false); ILogger logger = LoggerFactory.GetLogger(typeof(RootRenderer)); logger.Warn(String.Format(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "KeepTogether property will be ignored." )); if (storedArea != null) { nextStoredArea = currentArea; currentArea = storedArea; currentPageNumber = storedArea.GetPageNumber(); } storedArea = currentArea; } else { result.GetOverflowRenderer().SetProperty(Property.FORCED_PLACEMENT, true); ILogger logger = LoggerFactory.GetLogger(typeof(RootRenderer)); logger.Warn(String.Format(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "")); } renderer = result.GetOverflowRenderer(); continue; } storedArea = currentArea; if (nextStoredArea != null) { currentArea = nextStoredArea; currentPageNumber = nextStoredArea.GetPageNumber(); nextStoredArea = null; } else { UpdateCurrentArea(result); } } } } renderer = result.GetOverflowRenderer(); } if (currentArea != null) { System.Diagnostics.Debug.Assert(result != null && result.GetOccupiedArea() != null); currentArea.GetBBox().SetHeight(currentArea.GetBBox().GetHeight() - result.GetOccupiedArea().GetBBox().GetHeight ()); currentArea.SetEmptyArea(false); if (renderer != null) { ProcessRenderer(renderer, resultRenderers); } } if (!immediateFlush) { childRenderers.AddAll(resultRenderers); } } else { if (positionedRenderers.Count > 0 && positionedRenderers[positionedRenderers.Count - 1] == renderer) { int?positionedPageNumber = renderer.GetProperty <int?>(Property.PAGE_NUMBER); if (positionedPageNumber == null) { positionedPageNumber = currentPageNumber; } renderer.SetParent(this).Layout(new LayoutContext(new LayoutArea((int)positionedPageNumber, currentArea.GetBBox ().Clone()))); if (immediateFlush) { FlushSingleRenderer(renderer); positionedRenderers.JRemoveAt(positionedRenderers.Count - 1); } } } }
private void ProcessWaitingKeepWithNextElement(IRenderer renderer) { if (keepWithNextHangingRenderer != null) { LayoutArea rest = currentArea.Clone(); rest.GetBBox().SetHeight(rest.GetBBox().GetHeight() - keepWithNextHangingRendererLayoutResult.GetOccupiedArea ().GetBBox().GetHeight()); bool ableToProcessKeepWithNext = false; if (renderer.SetParent(this).Layout(new LayoutContext(rest)).GetStatus() != LayoutResult.NOTHING) { // The area break will not be introduced and we are safe to place everything as is ShrinkCurrentAreaAndProcessRenderer(keepWithNextHangingRenderer, new List <IRenderer>(), keepWithNextHangingRendererLayoutResult ); ableToProcessKeepWithNext = true; } else { float originalElementHeight = keepWithNextHangingRendererLayoutResult.GetOccupiedArea().GetBBox().GetHeight (); IList <float> trySplitHeightPoints = new List <float>(); float delta = 35; for (int i = 1; i <= 5 && originalElementHeight - delta * i > originalElementHeight / 2; i++) { trySplitHeightPoints.Add(originalElementHeight - delta * i); } for (int i = 0; i < trySplitHeightPoints.Count && !ableToProcessKeepWithNext; i++) { float curElementSplitHeight = trySplitHeightPoints[i]; RootLayoutArea firstElementSplitLayoutArea = (RootLayoutArea)currentArea.Clone(); firstElementSplitLayoutArea.GetBBox().SetHeight(curElementSplitHeight).MoveUp(currentArea.GetBBox().GetHeight () - curElementSplitHeight); LayoutResult firstElementSplitLayoutResult = keepWithNextHangingRenderer.SetParent(this).Layout(new LayoutContext (firstElementSplitLayoutArea.Clone())); if (firstElementSplitLayoutResult.GetStatus() == LayoutResult.PARTIAL) { RootLayoutArea storedArea = currentArea; UpdateCurrentAndInitialArea(firstElementSplitLayoutResult); LayoutResult firstElementOverflowLayoutResult = firstElementSplitLayoutResult.GetOverflowRenderer().Layout (new LayoutContext(currentArea.Clone())); if (firstElementOverflowLayoutResult.GetStatus() == LayoutResult.FULL) { LayoutArea secondElementLayoutArea = currentArea.Clone(); secondElementLayoutArea.GetBBox().SetHeight(secondElementLayoutArea.GetBBox().GetHeight() - firstElementOverflowLayoutResult .GetOccupiedArea().GetBBox().GetHeight()); LayoutResult secondElementLayoutResult = renderer.SetParent(this).Layout(new LayoutContext(secondElementLayoutArea )); if (secondElementLayoutResult.GetStatus() != LayoutResult.NOTHING) { ableToProcessKeepWithNext = true; currentArea = firstElementSplitLayoutArea; currentPageNumber = firstElementSplitLayoutArea.GetPageNumber(); ShrinkCurrentAreaAndProcessRenderer(firstElementSplitLayoutResult.GetSplitRenderer(), new List <IRenderer>( ), firstElementSplitLayoutResult); UpdateCurrentAndInitialArea(firstElementSplitLayoutResult); ShrinkCurrentAreaAndProcessRenderer(firstElementSplitLayoutResult.GetOverflowRenderer(), new List <IRenderer >(), firstElementOverflowLayoutResult); } } if (!ableToProcessKeepWithNext) { currentArea = storedArea; currentPageNumber = storedArea.GetPageNumber(); } } } } if (!ableToProcessKeepWithNext && !currentArea.IsEmptyArea()) { RootLayoutArea storedArea = currentArea; UpdateCurrentAndInitialArea(null); LayoutResult firstElementLayoutResult = keepWithNextHangingRenderer.SetParent(this).Layout(new LayoutContext (currentArea.Clone())); if (firstElementLayoutResult.GetStatus() == LayoutResult.FULL) { LayoutArea secondElementLayoutArea = currentArea.Clone(); secondElementLayoutArea.GetBBox().SetHeight(secondElementLayoutArea.GetBBox().GetHeight() - firstElementLayoutResult .GetOccupiedArea().GetBBox().GetHeight()); LayoutResult secondElementLayoutResult = renderer.SetParent(this).Layout(new LayoutContext(secondElementLayoutArea )); if (secondElementLayoutResult.GetStatus() != LayoutResult.NOTHING) { ableToProcessKeepWithNext = true; ShrinkCurrentAreaAndProcessRenderer(keepWithNextHangingRenderer, new List <IRenderer>(), keepWithNextHangingRendererLayoutResult ); } } if (!ableToProcessKeepWithNext) { currentArea = storedArea; currentPageNumber = storedArea.GetPageNumber(); } } if (!ableToProcessKeepWithNext) { ILog logger = LogManager.GetLogger(typeof(RootRenderer)); logger.Warn(iText.IO.LogMessageConstant.RENDERER_WAS_NOT_ABLE_TO_PROCESS_KEEP_WITH_NEXT); ShrinkCurrentAreaAndProcessRenderer(keepWithNextHangingRenderer, new List <IRenderer>(), keepWithNextHangingRendererLayoutResult ); } keepWithNextHangingRenderer = null; keepWithNextHangingRendererLayoutResult = null; } }
// TODO underlying should not be applied // https://jira.itextsupport.com/browse/SUP-952 public override LayoutResult Layout(LayoutContext layoutContext) { if (!HasOwnProperty(Property.LIST_SYMBOLS_INITIALIZED)) { IList <IRenderer> symbolRenderers = new List <IRenderer>(); int listItemNum = (int)this.GetProperty <int?>(Property.LIST_START, 1); for (int i = 0; i < childRenderers.Count; i++) { if (childRenderers[i].GetModelElement() is ListItem) { childRenderers[i].SetParent(this); IRenderer currentSymbolRenderer = MakeListSymbolRenderer(listItemNum++, childRenderers[i]); childRenderers[i].SetParent(null); symbolRenderers.Add(currentSymbolRenderer); LayoutResult listSymbolLayoutResult = currentSymbolRenderer.SetParent(this).Layout(layoutContext); currentSymbolRenderer.SetParent(null); if (listSymbolLayoutResult.GetStatus() != LayoutResult.FULL) { return(new LayoutResult(LayoutResult.NOTHING, null, null, this, listSymbolLayoutResult.GetCauseOfNothing() )); } } } float maxSymbolWidth = 0; foreach (IRenderer symbolRenderer in symbolRenderers) { maxSymbolWidth = Math.Max(maxSymbolWidth, symbolRenderer.GetOccupiedArea().GetBBox().GetWidth()); } float?symbolIndent = modelElement.GetProperty <float?>(Property.LIST_SYMBOL_INDENT); listItemNum = 0; foreach (IRenderer childRenderer in childRenderers) { childRenderer.DeleteOwnProperty(Property.MARGIN_LEFT); childRenderer.SetProperty(Property.MARGIN_LEFT, childRenderer.GetProperty(Property.MARGIN_LEFT, (float?)0f ) + maxSymbolWidth + (symbolIndent != null ? symbolIndent : 0f)); if (childRenderer.GetModelElement() is ListItem) { IRenderer symbolRenderer_1 = symbolRenderers[listItemNum++]; ((ListItemRenderer)childRenderer).AddSymbolRenderer(symbolRenderer_1, maxSymbolWidth); } } } LayoutResult result = base.Layout(layoutContext); // cannot place even the first ListItemRenderer if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT)) && null != result.GetCauseOfNothing()) { if (LayoutResult.FULL == result.GetStatus()) { result = CorrectListSplitting(this, null, result.GetCauseOfNothing(), result.GetOccupiedArea()); } else { if (LayoutResult.PARTIAL == result.GetStatus()) { result = CorrectListSplitting(result.GetSplitRenderer(), result.GetOverflowRenderer(), result.GetCauseOfNothing (), result.GetOccupiedArea()); } } } return(result); }
public override void AddChild(IRenderer renderer) { base.AddChild(renderer); if (currentArea == null) { UpdateCurrentArea(null); } // Static layout if (currentArea != null && !childRenderers.IsEmpty() && childRenderers[childRenderers.Count - 1] == renderer ) { childRenderers.JRemoveAt(childRenderers.Count - 1); ProcessWaitingKeepWithNextElement(renderer); IList <IRenderer> resultRenderers = new List <IRenderer>(); LayoutResult result = null; LayoutArea storedArea = null; LayoutArea nextStoredArea = null; while (currentArea != null && renderer != null && (result = renderer.SetParent(this).Layout(new LayoutContext (currentArea.Clone()))).GetStatus() != LayoutResult.FULL) { if (result.GetStatus() == LayoutResult.PARTIAL) { if (result.GetOverflowRenderer() is ImageRenderer) { ((ImageRenderer)result.GetOverflowRenderer()).AutoScale(currentArea); } else { ProcessRenderer(result.GetSplitRenderer(), resultRenderers); if (nextStoredArea != null) { currentArea = nextStoredArea; currentPageNumber = nextStoredArea.GetPageNumber(); nextStoredArea = null; } else { UpdateCurrentArea(result); } } } else { if (result.GetStatus() == LayoutResult.NOTHING) { if (result.GetOverflowRenderer() is ImageRenderer) { if (currentArea.GetBBox().GetHeight() < ((ImageRenderer)result.GetOverflowRenderer()).imageHeight && !currentArea .IsEmptyArea()) { UpdateCurrentArea(result); } ((ImageRenderer)result.GetOverflowRenderer()).AutoScale(currentArea); result.GetOverflowRenderer().SetProperty(Property.FORCED_PLACEMENT, true); } else { if (currentArea.IsEmptyArea() && !(renderer is AreaBreakRenderer)) { if (true.Equals(result.GetOverflowRenderer().GetModelElement().GetProperty <bool?>(Property.KEEP_TOGETHER)) ) { result.GetOverflowRenderer().GetModelElement().SetProperty(Property.KEEP_TOGETHER, false); ILogger logger = LoggerFactory.GetLogger(typeof(RootRenderer)); logger.Warn(String.Format(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "KeepTogether property will be ignored." )); if (storedArea != null) { nextStoredArea = currentArea; currentArea = storedArea; currentPageNumber = storedArea.GetPageNumber(); } storedArea = currentArea; } else { if (null != result.GetCauseOfNothing() && true.Equals(result.GetCauseOfNothing().GetProperty <bool?>(Property .KEEP_TOGETHER))) { // set KEEP_TOGETHER false on the deepest parent (maybe the element itself) to have KEEP_TOGETHER == true IRenderer theDeepestKeptTogether = result.GetCauseOfNothing(); while (null == theDeepestKeptTogether.GetModelElement() || null == theDeepestKeptTogether.GetModelElement( ).GetOwnProperty <bool?>(Property.KEEP_TOGETHER)) { theDeepestKeptTogether = ((AbstractRenderer)theDeepestKeptTogether).parent; } theDeepestKeptTogether.GetModelElement().SetProperty(Property.KEEP_TOGETHER, false); ILogger logger = LoggerFactory.GetLogger(typeof(RootRenderer)); logger.Warn(String.Format(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "KeepTogether property of inner element will be ignored." )); } else { result.GetOverflowRenderer().SetProperty(Property.FORCED_PLACEMENT, true); ILogger logger = LoggerFactory.GetLogger(typeof(RootRenderer)); logger.Warn(String.Format(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "")); } } renderer = result.GetOverflowRenderer(); continue; } storedArea = currentArea; if (nextStoredArea != null) { currentArea = nextStoredArea; currentPageNumber = nextStoredArea.GetPageNumber(); nextStoredArea = null; } else { UpdateCurrentArea(result); } } } } renderer = result.GetOverflowRenderer(); } // Keep renderer until next element is added for future keep with next adjustments if (renderer != null && true.Equals(renderer.GetProperty <bool?>(Property.KEEP_WITH_NEXT))) { if (true.Equals(renderer.GetProperty <bool?>(Property.FORCED_PLACEMENT))) { ILogger logger = LoggerFactory.GetLogger(typeof(RootRenderer)); logger.Warn(LogMessageConstant.ELEMENT_WAS_FORCE_PLACED_KEEP_WITH_NEXT_WILL_BE_IGNORED); UpdateCurrentAreaAndProcessRenderer(renderer, resultRenderers, result); } else { keepWithNextHangingRenderer = renderer; keepWithNextHangingRendererLayoutResult = result; } } else { UpdateCurrentAreaAndProcessRenderer(renderer, resultRenderers, result); } } else { if (positionedRenderers.Count > 0 && positionedRenderers[positionedRenderers.Count - 1] == renderer) { int?positionedPageNumber = renderer.GetProperty <int?>(Property.PAGE_NUMBER); if (positionedPageNumber == null) { positionedPageNumber = currentPageNumber; } renderer.SetParent(this).Layout(new LayoutContext(new LayoutArea((int)positionedPageNumber, currentArea.GetBBox ().Clone()))); if (immediateFlush) { FlushSingleRenderer(renderer); positionedRenderers.JRemoveAt(positionedRenderers.Count - 1); } } } }
private LayoutResult InitializeListSymbols(LayoutContext layoutContext) { if (!HasOwnProperty(Property.LIST_SYMBOLS_INITIALIZED)) { IList <IRenderer> symbolRenderers = new List <IRenderer>(); int listItemNum = (int)this.GetProperty <int?>(Property.LIST_START, 1); for (int i = 0; i < childRenderers.Count; i++) { childRenderers[i].SetParent(this); listItemNum = (childRenderers[i].GetProperty <int?>(Property.LIST_SYMBOL_ORDINAL_VALUE) != null) ? (int)childRenderers [i].GetProperty <int?>(Property.LIST_SYMBOL_ORDINAL_VALUE) : listItemNum; IRenderer currentSymbolRenderer = MakeListSymbolRenderer(listItemNum, childRenderers[i]); if (BaseDirection.RIGHT_TO_LEFT.Equals(this.GetProperty <BaseDirection?>(Property.BASE_DIRECTION))) { currentSymbolRenderer.SetProperty(Property.BASE_DIRECTION, BaseDirection.RIGHT_TO_LEFT); } LayoutResult listSymbolLayoutResult = null; if (currentSymbolRenderer != null) { ++listItemNum; currentSymbolRenderer.SetParent(childRenderers[i]); listSymbolLayoutResult = currentSymbolRenderer.Layout(layoutContext); currentSymbolRenderer.SetParent(null); } childRenderers[i].SetParent(null); bool isForcedPlacement = true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT)); bool listSymbolNotFit = listSymbolLayoutResult != null && listSymbolLayoutResult.GetStatus() != LayoutResult .FULL; // TODO DEVSIX-1001: partially not fitting list symbol not shown at all, however this might be improved if (listSymbolNotFit && isForcedPlacement) { currentSymbolRenderer = null; } symbolRenderers.Add(currentSymbolRenderer); if (listSymbolNotFit && !isForcedPlacement) { return(new LayoutResult(LayoutResult.NOTHING, null, null, this, listSymbolLayoutResult.GetCauseOfNothing() )); } } float maxSymbolWidth = 0; for (int i = 0; i < childRenderers.Count; i++) { IRenderer symbolRenderer = symbolRenderers[i]; if (symbolRenderer != null) { IRenderer listItemRenderer = childRenderers[i]; if ((ListSymbolPosition)GetListItemOrListProperty(listItemRenderer, this, Property.LIST_SYMBOL_POSITION) != ListSymbolPosition.INSIDE) { maxSymbolWidth = Math.Max(maxSymbolWidth, symbolRenderer.GetOccupiedArea().GetBBox().GetWidth()); } } } float?symbolIndent = this.GetPropertyAsFloat(Property.LIST_SYMBOL_INDENT); listItemNum = 0; foreach (IRenderer childRenderer in childRenderers) { childRenderer.SetParent(this); childRenderer.DeleteOwnProperty(Property.MARGIN_LEFT); UnitValue marginLeftUV = childRenderer.GetProperty(Property.MARGIN_LEFT, UnitValue.CreatePointValue(0f)); if (!marginLeftUV.IsPointValue()) { ILog logger = LogManager.GetLogger(typeof(iText.Layout.Renderer.ListRenderer)); logger.Error(MessageFormatUtil.Format(iText.IO.LogMessageConstant.PROPERTY_IN_PERCENTS_NOT_SUPPORTED, Property .MARGIN_LEFT)); } float calculatedMargin = marginLeftUV.GetValue(); if ((ListSymbolPosition)GetListItemOrListProperty(childRenderer, this, Property.LIST_SYMBOL_POSITION) == ListSymbolPosition .DEFAULT) { calculatedMargin += maxSymbolWidth + (float)(symbolIndent != null ? symbolIndent : 0f); } childRenderer.SetProperty(Property.MARGIN_LEFT, UnitValue.CreatePointValue(calculatedMargin)); IRenderer symbolRenderer = symbolRenderers[listItemNum++]; ((ListItemRenderer)childRenderer).AddSymbolRenderer(symbolRenderer, maxSymbolWidth); if (symbolRenderer != null) { LayoutTaggingHelper taggingHelper = this.GetProperty <LayoutTaggingHelper>(Property.TAGGING_HELPER); if (taggingHelper != null) { if (symbolRenderer is LineRenderer) { taggingHelper.SetRoleHint(symbolRenderer.GetChildRenderers()[1], StandardRoles.LBL); } else { taggingHelper.SetRoleHint(symbolRenderer, StandardRoles.LBL); } } } } } return(null); }
/* (non-Javadoc) * @see com.itextpdf.layout.renderer.DocumentRenderer#updateCurrentArea(com.itextpdf.layout.layout.LayoutResult) */ protected override LayoutArea UpdateCurrentArea(LayoutResult overflowResult) { AreaBreak areaBreak = overflowResult != null?overflowResult.GetAreaBreak() : null; if (areaBreak is HtmlPageBreak) { HtmlPageBreakType htmlPageBreakType = ((HtmlPageBreak)areaBreak).GetBreakType(); if (shouldTrimFirstBlankPagesCausedByBreakBeforeFirstElement && currentArea != null && overflowResult.GetStatus () == LayoutResult.NOTHING && currentArea.IsEmptyArea() && currentArea.GetPageNumber() == 1) { // Remove blank page that was added just to have area for elements to layout on. // Now we will add a page with dimensions and all the stuff that is requested by page-break-before document.GetPdfDocument().RemovePage(1); currentPageNumber = 0; overflowResult = null; currentArea = null; shouldTrimFirstBlankPagesCausedByBreakBeforeFirstElement = false; if (HtmlPageBreakType.LEFT.Equals(htmlPageBreakType) && !IsPageLeft(1) || HtmlPageBreakType.RIGHT.Equals(htmlPageBreakType ) && !IsPageRight(1)) { evenPagesAreLeft = !evenPagesAreLeft; } } // hack to change the "evenness" of the first page without adding an unnecessary blank page anythingAddedToCurrentArea = anythingAddedToCurrentArea || overflowResult != null && overflowResult.GetStatus () == LayoutResult.PARTIAL; if (HtmlPageBreakType.ALWAYS.Equals(htmlPageBreakType)) { LayoutArea nextArea = currentArea; if (anythingAddedToCurrentArea || currentArea == null) { nextArea = base.UpdateCurrentArea(overflowResult); } anythingAddedToCurrentArea = false; return(nextArea); } else { if (HtmlPageBreakType.LEFT.Equals(htmlPageBreakType)) { LayoutArea nextArea = currentArea; if (anythingAddedToCurrentArea || currentArea == null || !IsPageLeft(currentPageNumber)) { do { nextArea = base.UpdateCurrentArea(overflowResult); }while (!IsPageLeft(currentPageNumber)); } anythingAddedToCurrentArea = false; return(nextArea); } else { if (HtmlPageBreakType.RIGHT.Equals(htmlPageBreakType)) { LayoutArea nextArea = currentArea; if (anythingAddedToCurrentArea || currentArea == null || !IsPageRight(currentPageNumber)) { do { nextArea = base.UpdateCurrentArea(overflowResult); }while (!IsPageRight(currentPageNumber)); } anythingAddedToCurrentArea = false; return(nextArea); } } } } anythingAddedToCurrentArea = false; return(base.UpdateCurrentArea(overflowResult)); }
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)); } }