Skip to content

Commit 1371435

Browse files
BezrukovMiText-CI
authored andcommitted
KeepTogether disable for not fit in keepTogether tree fix
DEVSIX-3468 Autoported commit. Original commit hash: [91bea8fa7]
1 parent 94c2547 commit 1371435

10 files changed

+90
-56
lines changed

itext.tests/itext.layout.tests/itext/layout/KeepTogetherTest.cs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -780,9 +780,9 @@ public virtual void SmallFloatInsideKeptTogetherTableTest02() {
780780
}
781781

782782
[NUnit.Framework.Test]
783-
[LogMessage(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, Count = 2)]
784-
public virtual void ContentOverlappingInDivWithKeepTogetherTest() {
785-
String filename = "contentOverlappingInDivWithKeepTogether.pdf";
783+
[LogMessage(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA)]
784+
public virtual void KeepTogetherTreeWithParentNotFitOnDocumentTest() {
785+
String filename = "keepTogetherTreeWithParentNotFitOnDocument.pdf";
786786
String outFile = destinationFolder + filename;
787787
String cmpFileName = sourceFolder + "cmp_" + filename;
788788
using (Document doc = new Document(new PdfDocument(new PdfWriter(outFile)))) {
@@ -803,9 +803,9 @@ public virtual void ContentOverlappingInDivWithKeepTogetherTest() {
803803
}
804804

805805
[NUnit.Framework.Test]
806-
[LogMessage(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, Count = 2)]
807-
public virtual void MissContentAndOverlappingInDivNoKeepTogetherTest() {
808-
String filename = "missContentAndOverlappingInDivNoKeepTogether.pdf";
806+
[LogMessage(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA)]
807+
public virtual void KeepTogetherSubTreeWithParentNotFitOnDocumentTest() {
808+
String filename = "keepTogetherSubTreeWithParentNotFitOnDocument.pdf";
809809
String outFile = destinationFolder + filename;
810810
String cmpFileName = sourceFolder + "cmp_" + filename;
811811
using (Document doc = new Document(new PdfDocument(new PdfWriter(outFile)))) {
@@ -827,9 +827,33 @@ public virtual void MissContentAndOverlappingInDivNoKeepTogetherTest() {
827827
}
828828

829829
[NUnit.Framework.Test]
830-
[LogMessage(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, Count = 2)]
831-
public virtual void ContentOverlappingDivKeepTogetherInRectTest() {
832-
String filename = "contentOverlappingDivKeepTogetherInRect.pdf";
830+
[LogMessage(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA)]
831+
public virtual void KeepTogetherSubTreeWithChildKeepTogetherFalseAndParentNotFitOnDocumentTest() {
832+
String filename = "keepTogetherSubTreeWithChildKeepTogetherFalseAndParentNotFitOnDocument.pdf";
833+
String outFile = destinationFolder + filename;
834+
String cmpFileName = sourceFolder + "cmp_" + filename;
835+
using (Document doc = new Document(new PdfDocument(new PdfWriter(outFile)))) {
836+
doc.GetPdfDocument().AddNewPage(PageSize.A5.Rotate());
837+
Div main = new Div();
838+
Div child1 = CreateChildDivWithText(main, null).SetKeepTogether(true);
839+
CreateChildDivWithText(child1, BIG_TEXT);
840+
Div div1_2 = CreateChildDivWithText(child1, null).SetKeepTogether(false);
841+
CreateChildDivWithText(div1_2, "Section A");
842+
CreateChildDivWithText(div1_2, null).Add(new Paragraph(MEDIUM_TEXT).SetFirstLineIndent(20));
843+
// KEEP_TOGETHER is not set here
844+
Div child2 = CreateChildDivWithText(main, null);
845+
CreateChildDivWithText(child2, "Section B");
846+
CreateChildDivWithText(child2, null);
847+
CreateChildDivWithText(child2, "Lorem ipsum dolor sit amet!");
848+
doc.Add(main);
849+
}
850+
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFile, cmpFileName, destinationFolder));
851+
}
852+
853+
[NUnit.Framework.Test]
854+
[LogMessage(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA)]
855+
public virtual void KeepTogetherTreeWithParentNotFitOnPageCanvasTest() {
856+
String filename = "keepTogetherTreeWithParentNotFitOnPageCanvas.pdf";
833857
String outFile = destinationFolder + filename;
834858
String cmpFileName = sourceFolder + "cmp_" + filename;
835859
using (PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFile))) {

itext/itext.layout/itext/layout/renderer/RootRenderer.cs

Lines changed: 56 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -163,53 +163,19 @@ public override void AddChild(IRenderer renderer) {
163163
}
164164
else {
165165
if (currentArea.IsEmptyArea() && result.GetAreaBreak() == null) {
166-
if (true.Equals(result.GetOverflowRenderer().GetModelElement().GetProperty<bool?>(Property.KEEP_TOGETHER))
167-
) {
168-
result.GetOverflowRenderer().GetModelElement().SetProperty(Property.KEEP_TOGETHER, false);
169-
ILog logger = LogManager.GetLogger(typeof(RootRenderer));
170-
logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "KeepTogether property will be ignored."
171-
));
172-
if (!rendererIsFloat) {
173-
rootRendererStateHandler.AttemptGoBackToStoredPreviousStateAndStoreNextState(this);
174-
}
166+
bool keepTogetherChanged = TryDisableKeepTogether(result, rendererIsFloat, rootRendererStateHandler);
167+
bool areKeepTogetherAndForcedPlacementBothNotChanged = !keepTogetherChanged;
168+
if (areKeepTogetherAndForcedPlacementBothNotChanged) {
169+
areKeepTogetherAndForcedPlacementBothNotChanged = !UpdateForcedPlacement(renderer, result.GetOverflowRenderer
170+
());
175171
}
176-
else {
177-
if (null != result.GetCauseOfNothing() && true.Equals(result.GetCauseOfNothing().GetProperty<bool?>(Property
178-
.KEEP_TOGETHER))) {
179-
// set KEEP_TOGETHER false on the deepest parent (maybe the element itself) to have KEEP_TOGETHER == true
180-
IRenderer theDeepestKeptTogether = result.GetCauseOfNothing();
181-
IRenderer parent;
182-
while (null == theDeepestKeptTogether.GetModelElement() || null == theDeepestKeptTogether.GetModelElement(
183-
).GetOwnProperty<bool?>(Property.KEEP_TOGETHER)) {
184-
parent = ((AbstractRenderer)theDeepestKeptTogether).parent;
185-
if (parent == null) {
186-
break;
187-
}
188-
theDeepestKeptTogether = parent;
189-
}
190-
theDeepestKeptTogether.GetModelElement().SetProperty(Property.KEEP_TOGETHER, false);
191-
ILog logger = LogManager.GetLogger(typeof(RootRenderer));
192-
logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "KeepTogether property of inner element will be ignored."
193-
));
194-
if (!rendererIsFloat) {
195-
rootRendererStateHandler.AttemptGoBackToStoredPreviousStateAndStoreNextState(this);
196-
}
197-
}
198-
else {
199-
if (!true.Equals(renderer.GetProperty<bool?>(Property.FORCED_PLACEMENT))) {
200-
result.GetOverflowRenderer().SetProperty(Property.FORCED_PLACEMENT, true);
201-
ILog logger = LogManager.GetLogger(typeof(RootRenderer));
202-
logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, ""));
203-
}
204-
else {
205-
// FORCED_PLACEMENT was already set to the renderer and
206-
// LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA message was logged.
207-
// This else-clause should never be hit, otherwise there is a bug in FORCED_PLACEMENT implementation.
208-
System.Diagnostics.Debug.Assert(false);
209-
// Still handling this case in order to avoid nasty infinite loops.
210-
break;
211-
}
212-
}
172+
if (areKeepTogetherAndForcedPlacementBothNotChanged) {
173+
// FORCED_PLACEMENT was already set to the renderer and
174+
// LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA message was logged.
175+
// This else-clause should never be hit, otherwise there is a bug in FORCED_PLACEMENT implementation.
176+
System.Diagnostics.Debug.Assert(false);
177+
// Still handling this case in order to avoid nasty infinite loops.
178+
break;
213179
}
214180
}
215181
else {
@@ -520,5 +486,49 @@ private void AddWaitingNextPageRenderers() {
520486
AddChild(renderer);
521487
}
522488
}
489+
490+
private bool UpdateForcedPlacement(IRenderer currentRenderer, IRenderer overflowRenderer) {
491+
if (true.Equals(currentRenderer.GetProperty<bool?>(Property.FORCED_PLACEMENT))) {
492+
return false;
493+
}
494+
else {
495+
overflowRenderer.SetProperty(Property.FORCED_PLACEMENT, true);
496+
ILog logger = LogManager.GetLogger(typeof(RootRenderer));
497+
if (logger.IsWarnEnabled) {
498+
logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, ""));
499+
}
500+
return true;
501+
}
502+
}
503+
504+
private bool TryDisableKeepTogether(LayoutResult result, bool rendererIsFloat, RootRendererAreaStateHandler
505+
rootRendererStateHandler) {
506+
IRenderer toDisableKeepTogether = null;
507+
// looking for the most outer keep together element
508+
IRenderer current = result.GetCauseOfNothing();
509+
while (current != null) {
510+
if (true.Equals(current.GetProperty<bool?>(Property.KEEP_TOGETHER))) {
511+
toDisableKeepTogether = current;
512+
}
513+
current = current.GetParent();
514+
}
515+
if (toDisableKeepTogether == null) {
516+
return false;
517+
}
518+
// Ideally the disabling of keep together property should be done on the renderers layer,
519+
// but due to the problem with renderers tree (parent links from causeOfNothing
520+
// may not lead to overflowRenderer) such approach does not work now. So we
521+
// disabling keep together on the models layer.
522+
toDisableKeepTogether.GetModelElement().SetProperty(Property.KEEP_TOGETHER, false);
523+
ILog logger = LogManager.GetLogger(typeof(RootRenderer));
524+
if (logger.IsWarnEnabled) {
525+
logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "KeepTogether property will be ignored."
526+
));
527+
}
528+
if (!rendererIsFloat) {
529+
rootRendererStateHandler.AttemptGoBackToStoredPreviousStateAndStoreNextState(this);
530+
}
531+
return true;
532+
}
523533
}
524534
}

port-hash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
451ef20ef4a4d0eabe9ad2184dab4b746c37fa3f
1+
91bea8fa7cbe39088fe8761c5eb979eb1c5947d2

0 commit comments

Comments
 (0)