@@ -23,8 +23,16 @@ This file is part of the iText (R) project.
2323package com .itextpdf .layout .renderer ;
2424
2525import com .itextpdf .io .logs .IoLogMessageConstant ;
26+ import com .itextpdf .kernel .pdf .PdfPage ;
27+ import com .itextpdf .kernel .pdf .canvas .PdfCanvas ;
28+ import com .itextpdf .layout .Document ;
2629import com .itextpdf .layout .element .List ;
27- import com .itextpdf .test .ExtendedITextTest ;
30+ import com .itextpdf .layout .element .ListItem ;
31+ import com .itextpdf .layout .element .Paragraph ;
32+ import com .itextpdf .layout .element .Text ;
33+ import com .itextpdf .layout .layout .LayoutResult ;
34+ import com .itextpdf .layout .properties .ListSymbolPosition ;
35+ import com .itextpdf .layout .properties .Property ;
2836import com .itextpdf .test .annotations .LogMessage ;
2937import com .itextpdf .test .annotations .LogMessages ;
3038import com .itextpdf .test .annotations .type .UnitTest ;
@@ -34,7 +42,7 @@ This file is part of the iText (R) project.
3442import org .junit .experimental .categories .Category ;
3543
3644@ Category (UnitTest .class )
37- public class ListRendererUnitTest extends ExtendedITextTest {
45+ public class ListRendererUnitTest extends RendererUnitTest {
3846
3947 @ Test
4048 @ LogMessages (messages = {
@@ -47,4 +55,81 @@ public void getNextRendererShouldBeOverriddenTest() {
4755
4856 Assert .assertEquals (ListRenderer .class , listRenderer .getNextRenderer ().getClass ());
4957 }
58+
59+ @ Test
60+ public void symbolPositioningInsideDrawnOnceTest () {
61+ InvocationsCounter invocationsCounter = new InvocationsCounter ();
62+
63+ List modelElement = new List ();
64+ modelElement .setNextRenderer (new ListRendererCreatingNotifyingListSymbols (modelElement , invocationsCounter ));
65+ modelElement .add ((ListItem ) new ListItem ().add (new Paragraph ("ListItem1" )).add (new Paragraph ("ListItem2" )));
66+ modelElement .setProperty (Property .LIST_SYMBOL_POSITION , ListSymbolPosition .INSIDE );
67+ modelElement .setFontSize (30 );
68+
69+ // A hack for a test in order to layout the list at the very left border of the parent area.
70+ // List symbols are not drawn outside the parent area, so we want to make sure that symbol renderer
71+ // won't be drawn twice even if there's enough space around the list.
72+ modelElement .setMarginLeft (500 );
73+ IRenderer listRenderer = modelElement .createRendererSubTree ();
74+
75+ Document document = createDummyDocument ();
76+ listRenderer .setParent (document .getRenderer ());
77+ PdfPage pdfPage = document .getPdfDocument ().addNewPage ();
78+
79+ // should be enough to fit a single list-item, but not both
80+ int height = 80 ;
81+
82+ // we don't want to impose any width restrictions
83+ int width = 1000 ;
84+ LayoutResult result = listRenderer .layout (createLayoutContext (width , height ));
85+ assert result .getStatus () == LayoutResult .PARTIAL ;
86+ result .getSplitRenderer ().draw (new DrawContext (document .getPdfDocument (), new PdfCanvas (pdfPage )));
87+
88+ // only split part is drawn, list symbol is expected to be drawn only once.
89+ Assert .assertEquals (1 , invocationsCounter .getInvocationsCount ());
90+ }
91+
92+ private static class ListRendererCreatingNotifyingListSymbols extends ListRenderer {
93+ private InvocationsCounter counter ;
94+
95+ public ListRendererCreatingNotifyingListSymbols (List modelElement , InvocationsCounter counter ) {
96+ super (modelElement );
97+ this .counter = counter ;
98+ }
99+
100+ @ Override
101+ protected IRenderer makeListSymbolRenderer (int index , IRenderer renderer ) {
102+ return new NotifyingListSymbolRenderer (new Text ("-" ), counter );
103+ }
104+
105+ @ Override
106+ public IRenderer getNextRenderer () {
107+ return new ListRendererCreatingNotifyingListSymbols ((List ) getModelElement (), counter );
108+ }
109+ }
110+
111+ private static class NotifyingListSymbolRenderer extends TextRenderer {
112+ private InvocationsCounter counter ;
113+
114+ public NotifyingListSymbolRenderer (Text textElement , InvocationsCounter counter ) {
115+ super (textElement );
116+ this .counter = counter ;
117+ }
118+
119+ @ Override
120+ public void draw (DrawContext drawContext ) {
121+ counter .registerInvocation ();
122+ super .draw (drawContext );
123+ }
124+ }
125+
126+ private static class InvocationsCounter {
127+ private int counter = 0 ;
128+ void registerInvocation () {
129+ ++counter ;
130+ }
131+ int getInvocationsCount () {
132+ return counter ;
133+ }
134+ }
50135}
0 commit comments