private LayoutResult MakeLayoutResultFull(LayoutArea layoutArea, LayoutResult layoutResult) { IRenderer splitRenderer = layoutResult.GetSplitRenderer() != null?layoutResult.GetSplitRenderer() : this; if (occupiedArea == null) { occupiedArea = new LayoutArea(layoutArea.GetPageNumber(), new Rectangle(layoutArea.GetBBox().GetLeft(), layoutArea .GetBBox().GetTop(), 0, 0)); } layoutResult = new LayoutResult(LayoutResult.FULL, occupiedArea, splitRenderer, null); return(layoutResult); }
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); }
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 virtual void OrphansWidowsAwareAndDirectLayoutProduceSameResult() { PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new MemoryStream())); Document document = new Document(pdfDocument); int minAllowedWidows = 3; int overflowedToNextPageLinesNum = 5; Paragraph widowsParagraph = new Paragraph(OrphansWidowsTestUtil.PARA_TEXT); IRenderer paragraphRenderer = widowsParagraph.CreateRendererSubTree().SetParent(document.GetRenderer()); Rectangle effectiveArea = document.GetPageEffectiveArea(pdfDocument.GetDefaultPageSize()); float linesHeight = OrphansWidowsTestUtil.CalculateHeightForLinesNum(document, widowsParagraph, effectiveArea .GetWidth(), overflowedToNextPageLinesNum, false); Rectangle layoutAreaRect = new Rectangle(effectiveArea).SetHeight(linesHeight + OrphansWidowsTestUtil.LINES_SPACE_EPS ); LayoutContext layoutContext = new LayoutContext(new LayoutArea(1, layoutAreaRect)); LayoutResult noWidowsControlLayoutResult = paragraphRenderer.Layout(layoutContext); ParagraphWidowsControl widowsControl = new ParagraphWidowsControl(minAllowedWidows, 1, false); widowsParagraph.SetWidowsControl(widowsControl); LayoutResult widowsControlLayoutResult = paragraphRenderer.Layout(layoutContext); // toString() comparison is used since it contains report on status, areaBreak and occupiedArea NUnit.Framework.Assert.AreEqual(noWidowsControlLayoutResult.ToString(), widowsControlLayoutResult.ToString ()); ParagraphRenderer firstSplitRenderer = (ParagraphRenderer)noWidowsControlLayoutResult.GetSplitRenderer(); ParagraphRenderer secondSplitRenderer = (ParagraphRenderer)widowsControlLayoutResult.GetSplitRenderer(); NUnit.Framework.Assert.IsNotNull(firstSplitRenderer); NUnit.Framework.Assert.IsNotNull(secondSplitRenderer); NUnit.Framework.Assert.AreEqual(firstSplitRenderer.ToString(), secondSplitRenderer.ToString()); NUnit.Framework.Assert.IsNotNull(noWidowsControlLayoutResult.GetOverflowRenderer()); NUnit.Framework.Assert.IsNotNull(widowsControlLayoutResult.GetOverflowRenderer()); }
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()); }
public static void ProduceOrphansAndWidowsTestCase(String outPdf, Paragraph testPara) { Document doc = new Document(new PdfDocument(new PdfWriter(outPdf))); PageSize pageSize = new PageSize(PageSize.A4.GetWidth(), PageSize.A5.GetHeight()); doc.GetPdfDocument().SetDefaultPageSize(pageSize); Rectangle[] columns = InitUniformColumns(pageSize, 2); doc.SetRenderer(new ColumnDocumentRenderer(doc, columns)); String paraText = "A one line string\n"; testPara.SetMargin(0).SetBackgroundColor(new DeviceRgb(232, 232, 232)); testPara.Add(paraText); float linesHeight = CalculateHeightForLinesNum(doc, testPara, columns[1].GetWidth(), 1, true); float adjustmentHeight = columns[0].GetHeight() - linesHeight - LINES_SPACE_EPS; String description = "Test orphans and widows case at once. This block height" + " is adjusted in such way that both orphans and widows cases occur.\n " + "The following paragraph contains as many fitting in one line text strings as needed" + " to reproduce the case with both orphans and widows\n" + "Reference example without orphans and widows" + " control can be found on the next page"; doc.Add(new Paragraph(description).SetMargin(0).SetBorder(new SolidBorder(1)).SetHeight(adjustmentHeight)); Paragraph tempPara = new Paragraph().SetMargin(0); for (int i = 0; i < 50; i++) { tempPara.Add(paraText); } ParagraphRenderer renderer = (ParagraphRenderer)tempPara.CreateRendererSubTree().SetParent(doc.GetRenderer ()); LayoutResult layoutRes = renderer.Layout(new LayoutContext(new LayoutArea(1, new Rectangle(columns[1].GetWidth (), columns[1].GetHeight())))); int numberOfLines = ((ParagraphRenderer)layoutRes.GetSplitRenderer()).GetLines().Count; for (int i = 0; i <= numberOfLines; i++) { testPara.Add(paraText); } doc.Add(testPara); doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE)); doc.Add(new Paragraph("Reference example without orphans and widows control.").SetMargin(0).SetBorder(new SolidBorder(1)).SetHeight(adjustmentHeight)); Paragraph paragraph = new Paragraph(); for (int i = 0; i <= numberOfLines + 1; i++) { paragraph.Add(paraText); } paragraph.SetMargin(0).SetBackgroundColor(new DeviceRgb(232, 232, 232)); doc.Add(paragraph); doc.Add(new Paragraph(paraText).SetMargin(0).SetBackgroundColor(new DeviceRgb(232, 232, 232))); doc.Close(); }
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); }
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 SpecialScriptsWordBreakPointsSplit() { PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new MemoryStream())); Document document = new Document(pdfDocument); TextRenderer textRenderer = new TextRenderer(new Text("")); textRenderer.SetProperty(Property.FONT, PdfFontFactory.CreateFont(THAI_FONT, PdfEncodings.IDENTITY_H)); textRenderer.SetText(THAI_TEXT); textRenderer.SetSpecialScriptsWordBreakPoints(new List <int>(JavaUtil.ArraysAsList(3, 8, 10, 12, 15, 20, 23 , 26, 28, 30, 36))); LineRenderer lineRenderer = new LineRenderer(); lineRenderer.SetParent(document.GetRenderer()); lineRenderer.AddChild(textRenderer); MinMaxWidth minMaxWidth = lineRenderer.GetMinMaxWidth(); float width = minMaxWidth.GetMinWidth() + minMaxWidth.GetMaxWidth() / 2; LayoutResult layoutResult = lineRenderer.Layout(new LayoutContext(new LayoutArea(1, new Rectangle(width, 500 )))); IRenderer lineSplitRenderer = layoutResult.GetSplitRenderer(); NUnit.Framework.Assert.IsNotNull(lineSplitRenderer); NUnit.Framework.Assert.IsNotNull(lineSplitRenderer.GetChildRenderers()); NUnit.Framework.Assert.IsTrue(lineSplitRenderer.GetChildRenderers()[0] is TextRenderer); TextRenderer textSplitRenderer = (TextRenderer)lineSplitRenderer.GetChildRenderers()[0]; NUnit.Framework.Assert.IsNotNull(textSplitRenderer.GetSpecialScriptsWordBreakPoints()); IRenderer lineOverflowRenderer = layoutResult.GetOverflowRenderer(); NUnit.Framework.Assert.IsNotNull(lineOverflowRenderer); NUnit.Framework.Assert.IsNotNull(lineOverflowRenderer.GetChildRenderers()); NUnit.Framework.Assert.IsTrue(lineOverflowRenderer.GetChildRenderers()[0] is TextRenderer); TextRenderer textOverflowRenderer = (TextRenderer)lineOverflowRenderer.GetChildRenderers()[0]; NUnit.Framework.Assert.IsNotNull(textOverflowRenderer.GetSpecialScriptsWordBreakPoints()); int textSplitRendererTextLength = textSplitRenderer.text.ToString().Length; foreach (int specialScriptsWordBreakPoint in textSplitRenderer.GetSpecialScriptsWordBreakPoints()) { NUnit.Framework.Assert.IsTrue(specialScriptsWordBreakPoint <= textSplitRendererTextLength); } foreach (int specialScriptsWordBreakPoint in textOverflowRenderer.GetSpecialScriptsWordBreakPoints()) { NUnit.Framework.Assert.IsTrue(specialScriptsWordBreakPoint > textSplitRendererTextLength && specialScriptsWordBreakPoint <= textOverflowRenderer.text.Size()); } }
/// <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())); } } }
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; } }
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 virtual void MultipleRenderers() { PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new MemoryStream())); Document document = new Document(pdfDocument); document.SetFont(PdfFontFactory.CreateFont(THAI_FONT, PdfEncodings.IDENTITY_H)); List <int> possibleBreaks = new List <int>(JavaUtil.ArraysAsList(3, 8, 10, 12, 15, 20, 23, 26, 28, 30, 36)); TextRenderer textRenderer = new TextRenderer(new Text(THAI_TEXT)); textRenderer.SetSpecialScriptsWordBreakPoints(possibleBreaks); LineRenderer lineRendererWithOneChild = new LineRenderer(); lineRendererWithOneChild.SetParent(document.GetRenderer()); lineRendererWithOneChild.AddChild(textRenderer); float maxWidth = lineRendererWithOneChild.GetMinMaxWidth().GetMaxWidth(); LayoutArea layoutArea = new LayoutArea(1, new Rectangle(maxWidth / 2, 100)); LayoutResult layoutResultSingleTextRenderer = lineRendererWithOneChild.Layout(new LayoutContext(layoutArea )); IRenderer splitRendererOneChild = layoutResultSingleTextRenderer.GetSplitRenderer(); NUnit.Framework.Assert.IsNotNull(splitRendererOneChild); NUnit.Framework.Assert.AreEqual(1, splitRendererOneChild.GetChildRenderers().Count); String splitTextOneChild = ((TextRenderer)splitRendererOneChild.GetChildRenderers()[0]).text.ToString(); IRenderer overflowRendererOneChild = layoutResultSingleTextRenderer.GetOverflowRenderer(); NUnit.Framework.Assert.IsNotNull(overflowRendererOneChild); NUnit.Framework.Assert.AreEqual(1, overflowRendererOneChild.GetChildRenderers().Count); String overflowTextOneChild = ((TextRenderer)overflowRendererOneChild.GetChildRenderers()[0]).text.ToString (); LineRenderer lineRendererMultipleChildren = new LineRenderer(); lineRendererMultipleChildren.SetParent(document.GetRenderer()); for (int i = 0; i < THAI_TEXT.Length; i++) { TextRenderer oneGlyphRenderer = new TextRenderer(new Text(new String(new char[] { THAI_TEXT[i] }))); IList <int> specialScriptsWordBreakPoints = new List <int>(); if (possibleBreaks.Contains(i)) { specialScriptsWordBreakPoints.Add(i); } oneGlyphRenderer.SetSpecialScriptsWordBreakPoints(specialScriptsWordBreakPoints); lineRendererMultipleChildren.AddChild(oneGlyphRenderer); } LayoutResult layoutResultMultipleTextRenderers = lineRendererMultipleChildren.Layout(new LayoutContext(layoutArea )); IRenderer splitRendererMultipleChildren = layoutResultMultipleTextRenderers.GetSplitRenderer(); NUnit.Framework.Assert.IsNotNull(splitRendererMultipleChildren); NUnit.Framework.Assert.IsTrue(splitRendererMultipleChildren.GetChildRenderers().Count > 0); StringBuilder stringBuilder = new StringBuilder(); foreach (IRenderer childRenderer in splitRendererMultipleChildren.GetChildRenderers()) { stringBuilder.Append(((TextRenderer)childRenderer).text.ToString()); } String splitTextMultipleChildren = stringBuilder.ToString(); IRenderer overflowRendererMultipleChildren = layoutResultMultipleTextRenderers.GetOverflowRenderer(); NUnit.Framework.Assert.IsNotNull(overflowRendererMultipleChildren); NUnit.Framework.Assert.IsTrue(overflowRendererMultipleChildren.GetChildRenderers().Count > 0); stringBuilder.Length = 0; foreach (IRenderer childRenderer in overflowRendererMultipleChildren.GetChildRenderers()) { stringBuilder.Append(((TextRenderer)childRenderer).text.ToString()); } String overflowTextMultipleChildren = stringBuilder.ToString(); NUnit.Framework.Assert.AreEqual(splitTextOneChild, splitTextMultipleChildren); NUnit.Framework.Assert.AreEqual(overflowTextOneChild, overflowTextMultipleChildren); }
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); } } } }
// 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); 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); } } } }