private void ApplyListSymbolPosition() { if (symbolRenderer != null) { ListSymbolPosition symbolPosition = (ListSymbolPosition)ListRenderer.GetListItemOrListProperty(this, parent , Property.LIST_SYMBOL_POSITION); if (symbolPosition == ListSymbolPosition.INSIDE) { if (childRenderers.Count > 0 && childRenderers[0] is ParagraphRenderer) { ParagraphRenderer paragraphRenderer = (ParagraphRenderer)childRenderers[0]; float? symbolIndent = this.GetPropertyAsFloat(Property.LIST_SYMBOL_INDENT); if (symbolIndent != null) { symbolRenderer.SetProperty(Property.MARGIN_RIGHT, UnitValue.CreatePointValue((float)symbolIndent)); } paragraphRenderer.childRenderers.Add(0, symbolRenderer); symbolAddedInside = true; } else { if (childRenderers.Count > 0 && childRenderers[0] is ImageRenderer) { Paragraph p = new Paragraph(); p.GetAccessibilityProperties().SetRole(null); IRenderer paragraphRenderer = p.SetMargin(0).CreateRendererSubTree(); float? symbolIndent = this.GetPropertyAsFloat(Property.LIST_SYMBOL_INDENT); if (symbolIndent != null) { symbolRenderer.SetProperty(Property.MARGIN_RIGHT, UnitValue.CreatePointValue((float)symbolIndent)); } paragraphRenderer.AddChild(symbolRenderer); paragraphRenderer.AddChild(childRenderers[0]); childRenderers[0] = paragraphRenderer; symbolAddedInside = true; } } if (!symbolAddedInside) { Paragraph p = new Paragraph(); p.GetAccessibilityProperties().SetRole(null); IRenderer paragraphRenderer = p.SetMargin(0).CreateRendererSubTree(); float? symbolIndent = this.GetPropertyAsFloat(Property.LIST_SYMBOL_INDENT); if (symbolIndent != null) { symbolRenderer.SetProperty(Property.MARGIN_RIGHT, UnitValue.CreatePointValue((float)symbolIndent)); } paragraphRenderer.AddChild(symbolRenderer); childRenderers.Add(0, paragraphRenderer); symbolAddedInside = true; } } } }
public virtual void ParagraphRendererAddByIDTest() { DocumentRenderer documentRenderer = new DocumentRenderer(null); ParagraphRenderer paragraphRenderer = new ParagraphRenderer(new Paragraph()); paragraphRenderer.SetParent(documentRenderer); String id = "id5"; paragraphRenderer.SetProperty(Property.ID, id); LayoutContext layoutContext = new LayoutContext(new LayoutArea(4, new Rectangle(50, 50))); paragraphRenderer.Layout(layoutContext); documentRenderer.GetTargetCounterHandler().PrepareHandlerToRelayout(); NUnit.Framework.Assert.AreEqual((int?)4, TargetCounterHandler.GetPageByID(paragraphRenderer, id)); }
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)); } }
private static OrphansWidowsLayoutHelper.OrphansWidowsLayoutAttempt AttemptLayout(ParagraphRenderer renderer , LayoutContext originalContext, LayoutArea attemptArea) { OrphansWidowsLayoutHelper.OrphansWidowsLayoutAttempt attemptResult = new OrphansWidowsLayoutHelper.OrphansWidowsLayoutAttempt (); MarginsCollapseInfo copiedMarginsCollapseInfo = null; if (originalContext.GetMarginsCollapseInfo() != null) { copiedMarginsCollapseInfo = MarginsCollapseInfo.CreateDeepCopy(originalContext.GetMarginsCollapseInfo()); } List <Rectangle> attemptFloatRectsList = new List <Rectangle>(originalContext.GetFloatRendererAreas()); LayoutContext attemptContext = new LayoutContext(attemptArea, copiedMarginsCollapseInfo, attemptFloatRectsList , originalContext.IsClippedHeight()); attemptResult.attemptContext = attemptContext; attemptResult.attemptResult = renderer.DirectLayout(attemptContext); return(attemptResult); }
private void ApplyListSymbolPosition() { if (symbolRenderer != null) { ListSymbolPosition symbolPosition = (ListSymbolPosition)ListRenderer.GetListItemOrListProperty(this, parent , Property.LIST_SYMBOL_POSITION); if (symbolPosition == ListSymbolPosition.INSIDE) { bool isRtl = BaseDirection.RIGHT_TO_LEFT.Equals(this.GetProperty <BaseDirection?>(Property.BASE_DIRECTION)); if (childRenderers.Count > 0 && childRenderers[0] is ParagraphRenderer) { ParagraphRenderer paragraphRenderer = (ParagraphRenderer)childRenderers[0]; float? symbolIndent = this.GetPropertyAsFloat(Property.LIST_SYMBOL_INDENT); if (symbolRenderer is LineRenderer) { if (symbolIndent != null) { symbolRenderer.GetChildRenderers()[1].SetProperty(isRtl ? Property.MARGIN_LEFT : Property.MARGIN_RIGHT, UnitValue .CreatePointValue((float)symbolIndent)); } foreach (IRenderer childRenderer in symbolRenderer.GetChildRenderers()) { paragraphRenderer.childRenderers.Add(0, childRenderer); } } else { if (symbolIndent != null) { symbolRenderer.SetProperty(isRtl ? Property.MARGIN_LEFT : Property.MARGIN_RIGHT, UnitValue.CreatePointValue ((float)symbolIndent)); } paragraphRenderer.childRenderers.Add(0, symbolRenderer); } symbolAddedInside = true; } else { if (childRenderers.Count > 0 && childRenderers[0] is ImageRenderer) { Paragraph p = new Paragraph(); p.GetAccessibilityProperties().SetRole(null); IRenderer paragraphRenderer = p.SetMargin(0).CreateRendererSubTree(); float? symbolIndent = this.GetPropertyAsFloat(Property.LIST_SYMBOL_INDENT); if (symbolIndent != null) { symbolRenderer.SetProperty(Property.MARGIN_RIGHT, UnitValue.CreatePointValue((float)symbolIndent)); } paragraphRenderer.AddChild(symbolRenderer); paragraphRenderer.AddChild(childRenderers[0]); childRenderers[0] = paragraphRenderer; symbolAddedInside = true; } } if (!symbolAddedInside) { Paragraph p = new Paragraph(); p.GetAccessibilityProperties().SetRole(null); IRenderer paragraphRenderer = p.SetMargin(0).CreateRendererSubTree(); float? symbolIndent = this.GetPropertyAsFloat(Property.LIST_SYMBOL_INDENT); if (symbolIndent != null) { symbolRenderer.SetProperty(Property.MARGIN_RIGHT, UnitValue.CreatePointValue((float)symbolIndent)); } paragraphRenderer.AddChild(symbolRenderer); childRenderers.Add(0, paragraphRenderer); symbolAddedInside = true; } } } }