diff --git a/Classes/PHPPowerPoint/Shared/Drawing.php b/Classes/PHPPowerPoint/Shared/Drawing.php
index 0ebbb7163..dfc599a81 100644
--- a/Classes/PHPPowerPoint/Shared/Drawing.php
+++ b/Classes/PHPPowerPoint/Shared/Drawing.php
@@ -83,6 +83,30 @@ public static function pointsToPixels($pValue = 0) {
}
}
+ /**
+ * Convert pixels to centimeters
+ *
+ * @param int $pValue Value in pixels
+ * @return int Value in centimeters
+ */
+ public static function pixelsToCentimeters($pValue = 0) {
+ return $pValue * 0.028;
+ }
+
+ /**
+ * Convert centimeters width to pixels
+ *
+ * @param int $pValue Value in centimeters
+ * @return int Value in pixels
+ */
+ public static function centimetersToPixels($pValue = 0) {
+ if ($pValue != 0) {
+ return $pValue * 0.028;
+ } else {
+ return 0;
+ }
+ }
+
/**
* Convert degrees to angle
*
diff --git a/Classes/PHPPowerPoint/Writer/ODPresentation.php b/Classes/PHPPowerPoint/Writer/ODPresentation.php
new file mode 100644
index 000000000..4514201d5
--- /dev/null
+++ b/Classes/PHPPowerPoint/Writer/ODPresentation.php
@@ -0,0 +1,278 @@
+setPHPPowerPoint($pPHPPowerPoint);
+
+ // Set up disk caching location
+ $this->_diskCachingDirectory = './';
+
+ // Initialise writer parts
+ $this->_writerParts['content'] = new PHPPowerPoint_Writer_ODPresentation_Content();
+ $this->_writerParts['manifest'] = new PHPPowerPoint_Writer_ODPresentation_Manifest();
+ $this->_writerParts['meta'] = new PHPPowerPoint_Writer_ODPresentation_Meta();
+ $this->_writerParts['mimetype'] = new PHPPowerPoint_Writer_ODPresentation_Mimetype();
+
+ $this->_writerParts['drawing'] = new PHPPowerPoint_Writer_ODPresentation_Drawing();
+
+ // Assign parent IWriter
+ foreach ($this->_writerParts as $writer) {
+ $writer->setParentWriter($this);
+ }
+
+ // Set HashTable variables
+ $this->_drawingHashTable = new PHPPowerPoint_HashTable();
+ }
+
+ /**
+ * Save PHPPowerPoint to file
+ *
+ * @param string $pFileName
+ * @throws Exception
+ */
+ public function save($pFilename = null)
+ {
+ if (!is_null($this->_presentation)) {
+ // If $pFilename is php://output or php://stdout, make it a temporary file...
+ $originalFilename = $pFilename;
+ if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
+ $pFilename = @tempnam('./', 'phppttmp');
+ if ($pFilename == '') {
+ $pFilename = $originalFilename;
+ }
+ }
+
+ // Create drawing dictionary
+ $this->_drawingHashTable->addFromSource($this->getWriterPart('Drawing')->allDrawings($this->_presentation));
+
+ // Create new ZIP file and open it for writing
+ $objZip = new ZipArchive();
+
+ // Try opening the ZIP file
+ if ($objZip->open($pFilename, ZIPARCHIVE::OVERWRITE) !== true) {
+ if ($objZip->open($pFilename, ZIPARCHIVE::CREATE) !== true) {
+ throw new Exception("Could not open " . $pFilename . " for writing.");
+ }
+ }
+
+ // Add mimetype to ZIP file
+ //@todo Not in ZIPARCHIVE::CM_STORE mode
+ $objZip->addFromString('mimetype', $this->getWriterPart('mimetype')->writeMimetype($this->_presentation));
+
+ // Add content.xml to ZIP file
+ $objZip->addFromString('content.xml', $this->getWriterPart('content')->writeContent($this->_presentation));
+
+ // Add meta.xml to ZIP file
+ $objZip->addFromString('meta.xml', $this->getWriterPart('meta')->writeMeta($this->_presentation));
+
+ // Add META-INF/manifest.xml
+ $objZip->addFromString('META-INF/manifest.xml', $this->getWriterPart('manifest')->writeManifest($this->_presentation));
+
+ // Add media
+ for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) {
+ if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPPowerPoint_Shape_Drawing) {
+ $imageContents = null;
+ $imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath();
+
+ if (strpos($imagePath, 'zip://') !== false) {
+ $imagePath = substr($imagePath, 6);
+ $imagePathSplitted = explode('#', $imagePath);
+
+ $imageZip = new ZipArchive();
+ $imageZip->open($imagePathSplitted[0]);
+ $imageContents = $imageZip->getFromName($imagePathSplitted[1]);
+ $imageZip->close();
+ unset($imageZip);
+ } else {
+ $imageContents = file_get_contents($imagePath);
+ }
+
+ $objZip->addFromString('Pictures/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);
+ } else if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPPowerPoint_Shape_MemoryDrawing) {
+ ob_start();
+ call_user_func(
+ $this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(),
+ $this->getDrawingHashTable()->getByIndex($i)->getImageResource()
+ );
+ $imageContents = ob_get_contents();
+ ob_end_clean();
+
+ $objZip->addFromString('Pictures/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);
+ }
+ }
+
+ // Close file
+ if ($objZip->close() === false) {
+ throw new Exception("Could not close zip file $pFilename.");
+ }
+
+ // If a temporary file was used, copy it to the correct file stream
+ if ($originalFilename != $pFilename) {
+ if (copy($pFilename, $originalFilename) === false) {
+ throw new Exception("Could not copy temporary zip file $pFilename to $originalFilename.");
+ }
+ @unlink($pFilename);
+ }
+
+ } else {
+ throw new Exception("PHPPowerPoint object unassigned.");
+ }
+ }
+
+ /**
+ * Get PHPPowerPoint object
+ *
+ * @return PHPPowerPoint
+ * @throws Exception
+ */
+ public function getPHPPowerPoint() {
+ if (!is_null($this->_presentation)) {
+ return $this->_presentation;
+ } else {
+ throw new Exception("No PHPPowerPoint assigned.");
+ }
+ }
+
+ /**
+ * Get PHPPowerPoint object
+ *
+ * @param PHPPowerPoint $pPHPPowerPoint PHPPowerPoint object
+ * @throws Exception
+ * @return PHPPowerPoint_Writer_PowerPoint2007
+ */
+ public function setPHPPowerPoint(PHPPowerPoint $pPHPPowerPoint = null) {
+ $this->_presentation = $pPHPPowerPoint;
+ return $this;
+ }
+
+ /**
+ * Get PHPPowerPoint_Worksheet_BaseDrawing HashTable
+ *
+ * @return PHPPowerPoint_HashTable
+ */
+ public function getDrawingHashTable() {
+ return $this->_drawingHashTable;
+ }
+
+ /**
+ * Get writer part
+ *
+ * @param string $pPartName Writer part name
+ * @return PHPPowerPoint_Writer_ODPresentation_WriterPart
+ */
+ function getWriterPart($pPartName = '') {
+ if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) {
+ return $this->_writerParts[strtolower($pPartName)];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get use disk caching where possible?
+ *
+ * @return boolean
+ */
+ public function getUseDiskCaching() {
+ return $this->_useDiskCaching;
+ }
+
+ /**
+ * Set use disk caching where possible?
+ *
+ * @param boolean $pValue
+ * @param string $pDirectory Disk caching directory
+ * @throws Exception Exception when directory does not exist
+ * @return PHPPowerPoint_Writer_PowerPoint2007
+ */
+ public function setUseDiskCaching($pValue = false, $pDirectory = null) {
+ $this->_useDiskCaching = $pValue;
+
+ if (!is_null($pDirectory)) {
+ if (is_dir($pDirectory)) {
+ $this->_diskCachingDirectory = $pDirectory;
+ } else {
+ throw new Exception("Directory does not exist: $pDirectory");
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get disk caching directory
+ *
+ * @return string
+ */
+ public function getDiskCachingDirectory() {
+ return $this->_diskCachingDirectory;
+ }
+}
\ No newline at end of file
diff --git a/Classes/PHPPowerPoint/Writer/ODPresentation/Content.php b/Classes/PHPPowerPoint/Writer/ODPresentation/Content.php
new file mode 100644
index 000000000..07d9553d6
--- /dev/null
+++ b/Classes/PHPPowerPoint/Writer/ODPresentation/Content.php
@@ -0,0 +1,365 @@
+getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPPowerPoint_Shared_XMLWriter(PHPPowerPoint_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPPowerPoint_Shared_XMLWriter(PHPPowerPoint_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0','UTF-8');
+
+ // office:document-content
+ $objWriter->startElement('office:document-content');
+ $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
+ $objWriter->writeAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0');
+ $objWriter->writeAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0');
+ $objWriter->writeAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0');
+ $objWriter->writeAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0');
+ $objWriter->writeAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0');
+ $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+ $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
+ $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0');
+ $objWriter->writeAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0');
+ $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0');
+ $objWriter->writeAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0');
+ $objWriter->writeAttribute('xmlns:chart', 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0');
+ $objWriter->writeAttribute('xmlns:dr3d', 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0');
+ $objWriter->writeAttribute('xmlns:math', 'http://www.w3.org/1998/Math/MathML');
+ $objWriter->writeAttribute('xmlns:form', 'urn:oasis:names:tc:opendocument:xmlns:form:1.0');
+ $objWriter->writeAttribute('xmlns:script', 'urn:oasis:names:tc:opendocument:xmlns:script:1.0');
+ $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');
+ $objWriter->writeAttribute('xmlns:ooow', 'http://openoffice.org/2004/writer');
+ $objWriter->writeAttribute('xmlns:oooc', 'http://openoffice.org/2004/calc');
+ $objWriter->writeAttribute('xmlns:dom', 'http://www.w3.org/2001/xml-events');
+ $objWriter->writeAttribute('xmlns:xforms', 'http://www.w3.org/2002/xforms');
+ $objWriter->writeAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema');
+ $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
+ $objWriter->writeAttribute('xmlns:smil', 'urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0');
+ $objWriter->writeAttribute('xmlns:anim', 'urn:oasis:names:tc:opendocument:xmlns:animation:1.0');
+ $objWriter->writeAttribute('xmlns:rpt', 'http://openoffice.org/2005/report');
+ $objWriter->writeAttribute('xmlns:of', 'urn:oasis:names:tc:opendocument:xmlns:of:1.2');
+ $objWriter->writeAttribute('xmlns:rdfa', 'http://docs.oasis-open.org/opendocument/meta/rdfa#');
+ $objWriter->writeAttribute('xmlns:field', 'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0');
+ $objWriter->writeAttribute('office:version', '1.2');
+
+ // office:automatic-styles
+ $objWriter->startElement('office:automatic-styles');
+
+ $slideCount = $pPHPPowerPoint->getSlideCount();
+ for ($i = 0; $i < $slideCount; ++$i) {
+ $pSlide = $pPHPPowerPoint->getSlide($i);
+ // Images
+ $shapes = $pSlide->getShapeCollection();
+ $shapeId = 0;
+ foreach ($shapes as $shape)
+ {
+ // Increment $shapeId
+ ++$shapeId;
+
+ // Check type
+ if ($shape instanceof PHPPowerPoint_Shape_RichText) {
+
+ // style:style
+ $objWriter->startElement('style:style');
+ $objWriter->writeAttribute('style:name', 'gr'.$shapeId);
+ $objWriter->writeAttribute('style:family', 'graphic');
+ $objWriter->writeAttribute('style:parent-style-name', 'standard');
+ // style:graphic-properties
+ $objWriter->startElement('style:graphic-properties');
+ $objWriter->writeAttribute('draw:auto-grow-height', 'true');
+ $objWriter->writeAttribute('fo:wrap-option', 'wrap');
+
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $paragraphs = $shape->getParagraphs();
+ $paragraphId = 0;
+ foreach ($paragraphs as $paragraph){
+ ++$paragraphId;
+
+ // style:style
+ $objWriter->startElement('style:style');
+ $objWriter->writeAttribute('style:name', 'P'.$shapeId.'_'.$paragraphId);
+ $objWriter->writeAttribute('style:family', 'paragraph');
+ // style:paragraph-properties
+ $objWriter->startElement('style:paragraph-properties');
+ switch ($paragraph->getAlignment()->getHorizontal()) {
+ case PHPPowerPoint_Style_Alignment::HORIZONTAL_LEFT: $objWriter->writeAttribute('fo:text-align', 'left'); break;
+ case PHPPowerPoint_Style_Alignment::HORIZONTAL_RIGHT: $objWriter->writeAttribute('fo:text-align', 'right'); break;
+ case PHPPowerPoint_Style_Alignment::HORIZONTAL_CENTER: $objWriter->writeAttribute('fo:text-align', 'center'); break;
+ case PHPPowerPoint_Style_Alignment::HORIZONTAL_JUSTIFY: $objWriter->writeAttribute('fo:text-align', 'justify'); break;
+ case PHPPowerPoint_Style_Alignment::HORIZONTAL_DISTRIBUTED: $objWriter->writeAttribute('fo:text-align', 'justify'); break;
+ default: $objWriter->writeAttribute('fo:text-align', 'left'); break;
+ }
+
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $richtexts = $paragraph->getRichTextElements();
+ $richtextId = 0;
+ foreach ($richtexts as $richtext) {
+ ++$richtextId;
+
+ $elements = $paragraph->getRichTextElements();
+ $elementId = 0;
+ foreach ($elements as $element) {
+ // Not a line break
+ if ($element instanceof PHPPowerPoint_Shape_RichText_Run) {
+ // style:style
+ $objWriter->startElement('style:style');
+ $objWriter->writeAttribute('style:name', 'T'.$shapeId.'_'.$paragraphId.'_'.$richtextId.'_'.$elementId);
+ $objWriter->writeAttribute('style:family', 'text');
+ // style:text-properties
+ $objWriter->startElement('style:text-properties');
+ $objWriter->writeAttribute('fo:color', '#'.$element->getFont()->getColor()->getRGB());
+ $objWriter->writeAttribute('fo:font-family', $element->getFont()->getName());
+ $objWriter->writeAttribute('fo:font-size', $element->getFont()->getSize().'pt');
+ // @todo : fo:font-style
+ if($element->getFont()->getBold()){
+ $objWriter->writeAttribute('fo:font-weight', 'bold');
+ }
+ // @todo : style:text-underline-style
+ $objWriter->endElement();
+ $objWriter->endElement();
+ }
+ }
+ }
+ }
+ }
+ if ($shape instanceof PHPPowerPoint_Shape_BaseDrawing) {
+ if ($shape->getShadow()->getVisible()) {
+ // style:style
+ $objWriter->startElement('style:style');
+ $objWriter->writeAttribute('style:name', 'gr'.$shapeId);
+ $objWriter->writeAttribute('style:family', 'graphic');
+ $objWriter->writeAttribute('style:parent-style-name', 'standard');
+
+ // style:graphic-properties
+ $objWriter->startElement('style:graphic-properties');
+ $objWriter->writeAttribute('draw:stroke', 'none');
+ $objWriter->writeAttribute('draw:fill', 'none');
+ $objWriter->writeAttribute('draw:shadow', 'visible');
+ $objWriter->writeAttribute('draw:shadow-color', '#'.$shape->getShadow()->getColor()->getRGB());
+ if($shape->getShadow()->getDirection() == 0 || $shape->getShadow()->getDirection() == 360) {
+ $objWriter->writeAttribute('draw:shadow-offset-x', PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getShadow()->getDistance()).'cm');
+ $objWriter->writeAttribute('draw:shadow-offset-y', '0cm');
+ }
+ elseif($shape->getShadow()->getDirection() == 45) {
+ $objWriter->writeAttribute('draw:shadow-offset-x', PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getShadow()->getDistance()).'cm');
+ $objWriter->writeAttribute('draw:shadow-offset-y', PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getShadow()->getDistance()).'cm');
+ }
+ elseif($shape->getShadow()->getDirection() == 90) {
+ $objWriter->writeAttribute('draw:shadow-offset-x', '0cm');
+ $objWriter->writeAttribute('draw:shadow-offset-y', PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getShadow()->getDistance()).'cm');
+ }
+ elseif($shape->getShadow()->getDirection() == 135) {
+ $objWriter->writeAttribute('draw:shadow-offset-x', '-'.PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getShadow()->getDistance()).'cm');
+ $objWriter->writeAttribute('draw:shadow-offset-y', PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getShadow()->getDistance()).'cm');
+ }
+ elseif($shape->getShadow()->getDirection() == 180) {
+ $objWriter->writeAttribute('draw:shadow-offset-x', '-'.PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getShadow()->getDistance()).'cm');
+ $objWriter->writeAttribute('draw:shadow-offset-y', '0cm');
+ }
+ elseif($shape->getShadow()->getDirection() == 225) {
+ $objWriter->writeAttribute('draw:shadow-offset-x', '-'.PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getShadow()->getDistance()).'cm');
+ $objWriter->writeAttribute('draw:shadow-offset-y', '-'.PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getShadow()->getDistance()).'cm');
+ }
+ elseif($shape->getShadow()->getDirection() == 270) {
+ $objWriter->writeAttribute('draw:shadow-offset-x', '0cm');
+ $objWriter->writeAttribute('draw:shadow-offset-y', '-'.PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getShadow()->getDistance()).'cm');
+ }
+ elseif($shape->getShadow()->getDirection() == 315) {
+ $objWriter->writeAttribute('draw:shadow-offset-x', PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getShadow()->getDistance()).'cm');
+ $objWriter->writeAttribute('draw:shadow-offset-y', '-'.PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getShadow()->getDistance()).'cm');
+ }
+
+ $objWriter->writeAttribute('draw:shadow-opacity', (100 - $shape->getShadow()->getAlpha()).'%');
+ $objWriter->writeAttribute('style:mirror', 'none');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+ }
+ }
+ }
+
+ $objWriter->endElement();
+
+ // office:body
+ $objWriter->startElement('office:body');
+ // office:presentation
+ $objWriter->startElement('office:presentation');
+
+ // Write slides
+ $slideCount = $pPHPPowerPoint->getSlideCount();
+ for ($i = 0; $i < $slideCount; ++$i) {
+ $pSlide = $pPHPPowerPoint->getSlide($i);
+ $objWriter->startElement('draw:page');
+ $objWriter->writeAttribute('draw:name', 'page'.$i);
+ $objWriter->writeAttribute('draw:master-page-name', 'Default');
+
+ // Images
+ $shapes = $pSlide->getShapeCollection();
+ $shapeId = 0;
+ foreach ($shapes as $shape)
+ {
+ // Increment $shapeId
+ ++$shapeId;
+
+ // Check type
+ if ($shape instanceof PHPPowerPoint_Shape_RichText)
+ {
+ $this->_writeTxt($objWriter, $shape, $shapeId);
+ }
+ /*else if ($shape instanceof PHPPowerPoint_Shape_Table)
+ {
+ $this->_writeTable($objWriter, $shape, $shapeId);
+ }
+ else if ($shape instanceof PHPPowerPoint_Shape_Line)
+ {
+ $this->_writeLineShape($objWriter, $shape, $shapeId);
+ }
+ else if ($shape instanceof PHPPowerPoint_Shape_Chart)
+ {
+ $this->_writeChart($objWriter, $shape, $shapeId);
+ }
+ else*/ if ($shape instanceof PHPPowerPoint_Shape_BaseDrawing)
+ {
+ $this->_writePic($objWriter, $shape, $shapeId);
+ }
+ }
+
+
+ $objWriter->endElement();
+ $objWriter->endElement();
+ }
+
+ /*
+
+
+
+
+
+ */
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+ function _writePic(PHPPowerPoint_Shared_XMLWriter $objWriter = null, PHPPowerPoint_Shape_BaseDrawing $shape = null, $shapeId){
+ $objWriter->startElement('draw:frame');
+ $objWriter->writeAttribute('draw:name', $shape->getName());
+ $objWriter->writeAttribute('svg:width', number_format(PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getWidth()),3).'cm');
+ $objWriter->writeAttribute('svg:height', number_format(PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getHeight()),3).'cm');
+ $objWriter->writeAttribute('svg:x', number_format(PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getOffsetX()),3).'cm');
+ $objWriter->writeAttribute('svg:y', number_format(PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getOffsetY()),3).'cm');
+ if ($shape->getShadow()->getVisible()) {
+ $objWriter->writeAttribute('draw:style-name', 'gr'.$shapeId);
+ }
+
+ $objWriter->startElement('draw:image');
+ $objWriter->writeAttribute('xlink:href', 'Pictures/'.str_replace(' ', '_', $shape->getIndexedFilename()));
+ $objWriter->writeAttribute('xlink:type', 'simple');
+ $objWriter->writeAttribute('xlink:show', 'embed');
+ $objWriter->writeAttribute('xlink:actuate', 'onLoad');
+
+ $objWriter->writeElement('text:p');
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ function _writeTxt(PHPPowerPoint_Shared_XMLWriter $objWriter = null, PHPPowerPoint_Shape_RichText $shape = null, $shapeId){
+ // draw:custom-shape
+ $objWriter->startElement('draw:custom-shape');
+ $objWriter->writeAttribute('draw:style-name', 'gr'.$shapeId);
+ $objWriter->writeAttribute('svg:width', number_format(PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getWidth()),3).'cm');
+ $objWriter->writeAttribute('svg:height', number_format(PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getHeight()),3).'cm');
+ $objWriter->writeAttribute('svg:x', number_format(PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getOffsetX()),3).'cm');
+ $objWriter->writeAttribute('svg:y', number_format(PHPPowerPoint_Shared_Drawing::pixelsToCentimeters($shape->getOffsetY()),3).'cm');
+
+ $paragraphs = $shape->getParagraphs();
+ $paragraphId = 0;
+ foreach ($paragraphs as $paragraph){
+ ++$paragraphId;
+ // text:p
+ $objWriter->startElement('text:p');
+ $objWriter->writeAttribute('text:style-name', 'P'.$shapeId.'_'.$paragraphId);
+ // Loop trough rich text elements
+ $richtexts = $paragraph->getRichTextElements();
+ $richtextId = 0;
+ foreach ($richtexts as $richtext) {
+
+ ++$richtextId;
+
+ $elements = $paragraph->getRichTextElements();
+ $elementId = 0;
+ foreach ($elements as $element) {
+ // Not a line break
+ if ($element instanceof PHPPowerPoint_Shape_RichText_TextElement || $element instanceof PHPPowerPoint_Shape_RichText_Run) {
+ // text:span
+ $objWriter->startElement('text:span');
+ if($element instanceof PHPPowerPoint_Shape_RichText_Run){
+ $objWriter->writeAttribute('text:style-name', 'T'.$shapeId.'_'.$paragraphId.'_'.$richtextId.'_'.$elementId);
+ }
+ $objWriter->text($richtext->getText());
+ $objWriter->endElement();
+ }
+ }
+ }
+ $objWriter->endElement();
+ }
+ $objWriter->endElement();
+ }
+}
diff --git a/Classes/PHPPowerPoint/Writer/ODPresentation/Drawing.php b/Classes/PHPPowerPoint/Writer/ODPresentation/Drawing.php
new file mode 100644
index 000000000..22f0f3c5d
--- /dev/null
+++ b/Classes/PHPPowerPoint/Writer/ODPresentation/Drawing.php
@@ -0,0 +1,66 @@
+getSlideCount();
+ for ($i = 0; $i < $slideCount; ++$i) {
+ // Loop trough images and add to array
+ $iterator = $pPHPPowerPoint->getSlide($i)->getShapeCollection()->getIterator();
+ while ($iterator->valid()) {
+ if ($iterator->current() instanceof PHPPowerPoint_Shape_BaseDrawing && !($iterator->current() instanceof PHPPowerPoint_Shape_Table)) {
+ $aDrawings[] = $iterator->current();
+ }
+
+ $iterator->next();
+ }
+ }
+
+ return $aDrawings;
+ }
+}
diff --git a/Classes/PHPPowerPoint/Writer/ODPresentation/Manifest.php b/Classes/PHPPowerPoint/Writer/ODPresentation/Manifest.php
new file mode 100644
index 000000000..43b456d9c
--- /dev/null
+++ b/Classes/PHPPowerPoint/Writer/ODPresentation/Manifest.php
@@ -0,0 +1,126 @@
+getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPPowerPoint_Shared_XMLWriter(PHPPowerPoint_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPPowerPoint_Shared_XMLWriter(PHPPowerPoint_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0','UTF-8');
+
+ // manifest:manifest
+ $objWriter->startElement('manifest:manifest');
+ $objWriter->writeAttribute('xmlns:manifest', 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0');
+ $objWriter->writeAttribute('manifest:version', '1.2');
+
+ // manifest:file-entry
+ $objWriter->startElement('manifest:file-entry');
+ $objWriter->writeAttribute('manifest:media-type', 'application/vnd.oasis.opendocument.presentation');
+ $objWriter->writeAttribute('manifest:version', '1.2');
+ $objWriter->writeAttribute('manifest:full-path', '/');
+ $objWriter->endElement();
+ // manifest:file-entry
+ $objWriter->startElement('manifest:file-entry');
+ $objWriter->writeAttribute('manifest:media-type', 'text/xml');
+ $objWriter->writeAttribute('manifest:full-path', 'content.xml');
+ $objWriter->endElement();
+ // manifest:file-entry
+ $objWriter->startElement('manifest:file-entry');
+ $objWriter->writeAttribute('manifest:media-type', 'text/xml');
+ $objWriter->writeAttribute('manifest:full-path', 'meta.xml');
+ $objWriter->endElement();
+
+ for ($i = 0; $i < $this->getParentWriter()->getDrawingHashTable()->count(); ++$i) {
+ if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPPowerPoint_Shape_Drawing) {
+ $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension());
+ $mimeType = $this->_getImageMimeType( $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath() );
+
+ $objWriter->startElement('manifest:file-entry');
+ $objWriter->writeAttribute('manifest:media-type', $mimeType);
+ $objWriter->writeAttribute('manifest:full-path', 'Pictures/' . str_replace(' ', '_', $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()));
+ $objWriter->endElement();
+ } else if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPPowerPoint_Shape_MemoryDrawing) {
+ $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType());
+ $extension = explode('/', $extension);
+ $extension = $extension[1];
+
+ $mimeType = $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType();
+
+ $objWriter->startElement('manifest:file-entry');
+ $objWriter->writeAttribute('manifest:media-type', $mimeType);
+ $objWriter->writeAttribute('manifest:full-path', 'Pictures/' . str_replace(' ', '_', $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()));
+ $objWriter->endElement();
+ }
+ }
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+
+ /**
+ * Get image mime type
+ *
+ * @param string $pFile Filename
+ * @return string Mime Type
+ * @throws Exception
+ */
+ private function _getImageMimeType($pFile = '')
+ {
+ if (PHPPowerPoint_Shared_File::file_exists($pFile)) {
+ $image = getimagesize($pFile);
+ return image_type_to_mime_type($image[2]);
+ } else {
+ throw new Exception("File $pFile does not exist");
+ }
+ }
+}
diff --git a/Classes/PHPPowerPoint/Writer/ODPresentation/Meta.php b/Classes/PHPPowerPoint/Writer/ODPresentation/Meta.php
new file mode 100644
index 000000000..9dddee914
--- /dev/null
+++ b/Classes/PHPPowerPoint/Writer/ODPresentation/Meta.php
@@ -0,0 +1,105 @@
+getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPPowerPoint_Shared_XMLWriter(PHPPowerPoint_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPPowerPoint_Shared_XMLWriter(PHPPowerPoint_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0','UTF-8');
+
+ // office:document-meta
+ $objWriter->startElement('office:document-meta');
+ $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
+ $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+ $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
+ $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0');
+ $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0');
+ $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');
+ $objWriter->writeAttribute('xmlns:smil', 'urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0');
+ $objWriter->writeAttribute('xmlns:anim', 'urn:oasis:names:tc:opendocument:xmlns:animation:1.0');
+ $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#');
+ $objWriter->writeAttribute('xmlns:officeooo', 'http://openoffice.org/2009/office');
+ $objWriter->writeAttribute('xmlns:drawooo', 'http://openoffice.org/2010/draw');
+ $objWriter->writeAttribute('office:version', '1.2');
+
+ // office:meta
+ $objWriter->startElement('office:meta');
+
+ // dc:creator
+ $objWriter->writeElement('dc:creator', $pPHPPowerPoint->getProperties()->getLastModifiedBy());
+ // dc:date
+ $objWriter->writeElement('dc:date', gmdate('Y-m-d\TH:i:s.000' ,$pPHPPowerPoint->getProperties()->getModified()));
+ // dc:description
+ $objWriter->writeElement('dc:description', $pPHPPowerPoint->getProperties()->getDescription());
+ // dc:subject
+ $objWriter->writeElement('dc:subject', $pPHPPowerPoint->getProperties()->getSubject());
+ // dc:title
+ $objWriter->writeElement('dc:title', $pPHPPowerPoint->getProperties()->getTitle());
+ // meta:creation-date
+ $objWriter->writeElement('meta:creation-date', gmdate('Y-m-d\TH:i:s.000' ,$pPHPPowerPoint->getProperties()->getCreated()));
+ // meta:initial-creator
+ $objWriter->writeElement('meta:initial-creator', $pPHPPowerPoint->getProperties()->getCreator());
+ // meta:keyword
+ $objWriter->writeElement('meta:keyword', $pPHPPowerPoint->getProperties()->getKeywords());
+
+ // @todo : Where these properties are written ?
+ // $pPHPPowerPoint->getProperties()->getCategory()
+ // $pPHPPowerPoint->getProperties()->getCompany()
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+}
diff --git a/Classes/PHPPowerPoint/Writer/ODPresentation/Mimetype.php b/Classes/PHPPowerPoint/Writer/ODPresentation/Mimetype.php
new file mode 100644
index 000000000..42d80fd67
--- /dev/null
+++ b/Classes/PHPPowerPoint/Writer/ODPresentation/Mimetype.php
@@ -0,0 +1,51 @@
+_parentWriter = $pWriter;
+ }
+
+ /**
+ * Get parent IWriter object
+ *
+ * @return PHPPowerPoint_Writer_IWriter
+ * @throws Exception
+ */
+ public function getParentWriter() {
+ if (!is_null($this->_parentWriter)) {
+ return $this->_parentWriter;
+ } else {
+ throw new Exception("No parent PHPPowerPoint_Writer_IWriter assigned.");
+ }
+ }
+}
diff --git a/Tests/01simple.php b/Tests/01simple.php
index e223d4848..81cfcbc5f 100644
--- a/Tests/01simple.php
+++ b/Tests/01simple.php
@@ -84,6 +84,10 @@
$objWriter = PHPPowerPoint_IOFactory::createWriter($objPHPPowerPoint, 'PowerPoint2007');
$objWriter->save(str_replace('.php', '.pptx', __FILE__));
+echo date('H:i:s') . " Write to OpenDocumentPresentation format
";
+$objWriter = PHPPowerPoint_IOFactory::createWriter($objPHPPowerPoint, 'ODPresentation');
+$objWriter->save(str_replace('.php', '.odp', __FILE__));
+
// Echo memory peak usage
echo date('H:i:s') . " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB\r\n";