Skip to content

Commit d1706a9

Browse files
Fixed infinite loop in GetTolColumnFromPixels. (#2382)
* Fixed infinite loop in GetTolColumnFromPixels. Also fixed a crash when saving workbook with groupshape as a shape in a chart. * Fixed positioning of shapes in charts * get top and left no longer returns 0. * fixed From To calculation for chart drawings. * fixed absolute positioning --------- Co-authored-by: Jan Källman <jan.kallman@epplussoftware.com>
1 parent 243cefe commit d1706a9

6 files changed

Lines changed: 62 additions & 31 deletions

File tree

src/EPPlus/Drawing/ExcelDrawing.cs

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@ internal int GetPixelLeft()
788788
{
789789
return (int)(Math.Round(From.X * _drawings._screenWidth));
790790
}
791-
return 0;
791+
return Position == null ? 0 : Position.X / EMU_PER_PIXEL;
792792
}
793793
if (CellAnchor == eEditAs.Absolute)
794794
{
@@ -818,7 +818,7 @@ internal int GetPixelTop()
818818
{
819819
return (int)(Math.Round(From.Y * _drawings._screenHeight));
820820
}
821-
return 0;
821+
return Position == null ? 0 : Position.Y / EMU_PER_PIXEL;
822822
}
823823

824824
if (CellAnchor == eEditAs.Absolute)
@@ -928,14 +928,7 @@ internal void SetPixelTop(double pixels)
928928
_doNotAdjust = true;
929929
if (CellAnchor == eEditAs.Absolute)
930930
{
931-
if (_collectionType == DrawingsCollectionType.Worksheet)
932-
{
933-
Position.Y = (int)(pixels * EMU_PER_PIXEL);
934-
}
935-
else
936-
{
937-
From.Y= (double)pixels/_drawings._screenHeight;
938-
}
931+
Position.Y = (int)(pixels * EMU_PER_PIXEL);
939932
}
940933
else
941934
{
@@ -977,14 +970,7 @@ internal void SetPixelLeft(double pixels)
977970
_doNotAdjust = true;
978971
if (CellAnchor == eEditAs.Absolute)
979972
{
980-
if (_collectionType == DrawingsCollectionType.Worksheet)
981-
{
982-
Position.X = (int)(pixels * EMU_PER_PIXEL);
983-
}
984-
else
985-
{
986-
From.X = (double)pixels / _drawings._screenWidth;
987-
}
973+
Position.X = (int)(pixels * EMU_PER_PIXEL);
988974
}
989975
else
990976
{
@@ -1143,7 +1129,7 @@ internal void GetToColumnFromPixels(double pixels, out int col, out int colOff,
11431129
double pixOff = pixels - (PixelHelper.GetColumnWidth(ws, fromColumn + 1) - fromColumnOff / EMU_PER_PIXEL);
11441130
double offset = (double)fromColumnOff / EMU_PER_PIXEL + pixels;
11451131
col = fromColumn + 2;
1146-
while (pixOff >= 0)
1132+
while (pixOff >= 0 && col < ExcelPackage.MaxColumns)
11471133
{
11481134
offset = pixOff;
11491135
pixOff -= PixelHelper.GetColumnWidth(ws, col++);
@@ -1266,6 +1252,11 @@ private void AdjustFromToXY(double x, double y)
12661252
}
12671253
else
12681254
{
1255+
if (EditAs != eEditAs.Absolute)
1256+
{
1257+
To.X = x + To.X - From.X;
1258+
To.Y = y + To.Y - From.Y;
1259+
}
12691260
From.X = x;
12701261
From.Y = y;
12711262
}
@@ -1532,8 +1523,18 @@ private void SetWidthChartShape(double PixelWidth)
15321523
}
15331524
if (To != null)
15341525
{
1535-
To.X = (From.X + PixelWidth / _drawings._screenWidth);
1536-
if (To.X > 1) To.X = 1; else if (To.X < 0) To.X = 0;
1526+
var widthFraction = PixelWidth / _drawings._screenWidth;
1527+
To.X = From.X + widthFraction;
1528+
if (To.X > 1)
1529+
{
1530+
To.X = 1;
1531+
From.X = Math.Max(0, 1 - widthFraction);
1532+
}
1533+
else if (To.X < 0)
1534+
{
1535+
From.X = 0;
1536+
To.X = widthFraction;
1537+
}
15371538
}
15381539
if (Size != null)
15391540
{
@@ -1548,12 +1549,18 @@ private void SetHeightChartShape(double PixelHeight)
15481549
}
15491550
if (To != null)
15501551
{
1551-
1552-
1553-
if (To.X > 1) To.X = 1; else if (To.X < 0) To.X = 0;
1554-
1555-
To.Y = (From.Y + PixelHeight / _drawings._screenHeight);
1556-
if (To.Y > 1) To.Y = 1; else if (To.Y < 0) To.Y = 0;
1552+
var heightFraction = PixelHeight / _drawings._screenHeight;
1553+
To.Y = From.Y + heightFraction;
1554+
if (To.Y > 1)
1555+
{
1556+
To.Y = 1;
1557+
From.Y = Math.Max(0, 1 - heightFraction);
1558+
}
1559+
else if (To.Y < 0)
1560+
{
1561+
From.Y = 0;
1562+
To.Y = heightFraction;
1563+
}
15571564
}
15581565
if (Size != null)
15591566
{

src/EPPlus/Drawing/ExcelGroupShape.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ private void AdjustXmlAndMoveToGroup(ExcelDrawing d)
120120
}
121121
else if (d._drawings._collectionType == DrawingsCollectionType.Chart)
122122
{
123-
if (d is not ExcelGroupShape)
123+
if (d.ParentGroup is ExcelGroupShape)
124124
{
125125
d.RemoveFromToNodes();
126126
d.Position = new ExcelDrawingCoordinate(d.NameSpaceManager, d.TopNode, d.GetPositionSize);

src/EPPlus/ExcelWorksheet.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2556,6 +2556,7 @@ internal void Save(bool hasLoadedPivotTables)
25562556
}
25572557
}
25582558
}
2559+
25592560
private void SaveSlicers()
25602561
{
25612562
SlicerXmlSources.Save();

src/EPPlusTest/Drawing/Chart/ChartShapeTest.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ public void ShapeInChart()
2121
SaveAndCleanup(p);
2222
}
2323

24+
[TestMethod]
25+
public void ShapeInChartTest2()
26+
{
27+
using var p = OpenTemplatePackage("ShapeInChartTest2.xlsx");
28+
var ws = p.Workbook.Worksheets[0];
29+
var chart = ws.Drawings[0] as ExcelChartStandard;
30+
var cdr = chart.Drawings[0];
31+
cdr.SetPosition(150, 200);
32+
cdr.SetSize(200, 200);
33+
34+
SaveAndCleanup(p);
35+
}
2436

2537
[TestMethod]
2638
public void ShapeInChartTest()
@@ -257,6 +269,7 @@ public void GroupShapesWithPictures()
257269
Assert.IsTrue(chart.Drawings.Count == 5);
258270
var group = pic1.Group(pic2, pic3, pic4, pic5);
259271
Assert.IsTrue(chart.Drawings.Count == 1);
272+
SaveWorkbook("groupshapes2.xlsx", p);
260273
}
261274
[TestMethod]
262275
public void GroupShapesWithGroupShapes()
@@ -272,11 +285,14 @@ public void GroupShapesWithGroupShapes()
272285
var equal = chart.Drawings.AddShape("Equal", eShapeStyle.MathEqual);
273286
var roundRect = chart.Drawings.AddShape("RoundRect", eShapeStyle.Round1Rect);
274287
var triangle = chart.Drawings.AddShape("Triangle", eShapeStyle.Triangle);
275-
288+
276289
Assert.IsTrue(chart.Drawings.Count == 4);
277290
var group1 = arrow.Group(equal);
278291
var group2 = group1.Group(roundRect, triangle);
279-
Assert.IsTrue(chart.Drawings.Count == 1);
292+
//Assert.IsTrue(chart.Drawings.Count == 1);
293+
group2.SetPosition(100, 100);
294+
//group2.SetPosition(20, 20);
295+
SaveWorkbook("groupshapes1.xlsx", p);
280296
}
281297
[TestMethod]
282298
public void GroupShapesMixed()

src/EPPlusTest/Issues/DrawingIssues.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,13 @@ public void s1045()
216216
Console.WriteLine("Done (no crash).");
217217
SaveAndCleanup(destPackage);
218218
}
219+
220+
[TestMethod]
221+
public void s1055()
222+
{
223+
using var p = OpenTemplatePackage("s1055.xlsx");
224+
SaveAndCleanup(p);
225+
}
219226
}
220227
}
221228

src/EPPlusTest/TestBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ protected static void SaveWorkbook(string name, ExcelPackage pck)
249249
var fi = new FileInfo(_worksheetPath + name);
250250
if (fi.Exists)
251251
{
252-
//fi.Delete();
252+
fi.Delete();
253253
}
254254
pck.SaveAs(fi);
255255
}

0 commit comments

Comments
 (0)