From f777baf29db4d2b7f58de79c615d01335e9246c7 Mon Sep 17 00:00:00 2001 From: Dmitry Chubrick Date: Thu, 6 Jun 2024 11:41:46 +0000 Subject: [PATCH] Support row\column span values for cell in the grid DEVSIX-8363 Autoported commit. Original commit hash: [3193c1950] --- .../itext/layout/element/GridContainerTest.cs | 51 ++++++ .../itext/layout/renderer/GridUnitTest.cs | 27 --- .../GridContainerTest/cmp_columnSpanTest.pdf | Bin 0 -> 1395 bytes .../GridContainerTest/cmp_rowSpanTest.pdf | Bin 0 -> 1371 bytes .../itext/layout/properties/Property.cs | 6 +- .../itext/layout/renderer/GridCell.cs | 171 ++++++------------ .../itext/layout/renderer/GridTrackSizer.cs | 1 - port-hash | 2 +- 8 files changed, 115 insertions(+), 143 deletions(-) create mode 100644 itext.tests/itext.layout.tests/resources/itext/layout/GridContainerTest/cmp_columnSpanTest.pdf create mode 100644 itext.tests/itext.layout.tests/resources/itext/layout/GridContainerTest/cmp_rowSpanTest.pdf diff --git a/itext.tests/itext.layout.tests/itext/layout/element/GridContainerTest.cs b/itext.tests/itext.layout.tests/itext/layout/element/GridContainerTest.cs index 215d5976cb..089a3e5f4a 100644 --- a/itext.tests/itext.layout.tests/itext/layout/element/GridContainerTest.cs +++ b/itext.tests/itext.layout.tests/itext/layout/element/GridContainerTest.cs @@ -686,5 +686,56 @@ public virtual void FrColumnsTest() { NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(filename, cmpName, DESTINATION_FOLDER, "diff_" )); } + + [NUnit.Framework.Test] + public virtual void ColumnSpanTest() { + String filename = DESTINATION_FOLDER + "columnSpanTest.pdf"; + String cmpName = SOURCE_FOLDER + "cmp_columnSpanTest.pdf"; + IList templateColumns = new List(); + templateColumns.Add(GridValue.CreatePointValue(100.0f)); + templateColumns.Add(GridValue.CreatePointValue(100.0f)); + templateColumns.Add(GridValue.CreatePointValue(100.0f)); + SolidBorder border = new SolidBorder(ColorConstants.BLUE, 1); + using (Document document = new Document(new PdfDocument(new PdfWriter(filename)))) { + GridContainer grid = new GridContainer(); + grid.SetProperty(Property.GRID_TEMPLATE_COLUMNS, templateColumns); + Paragraph paragraph1 = new Paragraph("One").SetBorder(border); + paragraph1.SetProperty(Property.GRID_COLUMN_START, 1); + paragraph1.SetProperty(Property.GRID_COLUMN_SPAN, 2); + grid.Add(paragraph1); + grid.Add(new Paragraph("Two").SetBorder(border)); + grid.Add(new Paragraph("Three").SetBorder(border)); + grid.Add(new Paragraph("Four").SetBorder(border)); + document.Add(grid); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(filename, cmpName, DESTINATION_FOLDER, "diff_" + )); + } + + [NUnit.Framework.Test] + public virtual void RowSpanTest() { + String filename = DESTINATION_FOLDER + "rowSpanTest.pdf"; + String cmpName = SOURCE_FOLDER + "cmp_rowSpanTest.pdf"; + IList template = new List(); + template.Add(GridValue.CreatePointValue(100.0f)); + template.Add(GridValue.CreatePointValue(100.0f)); + template.Add(GridValue.CreatePointValue(100.0f)); + SolidBorder border = new SolidBorder(ColorConstants.BLUE, 1); + using (Document document = new Document(new PdfDocument(new PdfWriter(filename)))) { + GridContainer grid = new GridContainer(); + grid.SetProperty(Property.GRID_TEMPLATE_COLUMNS, template); + grid.SetProperty(Property.GRID_TEMPLATE_ROWS, template); + Paragraph paragraph1 = new Paragraph("One").SetBorder(border); + paragraph1.SetProperty(Property.GRID_ROW_SPAN, 2); + paragraph1.SetProperty(Property.GRID_ROW_END, 3); + grid.Add(paragraph1); + grid.Add(new Paragraph("Two").SetBorder(border)); + grid.Add(new Paragraph("Three").SetBorder(border)); + grid.Add(new Paragraph("Four").SetBorder(border)); + document.Add(grid); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(filename, cmpName, DESTINATION_FOLDER, "diff_" + )); + } } } diff --git a/itext.tests/itext.layout.tests/itext/layout/renderer/GridUnitTest.cs b/itext.tests/itext.layout.tests/itext/layout/renderer/GridUnitTest.cs index 2c328c4e23..6b6b87a319 100644 --- a/itext.tests/itext.layout.tests/itext/layout/renderer/GridUnitTest.cs +++ b/itext.tests/itext.layout.tests/itext/layout/renderer/GridUnitTest.cs @@ -218,32 +218,5 @@ public virtual void ColumnWithFixedTallCellPackingTest() { NUnit.Framework.Assert.AreEqual(cell5, grid.GetRows()[2][1]); NUnit.Framework.Assert.AreEqual(cell6, grid.GetRows()[0][2]); } - - [NUnit.Framework.Test] - public virtual void ColumnWithTallAndWideCellPackingTest() { - Grid grid = new Grid(3, 3, GridFlow.COLUMN); - GridCell cell1 = new GridCell(new TextRenderer(new Text("One"))); - GridCell tallCell = new GridCell(new TextRenderer(new Text("Two"))); - tallCell.GetGridArea().SetHeight(2); - GridCell cell3 = new GridCell(new TextRenderer(new Text("Three"))); - GridCell cell4 = new GridCell(new TextRenderer(new Text("Four"))); - cell4.GetGridArea().SetWidth(2); - GridCell cell5 = new GridCell(new TextRenderer(new Text("Five"))); - GridCell cell6 = new GridCell(new TextRenderer(new Text("Six"))); - grid.AddCell(cell1); - grid.AddCell(tallCell); - grid.AddCell(cell3); - grid.AddCell(cell4); - grid.AddCell(cell5); - grid.AddCell(cell6); - NUnit.Framework.Assert.AreEqual(cell1, grid.GetRows()[0][0]); - NUnit.Framework.Assert.AreEqual(tallCell, grid.GetRows()[1][0]); - NUnit.Framework.Assert.AreEqual(tallCell, grid.GetRows()[2][0]); - NUnit.Framework.Assert.AreEqual(cell3, grid.GetRows()[0][1]); - NUnit.Framework.Assert.AreEqual(cell4, grid.GetRows()[1][1]); - NUnit.Framework.Assert.AreEqual(cell4, grid.GetRows()[1][2]); - NUnit.Framework.Assert.AreEqual(cell5, grid.GetRows()[2][1]); - NUnit.Framework.Assert.AreEqual(cell6, grid.GetRows()[0][2]); - } } } diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/GridContainerTest/cmp_columnSpanTest.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/GridContainerTest/cmp_columnSpanTest.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2f27d333e8fa6d88dcec548de480c337ae9d79ac GIT binary patch literal 1395 zcmc&!Yitxn97nVoj+kgDRpNuuaHW@e-Pyw9IiDa-t!bCMS!ZZ^j?Q{d4 zgTbKfSOjN1`Jvu@hg+Y6w>*EYxBu?KuGf8;lVg2PqUzoowxP)UeSPN(yR$$3v3vh2 ze&khqf zU`6Gc2R{A$$dN$p&TsDQer&$K`k98Rqs@K0MwTy~9D8e(o;=I^ko*4Ov5S*C@)wm2 z7ns876O+u1+5YrB2Rl~p5ta9DpGv(jbph?Ex{Iq`L@Nd-8Y3?q45W{rdiv+FrTGJw zCif?ft^G*ecV;26ZZC(xNgUrkgERt((iKfnCm#B9Zf!_n(Q zD+em^v8vCmTY1yw@t+P0bBp7@+JW1c+F|^~yF**P9Gp-iM_+tm&A`m5j~8D%&f?U! zzq~oxS^f1;#c<1`zis*b9pARzi9cVC7BQuCT^Nk+v2ue-$8&x_4F1;+V4)Z|KAhsu^ntVMWJPd^?1FFZ4u93$sWsR literal 0 HcmV?d00001 diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/GridContainerTest/cmp_rowSpanTest.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/GridContainerTest/cmp_rowSpanTest.pdf new file mode 100644 index 0000000000000000000000000000000000000000..915fba7a8be791a9490b182b941edaeb75a9ca90 GIT binary patch literal 1371 zcmc&!Yitx%6c*Z`j5H($(I_!D;HF)g-MM#m?#wRKHQh%kLfg%5r7zZacjnGIWOrsW zGmBl5CX}EEB%*>;!I;Lz02*DB)<@JxOe{nVnpm0`iIsck~}x~`p~|UonOKwJANzeUU7Ee2flM}y!1nJokgBSZ}oZmw)wA?mVMOpTE2HS@#NecspU8B9ACcRbat+3@6W?= z{O+Ij%-H0p=g6vfyr-dmVgL3u+ZR9bSpP)*#QnvOIXFE!IeH;#J^n@EMs$xnF>^w( zKRq>4H*)mRh7UI!`eu0Bj!(WCsXINrq`mirUmN{n4;*{(O2bh5+p8bW^;~WC@BH>s z;rc_vm+pIF>FjZi8fuj?wsI*JYg9)~!=Z*_1DF0J-$7NKM9jef$hJ6yK~NOZe1cdk z1_+gqB(=?=rBK@yieJ(~>G|6#be9U0mC4d@*oEVQ2(XN*-chEfqnk#I z>D?4tBS1lf5)_e)ML}+cfkp@$y?lqM{&zsaGS#9&ttP#j4m$6FsA*9U^g}=Pr8-*^ zsrIgJu(_#qU1B5HN-dimxY-Mi3J^k{dn9NrSS6c+b(UEyfX+?c8dg-p>Na6lsi<@n zB@W4%*;=qmMYXXAv8l@u-%fK|siP}|j~i^BbtB97=tiqy>$mo)V#aY private static readonly bool[] INHERITED_PROPERTIES; - private const int MAX_INHERITED_PROPERTY_ID = 154; + private const int MAX_INHERITED_PROPERTY_ID = 156; static Property() { INHERITED_PROPERTIES = new bool[MAX_INHERITED_PROPERTY_ID + 1]; diff --git a/itext/itext.layout/itext/layout/renderer/GridCell.cs b/itext/itext.layout/itext/layout/renderer/GridCell.cs index f4d18b2562..eeca98dcf5 100644 --- a/itext/itext.layout/itext/layout/renderer/GridCell.cs +++ b/itext/itext.layout/itext/layout/renderer/GridCell.cs @@ -29,39 +29,44 @@ namespace iText.Layout.Renderer { internal class GridCell { private readonly IRenderer value; - private readonly GridCell.IntRectangle gridArea; + private int gridX; - private Rectangle layoutArea = new Rectangle(0.0f, 0.0f, 0.0f, 0.0f); + private int gridY; - private bool isValueFitOnCellArea = true; + private readonly int spanColumn; + + private readonly int spanRow; + + private readonly Rectangle layoutArea = new Rectangle(0.0f, 0.0f, 0.0f, 0.0f); /// Create a grid cell and init value renderer position on a grid based on its properties. /// item renderer internal GridCell(IRenderer value) { this.value = value; - int[] rowValues = InitRowColumnsValues(value.GetProperty(Property.GRID_ROW_START), value.GetProperty - (Property.GRID_ROW_END)); - int height = rowValues[0] == 0 ? 1 : rowValues[1] - rowValues[0]; - int[] columnValues = InitRowColumnsValues(value.GetProperty(Property.GRID_COLUMN_START), value.GetProperty - (Property.GRID_COLUMN_END)); - int width = columnValues[0] == 0 ? 1 : columnValues[1] - columnValues[0]; - gridArea = new GridCell.IntRectangle(columnValues[0] - 1, rowValues[0] - 1, width, height); + int[] rowPlacement = InitAxisPlacement(value.GetProperty(Property.GRID_ROW_START), value.GetProperty + (Property.GRID_ROW_END), value.GetProperty(Property.GRID_ROW_SPAN)); + gridY = rowPlacement[0]; + spanRow = rowPlacement[1]; + int[] columnPlacement = InitAxisPlacement(value.GetProperty(Property.GRID_COLUMN_START), value.GetProperty + (Property.GRID_COLUMN_END), value.GetProperty(Property.GRID_COLUMN_SPAN)); + gridX = columnPlacement[0]; + spanColumn = columnPlacement[1]; } internal virtual int GetColumnStart() { - return gridArea.GetLeft(); + return gridX; } internal virtual int GetColumnEnd() { - return gridArea.GetRight(); + return gridX + spanColumn; } internal virtual int GetRowStart() { - return gridArea.GetBottom(); + return gridY; } internal virtual int GetRowEnd() { - return gridArea.GetTop(); + return gridY + spanRow; } internal virtual int GetStart(Grid.GridOrder order) { @@ -83,11 +88,11 @@ internal virtual int GetEnd(Grid.GridOrder order) { } internal virtual int GetGridHeight() { - return gridArea.GetHeight(); + return spanRow; } internal virtual int GetGridWidth() { - return gridArea.GetWidth(); + return spanColumn; } internal virtual int GetGridSpan(Grid.GridOrder order) { @@ -103,128 +108,68 @@ internal virtual IRenderer GetValue() { return value; } - internal virtual bool IsValueFitOnCellArea() { - return isValueFitOnCellArea; - } - internal virtual Rectangle GetLayoutArea() { return layoutArea; } - internal virtual GridCell.IntRectangle GetGridArea() { - return gridArea; - } - - internal virtual void SetLayoutArea(Rectangle layoutArea) { - this.layoutArea = layoutArea; - } - - internal virtual void SetValueFitOnCellArea(bool valueFitOnCellArea) { - isValueFitOnCellArea = valueFitOnCellArea; - } - internal virtual void SetPos(int y, int x) { - this.gridArea.SetY(y); - this.gridArea.SetX(x); + this.gridY = y; + this.gridX = x; } /// - /// init row/column start/end value + /// Init axis placement values /// if start > end values are swapped - /// if only start or end are specified - other value is initialized so cell would have height/width = 1 /// /// x/y pos of cell on a grid /// x/y + width/height pos of cell on a grid - /// row/column start/end values as a pair, where first value is start, second is end - private int[] InitRowColumnsValues(int? start, int? end) { - int[] result = new int[] { 0, 0 }; + /// vertical or horizontal span of the cell on a grid + /// row/column start + vertical/horizontal span values as a pair, where first value is start, second is span + /// + private int[] InitAxisPlacement(int? start, int? end, int? span) { + int[] result = new int[] { 0, 1 }; if (start != null && end != null) { - result[0] = (int)start; - result[1] = (int)end; - if (start > end) { - result[0] = (int)end; - result[1] = (int)start; + int intStart = (int)start; + int intEnd = (int)end; + if (intStart < intEnd) { + result[0] = intStart; + result[1] = intEnd - intStart; + } + else { + result[0] = intEnd; + result[1] = intStart - intEnd; } } else { if (start != null) { result[0] = (int)start; - result[1] = (int)start + 1; + if (span != null) { + result[1] = (int)span; + } } else { + // span default value 1 was set up on the result array initialization if (end != null) { - result[0] = end <= 1 ? 1 : ((int)end) - 1; - result[1] = end <= 1 ? 2 : (int)end; + int intEnd = (int)end; + if (span == null) { + result[0] = end <= 1 ? 1 : ((int)end) - 1; + } + else { + // span default value 1 was set up on the result array initialization + int intSpan = (int)span; + result[1] = intSpan; + result[0] = Math.Max(intEnd - intSpan, 1); + } + } + else { + if (span != null) { + result[1] = (int)span; + } } } } + result[0] -= 1; return result; } - - /// This class represents an integer rectangle. - /// - /// This class represents an integer rectangle. - /// x,y - represents a bottom left corner of this rectangle. - /// - internal class IntRectangle { - private int x; - - private int y; - - private int width; - - private int height; - - public IntRectangle(int x, int y, int width, int height) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - } - - public virtual int GetLeft() { - return x; - } - - public virtual int GetRight() { - return x + width; - } - - public virtual int GetTop() { - return y + height; - } - - public virtual int GetBottom() { - return y; - } - - public virtual int GetWidth() { - return width; - } - - public virtual int GetHeight() { - return height; - } - - public virtual void SetX(int x) { - this.x = x; - } - - public virtual void SetY(int y) { - this.y = y; - } - - public virtual void SetWidth(int width) { - this.width = width; - } - - public virtual void SetHeight(int height) { - this.height = height; - } - - public override String ToString() { - return "Rectangle: start(" + x + ',' + y + ") ," + width + 'x' + height; - } - } } } diff --git a/itext/itext.layout/itext/layout/renderer/GridTrackSizer.cs b/itext/itext.layout/itext/layout/renderer/GridTrackSizer.cs index 498960d28b..5cc024f956 100644 --- a/itext/itext.layout/itext/layout/renderer/GridTrackSizer.cs +++ b/itext/itext.layout/itext/layout/renderer/GridTrackSizer.cs @@ -479,7 +479,6 @@ private static float CalculateMaxContribution(GridCell cell, Grid.GridOrder grid LayoutResult inifiniteHeighLayoutResult = cell.GetValue().Layout(layoutContext); if (inifiniteHeighLayoutResult.GetStatus() == LayoutResult.NOTHING || inifiniteHeighLayoutResult.GetStatus () == LayoutResult.PARTIAL) { - cell.SetValueFitOnCellArea(false); return 0; } return inifiniteHeighLayoutResult.GetOccupiedArea().GetBBox().GetHeight(); diff --git a/port-hash b/port-hash index 484fec70d4..b59a432b0b 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -1102018db850e02522787c9bae2c4a7fda657cc5 +3193c19508fb694f46fa19844f6bec2281f2f69c