Skip to content

Commit

Permalink
ODPresentation Writer : Support for rotation for RichText
Browse files Browse the repository at this point in the history
  • Loading branch information
Progi1984 committed Feb 24, 2025
1 parent f16f996 commit 5bf5214
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 18 deletions.
7 changes: 4 additions & 3 deletions docs/changes/1.2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@

## Enhancements

- `phpoffice/phpspreadsheet`: Allow version 1.9 or 2.0 by [@Progi1984](https://github.com/Progi1984) fixing [#790](https://github.com/PHPOffice/PHPPresentation/pull/790), [#812](https://github.com/PHPOffice/PHPPresentation/pull/812) in [#816](https://github.com/PHPOffice/PHPPresentation/pull/816)
- `phpoffice/phpspreadsheet`: Allow version 1.9 or 2.0 by [@Progi1984](https://github.com/Progi1984) fixing [#790](https://github.com/PHPOffice/PHPPresentation/issues/790), [#812](https://github.com/PHPOffice/PHPPresentation/pull/812) in [#816](https://github.com/PHPOffice/PHPPresentation/pull/816)
- Group Shape: moving the shape now moves all contained shapes. Offsets and size are calculated based on the contained shapes by [@DennisBirkholz](https://github.com/DennisBirkholz) in [#690](https://github.com/PHPOffice/PHPPresentation/pull/690)
- Added support for PHP 8.4 by [@Progi1984](https://github.com/Progi1984) in [#839](https://github.com/PHPOffice/PHPPresentation/pull/839)
- `phpoffice/phpspreadsheet`: Allow version 3.0 by [@Progi1984](https://github.com/Progi1984) fixing [#836](https://github.com/PHPOffice/PHPPresentation/pull/836) in [#839](https://github.com/PHPOffice/PHPPresentation/pull/839)
- `phpoffice/phpspreadsheet`: Allow version 3.0 by [@Progi1984](https://github.com/Progi1984) fixing [#836](https://github.com/PHPOffice/PHPPresentation/issues/836) in [#839](https://github.com/PHPOffice/PHPPresentation/pull/839)
- `createAutoShape` : Add method to create geometric shapes by [@mhasanshahid](https://github.com/mhasanshahid) & [@Progi1984](https://github.com/Progi1984) in [#848](https://github.com/PHPOffice/PHPPresentation/pull/848)
- Reader : Option to not load images by [@Progi1984](https://github.com/Progi1984) fixing [#795](https://github.com/PHPOffice/PHPPresentation/pull/795) in [#850](https://github.com/PHPOffice/PHPPresentation/pull/850)
- Reader : Option to not load images by [@Progi1984](https://github.com/Progi1984) fixing [#795](https://github.com/PHPOffice/PHPPresentation/issues/795) in [#850](https://github.com/PHPOffice/PHPPresentation/pull/850)
- ODPresentation Writer : Support for rotation for RichText by [@Progi1984](https://github.com/Progi1984) fixing [#279](https://github.com/PHPOffice/PHPPresentation/pull/279) in [#409](https://github.com/PHPOffice/PHPPresentation/pull/409)

## Bug fixes

Expand Down
20 changes: 20 additions & 0 deletions samples/Sample_11_Shape.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,25 @@ function fnSlideRichTextLineSpacing(PhpPresentation $objPHPPresentation): void
$shape->createTextRun('Line Spacing 300');
}

function fnSlideRichTextRotation(PhpPresentation $objPHPPresentation): void
{
// Create templated slide
echo date('H:i:s') . ' Create templated slide' . EOL;
$currentSlide = createTemplatedSlide($objPHPPresentation);

// Create a shape (text)
echo date('H:i:s') . ' Create a shape (rich text) with rotation' . EOL;
$shape = $currentSlide->createRichTextShape();
$shape->setHeight(100);
$shape->setWidth(200);
$shape->setOffsetX(200);
$shape->setOffsetY(200);
$shape->getActiveParagraph()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT);
$shape->setRotation(90);

$shape->createTextRun('RichText with rotation');
}

function fnSlideRichTextShadow(PhpPresentation $objPHPPresentation): void
{
// Create templated slide
Expand Down Expand Up @@ -143,6 +162,7 @@ function fnSlideRichTextList(PhpPresentation $objPHPPresentation): void

fnSlideRichText($objPHPPresentation);
fnSlideRichTextLineSpacing($objPHPPresentation);
fnSlideRichTextRotation($objPHPPresentation);
fnSlideRichTextShadow($objPHPPresentation);
fnSlideRichTextList($objPHPPresentation);

Expand Down
1 change: 1 addition & 0 deletions samples/Sample_Header.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
if (preg_match('/^Sample_\d+_/', $file)) {
$name = str_replace('_', ' ', preg_replace('/(Sample_|\.php)/', '', $file));
$group = substr($name, 0, 1);
$id = substr($name, 0, 2);
if (!isset($files[$group])) {
$files[$group] = [];
}
Expand Down
14 changes: 4 additions & 10 deletions src/PhpPresentation/AbstractShape.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ abstract class AbstractShape implements ComparableInterface
*
* @var int
*/
protected $rotation;
protected $rotation = 0;

/**
* Shadow.
Expand Down Expand Up @@ -123,7 +123,7 @@ abstract class AbstractShape implements ComparableInterface
*/
public function __construct()
{
$this->offsetX = $this->offsetY = $this->width = $this->height = $this->rotation = 0;
$this->offsetX = $this->offsetY = $this->width = $this->height = 0;
$this->fill = new Fill();
$this->shadow = new Shadow();
$this->border = new Border();
Expand Down Expand Up @@ -319,22 +319,16 @@ public function setWidthAndHeight(int $width = 0, int $height = 0)

/**
* Get Rotation.
*
* @return int
*/
public function getRotation()
public function getRotation(): int
{
return $this->rotation;
}

/**
* Set Rotation.
*
* @param int $pValue
*
* @return $this
*/
public function setRotation($pValue = 0)
public function setRotation(int $pValue = 0): self
{
$this->rotation = $pValue;

Expand Down
47 changes: 45 additions & 2 deletions src/PhpPresentation/Writer/ODPresentation/Content.php
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,19 @@ protected function writeShapeTxt(XMLWriter $objWriter, RichText $shape): void
$objWriter->writeAttribute('draw:style-name', 'gr' . $this->shapeId);
$objWriter->writeAttribute('svg:width', Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getWidth()), 3) . 'cm');
$objWriter->writeAttribute('svg:height', Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getHeight()), 3) . 'cm');
$objWriter->writeAttribute('svg:x', Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getOffsetX()), 3) . 'cm');
$objWriter->writeAttribute('svg:y', Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getOffsetY()), 3) . 'cm');
if ($shape->getRotation() != 0) {
$rotRad = deg2rad($shape->getRotation());

$translateX = Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getOffsetY()), 3) . 'cm';
$translateY = Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getOffsetX()), 3) . 'cm';
$objWriter->writeAttribute(
'draw:transform',
'rotate (-' . $rotRad . ') translate (' . $translateX . ' ' . $translateY . ')'
);
} else {
$objWriter->writeAttribute('svg:x', Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getOffsetX()), 3) . 'cm');
$objWriter->writeAttribute('svg:y', Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getOffsetY()), 3) . 'cm');
}
// draw:text-box
$objWriter->startElement('draw:text-box');

