@@ -16,14 +16,18 @@ Date Author Change
1616using OfficeOpenXml . Drawing . OleObject ;
1717using OfficeOpenXml . Drawing . Slicer ;
1818using OfficeOpenXml . FormulaParsing . Excel . Functions . MathFunctions ;
19+ using OfficeOpenXml . FormulaParsing . Excel . Functions . RefAndLookup ;
1920using OfficeOpenXml . Packaging ;
21+ using OfficeOpenXml . Utils ;
22+ using OfficeOpenXml . Utils . Drawings ;
2023using OfficeOpenXml . Utils . EnumUtils ;
2124using OfficeOpenXml . Utils . FileUtils ;
2225using OfficeOpenXml . Utils . XML ;
2326using System ;
2427using System . Globalization ;
2528using System . IO ;
2629using System . Linq ;
30+ using System . Security . Cryptography ;
2731using System . Text ;
2832using System . Xml ;
2933
@@ -741,8 +745,8 @@ internal void GetFromBounds(out int fromRow, out int fromRowOff, out int fromCol
741745 {
742746 if ( CellAnchor == eEditAs . Absolute )
743747 {
744- GetToRowFromPixels ( Position . Y , out fromRow , out fromRowOff ) ;
745- GetToColumnFromPixels ( Position . X , out fromCol , out fromColOff ) ;
748+ GetToRowFromPixels ( Position . Y / ( double ) EMU_PER_PIXEL , out fromRow , out fromRowOff ) ;
749+ GetToColumnFromPixels ( Position . X / ( double ) EMU_PER_PIXEL , out fromCol , out fromColOff ) ;
746750 }
747751 else
748752 {
@@ -757,7 +761,7 @@ internal void GetToBounds(out int toRow, out int toRowOff, out int toCol, out in
757761 if ( CellAnchor == eEditAs . Absolute )
758762 {
759763 GetToRowFromPixels ( ( Position . Y + Size . Height ) / EMU_PER_PIXEL , out toRow , out toRowOff ) ;
760- GetToColumnFromPixels ( Position . X + Size . Width / EMU_PER_PIXEL , out toCol , out toColOff ) ;
764+ GetToColumnFromPixels ( ( Position . X + Size . Width ) / EMU_PER_PIXEL , out toCol , out toColOff ) ;
761765 }
762766 else
763767 {
@@ -865,15 +869,14 @@ internal double GetPixelWidth()
865869 if ( CellAnchor == eEditAs . TwoCell )
866870 {
867871 ExcelWorksheet ws = _drawings . Worksheet ;
868- double mdw = ws . Workbook . MaxFontWidth ;
869872
870873 pix = - From . ColumnOff / ( double ) EMU_PER_PIXEL ;
871874 for ( int col = From . Column + 1 ; col <= To . Column ; col ++ )
872875 {
873- pix += MathHelper . TruncateDouble ( ( ( 256 * ws . GetColumnWidth ( col ) + MathHelper . TruncateDouble ( 128 / mdw ) ) / 256 ) * mdw ) ;
876+ pix += PixelHelper . GetColumnWidth ( ws , col ) ;
874877 }
875878
876- var w = MathHelper . TruncateDouble ( ( ( 256 * ws . GetColumnWidth ( To . Column + 1 ) + MathHelper . TruncateDouble ( 128 / mdw ) ) / 256 ) * mdw ) ;
879+ var w = PixelHelper . GetColumnWidth ( ws , To . Column + 1 ) ;
877880 pix += Math . Min ( w , Convert . ToDouble ( To . ColumnOff ) / EMU_PER_PIXEL ) ;
878881 }
879882 else
@@ -908,9 +911,9 @@ internal double GetPixelHeight()
908911 pix = - ( From . RowOff / ( double ) EMU_PER_PIXEL ) ;
909912 for ( int row = From . Row + 1 ; row <= To . Row ; row ++ )
910913 {
911- pix += ws . GetRowHeight ( row ) / 0.75 ;
914+ pix += PixelHelper . GetRowHeight ( ws , row ) ;
912915 }
913- var h = ws . GetRowHeight ( To . Row + 1 ) / 0.75 ;
916+ var h = PixelHelper . GetRowHeight ( ws , To . Row + 1 ) ;
914917 pix += Math . Min ( h , Convert . ToDouble ( To . RowOff ) / EMU_PER_PIXEL ) ;
915918 }
916919 else
@@ -949,12 +952,12 @@ internal void CalcRowFromPixelTop(double pixels, out int row, out int rowOff)
949952 ExcelWorksheet ws = _drawings . Worksheet ;
950953 double mdw = ws . Workbook . MaxFontWidth ;
951954 double prevPix = 0 ;
952- double pix = ws . GetRowHeight ( 1 ) / 0.75 ;
955+ double pix = PixelHelper . GetRowHeight ( ws , 1 ) ;
953956 int r = 2 ;
954- while ( pix < pixels )
957+ while ( pix < pixels && r <= ExcelPackage . MaxRows )
955958 {
956959 prevPix = pix ;
957- pix += ( int ) ( ws . GetRowHeight ( r ++ ) / 0.75 ) ;
960+ pix += ( int ) PixelHelper . GetRowHeight ( ws , r ++ ) ;
958961 }
959962
960963 if ( pix == pixels )
@@ -997,15 +1000,14 @@ internal void CalcColFromPixelLeft(double pixels, out int column, out int column
9971000 {
9981001
9991002 ExcelWorksheet ws = _drawings . Worksheet ;
1000- double mdw = ws . Workbook . MaxFontWidth ;
10011003 double prevPix = 0 ;
1002- double pix = ( int ) MathHelper . TruncateDouble ( ( ( 256 * ws . GetColumnWidth ( 1 ) + MathHelper . TruncateDouble ( 128 / mdw ) ) / 256 ) * mdw ) ;
1004+ double pix = ( int ) PixelHelper . GetColumnWidth ( ws , 1 ) ;
10031005 int col = 2 ;
10041006
1005- while ( pix < pixels )
1007+ while ( pix < pixels && col <= ExcelPackage . MaxColumns )
10061008 {
10071009 prevPix = pix ;
1008- pix += ( int ) MathHelper . TruncateDouble ( ( ( 256 * ws . GetColumnWidth ( col ++ ) + MathHelper . TruncateDouble ( 128 / mdw ) ) / 256 ) * mdw ) ;
1010+ pix += ( int ) PixelHelper . GetColumnWidth ( ws , col ++ ) ;
10091011 }
10101012 if ( pix == pixels )
10111013 {
@@ -1043,20 +1045,40 @@ internal void SetPixelHeight(double pixels)
10431045
10441046 internal void GetToRowFromPixels ( double pixels , out int toRow , out int rowOff , int fromRow = - 1 , int fromRowOff = - 1 )
10451047 {
1048+ if ( From == null && this is not ExcelControl )
1049+ {
1050+ // Absolute anchor path
1051+ double remaining = pixels ;
1052+ int currentRow = 1 ;
1053+
1054+ while ( true && currentRow <= ExcelPackage . MaxRows )
1055+ {
1056+ double rowPix = PixelHelper . GetRowHeight ( _drawings . Worksheet , currentRow ) ;
1057+ if ( remaining < rowPix )
1058+ break ;
1059+
1060+ remaining -= rowPix ;
1061+ currentRow ++ ;
1062+ }
1063+
1064+ toRow = currentRow - 1 ;
1065+ rowOff = ( int ) ( remaining ) ;
1066+ return ;
1067+ }
10461068 if ( fromRow < 0 )
10471069 {
10481070 fromRow = From . Row ;
10491071 fromRowOff = From . RowOff ;
10501072 }
10511073 ExcelWorksheet ws = _drawings . Worksheet ;
1052- var pixOff = pixels - ( ( ws . GetRowHeight ( fromRow + 1 ) / 0.75 ) - ( fromRowOff / ( double ) EMU_PER_PIXEL ) ) ;
1074+ var pixOff = pixels - ( PixelHelper . GetRowHeight ( ws , fromRow + 1 ) - ( fromRowOff / ( double ) EMU_PER_PIXEL ) ) ;
10531075 double prevPixOff = pixels ;
10541076 int row = fromRow + 1 ;
10551077
1056- while ( pixOff >= 0 )
1078+ while ( pixOff >= 0 && row < ExcelPackage . MaxRows )
10571079 {
10581080 prevPixOff = pixOff ;
1059- pixOff -= ( ws . GetRowHeight ( ++ row ) / 0.75 ) ;
1081+ pixOff -= PixelHelper . GetRowHeight ( ws , ++ row ) ;
10601082 }
10611083 toRow = row - 1 ;
10621084 if ( fromRow == toRow )
@@ -1096,19 +1118,35 @@ internal void SetPixelWidth(double pixels)
10961118 internal void GetToColumnFromPixels ( double pixels , out int col , out int colOff , int fromColumn = - 1 , int fromColumnOff = - 1 )
10971119 {
10981120 ExcelWorksheet ws = _drawings . Worksheet ;
1099- double mdw = ws . Workbook . MaxFontWidth ;
1100- if ( fromColumn < 0 )
1121+ if ( From == null && this is not ExcelControl )
1122+ {
1123+ // Absolute anchor path
1124+ double remaining = pixels ;
1125+ int currentCol = 1 ;
1126+ double colPix = PixelHelper . GetColumnWidth ( ws , currentCol ) ;
1127+ while ( remaining >= colPix && currentCol < ExcelPackage . MaxColumns )
1128+ {
1129+ remaining -= colPix ;
1130+ currentCol ++ ;
1131+ colPix = PixelHelper . GetColumnWidth ( ws , currentCol ) ;
1132+ }
1133+
1134+ col = currentCol - 1 ;
1135+ colOff = ( int ) ( remaining ) ;
1136+ return ;
1137+ }
1138+ if ( From != null && fromColumn < 0 )
11011139 {
11021140 fromColumn = From . Column ;
11031141 fromColumnOff = From . ColumnOff ;
11041142 }
1105- double pixOff = pixels - ( MathHelper . TruncateDouble ( ( ( 256 * ws . GetColumnWidth ( fromColumn + 1 ) + MathHelper . TruncateDouble ( 128 / mdw ) ) / 256 ) * mdw ) - fromColumnOff / EMU_PER_PIXEL ) ;
1143+ double pixOff = pixels - ( PixelHelper . GetColumnWidth ( ws , fromColumn + 1 ) - fromColumnOff / EMU_PER_PIXEL ) ;
11061144 double offset = ( double ) fromColumnOff / EMU_PER_PIXEL + pixels ;
11071145 col = fromColumn + 2 ;
11081146 while ( pixOff >= 0 )
11091147 {
11101148 offset = pixOff ;
1111- pixOff -= MathHelper . TruncateDouble ( ( ( 256 * ws . GetColumnWidth ( col ++ ) + MathHelper . TruncateDouble ( 128 / mdw ) ) / 256 ) * mdw ) ;
1149+ pixOff -= PixelHelper . GetColumnWidth ( ws , col ++ ) ;
11121150 }
11131151 colOff = ( int ) offset ;
11141152 }
@@ -1394,10 +1432,20 @@ public void SetPosition(int Row, int RowOffsetPixels, int Column, int ColumnOffs
13941432 _height = GetPixelHeight ( ) ;
13951433 }
13961434
1397- From . Row = Row ;
1398- From . RowOff = RowOffsetPixels * EMU_PER_PIXEL ;
1399- From . Column = Column ;
1400- From . ColumnOff = ColumnOffsetPixels * EMU_PER_PIXEL ;
1435+ if ( CellAnchor == eEditAs . Absolute )
1436+ {
1437+ GetPixelHeightFromRow ( Row , RowOffsetPixels , out int pixelHeight ) ;
1438+
1439+ Position . Y = ( int ) ( pixelHeight * EMU_PER_PIXEL ) ;
1440+ Position . X = ( int ) ( ColumnOffsetPixels * EMU_PER_PIXEL ) ;
1441+ }
1442+ else
1443+ {
1444+ From . Row = Row ;
1445+ From . RowOff = RowOffsetPixels * EMU_PER_PIXEL ;
1446+ From . Column = Column ;
1447+ From . ColumnOff = ColumnOffsetPixels * EMU_PER_PIXEL ;
1448+ }
14011449 if ( CellAnchor == eEditAs . TwoCell )
14021450 {
14031451 _left = GetPixelLeft ( ) ;
@@ -1409,6 +1457,36 @@ public void SetPosition(int Row, int RowOffsetPixels, int Column, int ColumnOffs
14091457 _doNotAdjust = false ;
14101458 UpdatePositionAndSizeXml ( ) ;
14111459 }
1460+ private void GetPixelWidthFromRow ( int toCol , int colOffsetPixels , out int pixelWidth )
1461+ {
1462+ ExcelWorksheet ws = _drawings . Worksheet ;
1463+ double mdw = ws . Workbook . MaxFontWidth ;
1464+
1465+ pixelWidth = 0 ;
1466+ for ( int col = 0 ; col < toCol ; col ++ )
1467+ {
1468+ pixelWidth += ws . GetColumnWidthPixels ( col , mdw ) ;
1469+ }
1470+ pixelWidth += colOffsetPixels ;
1471+ }
1472+ private void GetPixelHeightFromRow ( int toRow , int rowOffsetPixels , out int pixelHeight )
1473+ {
1474+ pixelHeight = 0 ;
1475+ var cache = _drawings . Worksheet . RowHeightCache ;
1476+ for ( int row = 0 ; row < toRow ; row ++ )
1477+ {
1478+ lock ( cache )
1479+ {
1480+ if ( ! cache . ContainsKey ( row ) )
1481+ {
1482+ cache . Add ( row , _drawings . Worksheet . GetRowHeight ( row + 1 ) ) ;
1483+ }
1484+ }
1485+ pixelHeight += ( int ) ( cache [ row ] / 0.75 ) ;
1486+ }
1487+ pixelHeight += rowOffsetPixels ;
1488+ }
1489+
14121490 /// <summary>
14131491 /// Set size in Percent.
14141492 /// Note that resizing columns / rows after using this function will effect the size of the drawing
0 commit comments