diff --git a/CHANGELOG.md b/CHANGELOG.md index 274981073..bac167f9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org). - Writer ODS : Write Border Style for cells [Issue #3690](https://github.com/PHPOffice/PhpSpreadsheet/issues/3690) [PR #3693](https://github.com/PHPOffice/PhpSpreadsheet/pull/3693) - Sheet Background Images [Issue #1649](https://github.com/PHPOffice/PhpSpreadsheet/issues/1649) [PR #3795](https://github.com/PHPOffice/PhpSpreadsheet/pull/3795) - Check if Coordinate is Inside Range [PR #3779](https://github.com/PHPOffice/PhpSpreadsheet/pull/3779) +- Flipping Images [Issue #731](https://github.com/PHPOffice/PhpSpreadsheet/issues/731) [PR #3801](https://github.com/PHPOffice/PhpSpreadsheet/pull/3801) +- Chart Dynamic Title and Font Properties [Issue #3797](https://github.com/PHPOffice/PhpSpreadsheet/issues/3797) [PR #3800](https://github.com/PHPOffice/PhpSpreadsheet/pull/3800) ### Changed diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 73ac43afd..109a593ed 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -1424,6 +1424,8 @@ class Xlsx extends BaseReader $objDrawing->setHeight(Drawing::EMUToPixels(self::getArrayItem(self::getAttributes($oneCellAnchor->ext), 'cy'))); if ($xfrm) { $objDrawing->setRotation((int) Drawing::angleToDegrees(self::getArrayItem(self::getAttributes($xfrm), 'rot'))); + $objDrawing->setFlipVertical((bool) self::getArrayItem(self::getAttributes($xfrm), 'flipV')); + $objDrawing->setFlipHorizontal((bool) self::getArrayItem(self::getAttributes($xfrm), 'flipH')); } if ($outerShdw) { $shadow = $objDrawing->getShadow(); @@ -1518,6 +1520,8 @@ class Xlsx extends BaseReader $objDrawing->setWidth(Drawing::EMUToPixels(self::getArrayItem(self::getAttributes($xfrm->ext), 'cx'))); $objDrawing->setHeight(Drawing::EMUToPixels(self::getArrayItem(self::getAttributes($xfrm->ext), 'cy'))); $objDrawing->setRotation(Drawing::angleToDegrees(self::getArrayItem(self::getAttributes($xfrm), 'rot'))); + $objDrawing->setFlipVertical((bool) self::getArrayItem(self::getAttributes($xfrm), 'flipV')); + $objDrawing->setFlipHorizontal((bool) self::getArrayItem(self::getAttributes($xfrm), 'flipH')); } if ($outerShdw) { $shadow = $objDrawing->getShadow(); diff --git a/src/PhpSpreadsheet/Worksheet/BaseDrawing.php b/src/PhpSpreadsheet/Worksheet/BaseDrawing.php index 2310e64ea..d59d4b39a 100644 --- a/src/PhpSpreadsheet/Worksheet/BaseDrawing.php +++ b/src/PhpSpreadsheet/Worksheet/BaseDrawing.php @@ -131,6 +131,10 @@ class BaseDrawing implements IComparable */ protected $rotation = 0; + protected bool $flipVertical = false; + + protected bool $flipHorizontal = false; + /** * Shadow. */ @@ -542,4 +546,28 @@ class BaseDrawing implements IComparable return $this; } + + public function setFlipHorizontal(bool $flipHorizontal): self + { + $this->flipHorizontal = $flipHorizontal; + + return $this; + } + + public function getFlipHorizontal(): bool + { + return $this->flipHorizontal; + } + + public function setFlipVertical(bool $flipVertical): self + { + $this->flipVertical = $flipVertical; + + return $this; + } + + public function getFlipVertical(): bool + { + return $this->flipVertical; + } } diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php b/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php index 6763b508f..cb8b1c403 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php @@ -294,6 +294,8 @@ class Drawing extends WriterPart // a:xfrm $objWriter->startElement('a:xfrm'); $objWriter->writeAttribute('rot', (string) SharedDrawing::degreesToAngle($drawing->getRotation())); + self::writeAttributeIf($objWriter, $drawing->getFlipVertical(), 'flipV', '1'); + self::writeAttributeIf($objWriter, $drawing->getFlipHorizontal(), 'flipH', '1'); if ($isTwoCellAnchor) { $objWriter->startElement('a:ext'); $objWriter->writeAttribute('cx', self::stringEmu($drawing->getWidth())); @@ -579,4 +581,11 @@ class Drawing extends WriterPart { return (string) SharedDrawing::pixelsToEMU($pixelValue); } + + private static function writeAttributeIf(XMLWriter $objWriter, ?bool $condition, string $attr, string $val): void + { + if ($condition) { + $objWriter->writeAttribute($attr, $val); + } + } } diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue731Test.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue731Test.php new file mode 100644 index 000000000..929320c55 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue731Test.php @@ -0,0 +1,38 @@ +load(self::$testbook); + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx'); + $spreadsheet->disconnectWorksheets(); + $reloadedSheet = $reloadedSpreadsheet->getActiveSheet(); + $expected = [ + [0, false, false], + [90, false, false], + [270, false, false], + [0, false, true], + [0, true, false], + [20, false, false], + [20, false, true], + [0, true, true], + ]; + $actual = []; + foreach ($reloadedSheet->getDrawingCollection() as $drawing) { + $actual[] = [$drawing->getRotation(), $drawing->getFlipHorizontal(), $drawing->getFlipVertical()]; + } + self::assertSame($expected, $actual); + $reloadedSpreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/data/Reader/XLSX/issue.731.xlsx b/tests/data/Reader/XLSX/issue.731.xlsx new file mode 100644 index 000000000..91f865d4a Binary files /dev/null and b/tests/data/Reader/XLSX/issue.731.xlsx differ