iTextSharp.text.Table.MergeInsertedTables C# (CSharp) Method

MergeInsertedTables() private method

Integrates all added tables and recalculates column widths.
private MergeInsertedTables ( ) : void
return void
        private void MergeInsertedTables() {
            int i=0, j=0;
            float [] lNewWidths = null;
            int [] lDummyWidths = new int[columns];     // to keep track in how many new cols this one will be split
            float[][] lDummyColumnWidths = new float[columns][]; // bugfix Tony Copping
            int [] lDummyHeights = new int[rows.Count]; // to keep track in how many new rows this one will be split
            ArrayList newRows = null;
            bool isTable=false;
            int lTotalRows  = 0, lTotalColumns      = 0;
            int lNewMaxRows = 0, lNewMaxColumns     = 0;
            
            Table lDummyTable = null;
            
            // first we'll add new columns when needed
            // check one column at a time, find maximum needed nr of cols
            // Search internal tables and find one with max columns
            for (j=0; j < columns; j++) {
                lNewMaxColumns = 1; // value to hold in how many columns the current one will be split
                float [] tmpWidths = null;
                for (i=0; i < rows.Count; i++) {
                    if (((Row) rows[i]).GetCell(j) is Table) {
                        isTable=true;
                        lDummyTable = ((Table) ((Row) rows[i]).GetCell(j));
                        if ( tmpWidths == null) {
                            tmpWidths = lDummyTable.widths;
                            lNewMaxColumns=tmpWidths.Length;
                        }
                        else {
                            int cols = lDummyTable.Dimension.width;
                            float [] tmpWidthsN = new float[ cols * tmpWidths.Length];
                            float tpW=0, btW=0, totW=0;
                            int tpI=0, btI=0, totI=0;
                            tpW+=tmpWidths[0];
                            btW+=lDummyTable.widths[0];
                            while ( tpI<tmpWidths.Length && btI<cols) {
                                if ( btW>tpW) {
                                    tmpWidthsN[totI] = tpW-totW;
                                    tpI++;
                                    if (tpI<tmpWidths.Length) {
                                        tpW+=tmpWidths[tpI];
                                    }
                                }
                                else {
                                    tmpWidthsN[totI] = btW-totW;
                                    btI++;
                                    if (Math.Abs(btW - tpW) < 0.0001) {
                                        tpI++;
                                        if (tpI<tmpWidths.Length) {
                                            tpW+=tmpWidths[tpI];
                                        }
                                    }
                                    if (btI<cols) {
                                        btW+=lDummyTable.widths[btI];
                                    }
                                }
                                totW+=tmpWidthsN[totI];
                                totI++;
                            }
                            tmpWidths = new float[totI];
                            Array.Copy(tmpWidthsN, 0, tmpWidths, 0, totI);
                            lNewMaxColumns=totI;
                        }
                    }
                }
                lDummyColumnWidths[j] = tmpWidths;
                lTotalColumns += lNewMaxColumns;
                lDummyWidths [j] = lNewMaxColumns;
            }
            
            // next we'll add new rows when needed
            for (i=0; i < rows.Count; i++) {
                lNewMaxRows = 1;    // holds value in how many rows the current one will be split
                for (j=0; j < columns; j++) {
                    if (((Row) rows[i]).GetCell(j) is Table ) {
                        isTable=true;
                        lDummyTable = (Table) ((Row) rows[i]).GetCell(j);
                        if ( lDummyTable.Dimension.height > lNewMaxRows ) {
                            lNewMaxRows = lDummyTable.Dimension.height;
                        }
                    }
                }
                lTotalRows += lNewMaxRows;
                lDummyHeights [i] = lNewMaxRows;
            }
            
            if ( (lTotalColumns != columns) || (lTotalRows != rows.Count) || isTable)    // NO ADJUSTMENT
            {
                // ** WIDTH
                // set correct width for new columns
                // divide width over new nr of columns
                // Take new max columns of internal table and work out widths for each col
                lNewWidths = new float [lTotalColumns];
                int lDummy = 0;
                for (int tel=0; tel < widths.Length;tel++) {
                    if ( lDummyWidths[tel] != 1) {
                        // divide
                        for (int tel2 = 0; tel2 < lDummyWidths[tel]; tel2++) {
                            lNewWidths[lDummy] = widths[tel] * lDummyColumnWidths[tel][tel2] / 100f; // bugfix Tony Copping
                            lDummy++;
                        }
                    }
                    else {
                        lNewWidths[lDummy] = widths[tel];
                        lDummy++;
                    }
                }
                
                // ** FILL OUR NEW TABLE
                // generate new table
                // set new widths
                // copy old values
                newRows = new ArrayList(lTotalRows);
                for (i = 0; i < lTotalRows; i++) {
                    newRows.Add(new Row(lTotalColumns));
                }
                int lDummyRow = 0, lDummyColumn = 0;        // to remember where we are in the new, larger table
                Object lDummyElement = null;
                for (i=0; i < rows.Count; i++) {
                    lDummyColumn = 0;
                    lNewMaxRows = 1;
                    for (j=0; j < columns; j++) {
                        if (((Row) rows[i]).GetCell(j) is Table )       // copy values from embedded table
                        {
                            lDummyTable = (Table) ((Row) rows[i]).GetCell(j);
                            
                            // Work out where columns in table table correspond to columns in current table
                            int[] colMap = new int[lDummyTable.widths.Length+1];
                            int cb=0, ct=0;
                            
                            for ( ; cb<lDummyTable.widths.Length;cb++) {
                                colMap[cb] = lDummyColumn+ct;
                                
                                float wb;
                                wb = lDummyTable.widths[cb];
                                
                                float wt=0;
                                while ( ct<lDummyWidths[j]) {
                                    wt+=lDummyColumnWidths[j][ct++];
                                    if (Math.Abs(wb - wt) < 0.0001) break;
                                }
                            }
                            colMap[cb] = lDummyColumn+ct;
                            
                            // need to change this to work out how many cols to span
                            for (int k=0; k < lDummyTable.Dimension.height; k++) {
                                for (int l=0; l < lDummyTable.Dimension.width; l++) {
                                    lDummyElement = lDummyTable.GetElement(k,l);
                                    if (lDummyElement != null) {
                                        int col=lDummyColumn+l;
                                        
                                        if (lDummyElement is Cell) {
                                            Cell lDummyC = (Cell)lDummyElement;
                                            // Find col to add cell in and set col span
                                            col = colMap[l];
                                            int ot = colMap[l+lDummyC.Colspan];
                                            
                                            lDummyC.Colspan = ot-col;
                                        }
                                        
                                        ((Row) newRows[k + lDummyRow]).AddElement(lDummyElement,col);  // use addElement to set reserved status ok in row
                                    }
                                }
                            }
                        }
                        else        // copy others values
                        {
                            Object aElement = GetElement(i,j);
                            
                            if (aElement is Cell) {
                                
                                // adjust spans for cell
                                ((Cell) aElement).Rowspan = ((Cell) ((Row) rows[i]).GetCell(j)).Rowspan + lDummyHeights[i] - 1;
                                ((Cell) aElement).Colspan = ((Cell) ((Row) rows[i]).GetCell(j)).Colspan + lDummyWidths[j] - 1;
                                
                                // most likely this cell covers a larger area because of the row/cols splits : define not-to-be-filled cells
                                PlaceCell(newRows,((Cell) aElement), new System.Drawing.Point(lDummyRow,lDummyColumn));
                            }
                        }
                        lDummyColumn += lDummyWidths[j];
                    }
                    lDummyRow += lDummyHeights[i];
                }
                
                // Set our new matrix
                columns     = lTotalColumns;
                rows = newRows;
                this.widths = lNewWidths;
            }
        }