2020namespace PhpOffice \PhpPresentation \Shape ;
2121
2222use PhpOffice \PhpPresentation \AbstractShape ;
23- use PhpOffice \PhpPresentation \GeometryCalculator ;
2423use PhpOffice \PhpPresentation \ShapeContainerInterface ;
2524use PhpOffice \PhpPresentation \Traits \ShapeCollection ;
2625
2726class Group extends AbstractShape implements ShapeContainerInterface
2827{
2928 use ShapeCollection;
3029
31- /**
32- * Extent X.
33- *
34- * @var int
35- */
36- protected $ extentX ;
37-
38- /**
39- * Extent Y.
40- *
41- * @var int
42- */
43- protected $ extentY ;
44-
4530 public function __construct ()
4631 {
4732 parent ::__construct ();
@@ -52,22 +37,33 @@ public function __construct()
5237 */
5338 public function getOffsetX (): int
5439 {
55- if (empty ($ this ->offsetX )) {
56- $ offsets = GeometryCalculator::calculateOffsets ($ this );
57- $ this ->offsetX = $ offsets [GeometryCalculator::X];
58- $ this ->offsetY = $ offsets [GeometryCalculator::Y];
40+ $ offsetX = null ;
41+
42+ foreach ($ this ->getShapeCollection () as $ shape ) {
43+ if ($ offsetX === null ) {
44+ $ offsetX = $ shape ->getOffsetX ();
45+ } else {
46+ $ offsetX = \min ($ offsetX , $ shape ->getOffsetX ());
47+ }
5948 }
6049
61- return $ this -> offsetX ;
50+ return $ offsetX ?? 0 ;
6251 }
6352
6453 /**
65- * Ignores setting the X Offset, preserving the default behavior .
54+ * Change the X offset by moving all contained shapes .
6655 *
6756 * @return $this
6857 */
69- public function setOffsetX (int $ pValue = 0 )
58+ public function setOffsetX (int $ pValue = 0 ): self
7059 {
60+ $ offsetX = $ this ->getOffsetX ();
61+ $ diff = $ pValue - $ offsetX ;
62+
63+ foreach ($ this ->getShapeCollection () as $ shape ) {
64+ $ shape ->setOffsetX ($ shape ->getOffsetX () + $ diff );
65+ }
66+
7167 return $ this ;
7268 }
7369
@@ -76,22 +72,33 @@ public function setOffsetX(int $pValue = 0)
7672 */
7773 public function getOffsetY (): int
7874 {
79- if (empty ($ this ->offsetY )) {
80- $ offsets = GeometryCalculator::calculateOffsets ($ this );
81- $ this ->offsetX = $ offsets [GeometryCalculator::X];
82- $ this ->offsetY = $ offsets [GeometryCalculator::Y];
75+ $ offsetY = null ;
76+
77+ foreach ($ this ->getShapeCollection () as $ shape ) {
78+ if ($ offsetY === null ) {
79+ $ offsetY = $ shape ->getOffsetY ();
80+ } else {
81+ $ offsetY = \min ($ offsetY , $ shape ->getOffsetY ());
82+ }
8383 }
8484
85- return $ this -> offsetY ;
85+ return $ offsetY ?? 0 ;
8686 }
8787
8888 /**
89- * Ignores setting the Y Offset, preserving the default behavior .
89+ * Change the Y offset by moving all contained shapes .
9090 *
9191 * @return $this
9292 */
93- public function setOffsetY (int $ pValue = 0 )
93+ public function setOffsetY (int $ pValue = 0 ): self
9494 {
95+ $ offsetY = $ this ->getOffsetY ();
96+ $ diff = $ pValue - $ offsetY ;
97+
98+ foreach ($ this ->getShapeCollection () as $ shape ) {
99+ $ shape ->setOffsetY ($ shape ->getOffsetY () + $ diff );
100+ }
101+
95102 return $ this ;
96103 }
97104
@@ -100,35 +107,51 @@ public function setOffsetY(int $pValue = 0)
100107 */
101108 public function getExtentX (): int
102109 {
103- if ( null === $ this -> extentX ) {
104- $ extents = GeometryCalculator:: calculateExtents ( $ this );
105- $ this ->extentX = $ extents [GeometryCalculator::X] - $ this -> getOffsetX ();
106- $ this -> extentY = $ extents [GeometryCalculator::Y] - $ this -> getOffsetY ( );
110+ $ extentX = 0 ;
111+
112+ foreach ( $ this ->getShapeCollection () as $ shape ) {
113+ $ extentX = \max ( $ extentX , $ shape -> getOffsetX () + $ shape -> getWidth () );
107114 }
108115
109- return $ this ->extentX ;
116+ return $ extentX - $ this ->getOffsetX () ;
110117 }
111118
112119 /**
113120 * Get Y Extent.
114121 */
115122 public function getExtentY (): int
116123 {
117- if ( null === $ this -> extentY ) {
118- $ extents = GeometryCalculator:: calculateExtents ( $ this );
119- $ this ->extentX = $ extents [GeometryCalculator::X] - $ this -> getOffsetX ();
120- $ this -> extentY = $ extents [GeometryCalculator::Y] - $ this -> getOffsetY ( );
124+ $ extentY = 0 ;
125+
126+ foreach ( $ this ->getShapeCollection () as $ shape ) {
127+ $ extentY = \max ( $ extentY , $ shape -> getOffsetY () + $ shape -> getHeight () );
121128 }
122129
123- return $ this ->extentY ;
130+ return $ extentY - $ this ->getOffsetY ();
131+ }
132+
133+ /**
134+ * Calculate the width based on the size/position of the contained shapes.
135+ */
136+ public function getWidth (): int
137+ {
138+ return $ this ->getExtentX ();
139+ }
140+
141+ /**
142+ * Calculate the height based on the size/position of the contained shapes.
143+ */
144+ public function getHeight (): int
145+ {
146+ return $ this ->getExtentY ();
124147 }
125148
126149 /**
127150 * Ignores setting the width, preserving the default behavior.
128151 *
129- * @return self
152+ * @return $this
130153 */
131- public function setWidth (int $ pValue = 0 )
154+ public function setWidth (int $ pValue = 0 ): self
132155 {
133156 return $ this ;
134157 }
@@ -138,7 +161,7 @@ public function setWidth(int $pValue = 0)
138161 *
139162 * @return $this
140163 */
141- public function setHeight (int $ pValue = 0 )
164+ public function setHeight (int $ pValue = 0 ): self
142165 {
143166 return $ this ;
144167 }
0 commit comments