@@ -43,6 +43,7 @@ This file is part of the iText (R) project.
43
43
package com .itextpdf .layout .renderer ;
44
44
45
45
import com .itextpdf .io .LogMessageConstant ;
46
+ import com .itextpdf .io .util .ArrayUtil ;
46
47
import com .itextpdf .layout .border .Border ;
47
48
import com .itextpdf .layout .element .Table ;
48
49
import com .itextpdf .layout .minmaxwidth .MinMaxWidthUtils ;
@@ -94,11 +95,12 @@ float[] autoLayout(float[] minWidths, float[] maxWidths) {
94
95
95
96
//region Process cells
96
97
97
- boolean [] minColumns = new boolean [numberOfColumns ];
98
98
for (CellInfo cell : cells ) {
99
- //NOTE in automatic layout algorithm percents have higher priority
100
- UnitValue cellWidth = cell .getWidth ();
101
- if (cellWidth != null && cellWidth .getValue () >= 0 ) {
99
+ // For automatic layout algorithm percents have higher priority
100
+ // value must be > 0, while for fixed layout >= 0
101
+ UnitValue cellWidth = getCellWidth (cell .getCell (), false );
102
+ if (cellWidth != null ) {
103
+ assert cellWidth .getValue () > 0 ;
102
104
if (cellWidth .isPercentValue ()) {
103
105
//cellWidth has percent value
104
106
if (cell .getColspan () == 1 ) {
@@ -132,50 +134,57 @@ float[] autoLayout(float[] minWidths, float[] maxWidths) {
132
134
}
133
135
} else {
134
136
//cellWidth has point value
135
- if (cell .getCol () == 1 ) {
137
+ if (cell .getColspan () == 1 ) {
136
138
if (!widths [cell .getCol ()].isPercent ) {
137
- widths [cell .getCol ()].setPoints (cellWidth .getValue ()).setFixed (true );
138
- if (widths [cell .getCol ()].hasCollision ()) {
139
- minColumns [cell .getCol ()] = true ;
139
+ if (widths [cell .getCol ()].min <= cellWidth .getValue ()) {
140
+ widths [cell .getCol ()].setPoints (cellWidth .getValue ()).setFixed (true );
141
+ } else {
142
+ widths [cell .getCol ()].setPoints (widths [cell .getCol ()].min );
140
143
}
141
144
}
142
145
} else {
143
146
int flexibleCols = 0 ;
144
- float colspanRemain = cellWidth .getValue ();
147
+ float remainWidth = cellWidth .getValue ();
145
148
for (int i = cell .getCol (); i < cell .getCol () + cell .getColspan (); i ++) {
146
149
if (!widths [i ].isPercent ) {
147
- colspanRemain -= widths [i ].width ;
148
- if (!widths [i ].isFixed ){
150
+ remainWidth -= widths [i ].width ;
151
+ if (!widths [i ].isFixed ) {
149
152
flexibleCols ++;
150
153
}
151
154
} else {
152
- colspanRemain = -1 ;
155
+ // if any col has percent value, we cannot predict remaining width.
156
+ remainWidth = 0 ;
153
157
break ;
154
158
}
155
159
}
156
- if (colspanRemain > 0 ) {
160
+ if (remainWidth > 0 ) {
161
+ int [] flexibleColIndexes = ArrayUtil .fillWithValue (new int [cell .getColspan ()], -1 );
157
162
if (flexibleCols > 0 ) {
158
163
// check min width in columns
159
164
for (int i = cell .getCol (); i < cell .getCol () + cell .getColspan (); i ++) {
160
- if (widths [i ].isFlexible () && widths [i ].checkCollision (colspanRemain / flexibleCols )) {
161
- widths [i ].setPoints (widths [i ].min ).setFixed (true );
162
- colspanRemain -= widths [i ].min ;
165
+ if (!widths [i ].isFlexible ())
166
+ continue ;
167
+ if (widths [i ].min > widths [i ].width + remainWidth / flexibleCols ) {
168
+ widths [i ].resetPoints (widths [i ].min );
169
+ remainWidth -= widths [i ].min - widths [i ].width ;
163
170
flexibleCols --;
164
- if (colspanRemain <= 0 || flexibleCols <= 0 ) {
171
+ if (flexibleCols == 0 || remainWidth <= 0 ) {
165
172
break ;
166
173
}
174
+ } else {
175
+ flexibleColIndexes [i - cell .getCol ()] = i ;
167
176
}
168
177
}
169
- if (colspanRemain > 0 && flexibleCols > 0 ) {
170
- for (int k = cell . getCol (); k < cell . getCol () + cell . getColspan (); k ++) {
171
- if (widths [ k ]. isFlexible () ) {
172
- widths [k ] .addPoints (colspanRemain / flexibleCols ).setFixed (true );
178
+ if (flexibleCols > 0 && remainWidth > 0 ) {
179
+ for (int i = 0 ; i < flexibleColIndexes . length ; i ++) {
180
+ if (flexibleColIndexes [ i ] >= 0 ) {
181
+ widths [flexibleColIndexes [ i ]] .addPoints (remainWidth / flexibleCols ).setFixed (true );
173
182
}
174
183
}
175
184
}
176
185
} else {
177
186
for (int i = cell .getCol (); i < cell .getCol () + cell .getColspan (); i ++) {
178
- widths [i ].addPoints (colspanRemain / cell .getColspan ());
187
+ widths [i ].addPoints (remainWidth / cell .getColspan ());
179
188
}
180
189
}
181
190
}
@@ -200,12 +209,6 @@ float[] autoLayout(float[] minWidths, float[] maxWidths) {
200
209
}
201
210
}
202
211
}
203
- for (int col = 0 ; col < minColumns .length ; col ++) {
204
- if (minColumns [col ] && !widths [col ].isPercent && widths [col ].isFixed && widths [col ].hasCollision ()) {
205
- minSum += widths [col ].min - widths [col ].width ;
206
- widths [col ].setPoints (widths [col ].min );
207
- }
208
- }
209
212
210
213
//endregion
211
214
@@ -445,11 +448,16 @@ float[] fixedLayout() {
445
448
if (columnWidths [i ] == -1 ) {
446
449
CellRenderer cell = firtsRow [i ];
447
450
if (cell != null ) {
448
- Float cellWidth = cell .retrieveUnitValue (tableWidth , Property .WIDTH );
449
- if (cellWidth != null && cellWidth >= 0 ) {
451
+ UnitValue cellWidth = getCellWidth (cell , true );
452
+ if (cellWidth != null ) {
453
+ assert cellWidth .getValue () >= 0 ;
454
+ float width = cellWidth .getValue ();
455
+ if (cellWidth .isPercentValue ()) {
456
+ width = tableWidth * width / 100 ;
457
+ }
450
458
int colspan = cell .getModelElement ().getColspan ();
451
459
for (int j = 0 ; j < colspan ; j ++) {
452
- columnWidths [i + j ] = ( float ) cellWidth / colspan ;
460
+ columnWidths [i + j ] = width / colspan ;
453
461
}
454
462
remainWidth -= columnWidths [i ];
455
463
processedColumns ++;
@@ -618,11 +626,13 @@ private static class ColumnWidthData {
618
626
619
627
ColumnWidthData setPoints (float width ) {
620
628
assert !isPercent ;
629
+ assert this .min <= width ;
621
630
this .width = Math .max (this .width , width );
622
631
return this ;
623
632
}
624
633
625
634
ColumnWidthData resetPoints (float width ) {
635
+ assert this .min <= width ;
626
636
this .width = width ;
627
637
this .isPercent = false ;
628
638
return this ;
@@ -673,12 +683,12 @@ boolean hasCollision() {
673
683
/**
674
684
* Check collusion between min value and available point width.
675
685
*
676
- * @param availableWidth additional available point width.
686
+ * @param additional additional available point width.
677
687
* @return true, if {@link #min} greater than ({@link #width} + additionalWidth).
678
688
*/
679
- boolean checkCollision (float availableWidth ) {
689
+ boolean checkCollision (float additional ) {
680
690
assert !isPercent ;
681
- return min > width + availableWidth ;
691
+ return min > width + additional ;
682
692
}
683
693
684
694
@ Override
@@ -692,6 +702,27 @@ public String toString() {
692
702
}
693
703
}
694
704
705
+ //TODO DEVSIX-1174, box-sizing property
706
+ UnitValue getCellWidth (CellRenderer cell , boolean zeroIsValid ) {
707
+ UnitValue widthValue = cell .<UnitValue >getProperty (Property .WIDTH );
708
+ if (widthValue == null || widthValue .getValue () < 0 ) return null ;
709
+ if (!zeroIsValid && widthValue .getValue () == 0 ) return null ;
710
+ if (widthValue == null || widthValue .isPercentValue ()) {
711
+ return widthValue ;
712
+ } else {
713
+ Border [] borders = cell .getBorders ();
714
+ if (borders [1 ] != null ) {
715
+ widthValue .setValue (widthValue .getValue () + borders [1 ].getWidth () / 2 );
716
+ }
717
+ if (borders [3 ] != null ) {
718
+ widthValue .setValue (widthValue .getValue () + borders [3 ].getWidth () / 2 );
719
+ }
720
+ float [] paddings = cell .getPaddings ();
721
+ widthValue .setValue (widthValue .getValue () + paddings [1 ] + paddings [3 ]);
722
+ return widthValue ;
723
+ }
724
+ }
725
+
695
726
private static class CellInfo implements Comparable <CellInfo > {
696
727
static final byte HEADER = 1 ;
697
728
static final byte BODY = 2 ;
@@ -725,25 +756,6 @@ int getRowspan() {
725
756
return cell .getModelElement ().getRowspan ();
726
757
}
727
758
728
- //TODO DEVSIX-1057, DEVSIX-1021
729
- UnitValue getWidth () {
730
- UnitValue widthValue = cell .<UnitValue >getProperty (Property .WIDTH );
731
- if (widthValue == null || widthValue .isPercentValue ()) {
732
- return widthValue ;
733
- } else {
734
- Border [] borders = cell .getBorders ();
735
- if (borders [1 ] != null ) {
736
- widthValue .setValue (widthValue .getValue () + borders [1 ].getWidth () / 2 );
737
- }
738
- if (borders [3 ] != null ) {
739
- widthValue .setValue (widthValue .getValue () + borders [3 ].getWidth () / 2 );
740
- }
741
- float [] paddings = cell .getPaddings ();
742
- widthValue .setValue (widthValue .getValue () + paddings [1 ] + paddings [3 ]);
743
- return widthValue ;
744
- }
745
- }
746
-
747
759
@ Override
748
760
public int compareTo (CellInfo o ) {
749
761
if (getColspan () == 1 ^ o .getColspan () == 1 ) {
0 commit comments