Expand Down Expand Up @@ -642,6 +653,38 @@ protected function writeShapeTxt(XMLWriter $objWriter, RichText $shape): void
}
}

if ($shape->getRotation() != 0) {
$objWriter->startElement('draw:enhanced-geometry');
$objWriter->writeAttribute('draw:mirror-horizontal', 'false');
$objWriter->writeAttribute('draw:mirror-vertical', 'false');
$objWriter->writeAttribute('svg:viewBox', '0 0 0 0');
$objWriter->writeAttribute('draw:text-areas', '0 0 ?f3 ?f2');
$objWriter->writeAttribute('draw:type', 'ooxml-rect');
$objWriter->writeAttribute('draw:enhanced-path', 'M 0 0 L ?f3 0 ?f3 ?f2 0 ?f2 Z N');

$objWriter->startElement('draw:equation');
$objWriter->writeAttribute('draw:name', 'f0');
$objWriter->writeAttribute('draw:formula', 'logwidth/2');
$objWriter->endElement();

$objWriter->startElement('draw:equation');
$objWriter->writeAttribute('draw:name', 'f1');
$objWriter->writeAttribute('draw:formula', 'logheight/2');
$objWriter->endElement();

$objWriter->startElement('draw:equation');
$objWriter->writeAttribute('draw:name', 'f2');
$objWriter->writeAttribute('draw:formula', 'logheight');
$objWriter->endElement();

$objWriter->startElement('draw:equation');
$objWriter->writeAttribute('draw:name', 'f3');
$objWriter->writeAttribute('draw:formula', 'logwidth');
$objWriter->endElement();

$objWriter->endElement();
}

