From 1ea39dd439945f48defc34a359107c7e0aeb942a Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Fri, 14 Aug 2020 17:10:01 +0200 Subject: [PATCH 01/24] Add read/write Revision document attribut Add read/write Revision document attribut. Informations are stored into document properties. Available for Powerpoint 2007 (reading/writing) --- src/PhpPresentation/DocumentProperties.php | 34 ++++++++++++++++++- src/PhpPresentation/Reader/PowerPoint2007.php | 1 + .../Writer/PowerPoint2007/DocPropsCore.php | 3 ++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/PhpPresentation/DocumentProperties.php b/src/PhpPresentation/DocumentProperties.php index c9344fed25..214fb12f05 100644 --- a/src/PhpPresentation/DocumentProperties.php +++ b/src/PhpPresentation/DocumentProperties.php @@ -91,7 +91,14 @@ class DocumentProperties * @var string */ private $company; - + + /** + * revision + * + * @var string + */ + private $revision; + /** * Create a new \PhpOffice\PhpPresentation\DocumentProperties */ @@ -108,6 +115,7 @@ public function __construct() $this->keywords = ''; $this->category = ''; $this->company = 'Microsoft Corporation'; + $this->revision = ''; } /** @@ -345,4 +353,28 @@ public function setCompany($pValue = '') return $this; } + + /** + * Get Revision + * + * @return string + */ + public function getRevision() + { + return $this->revision; + } + + /** + * Set Revision + * + * @param string $pValue + * @return \PhpOffice\PhpPresentation\DocumentProperties + */ + public function setRevision($pValue = '') + { + $this->revision = $pValue; + + return $this; + } + } diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index aa3b847acc..7b9ff3bc60 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -211,6 +211,7 @@ protected function loadDocumentProperties($sPart) '/cp:coreProperties/cp:category' => 'setCategory', '/cp:coreProperties/dcterms:created' => 'setCreated', '/cp:coreProperties/dcterms:modified' => 'setModified', + '/cp:coreProperties/cp:revision' => 'setRevision', ); $oProperties = $this->oPhpPresentation->getDocumentProperties(); foreach ($arrayProperties as $path => $property) { diff --git a/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php b/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php index 591f42be12..c45d3442d5 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php @@ -56,6 +56,9 @@ public function render() // cp:keywords $objWriter->writeElement('cp:keywords', $this->oPresentation->getDocumentProperties()->getKeywords()); + // cp:revision + $objWriter->writeElement('cp:revision', $this->oPresentation->getDocumentProperties()->getRevision()); + // cp:category $objWriter->writeElement('cp:category', $this->oPresentation->getDocumentProperties()->getCategory()); From 6fc41b35c75e555247f36136cf5415f30ed112de Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Fri, 14 Aug 2020 23:12:38 +0200 Subject: [PATCH 02/24] Conserve thumbnail if already exist in file Conserve thumbnail if already exist in file: If an thumbnail exist in a file, when open it, thumbnail is loaded and when you save existing thumbnail is save to output --- .../PresentationProperties.php | 57 +++++++++++++++++-- src/PhpPresentation/Reader/PowerPoint2007.php | 25 ++++++++ .../PowerPoint2007/DocPropsThumbnail.php | 18 +++++- .../Writer/PowerPoint2007/Relationships.php | 16 +++++- 4 files changed, 107 insertions(+), 9 deletions(-) diff --git a/src/PhpPresentation/PresentationProperties.php b/src/PhpPresentation/PresentationProperties.php index 05b6dbf82d..ba3ab4683a 100644 --- a/src/PhpPresentation/PresentationProperties.php +++ b/src/PhpPresentation/PresentationProperties.php @@ -29,6 +29,8 @@ class PresentationProperties const VIEW_SLIDE_MASTER = 'sldMasterView'; const VIEW_SLIDE_SORTER = 'sldSorterView'; const VIEW_SLIDE_THUMBNAIL = 'sldThumbnailView'; + const THUMBNAIL_FILE = 'file'; // Thumbnail path is out of PPT + const THUMBNAIL_ZIP = 'zip'; // Thumbnail path point to an image store into file loaded protected $arrayView = array( self::VIEW_HANDOUT, @@ -53,9 +55,19 @@ class PresentationProperties protected $markAsFinal = false; /* - * @var string + * @var string Define the thumbnail content (if content into zip file) + */ + protected $thumbnail = null; + + /* + * @var string Define the thumbnail place + */ + protected $thumbnailPath = ''; + + /* + * @var string Define if thumbnail is out of PPT or previouly store into PPT */ - protected $thumbnail; + protected $thumbnailType = self::THUMBNAIL_FILE; /** * Zoom @@ -99,7 +111,27 @@ public function setLoopContinuouslyUntilEsc($value = false) */ public function getThumbnailPath() { + return $this->thumbnailPath; + } + + /** + * Return the content of thumbnail + * + * @return binary Content of image + */ + public function getThumbnail() + { + // Return content of local file + if ($this->getThumbnailType() == self::THUMBNAIL_FILE) { + if (file_exists($this->getThumbnailPath())) + return file_get_contents($this->getThumbnailPath()); + } + // Return content of image stored into zip file + if ($this->getThumbnailType() == self::THUMBNAIL_ZIP) { return $this->thumbnail; + } + // Return null if no thumbnail + return null; } /** @@ -107,14 +139,29 @@ public function getThumbnailPath() * @param string $path * @return \PhpOffice\PhpPresentation\PresentationProperties */ - public function setThumbnailPath($path = '') + public function setThumbnailPath($path = '', $type = self::THUMBNAIL_FILE, $content = null) { - if (file_exists($path)) { - $this->thumbnail = $path; + if (file_exists($path) && ($type == self::THUMBNAIL_FILE)) { + $this->thumbnailPath = $path; + $this->thumbnailType = $type; + } + if (($path != '') && ($type == self::THUMBNAIL_ZIP)) { + $this->thumbnailPath = $path; + $this->thumbnailType = $type; + $this->thumbnail = $content; } return $this; } + /** + * Return the thumbnail type + * @return string + */ + public function getThumbnailType() + { + return $this->thumbnailType; + } + /** * Mark a document as final * @param bool $state diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index 7b9ff3bc60..7c56f41723 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -147,6 +147,11 @@ protected function loadFile($pFilename) $this->loadDocumentProperties($docPropsCore); } + $docThumbnail = $this->oZip->getFromName('_rels/.rels'); + if ($docThumbnail !== false) { + $this->loadThumbnailProperties($docThumbnail); + } + $docPropsCustom = $this->oZip->getFromName('docProps/custom.xml'); if ($docPropsCustom !== false) { $this->loadCustomProperties($docPropsCustom); @@ -229,6 +234,26 @@ protected function loadDocumentProperties($sPart) } } + /** + * Read information of the document thumbnail + * @param string $sPart Content of XML file for retrieving data + */ + protected function loadThumbnailProperties($sPart) + { + $xmlReader = new XMLReader(); + if ($xmlReader->getDomFromString($sPart)) { + $oElement = $xmlReader->getElement('*[@Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"]'); + if ($oElement instanceof \DOMElement) { + $path = $oElement->getAttribute('Target'); + $this->oPhpPresentation + ->getPresentationProperties() + ->setThumbnailPath($path + , \PhpOffice\PhpPresentation\PresentationProperties::THUMBNAIL_ZIP + , $this->oZip->getFromName($path)); + } + } + } + /** * Read Custom Properties * @param string $sPart diff --git a/src/PhpPresentation/Writer/PowerPoint2007/DocPropsThumbnail.php b/src/PhpPresentation/Writer/PowerPoint2007/DocPropsThumbnail.php index 64308a41ce..6110bcc700 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/DocPropsThumbnail.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/DocPropsThumbnail.php @@ -11,8 +11,10 @@ class DocPropsThumbnail extends AbstractDecoratorWriter public function render() { $pathThumbnail = $this->getPresentation()->getPresentationProperties()->getThumbnailPath(); + $type = $this->getPresentation()->getPresentationProperties()->getThumbnailType(); - if ($pathThumbnail) { + // From local file + if ($pathThumbnail && $type == \PhpOffice\PhpPresentation\PresentationProperties::THUMBNAIL_FILE) { $fileThumbnail = file_get_contents($pathThumbnail); $gdImage = imagecreatefromstring($fileThumbnail); if ($gdImage) { @@ -21,7 +23,19 @@ public function render() $imageContents = ob_get_contents(); ob_end_clean(); imagedestroy($gdImage); - + $this->getZip()->addFromString('docProps/thumbnail.jpeg', $imageContents); + } + } + + // From ZIP original file + if ($pathThumbnail && $type == \PhpOffice\PhpPresentation\PresentationProperties::THUMBNAIL_ZIP) { + $gdImage = imagecreatefromstring($this->getPresentation()->getPresentationProperties()->getThumbnail()); + if ($gdImage) { + ob_start(); + imagejpeg($gdImage); + $imageContents = ob_get_contents(); + ob_end_clean(); + imagedestroy($gdImage); $this->getZip()->addFromString('docProps/thumbnail.jpeg', $imageContents); } } diff --git a/src/PhpPresentation/Writer/PowerPoint2007/Relationships.php b/src/PhpPresentation/Writer/PowerPoint2007/Relationships.php index ccc5768592..74da18f4af 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/Relationships.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/Relationships.php @@ -49,8 +49,11 @@ public function writeRelationships() $idxRelation = 5; // Thumbnail - if ($this->getPresentation()->getPresentationProperties()->getThumbnailPath()) { - $pathThumbnail = file_get_contents($this->getPresentation()->getPresentationProperties()->getThumbnailPath()); + $path = $this->getPresentation()->getPresentationProperties()->getThumbnailPath(); + $type = $this->getPresentation()->getPresentationProperties()->getThumbnailType(); + // From local file + if ($path && $type == \PhpOffice\PhpPresentation\PresentationProperties::THUMBNAIL_FILE) { + $pathThumbnail = file_get_contents($path); $gdImage = imagecreatefromstring($pathThumbnail); if ($gdImage) { imagedestroy($gdImage); @@ -58,6 +61,15 @@ public function writeRelationships() $this->writeRelationship($objWriter, $idxRelation, 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail', 'docProps/thumbnail.jpeg'); } } + // From ZIP original file + if ($path && $type == \PhpOffice\PhpPresentation\PresentationProperties::THUMBNAIL_ZIP) { + $gdImage = imagecreatefromstring($this->getPresentation()->getPresentationProperties()->getThumbnail()); + if ($gdImage) { + imagedestroy($gdImage); + // Relationship docProps/thumbnail.jpeg + $this->writeRelationship($objWriter, $idxRelation, 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail', 'docProps/thumbnail.jpeg'); + } + } // ++$idxRelation $objWriter->endElement(); From 27898cfe29e59b9f1db41998898bec4e4cf9d1be Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Sun, 16 Aug 2020 18:25:43 +0200 Subject: [PATCH 03/24] BUGFIX whe setting image ressource Sometime when loading PPTX I've some error --- src/PhpPresentation/Shape/Drawing/Gd.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PhpPresentation/Shape/Drawing/Gd.php b/src/PhpPresentation/Shape/Drawing/Gd.php index d4509d922d..854fa21939 100644 --- a/src/PhpPresentation/Shape/Drawing/Gd.php +++ b/src/PhpPresentation/Shape/Drawing/Gd.php @@ -75,8 +75,8 @@ public function setImageResource($value = null) if (!is_null($this->imageResource)) { // Get width/height - $this->width = imagesx($this->imageResource); - $this->height = imagesy($this->imageResource); + $this->width = (int)@imagesx($this->imageResource); + $this->height = (int)@imagesy($this->imageResource); } return $this; From 18b3c2cbbf8bfb4560440ec97a0d2a02d91f3a25 Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Sun, 16 Aug 2020 18:41:30 +0200 Subject: [PATCH 04/24] BUGFIX While loading some kind of image (EMF) I foud that when an image type like EMF is loaded getimagesizefromstring function does not work --- src/PhpPresentation/Reader/PowerPoint2007.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index 7c56f41723..c4de096023 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -788,9 +788,11 @@ protected function loadShapeDrawing(XMLReader $document, \DOMElement $node, Abst $imageFile = $this->oZip->getFromName($pathImage); if (!empty($imageFile)) { $info = getimagesizefromstring($imageFile); - $oShape->setMimeType($info['mime']); - $oShape->setRenderingFunction(str_replace('/', '', $info['mime'])); - $oShape->setImageResource(imagecreatefromstring($imageFile)); + if (is_array($info)) { + $oShape->setMimeType($info['mime']); + $oShape->setRenderingFunction(str_replace('/', '', $info['mime'])); + $oShape->setImageResource(imagecreatefromstring($imageFile)); + } } } } From 7de13f51e7258fb41bafa2d732a37ae161480462 Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Sun, 16 Aug 2020 23:07:13 +0200 Subject: [PATCH 05/24] EVOL Move Shape name to AbstractShape Evolution : - move Shape::name to AbstractShape - add reading name for Shape in PowerPoint2007 --- src/PhpPresentation/AbstractShape.php | 30 +++++++++++++++++++ src/PhpPresentation/Reader/PowerPoint2007.php | 4 +++ src/PhpPresentation/Shape/AbstractGraphic.php | 29 ------------------ 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/PhpPresentation/AbstractShape.php b/src/PhpPresentation/AbstractShape.php index 9c588df707..32b17e3487 100644 --- a/src/PhpPresentation/AbstractShape.php +++ b/src/PhpPresentation/AbstractShape.php @@ -110,6 +110,13 @@ abstract class AbstractShape implements ComparableInterface */ private $hashIndex; + /** + * Name + * + * @var string + */ + protected $name; + /** * Create a new self */ @@ -122,6 +129,7 @@ public function __construct() $this->width = 0; $this->height = 0; $this->rotation = 0; + $this->name = ''; $this->fill = new Style\Fill(); $this->border = new Style\Border(); $this->shadow = new Style\Shadow(); @@ -190,6 +198,28 @@ public function setContainer(ShapeContainerInterface $pValue = null, $pOverrideO return $this; } + /** + * Get Name + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Set Name + * + * @param string $pValue + * @return \PhpOffice\PhpPresentation\Shape\AbstractGraphic + */ + public function setName($pValue = '') + { + $this->name = $pValue; + return $this; + } + /** * Get OffsetX * diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index c4de096023..0a74d3bb2b 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -889,6 +889,10 @@ protected function loadShapeRichText(XMLReader $document, \DOMElement $node, $oS $this->fileRels = $oSlide->getRelsIndex(); } + $oElement = $document->getElement('p:nvSpPr/p:cNvPr', $node); + if ($oElement instanceof \DOMElement) + $oShape->setName($oElement->hasAttribute('name') ? $oElement->getAttribute('name') : ''); + $oElement = $document->getElement('p:spPr/a:xfrm', $node); if ($oElement instanceof \DOMElement && $oElement->hasAttribute('rot')) { $oShape->setRotation(CommonDrawing::angleToDegrees($oElement->getAttribute('rot'))); diff --git a/src/PhpPresentation/Shape/AbstractGraphic.php b/src/PhpPresentation/Shape/AbstractGraphic.php index 982a08b228..5618021502 100644 --- a/src/PhpPresentation/Shape/AbstractGraphic.php +++ b/src/PhpPresentation/Shape/AbstractGraphic.php @@ -39,13 +39,6 @@ abstract class AbstractGraphic extends AbstractShape implements ComparableInterf */ private $imageIndex = 0; - /** - * Name - * - * @var string - */ - protected $name; - /** * Description * @@ -103,28 +96,6 @@ public function getImageIndex() return $this->imageIndex; } - /** - * Get Name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Set Name - * - * @param string $pValue - * @return $this - */ - public function setName($pValue = '') - { - $this->name = $pValue; - return $this; - } - /** * Get Description * From c70b4039e11b7e55b1b241e0355e322a40a69495 Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Sat, 12 Sep 2020 21:48:07 +0200 Subject: [PATCH 06/24] BUGFIX - Name, in shape, is not preserved if not a placeholder While wrting shape, the name is not preserved if it is not a placehoder --- src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php index 0c220f00f0..7e7e0ba29a 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php @@ -167,7 +167,7 @@ protected function writeShapeText(XMLWriter $objWriter, RichText $shape, $shapeI if ($shape->isPlaceholder()) { $objWriter->writeAttribute('name', 'Placeholder for ' . $shape->getPlaceholder()->getType()); } else { - $objWriter->writeAttribute('name', ''); + $objWriter->writeAttribute('name', $shape->getName()); } // Hyperlink if ($shape->hasHyperlink()) { From 4ee33ec768768b8acbb2287bcc94e08d89e3ae2f Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Sat, 12 Sep 2020 21:54:38 +0200 Subject: [PATCH 07/24] CHG-Load also richtext shape without text It seems tha Powerpoint 2007 use also richtext to define rectangle with or without text. So keep loading richtext without text --- src/PhpPresentation/Reader/PowerPoint2007.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index 0a74d3bb2b..241786318e 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -878,9 +878,6 @@ protected function loadShapeDrawing(XMLReader $document, \DOMElement $node, Abst */ protected function loadShapeRichText(XMLReader $document, \DOMElement $node, $oSlide) { - if (!$document->elementExists('p:txBody/a:p/a:r', $node)) { - return; - } // Core $oShape = $oSlide->createRichTextShape(); $oShape->setParagraphs(array()); From 4796c2874a664f6028c11af6269bd71315b4da1d Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Sat, 12 Sep 2020 22:55:04 +0200 Subject: [PATCH 08/24] ADD-Preserve shape properties (background color, etc.) for richttext When loading richt text shape, read also properties who defining backgroupnd color, border color, etc. use loadStyleFill function --- src/PhpPresentation/Reader/PowerPoint2007.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index 241786318e..5e592aedf0 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -928,6 +928,12 @@ protected function loadShapeRichText(XMLReader $document, \DOMElement $node, $oS $this->loadParagraph($document, $oElement, $oShape); } + $oElement = $document->getElement('p:spPr', $node); + if ($oElement instanceof \DOMElement) { + $oFill = $this->loadStyleFill($document, $oElement); + $oShape->setFill($oFill); + } + if (count($oShape->getParagraphs()) > 0) { $oShape->setActiveParagraph(0); } From 4fa8686a32e481b60815f4ed8a7cedd5f99df3e1 Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Sat, 12 Sep 2020 23:17:59 +0200 Subject: [PATCH 09/24] ADD-Shape RichtText preserve spelling lang while loading When loading a ric text shape, get the spelling lang --- src/PhpPresentation/Reader/PowerPoint2007.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index 5e592aedf0..f9022af202 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -1178,6 +1178,9 @@ protected function loadParagraph(XMLReader $document, \DOMElement $oElement, $oS if ($oElementrPr->hasAttribute('u')) { $oText->getFont()->setUnderline($oElementrPr->getAttribute('u')); } + if ($oElementrPr->hasAttribute('lang')) { + $oText->setLanguage($oElementrPr->getAttribute('lang')); + } // Color $oElementSrgbClr = $document->getElement('a:solidFill/a:srgbClr', $oElementrPr); if (is_object($oElementSrgbClr) && $oElementSrgbClr->hasAttribute('val')) { From 7ac99b8f4fb9dbf2576af7a9069d5510e7c03812 Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Sun, 13 Sep 2020 00:01:17 +0200 Subject: [PATCH 10/24] ADD-Preserve shape richtext font face while loading file Add reading typeface while load file in shape richt text Preserving loading to save --- src/PhpPresentation/Reader/PowerPoint2007.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index f9022af202..08f8d1da09 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -1198,7 +1198,14 @@ protected function loadParagraph(XMLReader $document, \DOMElement $oElement, $oS $oText->getHyperlink()->setUrl($this->arrayRels[$this->fileRels][$oElementHlinkClick->getAttribute('r:id')]['Target']); } } - //} else { + // Font definition + $oElementFont = $document->getElement('a:latin', $oElementrPr); + if (is_object($oElementFont)) { + if ($oElementFont->hasAttribute('typeface')) { + $oText->getFont()->setName($oElementFont->getAttribute('typeface')); + } + } + //} else { // $oText = $oParagraph->createText(); $oSubSubElement = $document->getElement('a:t', $oSubElement); From 19c26f7f5ed4d997d3a08bc4a1661780886adb2d Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Sun, 13 Sep 2020 12:58:15 +0200 Subject: [PATCH 11/24] EVOL-Allow different style of strick paragraph Paragraph double strick were not supported, modification has been done to support different strick type --- src/PhpPresentation/Reader/PowerPoint2007.php | 2 +- src/PhpPresentation/Style/Font.php | 6 +++--- src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index 08f8d1da09..5e9fa2e79f 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -1170,7 +1170,7 @@ protected function loadParagraph(XMLReader $document, \DOMElement $oElement, $oS $oText->getFont()->setItalic($att == 'true' || $att == '1' ? true : false); } if ($oElementrPr->hasAttribute('strike')) { - $oText->getFont()->setStrikethrough($oElementrPr->getAttribute('strike') == 'noStrike' ? false : true); + $oText->getFont()->setStrikethrough($oElementrPr->getAttribute('strike')); } if ($oElementrPr->hasAttribute('sz')) { $oText->getFont()->setSize((int)($oElementrPr->getAttribute('sz') / 100)); diff --git a/src/PhpPresentation/Style/Font.php b/src/PhpPresentation/Style/Font.php index e4b49d0f36..cc22c334ab 100644 --- a/src/PhpPresentation/Style/Font.php +++ b/src/PhpPresentation/Style/Font.php @@ -135,7 +135,7 @@ public function __construct() $this->superScript = false; $this->subScript = false; $this->underline = self::UNDERLINE_NONE; - $this->strikethrough = false; + $this->strikethrough = 'noStrike'; $this->color = new Color(Color::COLOR_BLACK); } @@ -375,10 +375,10 @@ public function isStrikethrough() * @param boolean $pValue * @return \PhpOffice\PhpPresentation\Style\Font */ - public function setStrikethrough($pValue = false) + public function setStrikethrough($pValue = 'noStrike') { if ($pValue == '') { - $pValue = false; + $pValue = 'noStrike'; } $this->strikethrough = $pValue; diff --git a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php index 7e7e0ba29a..a1e184a9f4 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php @@ -581,7 +581,7 @@ protected function writeParagraphs(XMLWriter $objWriter, $paragraphs, $bIsPlaceh $objWriter->writeAttribute('lang', ($element->getLanguage() ? $element->getLanguage() : 'en-US')); $objWriter->writeAttributeIf($element->getFont()->isBold(), 'b', '1'); $objWriter->writeAttributeIf($element->getFont()->isItalic(), 'i', '1'); - $objWriter->writeAttributeIf($element->getFont()->isStrikethrough(), 'strike', 'sngStrike'); + $objWriter->writeAttributeIf($element->getFont()->isStrikethrough(), 'strike', $element->getFont()->isStrikethrough()); $objWriter->writeAttribute('sz', ($element->getFont()->getSize() * 100)); $objWriter->writeAttribute('spc', $element->getFont()->getCharacterSpacing()); $objWriter->writeAttribute('u', $element->getFont()->getUnderline()); From 866a7a2778930225176356917bc215a74904d465 Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Sun, 13 Sep 2020 13:05:03 +0200 Subject: [PATCH 12/24] EVOL-Define const for strike types --- src/PhpPresentation/Style/Font.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/PhpPresentation/Style/Font.php b/src/PhpPresentation/Style/Font.php index cc22c334ab..78a97875be 100644 --- a/src/PhpPresentation/Style/Font.php +++ b/src/PhpPresentation/Style/Font.php @@ -43,6 +43,11 @@ class Font implements ComparableInterface const UNDERLINE_WAVYDOUBLE = 'wavyDbl'; const UNDERLINE_WAVYHEAVY = 'wavyHeavy'; const UNDERLINE_WORDS = 'words'; + + /* Strike types */ + const STRIKE_NONE = 'noStrike'; + const STRIKE_SINGLE = 'sngStrike'; + const STRIKE_DOUBLE = 'dblStrike'; /** * Name @@ -135,7 +140,7 @@ public function __construct() $this->superScript = false; $this->subScript = false; $this->underline = self::UNDERLINE_NONE; - $this->strikethrough = 'noStrike'; + $this->strikethrough = self::STRIKE_NONE; $this->color = new Color(Color::COLOR_BLACK); } @@ -375,10 +380,10 @@ public function isStrikethrough() * @param boolean $pValue * @return \PhpOffice\PhpPresentation\Style\Font */ - public function setStrikethrough($pValue = 'noStrike') + public function setStrikethrough($pValue = self::STRIKE_NONE) { if ($pValue == '') { - $pValue = 'noStrike'; + $pValue = self::STRIKE_NONE; } $this->strikethrough = $pValue; From 3d1b3e2d82cf1fd5a0a3a42220b2671bdae12ca3 Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Sun, 13 Sep 2020 13:39:40 +0200 Subject: [PATCH 13/24] EVOL-Super script and sub script for paragraph Using true/fasle and default value 300000 or -250000 are too mutch (in Office 365). So when reading, get values setted by PowerPoint and modify default values into the code to set values seen during my tests --- src/PhpPresentation/Reader/PowerPoint2007.php | 7 ++++ src/PhpPresentation/Style/Font.php | 32 +++++++++++-------- .../Writer/PowerPoint2007/AbstractSlide.php | 4 +-- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index 5e9fa2e79f..326f4e65fb 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -1181,6 +1181,13 @@ protected function loadParagraph(XMLReader $document, \DOMElement $oElement, $oS if ($oElementrPr->hasAttribute('lang')) { $oText->setLanguage($oElementrPr->getAttribute('lang')); } + if ($oElementrPr->hasAttribute('baseline')) { + if ((int)$oElementrPr->getAttribute('baseline')>0) { + $oText->getFont()->setSuperScript((int)$oElementrPr->getAttribute('baseline')); + } else if ((int)$oElementrPr->getAttribute('baseline')<0) { + $oText->getFont()->setSubScript((int)$oElementrPr->getAttribute('baseline')); + } + } // Color $oElementSrgbClr = $document->getElement('a:solidFill/a:srgbClr', $oElementrPr); if (is_object($oElementSrgbClr) && $oElementSrgbClr->hasAttribute('val')) { diff --git a/src/PhpPresentation/Style/Font.php b/src/PhpPresentation/Style/Font.php index 78a97875be..85c2a2c297 100644 --- a/src/PhpPresentation/Style/Font.php +++ b/src/PhpPresentation/Style/Font.php @@ -48,6 +48,10 @@ class Font implements ComparableInterface const STRIKE_NONE = 'noStrike'; const STRIKE_SINGLE = 'sngStrike'; const STRIKE_DOUBLE = 'dblStrike'; + + /* Script sub and super values */ + const SCRIPT_SUPER = 30000; + const SCRIPT_SUB = -25000; /** * Name @@ -137,8 +141,8 @@ public function __construct() $this->characterSpacing = 0; $this->bold = false; $this->italic = false; - $this->superScript = false; - $this->subScript = false; + $this->superScript = 0; + $this->subScript = 0; $this->underline = self::UNDERLINE_NONE; $this->strikethrough = self::STRIKE_NONE; $this->color = new Color(Color::COLOR_BLACK); @@ -277,7 +281,7 @@ public function setItalic($pValue = false) /** * Get SuperScript * - * @return boolean + * @return integer */ public function isSuperScript() { @@ -287,20 +291,20 @@ public function isSuperScript() /** * Set SuperScript * - * @param boolean $pValue + * @param integer $pValue * @return \PhpOffice\PhpPresentation\Style\Font */ - public function setSuperScript($pValue = false) + public function setSuperScript($pValue = 0) { if ($pValue == '') { - $pValue = false; + $pValue = 0; } $this->superScript = $pValue; // Set SubScript at false only if SuperScript is true - if ($pValue === true) { - $this->subScript = false; + if ($pValue != 0) { + $this->subScript = 0; } return $this; @@ -309,7 +313,7 @@ public function setSuperScript($pValue = false) /** * Get SubScript * - * @return boolean + * @return integer */ public function isSubScript() { @@ -319,20 +323,20 @@ public function isSubScript() /** * Set SubScript * - * @param boolean $pValue + * @param integer $pValue * @return \PhpOffice\PhpPresentation\Style\Font */ - public function setSubScript($pValue = false) + public function setSubScript($pValue = 0) { if ($pValue == '') { - $pValue = false; + $pValue = 0; } $this->subScript = $pValue; // Set SuperScript at false only if SubScript is true - if ($pValue === true) { - $this->superScript = false; + if ($pValue != 0) { + $this->superScript = 0; } return $this; diff --git a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php index a1e184a9f4..f490c4e306 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php @@ -585,8 +585,8 @@ protected function writeParagraphs(XMLWriter $objWriter, $paragraphs, $bIsPlaceh $objWriter->writeAttribute('sz', ($element->getFont()->getSize() * 100)); $objWriter->writeAttribute('spc', $element->getFont()->getCharacterSpacing()); $objWriter->writeAttribute('u', $element->getFont()->getUnderline()); - $objWriter->writeAttributeIf($element->getFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($element->getFont()->isSubScript(), 'baseline', '-250000'); + $objWriter->writeAttributeIf($element->getFont()->isSuperScript()!=0, 'baseline', (int)$element->getFont()->isSuperScript()); + $objWriter->writeAttributeIf($element->getFont()->isSubScript()!=0, 'baseline', (int)$element->getFont()->isSubScript()); // Color - a:solidFill $objWriter->startElement('a:solidFill'); From 2cc01a7e6c50cccaccf955217d3f64bd0dc5ee8d Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Sun, 13 Sep 2020 14:01:41 +0200 Subject: [PATCH 14/24] EVOL-Add capitalize managment for paragraphe Allow capitalize or small capitalize (reading and writing) --- src/PhpPresentation/Reader/PowerPoint2007.php | 3 ++ src/PhpPresentation/Style/Font.php | 37 +++++++++++++++++++ .../Writer/PowerPoint2007/AbstractSlide.php | 2 + 3 files changed, 42 insertions(+) diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index 326f4e65fb..a561065339 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -1188,6 +1188,9 @@ protected function loadParagraph(XMLReader $document, \DOMElement $oElement, $oS $oText->getFont()->setSubScript((int)$oElementrPr->getAttribute('baseline')); } } + if ($oElementrPr->hasAttribute('cap')) { + $oText->getFont()->setCapitalize($oElementrPr->getAttribute('cap')); + } // Color $oElementSrgbClr = $document->getElement('a:solidFill/a:srgbClr', $oElementrPr); if (is_object($oElementSrgbClr) && $oElementSrgbClr->hasAttribute('val')) { diff --git a/src/PhpPresentation/Style/Font.php b/src/PhpPresentation/Style/Font.php index 85c2a2c297..9f5b3f6d70 100644 --- a/src/PhpPresentation/Style/Font.php +++ b/src/PhpPresentation/Style/Font.php @@ -52,6 +52,11 @@ class Font implements ComparableInterface /* Script sub and super values */ const SCRIPT_SUPER = 30000; const SCRIPT_SUB = -25000; + + /* Capitalize types */ + const CAPS_NONE = ''; + const CAPS_SMALL = 'small'; + const CAPS_ALL = 'all'; /** * Name @@ -130,6 +135,13 @@ class Font implements ComparableInterface */ private $hashIndex; + /** + * Capitalize type + * + * @var string + */ + private $capitalize; + /** * Create a new \PhpOffice\PhpPresentation\Style\Font */ @@ -146,6 +158,7 @@ public function __construct() $this->underline = self::UNDERLINE_NONE; $this->strikethrough = self::STRIKE_NONE; $this->color = new Color(Color::COLOR_BLACK); + $this->capitalize = self::CAPS_NONE; } /** @@ -456,4 +469,28 @@ public function setHashIndex($value) { $this->hashIndex = $value; } + + /** + * Set Capitalize + * + * @param string $pValue + * @return \PhpOffice\PhpPresentation\Style\Font + */ + public function setCapitalize($value = self::CAPS_NONE) + { + $this->capitalize = $value; + return $this; + } + /** + * Get Capitalize + * + * @return string + */ + public function getCapitalize() + { + return $this->capitalize; + } + + + } diff --git a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php index f490c4e306..38cb17298d 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php @@ -587,6 +587,8 @@ protected function writeParagraphs(XMLWriter $objWriter, $paragraphs, $bIsPlaceh $objWriter->writeAttribute('u', $element->getFont()->getUnderline()); $objWriter->writeAttributeIf($element->getFont()->isSuperScript()!=0, 'baseline', (int)$element->getFont()->isSuperScript()); $objWriter->writeAttributeIf($element->getFont()->isSubScript()!=0, 'baseline', (int)$element->getFont()->isSubScript()); + if ($element->getFont()->getCapitalize()!='') + $objWriter->writeAttribute('cap', $element->getFont()->getCapitalize()); // Color - a:solidFill $objWriter->startElement('a:solidFill'); From 89d4d95e19137715b1f43508fd55f661c6063cbe Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Wed, 27 Jan 2021 20:27:38 +0100 Subject: [PATCH 15/24] ADD Property 'status' reading and writing ADD the 'status' properties for reading and wrinting into the document --- src/PhpPresentation/DocumentProperties.php | 29 +++++++++++++++++++ src/PhpPresentation/Reader/PowerPoint2007.php | 1 + .../Writer/PowerPoint2007/DocPropsCore.php | 3 ++ 3 files changed, 33 insertions(+) diff --git a/src/PhpPresentation/DocumentProperties.php b/src/PhpPresentation/DocumentProperties.php index 214fb12f05..0d523e15ba 100644 --- a/src/PhpPresentation/DocumentProperties.php +++ b/src/PhpPresentation/DocumentProperties.php @@ -99,6 +99,12 @@ class DocumentProperties */ private $revision; + /** + * status + * + * @var string + */ + private $status; /** * Create a new \PhpOffice\PhpPresentation\DocumentProperties */ @@ -116,6 +122,7 @@ public function __construct() $this->category = ''; $this->company = 'Microsoft Corporation'; $this->revision = ''; + $this->status = ''; } /** @@ -377,4 +384,26 @@ public function setRevision($pValue = '') return $this; } + /** + * Get Status + * + * @return string + */ + public function getStatus() + { + return $this->status; + } + + /** + * Set Status + * + * @param string $pValue + * @return \PhpOffice\PhpPresentation\DocumentProperties + */ + public function setStatus($pValue = '') + { + $this->status = $pValue; + + return $this; + } } diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index a561065339..e5fa53c49d 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -217,6 +217,7 @@ protected function loadDocumentProperties($sPart) '/cp:coreProperties/dcterms:created' => 'setCreated', '/cp:coreProperties/dcterms:modified' => 'setModified', '/cp:coreProperties/cp:revision' => 'setRevision', + '/cp:coreProperties/cp:contentStatus' => 'setStatus', ); $oProperties = $this->oPhpPresentation->getDocumentProperties(); foreach ($arrayProperties as $path => $property) { diff --git a/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php b/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php index c45d3442d5..d1665ef926 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php @@ -59,6 +59,9 @@ public function render() // cp:revision $objWriter->writeElement('cp:revision', $this->oPresentation->getDocumentProperties()->getRevision()); + // cp:contentStatus + $objWriter->writeElement('cp:contentStatus', $this->oPresentation->getDocumentProperties()->getStatus()); + // cp:category $objWriter->writeElement('cp:category', $this->oPresentation->getDocumentProperties()->getCategory()); From faa9610b2d5e7c3641b0dca4e4724a70c9981096 Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Mon, 1 Feb 2021 17:19:32 +0100 Subject: [PATCH 16/24] BUGFIX while cloning an existant slide BUGFIX while cloning an existant slide : - considere if existing object - cloning each object into collection - cloning each paragraph for RichText --- src/PhpPresentation/AbstractShape.php | 19 ++++++++++++++++--- src/PhpPresentation/Shape/RichText.php | 14 ++++++++++++++ src/PhpPresentation/Slide.php | 23 +++++++++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/PhpPresentation/AbstractShape.php b/src/PhpPresentation/AbstractShape.php index 32b17e3487..569944c1c5 100644 --- a/src/PhpPresentation/AbstractShape.php +++ b/src/PhpPresentation/AbstractShape.php @@ -143,9 +143,22 @@ public function __construct() public function __clone() { $this->container = null; - $this->fill = clone $this->fill; - $this->border = clone $this->border; - $this->shadow = clone $this->shadow; + $this->name = $this->name; + if (isset($this->fill)) { + $this->fill = clone $this->fill; + } + if (isset($this->border)) { + $this->border = clone $this->border; + } + if (isset($this->shadow)) { + $this->shadow = clone $this->shadow; + } + if (isset($this->placeholder)) { + $this->placeholder = clone $this->placeholder; + } + if (isset($this->hyperlink)) { + $this->hyperlink = clone $this->hyperlink; + } } /** diff --git a/src/PhpPresentation/Shape/RichText.php b/src/PhpPresentation/Shape/RichText.php index d7cc341523..b8d8986f4d 100644 --- a/src/PhpPresentation/Shape/RichText.php +++ b/src/PhpPresentation/Shape/RichText.php @@ -171,6 +171,20 @@ public function __construct() parent::__construct(); } + /** + * Magic Method : clone + */ + public function __clone() + { + // Call perent clonage for heritage + parent::__clone(); + // Clone each paragraph + if (isset($this->richTextParagraphs)) { + foreach ($this->richTextParagraphs as &$paragraph) { + $paragraph = clone $paragraph; + }} + } + /** * Get active paragraph index * diff --git a/src/PhpPresentation/Slide.php b/src/PhpPresentation/Slide.php index 473d7b73b4..b27b3a5d36 100644 --- a/src/PhpPresentation/Slide.php +++ b/src/PhpPresentation/Slide.php @@ -136,6 +136,29 @@ public function setSlideMasterId($masterId = 1) return $this; } + + public function __clone() + { + // Set parent + $this->parent = clone $this->parent; + // Shape collection + if (isset($this->shapeCollection)) { + $this->shapeCollection = clone $this->shapeCollection; + foreach ($this->shapeCollection as &$shape) { + $shape = clone $shape; + } + } + // Transition object + if (isset($this->slideTransition)) { + $this->slideTransition = clone $this->slideTransition; + } + // Note object + if (isset($this->slideNote)) { + $this->slideNote = clone $this->slideNote; + } + + } + /** * Copy slide (!= clone!) * From 42b844c688526b0748169c00e27799b488ff15bf Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Tue, 2 Feb 2021 15:53:57 +0100 Subject: [PATCH 17/24] ADD Read also texte zone margin RLTB ADD Read also from original PPTX mragin of shape (left,right,top,bottom) Writing already existing and object have been initialized by default (so now setted by reading existing file) --- src/PhpPresentation/Reader/PowerPoint2007.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index e5fa53c49d..4944d68ecd 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -924,6 +924,20 @@ protected function loadShapeRichText(XMLReader $document, \DOMElement $node, $oS } } + $bodyPr = $document->getElement('p:txBody/a:bodyPr', $node); + if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('lIns')) { + $oShape->setInsetLeft((int)$bodyPr->getAttribute('lIns')); + } + if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('tIns')) { + $oShape->setInsetTop((int)$bodyPr->getAttribute('tIns')); + } + if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('rIns')) { + $oShape->setInsetRight((int)$bodyPr->getAttribute('rIns')); + } + if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('bIns')) { + $oShape->setInsetBottom((int)$bodyPr->getAttribute('bIns')); + } + $arrayElements = $document->getElements('p:txBody/a:p', $node); foreach ($arrayElements as $oElement) { $this->loadParagraph($document, $oElement, $oShape); From a97e82c7e1f89550ee44344d1ac9b0a29b34995d Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Tue, 2 Feb 2021 17:03:05 +0100 Subject: [PATCH 18/24] ADD Vertical alignment for shape RichText ADD Vertical alignment for RichText position top,middle and bottom position center or not center Reading from file, editing and saving --- src/PhpPresentation/Reader/PowerPoint2007.php | 6 ++ src/PhpPresentation/Shape/RichText.php | 73 +++++++++++++++++++ .../Writer/PowerPoint2007/AbstractSlide.php | 3 + 3 files changed, 82 insertions(+) diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index 4944d68ecd..6c57b7e471 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -937,6 +937,12 @@ protected function loadShapeRichText(XMLReader $document, \DOMElement $node, $oS if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('bIns')) { $oShape->setInsetBottom((int)$bodyPr->getAttribute('bIns')); } + if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('anchor')) { + $oShape->setVerticalAlignment($bodyPr->getAttribute('anchor')); + } + if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('anchorCtr')) { + $oShape->setVerticalAlignCenter((int)$bodyPr->getAttribute('anchorCtr')); + } $arrayElements = $document->getElements('p:txBody/a:p', $node); foreach ($arrayElements as $oElement) { diff --git a/src/PhpPresentation/Shape/RichText.php b/src/PhpPresentation/Shape/RichText.php index b8d8986f4d..38f9da14f2 100644 --- a/src/PhpPresentation/Shape/RichText.php +++ b/src/PhpPresentation/Shape/RichText.php @@ -40,6 +40,15 @@ class RichText extends AbstractShape implements ComparableInterface /** Overflow */ const OVERFLOW_CLIP = 'clip'; const OVERFLOW_OVERFLOW = 'overflow'; + + /** Vertical alignment */ + const VALIGN_TOP = 't'; + const VALIGN_MIDDLE = 'ctr'; + const VALIGN_BOTTOM = 'b'; + + /** Vertical alignment center */ + const VALIGN_CENTER = 1; + const VALIGN_NOTCENTER = 0; /** * Rich text paragraphs @@ -155,6 +164,17 @@ class RichText extends AbstractShape implements ComparableInterface * @var float */ private $lnSpcReduction; + + /** + * Define vertical text position into shape (top,center,bottom) + * @var string + */ + private $verticalAlign = self::VALIGN_TOP; + /** + * Define vertical text center position into shape (center,not center) + * @var int + */ + private $verticalAlignCenter = self::VALIGN_NOTCENTER; /** * Create a new \PhpOffice\PhpPresentation\Shape\RichText instance @@ -542,6 +562,59 @@ public function setVertical($value = false) return $this; } + + /** + * Define the vertical alignment + * + * @param string|null $value top,center,bottom + * @return $this + * @see self::VALIGN_TOP, self::VALIGN_MIDLE, self::VALIGN_BOTTOM + */ + public function setVerticalAlignment(?string $value) + { + if (isset($value)) { + $this->verticalAlign = $value; + } else { + $this->verticalAlign = self::VALIGN_TOP; + } + return $this; + } + + /** + * Get the vertical alignment + * + * @return string + * @see self::VALIGN_TOP, self::VALIGN_MIDLE, self::VALIGN_BOTTOM + */ + public function getVerticalAlignment():string + { + return $this->verticalAlign; + } + + /** + * Define the vertical alignment if centered or not + * @param int|null $value 1=center 0=not center + * @return $this + * @see self::VALIGN_CENTER, self::VALIGN_NOTCENTER + */ + public function setVerticalAlignCenter(?int $value) + { + if (isset($value)) { + $this->verticalAlignCenter = $value; + } else { + $this->verticalAlignCenter = self::VALIGN_NOTCENTER; + } + return $this; + } + + /** + * Get the vertical alignment center + * @return int + */ + public function getVerticalAlignCenter():int + { + return $this->verticalAlignCenter; + } /** * Get columns diff --git a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php index 38cb17298d..5813ae22dd 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php @@ -258,6 +258,9 @@ protected function writeShapeText(XMLWriter $objWriter, RichText $shape, $shapeI $objWriter->writeAttribute('lIns', CommonDrawing::pixelsToEmu($shape->getInsetLeft())); $objWriter->writeAttribute('rIns', CommonDrawing::pixelsToEmu($shape->getInsetRight())); $objWriter->writeAttribute('tIns', CommonDrawing::pixelsToEmu($shape->getInsetTop())); + // Vertical alignment + $objWriter->writeAttribute('anchor', $shape->getVerticalAlignment()); + $objWriter->writeAttribute('anchorCtr', (int)$shape->getVerticalAlignCenter()); if ($shape->getColumns() <> 1) { $objWriter->writeAttribute('numCol', $shape->getColumns()); } From ecf8e866756036c34dd6048173b99c55aa9467a1 Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Wed, 3 Feb 2021 00:08:24 +0100 Subject: [PATCH 19/24] ADD Effect managment to Shape,Paragraph and Text ADD Effect mangment Effect is a collection of effect into each element (innerShadow, outerShadow, reflection, glos, etc. Actualy only shadow are supported, but the strucure is desgin for other effect --- src/PhpPresentation/AbstractShape.php | 47 +++ src/PhpPresentation/Reader/PowerPoint2007.php | 127 ++++--- .../Shape/RichText/Paragraph.php | 47 +++ src/PhpPresentation/Shape/RichText/Run.php | 47 +++ src/PhpPresentation/Style/Effect.php | 310 ++++++++++++++++++ .../Writer/PowerPoint2007/AbstractSlide.php | 56 +++- 6 files changed, 594 insertions(+), 40 deletions(-) create mode 100644 src/PhpPresentation/Style/Effect.php diff --git a/src/PhpPresentation/AbstractShape.php b/src/PhpPresentation/AbstractShape.php index 569944c1c5..3346488e1b 100644 --- a/src/PhpPresentation/AbstractShape.php +++ b/src/PhpPresentation/AbstractShape.php @@ -103,6 +103,12 @@ abstract class AbstractShape implements ComparableInterface */ protected $placeholder; + /** + * List of effect apply to shape + * @var array \PhpOffice\PhpPresentation\Style\Effect[] + */ + protected ?array $effectCollection = null; + /** * Hash index * @@ -133,6 +139,7 @@ public function __construct() $this->fill = new Style\Fill(); $this->border = new Style\Border(); $this->shadow = new Style\Shadow(); + $this->effectCollection = null; $this->border->setLineStyle(Style\Border::LINE_NONE); } @@ -450,6 +457,46 @@ public function setHyperlink(Hyperlink $pHyperlink = null) $this->hyperlink = $pHyperlink; return $this; } + + /** + * Add an effect to the shpae + * + * @param \PhpOffice\PhpPresentation\Style\Effect $effect + * @return $this + */ + public function addEffect(Shape\Effect $effect) + { + if (!isset($this->effectCollection)) { + $this->effectCollection = array(); + } + $this->effectCollection[] = $effect; + return $this; + } + + /** + * Get the effect collection + * + * @return array \PhpOffice\PhpPresentation\Style\Effect[] + */ + public function getEffectCollection():?array + { + return $this->effectCollection; + } + + /** + * Set the effect collection + * + * @param array \PhpOffice\PhpPresentation\Style\Effect $effectCollection + * @return $this + */ + public function setEffectCollection(array $effectCollection) + { + if ( isset($effectCollection) + && is_array($effectCollection)) { + $this->effectCollection = $effectCollection; + } + return $this; + } /** * Get hash code diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index 6c57b7e471..fe1db4f459 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -830,46 +830,81 @@ protected function loadShapeDrawing(XMLReader $document, \DOMElement $node, Abst $oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy'))); } } - - $oElement = $document->getElement('p:spPr/a:effectLst', $node); - if ($oElement instanceof \DOMElement) { - $oShape->getShadow()->setVisible(true); - - $oSubElement = $document->getElement('a:outerShdw', $oElement); - if ($oSubElement instanceof \DOMElement) { - if ($oSubElement->hasAttribute('blurRad')) { - $oShape->getShadow()->setBlurRadius(CommonDrawing::emuToPixels($oSubElement->getAttribute('blurRad'))); - } - if ($oSubElement->hasAttribute('dist')) { - $oShape->getShadow()->setDistance(CommonDrawing::emuToPixels($oSubElement->getAttribute('dist'))); - } - if ($oSubElement->hasAttribute('dir')) { - $oShape->getShadow()->setDirection(CommonDrawing::angleToDegrees($oSubElement->getAttribute('dir'))); - } - if ($oSubElement->hasAttribute('algn')) { - $oShape->getShadow()->setAlignment($oSubElement->getAttribute('algn')); - } - } - - $oSubElement = $document->getElement('a:outerShdw/a:srgbClr', $oElement); - if ($oSubElement instanceof \DOMElement) { - if ($oSubElement->hasAttribute('val')) { - $oColor = new Color(); - $oColor->setRGB($oSubElement->getAttribute('val')); - $oShape->getShadow()->setColor($oColor); - } - } - - $oSubElement = $document->getElement('a:outerShdw/a:srgbClr/a:alpha', $oElement); - if ($oSubElement instanceof \DOMElement) { - if ($oSubElement->hasAttribute('val')) { - $oShape->getShadow()->setAlpha((int)$oSubElement->getAttribute('val') / 1000); - } - } + // Load shape effects + $oEffect = $document->getElement('p:spPr/a:effectLst', $node); + if ($oEffect instanceof \DOMElement) { + $aEffect = $this->loadEffect($document, $oEffect); + if (isset($aEffect) && is_array($aEffect)) { + $oShape->setEffectCollection($aEffect); + } } - $oSlide->addShape($oShape); } + + /** + * Load Effect for shape or paragraph + * + * @param XMLReader $document + * @param \DOMElement $node + * @return array \PhpOffice\PhpPresentation\Style\Effect[] + */ + protected function loadEffect(XMLReader $document, \DOMElement $nodeEffect) + { + $aEffect = null; + if ($nodeEffect instanceof \DOMElement) { + + $aNodes = $document->getElements('*', $nodeEffect); + foreach ($aNodes as $node) { + + $type = explode(':', $node->tagName); + $type = array_pop($type); + if ( $type == 'outerShdw' + || $type == 'innerShdw') { +// @TODO || $type == 'reflection') { + + // Create a new effect + $effect = new \PhpOffice\PhpPresentation\Style\Effect($type); + // load blur radius + if ($node->hasAttribute('blurRad')) { + $effect->setBlurRadius(CommonDrawing::emuToPixels($node->getAttribute('blurRad'))); + } + // load distance + if ($node->hasAttribute('dist')) { + $effect->setDistance(CommonDrawing::emuToPixels($node->getAttribute('dist'))); + } + // load direction + if ($node->hasAttribute('dir')) { + $effect->setDirection(CommonDrawing::angleToDegrees($node->getAttribute('dir'))); + } + // load alignment + if ($node->hasAttribute('algn')) { + $effect->setAlignment($node->getAttribute('algn')); + } + + // Get color define by prstClr + $oSubElement = $document->getElement('a:prstClr', $node); + if ($oSubElement instanceof \DOMElement && $oSubElement->hasAttribute('val')) { + $oColor = new Color(); + $oColor->setRGB($oSubElement->getAttribute('val')); + $effect->setColor($oColor); + // Get Alpha + $oSubElt = $document->getElement('a:alpha', $oSubElement); + if ($oSubElt instanceof \DOMElement && $oSubElt->hasAttribute('val')) { + $effect->setAlpha((int)$oSubElt->getAttribute('val') / 1000); + } + } + // Load reflection atributs +// @TODO future implementation + if ($node->tagName == 'a:reflection') { + } + + if (!isset($aEffect)) $aEffect = array(); + $aEffect[] = $effect; + } + } + } + return $aEffect; + } /** * @param XMLReader $document @@ -924,6 +959,16 @@ protected function loadShapeRichText(XMLReader $document, \DOMElement $node, $oS } } + // Load shape effects + $oEffect = $document->getElement('p:spPr/a:effectLst', $node); + if ($oEffect instanceof \DOMElement) { + $aEffect = $this->loadEffect($document, $oEffect); + if (isset($aEffect) && is_array($aEffect)) { + $oShape->setEffectCollection($aEffect); + } + } + +// FBU-20210202+ Read body definitions $bodyPr = $document->getElement('p:txBody/a:bodyPr', $node); if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('lIns')) { $oShape->setInsetLeft((int)$bodyPr->getAttribute('lIns')); @@ -1235,6 +1280,14 @@ protected function loadParagraph(XMLReader $document, \DOMElement $oElement, $oS if ($oElementFont->hasAttribute('typeface')) { $oText->getFont()->setName($oElementFont->getAttribute('typeface')); } + } + // Load shape effects + $oEffect = $document->getElement('a:effectLst', $oElementrPr); + if ($oEffect instanceof \DOMElement) { + $aEffect = $this->loadEffect($document, $oEffect); + if (isset($aEffect) && is_array($aEffect)) { + $oText->setEffectCollection($aEffect); + } } //} else { // $oText = $oParagraph->createText(); diff --git a/src/PhpPresentation/Shape/RichText/Paragraph.php b/src/PhpPresentation/Shape/RichText/Paragraph.php index ab64b706ab..66a7d7badf 100644 --- a/src/PhpPresentation/Shape/RichText/Paragraph.php +++ b/src/PhpPresentation/Shape/RichText/Paragraph.php @@ -60,6 +60,12 @@ class Paragraph implements ComparableInterface */ private $lineSpacing = 100; + /** + * List of effect apply to paragraph + * @var array \PhpOffice\PhpPresentation\Style\Effect[] + */ + protected ?array $effectCollection = null; + /** * Hash index * @@ -77,6 +83,7 @@ public function __construct() $this->alignment = new Alignment(); $this->font = new Font(); $this->bulletStyle = new Bullet(); + $this->effectCollection = null; } /** @@ -266,6 +273,46 @@ public function setRichTextElements($pElements = null) return $this; } + /** + * Add an effect to the shpae + * + * @param \PhpOffice\PhpPresentation\Style\Effect $effect + * @return $this + */ + public function addEffect(Shape\Effect $effect) + { + if (!isset($this->effectCollection)) { + $this->effectCollection = array(); + } + $this->effectCollection[] = $effect; + return $this; + } + + /** + * Get the effect collection + * + * @return array \PhpOffice\PhpPresentation\Style\Effect[] + */ + public function getEffectCollection():?array + { + return $this->effectCollection; + } + + /** + * Set the effect collection + * + * @param array \PhpOffice\PhpPresentation\Style\Effect $effectCollection + * @return $this + */ + public function setEffectCollection(array $effectCollection) + { + if ( isset($effectCollection) + && is_array($effectCollection)) { + $this->effectCollection = $effectCollection; + } + return $this; + } + /** * Get hash code * diff --git a/src/PhpPresentation/Shape/RichText/Run.php b/src/PhpPresentation/Shape/RichText/Run.php index 97455c0f11..cfc318deb8 100644 --- a/src/PhpPresentation/Shape/RichText/Run.php +++ b/src/PhpPresentation/Shape/RichText/Run.php @@ -31,6 +31,12 @@ class Run extends TextElement implements TextElementInterface */ private $font; + /** + * List of effect apply to paragraph + * @var array \PhpOffice\PhpPresentation\Style\Effect[] + */ + protected ?array $effectCollection = null; + /** * Create a new \PhpOffice\PhpPresentation\Shape\RichText\Run instance * @@ -41,6 +47,7 @@ public function __construct($pText = '') // Initialise variables $this->setText($pText); $this->font = new Font(); + $this->effectCollection = null; } /** @@ -67,6 +74,46 @@ public function setFont(Font $pFont = null) return $this; } + /** + * Add an effect to the shpae + * + * @param \PhpOffice\PhpPresentation\Style\Effect $effect + * @return $this + */ + public function addEffect(Shape\Effect $effect) + { + if (!isset($this->effectCollection)) { + $this->effectCollection = array(); + } + $this->effectCollection[] = $effect; + return $this; + } + + /** + * Get the effect collection + * + * @return array \PhpOffice\PhpPresentation\Style\Effect[] + */ + public function getEffectCollection():?array + { + return $this->effectCollection; + } + + /** + * Set the effect collection + * + * @param array \PhpOffice\PhpPresentation\Style\Effect $effectCollection + * @return $this + */ + public function setEffectCollection(array $effectCollection) + { + if ( isset($effectCollection) + && is_array($effectCollection)) { + $this->effectCollection = $effectCollection; + } + return $this; + } + /** * Get hash code * diff --git a/src/PhpPresentation/Style/Effect.php b/src/PhpPresentation/Style/Effect.php new file mode 100644 index 0000000000..5c25ca4f4a --- /dev/null +++ b/src/PhpPresentation/Style/Effect.php @@ -0,0 +1,310 @@ +effectType = $type; + $this->blurRadius = 6; + $this->distance = 2; + $this->direction = 0; + $this->alignment = self::SHADOW_BOTTOM_RIGHT; + $this->color = new Color(Color::COLOR_BLACK); + $this->alpha = 50; + } + + /** + * Define the type effect + * + * @param string $type + * @return $this + * @see self::EFFECT_SHADOW_INNER, self::EFFECT_SHADOW_OUTER, self::EFFECT_REFLECTION + */ + public function setEffectType(string $type) + { + $this->effectType = $type; + return $this; + } + + /** + * Get the effect type + * + * @return string + */ + public function getEffectType():string + { + return $this->effectType; + } + + /** + * Set the direction + * + * @param int $dir + * @return $this + */ + public function setDirection(?int $dir) + { + if (!isset($dir)) $dir = 0; + $this->direction = (int)$dir; + return $this; + } + + /** + * Get the direction + * + * @return int + */ + public function getDirection():int + { + return $this->direction; + } + + /** + * Set the blur radius + * + * @param int $radius + * @return $this + */ + public function setBlurRadius(?int $radius) + { + if (!isset($radius)) $radius = 6; + $this->blurRadius = $radius; + return $this; + } + + /** + * Get the blur radius + * + * @return int + */ + public function getBlurRadius():int + { + return $this->blurRadius; + } + + /** + * Get Shadow distance + * + * @return int + */ + public function getDistance():int + { + return $this->distance; + } + + /** + * Set Shadow distance + * + * @param int $distance + * @return $this + */ + public function setDistance(int $distance = 2) + { + $this->distance = $distance; + + return $this; + } + + /** + * Set the effect alignment + * + * @param string $align + * @return $this + */ + public function setAlignment(?string $align) + { + if (!isset($align)) $align = self::SHADOW_BOTTOM_RIGHT; + $this->align = $align; + return $this; + } + + /** + * Get the effect alignment + * + * @return string + */ + public function getAlignment():string + { + return $this->align; + } + + /** + * Set Color + * + * @param \PhpOffice\PhpPresentation\Style\Color $color + * @return $this + */ + public function setColor(Color $color = null) + { + $this->color = $color; + + return $this; + } + + /** + * Get Color + * + * @return \PhpOffice\PhpPresentation\Style\Color + */ + public function getColor() + { + return $this->color; + } + + /** + * Set Alpha + * + * @param int $alpha + * @return $this + */ + public function setAlpha(?int $alpha) + { + if (!isset($alpha)) $alpha = 0; + $this->alpha = $alpha; + + return $this; + } + + /** + * Get Alpha + * + * @return int + */ + public function getAlpha():int + { + return $this->alpha; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() + { + return md5($this->effectType . $this->blurRadius . $this->distance . $this->direction . $this->alignment . $this->color->getHashCode() . $this->alpha . __CLASS__); + } + + /** + * Get hash index + * + * Note that this index may vary during script execution! Only reliable moment is + * while doing a write of a workbook and when changes are not allowed. + * + * @return string Hash index + */ + public function getHashIndex() + { + return $this->hashIndex; + } + + /** + * Set hash index + * + * Note that this index may vary during script execution! Only reliable moment is + * while doing a write of a workbook and when changes are not allowed. + * + * @param string $value Hash index + */ + public function setHashIndex($value) + { + $this->hashIndex = $value; + } + +} diff --git a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php index 5813ae22dd..a72f6832d5 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php @@ -224,7 +224,7 @@ protected function writeShapeText(XMLWriter $objWriter, RichText $shape, $shapeI } $this->writeFill($objWriter, $shape->getFill()); $this->writeBorder($objWriter, $shape->getBorder(), ''); - $this->writeShadow($objWriter, $shape->getShadow()); + $this->writeEffect($objWriter, $shape->getEffectCollection()); // > p:sp\p:spPr $objWriter->endElement(); @@ -597,7 +597,9 @@ protected function writeParagraphs(XMLWriter $objWriter, $paragraphs, $bIsPlaceh $objWriter->startElement('a:solidFill'); $this->writeColor($objWriter, $element->getFont()->getColor()); $objWriter->endElement(); - + // Write Effects + $this->writeEffect($objWriter, $element->getEffectCollection(), 'srgbClr'); + // Font - a:latin $objWriter->startElement('a:latin'); $objWriter->writeAttribute('typeface', $element->getFont()->getName()); @@ -750,6 +752,54 @@ protected function writeShadow(XMLWriter $objWriter, $oShadow) $objWriter->endElement(); } + /** + * Write Effect + * @param XMLWriter $objWriter + * @param array \PhpOffice\PhpPresentation\Style\Effect[] + * @param Shadow $oShadow + */ + protected function writeEffect(XMLWriter $objWriter, ?array $aEffect, ?string $tagClr=null) + { + // NO Effect => return + if (!isset($aEffect) && !is_array($aEffect)) { + return; + } + if (!isset($tagClr)) { + $tagClr = 'prstClr'; + } + + // a:effectLst + $objWriter->startElement('a:effectLst'); + // Write each effect + foreach($aEffect as $effect) { + // a: + if ( $effect->getEffectType() == 'outerShdw' + || $effect->getEffectType() == 'innerShdw') { +// @TODO || $effect->getEffectType() == 'reflection') { + + $objWriter->startElement('a:'.$effect->getEffectType()); + $objWriter->writeAttribute('blurRad', CommonDrawing::pixelsToEmu($effect->getBlurRadius())); + $objWriter->writeAttribute('dist', CommonDrawing::pixelsToEmu($effect->getDistance())); + $objWriter->writeAttribute('dir', CommonDrawing::degreesToAngle($effect->getDirection())); + $objWriter->writeAttribute('algn', $effect->getAlignment()); + $objWriter->writeAttribute('rotWithShape', '0'); + + // a:prstClr + $objWriter->startElement('a:'.$tagClr); + $objWriter->writeAttribute('val', $effect->getColor()->getRGB()); + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $effect->getAlpha() * 1000); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } + /** * Write hyperlink * @@ -1215,7 +1265,7 @@ protected function writeShapePic(XMLWriter $objWriter, AbstractGraphic $shape, $ $this->writeFill($objWriter, $shape->getFill()); $this->writeBorder($objWriter, $shape->getBorder(), ''); - $this->writeShadow($objWriter, $shape->getShadow()); + $this->writeEffect($objWriter, $shape->getEffectCollection()); $objWriter->endElement(); $objWriter->endElement(); From ab1f264892988e7ab4b9681c67ccd3898f0a6b18 Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Wed, 3 Feb 2021 15:33:07 +0100 Subject: [PATCH 20/24] BUGFIX for duplacting slide BUGFIX when duplicating slide an each composants, text into paragraph into richText where forget --- .../Shape/RichText/Paragraph.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/PhpPresentation/Shape/RichText/Paragraph.php b/src/PhpPresentation/Shape/RichText/Paragraph.php index 66a7d7badf..02fe28f4c6 100644 --- a/src/PhpPresentation/Shape/RichText/Paragraph.php +++ b/src/PhpPresentation/Shape/RichText/Paragraph.php @@ -86,6 +86,23 @@ public function __construct() $this->effectCollection = null; } + /** + * Magic Method : clone + */ + public function __clone() + { + // Clone each text + if (isset($this->richTextElements)) { + foreach ($this->richTextElements as &$txtElt) { + $txtElt = clone $txtElt; + }} + // Clone each effect + if (isset($this->effectCollection)) { + foreach ($this->effectCollection as &$effect) { + $effect = clone $effect; + }} + } + /** * Get alignment * From 106cb767ea150ddd01596c2d763a5cae86ec25cc Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Wed, 3 Feb 2021 15:35:03 +0100 Subject: [PATCH 21/24] ADD vertical alos need horz sometimes ADD vertical alos need horz sometimes --- src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php index a72f6832d5..800f4c4969 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php @@ -254,6 +254,9 @@ protected function writeShapeText(XMLWriter $objWriter, RichText $shape, $shapeI if ($shape->isVertical()) { $objWriter->writeAttribute('vert', 'vert'); } + else { + $objWriter->writeAttribute('vert', 'horz'); + } $objWriter->writeAttribute('bIns', CommonDrawing::pixelsToEmu($shape->getInsetBottom())); $objWriter->writeAttribute('lIns', CommonDrawing::pixelsToEmu($shape->getInsetLeft())); $objWriter->writeAttribute('rIns', CommonDrawing::pixelsToEmu($shape->getInsetRight())); From c3523891d6b73b6f030dcb096748bf36bdd634e4 Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Wed, 3 Feb 2021 15:42:46 +0100 Subject: [PATCH 22/24] ADD Get more font attributs Need some mor informations to be same as original when reading, like charset, etc --- src/PhpPresentation/Reader/PowerPoint2007.php | 15 ++- src/PhpPresentation/Style/Font.php | 94 +++++++++++++++++++ .../Writer/PowerPoint2007/AbstractSlide.php | 6 ++ 3 files changed, 111 insertions(+), 4 deletions(-) diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index fe1db4f459..e1f4253e7c 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -1276,10 +1276,17 @@ protected function loadParagraph(XMLReader $document, \DOMElement $oElement, $oS } // Font definition $oElementFont = $document->getElement('a:latin', $oElementrPr); - if (is_object($oElementFont)) { - if ($oElementFont->hasAttribute('typeface')) { - $oText->getFont()->setName($oElementFont->getAttribute('typeface')); - } + if (is_object($oElementFont) && $oElementFont->hasAttribute('typeface')) { + $oText->getFont()->setName($oElementFont->getAttribute('typeface')); + } + if (($oElementFont instanceof \DOMElement) && $oElementFont->hasAttribute('panose')) { + $oText->getFont()->setPanose($oElementFont->getAttribute('panose')); + } + if (($oElementFont instanceof \DOMElement) && $oElementFont->hasAttribute('pitchFamily')) { + $oText->getFont()->setPitchFamily($oElementFont->getAttribute('pitchFamily')); + } + if (($oElementFont instanceof \DOMElement) && $oElementFont->hasAttribute('charset')) { + $oText->getFont()->setCharset($oElementFont->getAttribute('charset')); } // Load shape effects $oEffect = $document->getElement('a:effectLst', $oElementrPr); diff --git a/src/PhpPresentation/Style/Font.php b/src/PhpPresentation/Style/Font.php index 9f5b3f6d70..a467ab60a6 100644 --- a/src/PhpPresentation/Style/Font.php +++ b/src/PhpPresentation/Style/Font.php @@ -65,6 +65,25 @@ class Font implements ComparableInterface */ private $name; + /** + * panose + * + * @var string + */ + private $panose; + /** + * pitchFamily + * + * @var string + */ + private $pitchFamily; + /** + * charset + * + * @var string + */ + private $charset; + /** * Font Size * @@ -183,6 +202,81 @@ public function setName($pValue = 'Calibri') $pValue = 'Calibri'; } $this->name = $pValue; + return $this; + } + + /** + * Get panose + * + * @return string + */ + public function getPanose() + { + return $this->panose; + } + + /** + * Set panose + * + * @param string $pValue + * @return \PhpOffice\PhpPresentation\Style\Font + */ + public function setPanose($pValue) + { + if ($pValue == '') { + $pValue = ''; + } + $this->panose = $pValue; + + return $this; + } + /** + * Get pitchFamily + * + * @return string + */ + public function getPitchFamily() + { + return $this->pitchFamily; + } + + /** + * Set pitchFamily + * + * @param string $pValue + * @return \PhpOffice\PhpPresentation\Style\Font + */ + public function setPitchFamily($pValue) + { + if ($pValue == '') { + $pValue = ''; + } + $this->pitchFamily = $pValue; + + return $this; + } + /** + * Get charset + * + * @return string + */ + public function getCharset() + { + return $this->charset; + } + + /** + * Set charset + * + * @param string $pValue + * @return \PhpOffice\PhpPresentation\Style\Font + */ + public function setCharset($pValue) + { + if ($pValue == '') { + $pValue = ''; + } + $this->charset = $pValue; return $this; } diff --git a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php index 800f4c4969..b055abed22 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php @@ -606,6 +606,12 @@ protected function writeParagraphs(XMLWriter $objWriter, $paragraphs, $bIsPlaceh // Font - a:latin $objWriter->startElement('a:latin'); $objWriter->writeAttribute('typeface', $element->getFont()->getName()); + if ($element->getFont()->getPanose()!="") + $objWriter->writeAttribute('panose', $element->getFont()->getPanose()); + if ($element->getFont()->getPitchFamily()!="") + $objWriter->writeAttribute('pitchFamily', $element->getFont()->getPitchFamily()); + if ($element->getFont()->getCharset()!="") + $objWriter->writeAttribute('charset', $element->getFont()->getCharset()); $objWriter->endElement(); // a:hlinkClick From cfb4a25e41482f47f8ef048fc010362129b9c560 Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Wed, 3 Feb 2021 17:04:50 +0100 Subject: [PATCH 23/24] BUGFIX Forgot clone for effect shape BUGFIX Forgot clone for effect shape --- src/PhpPresentation/AbstractShape.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/PhpPresentation/AbstractShape.php b/src/PhpPresentation/AbstractShape.php index 3346488e1b..22c90b738d 100644 --- a/src/PhpPresentation/AbstractShape.php +++ b/src/PhpPresentation/AbstractShape.php @@ -166,6 +166,11 @@ public function __clone() if (isset($this->hyperlink)) { $this->hyperlink = clone $this->hyperlink; } + // Clone each effect + if (isset($this->effectCollection)) { + foreach ($this->effectCollection as &$effect) { + $effect = clone $effect; + }} } /** From 0bb8b008a72184e51980a4c8c63c5fe5e4043682 Mon Sep 17 00:00:00 2001 From: devX2712 <69680982+devX2712@users.noreply.github.com> Date: Wed, 3 Feb 2021 17:06:59 +0100 Subject: [PATCH 24/24] ADD usefull function te search shape into a slide For modifing existing slide, usefull to search shape and doing action on it --- src/PhpPresentation/Slide/AbstractSlide.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/PhpPresentation/Slide/AbstractSlide.php b/src/PhpPresentation/Slide/AbstractSlide.php index 3e1c5c1730..30b44137ca 100644 --- a/src/PhpPresentation/Slide/AbstractSlide.php +++ b/src/PhpPresentation/Slide/AbstractSlide.php @@ -106,6 +106,24 @@ public function getShapeCollection() return $this->shapeCollection; } + /** + * Search into collection of shapes for a name (eventually filtered by type ex: RichText) + * + * @param string $name The name to find into the shape collection + * @param PhpOffice\PhpPresentation\Shape\RichText | PhpOffice\PhpPresentation\Shape\... $type Type of the class + * @return \ArrayObject|\PhpOffice\PhpPresentation\AbstractShape[] + */ + public function searchShapeByName(string $name, ?string $type=null) + { + if (isset($this->shapeCollection)) { + foreach ($this->shapeCollection as $shape) { + if ($shape->getName() == $name) { + if (!isset($type) || get_class($shape) == $type) { + return $shape; + }}}} + return null; + } + /** * Get collection of shapes *