From 949516efc01169faab391cdd27156441cf7330e2 Mon Sep 17 00:00:00 2001 From: NewVid Date: Fri, 2 Aug 2019 14:13:15 +0300 Subject: [PATCH 1/3] [Table] Fix error with colspan and rowspan at the same time --- .gitignore | 4 +++- Source/HtmlRenderer/Core/Dom/CssLayoutEngineTable.cs | 11 ++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index ce3a150ad..557e7ee6c 100644 --- a/.gitignore +++ b/.gitignore @@ -107,4 +107,6 @@ _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML -*.DotSettings \ No newline at end of file +*.DotSettings +/.vs +/Source/.vs/HtmlRenderer/v15/Server/sqlite3 diff --git a/Source/HtmlRenderer/Core/Dom/CssLayoutEngineTable.cs b/Source/HtmlRenderer/Core/Dom/CssLayoutEngineTable.cs index 79627161a..bad7ab68e 100644 --- a/Source/HtmlRenderer/Core/Dom/CssLayoutEngineTable.cs +++ b/Source/HtmlRenderer/Core/Dom/CssLayoutEngineTable.cs @@ -268,7 +268,16 @@ private void InsertEmptyBoxes() { if (colcount == realcol) { - rows[i].Boxes.Insert(colcount, new CssSpacingBox(_tableBox, ref cell, currow)); + // Philipp@inbox.ru 2019.08.02 + // if colspan more than one - add count of colspan + // Fix errors with colspan and rowspan at the same time + int insert_colspan = GetColSpan(cell); + + for (int ic = 0; ic < insert_colspan; ic++) + { + rows[i].Boxes.Insert(colcount, new CssSpacingBox(_tableBox, ref cell, currow)); + } + break; } colcount++; From df39c03b4452f2fdca2084401265f00f401701b8 Mon Sep 17 00:00:00 2001 From: Philipp <53603991+XPhilipp@users.noreply.github.com> Date: Fri, 2 Aug 2019 22:33:49 +0300 Subject: [PATCH 2/3] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5a21ca388..a9a41dec7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ HTML Renderer [![Build status](https://ci.appveyor.com/api/projects/status/cm8xpf8ebt3hyi3e)](https://ci.appveyor.com/project/ArthurHub/html-renderer) ============= +P.S. (Modified only for fix error with colspan and rowspan at the same time) ## Help Wanted * Looking for a contributor(s) to take this project forward as I'm unable to continue supporting it. From 4534d9fb7aa79def92c91f0d2dbb3538289eb9a7 Mon Sep 17 00:00:00 2001 From: NewVid Date: Tue, 6 Aug 2019 18:30:19 +0300 Subject: [PATCH 3/3] Change table logic for rowspan and colspan. Impossible to know where real empty box will be, therefore use post "insertes" of empty boxes --- .../Core/Dom/CssLayoutEngineTable.cs | 74 +++++++++++++++---- 1 file changed, 61 insertions(+), 13 deletions(-) diff --git a/Source/HtmlRenderer/Core/Dom/CssLayoutEngineTable.cs b/Source/HtmlRenderer/Core/Dom/CssLayoutEngineTable.cs index bad7ab68e..ba78c3845 100644 --- a/Source/HtmlRenderer/Core/Dom/CssLayoutEngineTable.cs +++ b/Source/HtmlRenderer/Core/Dom/CssLayoutEngineTable.cs @@ -251,43 +251,91 @@ private void InsertEmptyBoxes() int currow = 0; List rows = _bodyrows; + List> insertes = null; + foreach (CssBox row in rows) { for (int k = 0; k < row.Boxes.Count; k++) { CssBox cell = row.Boxes[k]; + + string attr = cell.GetAttribute("id"); + if (!string.IsNullOrEmpty(attr)) + { + int jk = 0; + } + int rowspan = GetRowSpan(cell); int realcol = GetCellRealColumnIndex(row, cell); //Real column of the cell + // Philipp@inbox.ru 2019.08.02-06 + // change logic of rowspan and colspan calculating + int colspan = GetColSpan(cell); for (int i = currow + 1; i < currow + rowspan; i++) { if (rows.Count > i) { - int colcount = 0; - for (int j = 0; j < rows[i].Boxes.Count; j++) + for (int ic = 0; ic < colspan; ic++) { - if (colcount == realcol) + // impossible to know where real empty box will be, therefore use "insertes" + if (insertes == null) { - // Philipp@inbox.ru 2019.08.02 - // if colspan more than one - add count of colspan - // Fix errors with colspan and rowspan at the same time - int insert_colspan = GetColSpan(cell); - - for (int ic = 0; ic < insert_colspan; ic++) + insertes = new List>(); + for (int ii = 0; ii < rows.Count; ii++) { - rows[i].Boxes.Insert(colcount, new CssSpacingBox(_tableBox, ref cell, currow)); + insertes.Add(new SortedList()); } + } + + int append_shift = 0; - break; + for (int d = 0; d < insertes[currow].Count; d++) + { + if (d == insertes[currow].Keys[d]) + append_shift = d + 1; + else + break; } - colcount++; - realcol -= GetColSpan(rows[i].Boxes[j]) - 1; + + insertes[i].Add(realcol + ic + append_shift, new CssSpacingBox(_tableBox, ref cell, currow)); } } } } currow++; } + if (insertes != null) // process insertes of empty boxex, prepared early + { + for (int i = 0; i < rows.Count; i++) + { + int d_prev = 0; + foreach (KeyValuePair kvp in insertes[i]) + { + if (d_prev == (kvp.Key - 1) || kvp.Key == 0) // First empty boxex - just insert + { + rows[i].Boxes.Insert(kvp.Key, kvp.Value); + d_prev = kvp.Key; + } + else + { + // get real index of column for inserts... check boxes + int real_insert_index = kvp.Key; + int min_count = rows[i].Boxes.Count < kvp.Key ? rows[i].Boxes.Count : kvp.Key; + + for (int j = 0; j < min_count; j++) + { + int colspan = GetColSpan(rows[i].Boxes[j]); + real_insert_index -= colspan - 1; + } + // real_insert_index containt real column for empty box in table + rows[i].Boxes.Insert(real_insert_index, kvp.Value); + d_prev = -2; + } + } + } + insertes.Clear(); + insertes = null; + } _tableBox._tableFixed = true; }