// > draw:text-box
$objWriter->endElement();
// > draw:frame
Expand Down
6 changes: 3 additions & 3 deletions src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,7 @@ protected function writeShapeAutoShape(XMLWriter $objWriter, AutoShape $shape, i

// p:sp\p:spPr\a:xfrm
$objWriter->startElement('a:xfrm');
$objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle((int) $shape->getRotation()));
$objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
// p:sp\p:spPr\a:xfrm\a:off
$objWriter->startElement('a:off');
$objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
Expand Down Expand Up @@ -1264,7 +1264,7 @@ protected function writeShapeChart(XMLWriter $objWriter, ShapeChart $shape, int
$objWriter->endElement();
// p:xfrm
$objWriter->startElement('p:xfrm');
$objWriter->writeAttributeIf(0 != $shape->getRotation(), 'rot', CommonDrawing::degreesToAngle((int) $shape->getRotation()));
$objWriter->writeAttributeIf(0 != $shape->getRotation(), 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
// a:off
$objWriter->startElement('a:off');
$objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
Expand Down Expand Up @@ -1427,7 +1427,7 @@ protected function writeShapePic(XMLWriter $objWriter, AbstractGraphic $shape, i
$objWriter->startElement('p:spPr');
// a:xfrm
$objWriter->startElement('a:xfrm');
$objWriter->writeAttributeIf(0 != $shape->getRotation(), 'rot', CommonDrawing::degreesToAngle((int) $shape->getRotation()));
$objWriter->writeAttributeIf(0 != $shape->getRotation(), 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));

// a:off
$objWriter->startElement('a:off');
Expand Down
14 changes: 14 additions & 0 deletions tests/PhpPresentation/Tests/Writer/ODPresentation/ContentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,20 @@ public function testRichTextBorder(): void
$this->assertIsSchemaOpenDocumentValid('1.2');
}

public function testRichTextRotation(): void
{
$expectedValue = mt_rand(1, 360);
$oRichText1 = $this->oPresentation->getActiveSlide()->createRichTextShape();
$oRichText1->setRotation($expectedValue);

$element = '/office:document-content/office:body/office:presentation/draw:page/draw:frame';
$this->assertZipXmlElementExists('content.xml', $element);
$this->assertZipXmlAttributeExists('content.xml', $element, 'draw:transform');
$this->assertZipXmlAttributeEquals('content.xml', $element, 'draw:transform', 'rotate (-' . deg2rad($expectedValue) . ') translate (0.000cm 0.000cm)');
$element = '/office:document-content/office:body/office:presentation/draw:page/draw:frame/draw:text-box/draw:enhanced-geometry';
$this->assertZipXmlElementExists('content.xml', $element);
}

public function testRichTextShadow(): void
{
$randAlpha = mt_rand(0, 100);
Expand Down

0 comments on commit 5bf5214

Please sign in to comment.