Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changes/1.3.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

## Enhancements
- `phpoffice/phpspreadsheet`: Allow version 5.0 by [@seanlynchwv](http://github.com/seanlynchwv) in [#879](https://github.com/PHPOffice/PHPPresentation/pull/879)
- Added ability to set rounded corner radius by [@seanlynchwv](http://github.com/seanlynchwv) in [#880](https://github.com/PHPOffice/PHPPresentation/pull/880)

## Bug fixes

24 changes: 24 additions & 0 deletions src/PhpPresentation/Shape/AutoShape.php
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,28 @@ public function setOutline(Outline $outline): self

return $this;
}

/** @var null|int */
private $roundRectCorner;

public function getRoundRectCorner(): ?int
{
return $this->roundRectCorner;
}

/**
* Set corner radius.
*/
public function setRoundRectCorner(int $pixels): self
{
$this->roundRectCorner = max(0, $pixels);

return $this;
}

// override the hash so radius works
public function getHashCode(): string
{
return md5(parent::getHashCode() . $this->type . $this->text . (string) $this->roundRectCorner . __CLASS__);
}
}
28 changes: 25 additions & 3 deletions src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php
Original file line number Diff line number Diff line change
Expand Up @@ -1187,9 +1187,31 @@ protected function writeShapeAutoShape(XMLWriter $objWriter, AutoShape $shape, i
// p:sp\p:spPr\a:prstGeom
$objWriter->startElement('a:prstGeom');
$objWriter->writeAttribute('prst', $shape->getType());
// p:sp\p:spPr\a:prstGeom\a:avLst
$objWriter->writeElement('a:avLst');
// p:sp\p:spPr\a:prstGeom\

// a:avLst (+ optional adj for roundRect)
$needsAdj = ($shape->getType() === AutoShape::TYPE_ROUNDED_RECTANGLE);
$cornerPx = $shape->getRoundRectCorner();

if ($needsAdj && $cornerPx !== null) {
$minHalf = (int) floor(min($shape->getWidth(), $shape->getHeight()) / 2);

if ($minHalf > 0) {
$adj = (int) round($cornerPx / $minHalf * 50000);
$adj = max(0, min(50000, $adj));

$objWriter->startElement('a:avLst');
$objWriter->startElement('a:gd');
$objWriter->writeAttribute('name', 'adj');
$objWriter->writeAttribute('fmla', 'val ' . (string) $adj);
$objWriter->endElement(); // a:gd
$objWriter->endElement(); // a:avLst
} else {
// invalid size, just emit empty avLst
$objWriter->writeElement('a:avLst');
}
} else {
$objWriter->writeElement('a:avLst');
}
$objWriter->endElement();
// Fill
$this->writeFill($objWriter, $shape->getFill());
Expand Down
57 changes: 57 additions & 0 deletions tests/PhpPresentation/Tests/Shape/AutoShapeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@

namespace PhpOffice\PhpPresentation\Tests\Shape;

use PhpOffice\PhpPresentation\PhpPresentation;
use PhpOffice\PhpPresentation\Shape\AutoShape;
use PhpOffice\PhpPresentation\Style\Color;
use PhpOffice\PhpPresentation\Style\Fill;
use PhpOffice\PhpPresentation\Style\Outline;
use PhpOffice\PhpPresentation\Writer\PowerPoint2007;
use PHPUnit\Framework\TestCase;
use ZipArchive;

class AutoShapeTest extends TestCase
{
Expand Down Expand Up @@ -64,4 +69,56 @@ public function testType(): void
self::assertInstanceOf(AutoShape::class, $object->setType(AutoShape::TYPE_HEXAGON));
self::assertEquals(AutoShape::TYPE_HEXAGON, $object->getType());
}

public function testNoRadiusByDefaultIsNull(): void
{
$shape = new AutoShape();
self::assertNull($shape->getRoundRectCorner());
}

public function testWriterEmitsAdjGuideForRoundRect(): void
{
$ppt = new PhpPresentation();
$slide = $ppt->getActiveSlide();

$width = 200;
$height = 100;
$padding = 5;
$minHalf = (int) floor(min($width, $height) / 2);
$expectedAdj = (int) round($padding / $minHalf * 50000); // 5000

$shape = (new AutoShape())
->setType(AutoShape::TYPE_ROUNDED_RECTANGLE)
->setWidth($width)->setHeight($height)
->setRoundRectCorner($padding);

// Give it a fill so it's an obvious shape
$shape->getFill()->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFFFFFFF'));
$slide->addShape($shape);

$tmpFile = tempnam(sys_get_temp_dir(), 'pptx_');
$writer = new PowerPoint2007($ppt);
$writer->save($tmpFile);

// Open the pptx and read slide1.xml
$zip = new ZipArchive();
self::assertTrue($zip->open($tmpFile) === true, 'Failed to open pptx zip');
$xml = $zip->getFromName('ppt/slides/slide1.xml');
$zip->close();
@unlink($tmpFile);

self::assertIsString($xml);

// Must contain roundRect geometry and the adj guide with expected value
self::assertStringContainsString('<a:prstGeom prst="roundRect">', $xml);

// fmla="val N" (there is a space after 'val' in writer)
self::assertSame(
1,
preg_match(
sprintf('/<a:gd[^>]+name="adj"[^>]+fmla="val %d"/', $expectedAdj),
(string) $xml
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ public function testTypeAxisTickLabelPosition(): void

public function testTypeAxisUnit(): void
{
$value = mt_rand(0, 100);
$value = max(1, mt_rand(0, 100));

$series = new Series('Downloads', $this->seriesData);
$line = new Line();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,28 @@ public function testParagraphSpacingBefore(): void
$this->assertIsSchemaECMA376Valid();
}

public function testRoundRectCornerPixelRadiusStoredAndAffectsHash(): void
{
$width = 200; // px
$height = 100; // px
$px1 = 5; // softer radius
$px2 = 10; // larger radius

$shape1 = (new AutoShape())
->setType(AutoShape::TYPE_ROUNDED_RECTANGLE)
->setWidth($width)
->setHeight($height)
->setRoundRectCorner($px1);

$shape2 = (clone $shape1)->setRoundRectCorner($px2);

self::assertSame($px1, $shape1->getRoundRectCorner());
self::assertSame($px2, $shape2->getRoundRectCorner());

// Hash must differ when radius differs
self::assertNotSame($shape1->getHashCode(), $shape2->getHashCode());
}

public function testPlaceHolder(): void
{
$expectedType = Placeholder::PH_TYPE_SLIDENUM;
Expand Down
Loading