Skip to content

Commit 5bf5214

Browse files
committed
ODPresentation Writer : Support for rotation for RichText
1 parent f16f996 commit 5bf5214

File tree

7 files changed

+91
-18
lines changed

7 files changed

+91
-18
lines changed

docs/changes/1.2.0.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44

55
## Enhancements
66

7-
- `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)
7+
- `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)
88
- 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)
99
- Added support for PHP 8.4 by [@Progi1984](https://github.com/Progi1984) in [#839](https://github.com/PHPOffice/PHPPresentation/pull/839)
10-
- `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)
10+
- `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)
1111
- `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)
12-
- 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)
12+
- 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)
13+
- 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)
1314

1415
## Bug fixes
1516

samples/Sample_11_Shape.php

+20
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,25 @@ function fnSlideRichTextLineSpacing(PhpPresentation $objPHPPresentation): void
8181
$shape->createTextRun('Line Spacing 300');
8282
}
8383

84+
function fnSlideRichTextRotation(PhpPresentation $objPHPPresentation): void
85+
{
86+
// Create templated slide
87+
echo date('H:i:s') . ' Create templated slide' . EOL;
88+
$currentSlide = createTemplatedSlide($objPHPPresentation);
89+
90+
// Create a shape (text)
91+
echo date('H:i:s') . ' Create a shape (rich text) with rotation' . EOL;
92+
$shape = $currentSlide->createRichTextShape();
93+
$shape->setHeight(100);
94+
$shape->setWidth(200);
95+
$shape->setOffsetX(200);
96+
$shape->setOffsetY(200);
97+
$shape->getActiveParagraph()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT);
98+
$shape->setRotation(90);
99+
100+
$shape->createTextRun('RichText with rotation');
101+
}
102+
84103
function fnSlideRichTextShadow(PhpPresentation $objPHPPresentation): void
85104
{
86105
// Create templated slide
@@ -143,6 +162,7 @@ function fnSlideRichTextList(PhpPresentation $objPHPPresentation): void
143162

144163
fnSlideRichText($objPHPPresentation);
145164
fnSlideRichTextLineSpacing($objPHPPresentation);
165+
fnSlideRichTextRotation($objPHPPresentation);
146166
fnSlideRichTextShadow($objPHPPresentation);
147167
fnSlideRichTextList($objPHPPresentation);
148168

samples/Sample_Header.php

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
if (preg_match('/^Sample_\d+_/', $file)) {
9393
$name = str_replace('_', ' ', preg_replace('/(Sample_|\.php)/', '', $file));
9494
$group = substr($name, 0, 1);
95+
$id = substr($name, 0, 2);
9596
if (!isset($files[$group])) {
9697
$files[$group] = [];
9798
}

src/PhpPresentation/AbstractShape.php

+4-10
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ abstract class AbstractShape implements ComparableInterface
8585
*
8686
* @var int
8787
*/
88-
protected $rotation;
88+
protected $rotation = 0;
8989

9090
/**
9191
* Shadow.
@@ -123,7 +123,7 @@ abstract class AbstractShape implements ComparableInterface
123123
*/
124124
public function __construct()
125125
{
126-
$this->offsetX = $this->offsetY = $this->width = $this->height = $this->rotation = 0;
126+
$this->offsetX = $this->offsetY = $this->width = $this->height = 0;
127127
$this->fill = new Fill();
128128
$this->shadow = new Shadow();
129129
$this->border = new Border();
@@ -319,22 +319,16 @@ public function setWidthAndHeight(int $width = 0, int $height = 0)
319319

320320
/**
321321
* Get Rotation.
322-
*
323-
* @return int
324322
*/
325-
public function getRotation()
323+
public function getRotation(): int
326324
{
327325
return $this->rotation;
328326
}
329327

330328
/**
331329
* Set Rotation.
332-
*
333-
* @param int $pValue
334-
*
335-
* @return $this
336330
*/
337-
public function setRotation($pValue = 0)
331+
public function setRotation(int $pValue = 0): self
338332
{
339333
$this->rotation = $pValue;
340334

src/PhpPresentation/Writer/ODPresentation/Content.php

+45-2
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,19 @@ protected function writeShapeTxt(XMLWriter $objWriter, RichText $shape): void
501501
$objWriter->writeAttribute('draw:style-name', 'gr' . $this->shapeId);
502502
$objWriter->writeAttribute('svg:width', Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getWidth()), 3) . 'cm');
503503
$objWriter->writeAttribute('svg:height', Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getHeight()), 3) . 'cm');
504-
$objWriter->writeAttribute('svg:x', Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getOffsetX()), 3) . 'cm');
505-
$objWriter->writeAttribute('svg:y', Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getOffsetY()), 3) . 'cm');
504+
if ($shape->getRotation() != 0) {
505+
$rotRad = deg2rad($shape->getRotation());
506+
507+
$translateX = Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getOffsetY()), 3) . 'cm';
508+
$translateY = Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getOffsetX()), 3) . 'cm';
509+
$objWriter->writeAttribute(
510+
'draw:transform',
511+
'rotate (-' . $rotRad . ') translate (' . $translateX . ' ' . $translateY . ')'
512+
);
513+
} else {
514+
$objWriter->writeAttribute('svg:x', Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getOffsetX()), 3) . 'cm');
515+
$objWriter->writeAttribute('svg:y', Text::numberFormat(CommonDrawing::pixelsToCentimeters((int) $shape->getOffsetY()), 3) . 'cm');
516+
}
506517
// draw:text-box
507518
$objWriter->startElement('draw:text-box');
508519

@@ -642,6 +653,38 @@ protected function writeShapeTxt(XMLWriter $objWriter, RichText $shape): void
642653
}
643654
}
644655

656+
if ($shape->getRotation() != 0) {
657+
$objWriter->startElement('draw:enhanced-geometry');
658+
$objWriter->writeAttribute('draw:mirror-horizontal', 'false');
659+
$objWriter->writeAttribute('draw:mirror-vertical', 'false');
660+
$objWriter->writeAttribute('svg:viewBox', '0 0 0 0');
661+
$objWriter->writeAttribute('draw:text-areas', '0 0 ?f3 ?f2');
662+
$objWriter->writeAttribute('draw:type', 'ooxml-rect');
663+
$objWriter->writeAttribute('draw:enhanced-path', 'M 0 0 L ?f3 0 ?f3 ?f2 0 ?f2 Z N');
664+
665+
$objWriter->startElement('draw:equation');
666+
$objWriter->writeAttribute('draw:name', 'f0');
667+
$objWriter->writeAttribute('draw:formula', 'logwidth/2');
668+
$objWriter->endElement();
669+
670+
$objWriter->startElement('draw:equation');
671+
$objWriter->writeAttribute('draw:name', 'f1');
672+
$objWriter->writeAttribute('draw:formula', 'logheight/2');
673+
$objWriter->endElement();
674+
675+
$objWriter->startElement('draw:equation');
676+
$objWriter->writeAttribute('draw:name', 'f2');
677+
$objWriter->writeAttribute('draw:formula', 'logheight');
678+
$objWriter->endElement();
679+
680+
$objWriter->startElement('draw:equation');
681+
$objWriter->writeAttribute('draw:name', 'f3');
682+
$objWriter->writeAttribute('draw:formula', 'logwidth');
683+
$objWriter->endElement();
684+
685+
$objWriter->endElement();
686+
}
687+
645688
// > draw:text-box
646689
$objWriter->endElement();
647690
// > draw:frame

src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,7 @@ protected function writeShapeAutoShape(XMLWriter $objWriter, AutoShape $shape, i
11701170

11711171
// p:sp\p:spPr\a:xfrm
11721172
$objWriter->startElement('a:xfrm');
1173-
$objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle((int) $shape->getRotation()));
1173+
$objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
11741174
// p:sp\p:spPr\a:xfrm\a:off
11751175
$objWriter->startElement('a:off');
11761176
$objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
@@ -1264,7 +1264,7 @@ protected function writeShapeChart(XMLWriter $objWriter, ShapeChart $shape, int
12641264
$objWriter->endElement();
12651265
// p:xfrm
12661266
$objWriter->startElement('p:xfrm');
1267-
$objWriter->writeAttributeIf(0 != $shape->getRotation(), 'rot', CommonDrawing::degreesToAngle((int) $shape->getRotation()));
1267+
$objWriter->writeAttributeIf(0 != $shape->getRotation(), 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
12681268
// a:off
12691269
$objWriter->startElement('a:off');
12701270
$objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
@@ -1427,7 +1427,7 @@ protected function writeShapePic(XMLWriter $objWriter, AbstractGraphic $shape, i
14271427
$objWriter->startElement('p:spPr');
14281428
// a:xfrm
14291429
$objWriter->startElement('a:xfrm');
1430-
$objWriter->writeAttributeIf(0 != $shape->getRotation(), 'rot', CommonDrawing::degreesToAngle((int) $shape->getRotation()));
1430+
$objWriter->writeAttributeIf(0 != $shape->getRotation(), 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
14311431

14321432
// a:off
14331433
$objWriter->startElement('a:off');

tests/PhpPresentation/Tests/Writer/ODPresentation/ContentTest.php

+14
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,20 @@ public function testRichTextBorder(): void
507507
$this->assertIsSchemaOpenDocumentValid('1.2');
508508
}
509509

510+
public function testRichTextRotation(): void
511+
{
512+
$expectedValue = mt_rand(1, 360);
513+
$oRichText1 = $this->oPresentation->getActiveSlide()->createRichTextShape();
514+
$oRichText1->setRotation($expectedValue);
515+
516+
$element = '/office:document-content/office:body/office:presentation/draw:page/draw:frame';
517+
$this->assertZipXmlElementExists('content.xml', $element);
518+
$this->assertZipXmlAttributeExists('content.xml', $element, 'draw:transform');
519+
$this->assertZipXmlAttributeEquals('content.xml', $element, 'draw:transform', 'rotate (-' . deg2rad($expectedValue) . ') translate (0.000cm 0.000cm)');
520+
$element = '/office:document-content/office:body/office:presentation/draw:page/draw:frame/draw:text-box/draw:enhanced-geometry';
521+
$this->assertZipXmlElementExists('content.xml', $element);
522+
}
523+
510524
public function testRichTextShadow(): void
511525
{
512526
$randAlpha = mt_rand(0, 100);

0 commit comments

Comments
 (0)