11using System ;
2- using System . Collections . Concurrent ;
32using System . Collections . Generic ;
4- using System . Diagnostics ;
53using System . Linq ;
64using FossPDF . Drawing ;
7- using FossPDF . Fluent ;
85using FossPDF . Infrastructure ;
96
107namespace FossPDF . Elements . Table
@@ -15,6 +12,10 @@ internal class Table : Element, IStateResettable, IContentDirectionAware
1512
1613 public List < TableColumnDefinition > Columns { get ; set ; } = new ( ) ;
1714 public List < TableCell > Cells { get ; set ; } = new ( ) ;
15+ public List < TableCell > AllCells { get ; set ; } = new ( ) ;
16+ public Dictionary < int , float > ColumnsWidth { get ; set ; } = new ( ) ;
17+ public Action < Dictionary < int , float > > AfterUpdateColumnsWidth { get ; set ; }
18+
1819 public bool ExtendLastCellsToTableBottom { get ; set ; }
1920
2021 private bool CacheInitialized { get ; set ; }
@@ -149,6 +150,15 @@ private int FindLastRenderedRow(ICollection<TableCellRenderingCommand> commands)
149150
150151 private void UpdateColumnsWidth ( float availableWidth )
151152 {
153+ if ( ColumnsWidth . Any ( ) )
154+ {
155+ foreach ( var column in Columns )
156+ {
157+ column . Width = ColumnsWidth [ Columns . IndexOf ( column ) ] ;
158+ }
159+ return ;
160+ }
161+
152162 var constantWidth = Columns . Sum ( x => x . ConstantSize ) ;
153163 var relativeWidth = Columns . Sum ( x => x . RelativeSize ) ;
154164
@@ -158,6 +168,64 @@ private void UpdateColumnsWidth(float availableWidth)
158168 {
159169 column . Width = column . ConstantSize + column . RelativeSize * widthPerRelativeUnit ;
160170 }
171+
172+ var cells = AllCells . Where ( c => c is { ColumnSpan : 1 , RowSpan : 1 } ) ;
173+
174+ foreach ( var column in Columns . Where ( c => c . AllowShrink ) )
175+ {
176+ var index = Columns . IndexOf ( column ) ;
177+ var cellsInColumn = cells . Where ( c => c . Column == index + 1 ) ;
178+ if ( cellsInColumn . Any ( ) )
179+ {
180+ ColumnsWidth . Add ( index , cellsInColumn . Max ( c => c . Measure ( Size . Max ) . Width ) ) ;
181+ column . Width = Math . Min ( column . Width , ColumnsWidth [ index ] ) ;
182+ }
183+ }
184+
185+ var remainingWidth = availableWidth - Columns . Sum ( c => c . Width ) ;
186+ while ( remainingWidth > 0 )
187+ {
188+ var columnsThatGrow = Columns . Where ( c => c . AllowGrow ) . ToList ( ) ;
189+ var growStep = remainingWidth / columnsThatGrow . Count ;
190+ var anyColumnHasGrown = false ;
191+ foreach ( var column in columnsThatGrow )
192+ {
193+ var index = Columns . IndexOf ( column ) ;
194+ var cellsInColumn = cells . Where ( c => c . Column == index + 1 ) ;
195+ if ( ! ColumnsWidth . ContainsKey ( index ) )
196+ {
197+ ColumnsWidth . Add ( index , cellsInColumn . Max ( c => c . Measure ( Size . Max ) . Width ) ) ;
198+ }
199+ var newWidth = Math . Min ( column . Width + growStep , ColumnsWidth [ index ] ) ;
200+ if ( newWidth > column . Width )
201+ {
202+ anyColumnHasGrown = true ;
203+ }
204+ column . Width = newWidth ;
205+ remainingWidth = availableWidth - Columns . Sum ( c => c . Width ) ;
206+ if ( remainingWidth <= 0 )
207+ {
208+ break ;
209+ }
210+ }
211+ if ( ! anyColumnHasGrown )
212+ {
213+ break ;
214+ }
215+ }
216+
217+ if ( remainingWidth > 0 )
218+ {
219+ Columns . Last ( ) . Width += remainingWidth ;
220+ }
221+
222+ foreach ( var column in Columns )
223+ {
224+ // Add missing columns, that don't auto size.
225+ ColumnsWidth [ Columns . IndexOf ( column ) ] = column . Width ;
226+ }
227+
228+ AfterUpdateColumnsWidth ? . Invoke ( ColumnsWidth ) ;
161229 }
162230
163231 private ICollection < TableCellRenderingCommand > PlanLayout ( Size availableSpace )
@@ -309,4 +377,4 @@ float GetCellWidth(TableCell cell)
309377 }
310378 }
311379 }
312- }
380+ }
0 commit comments