Skip to content

Commit 735dbe5

Browse files
committed
#218 : PowerPoint2007 : Support text direction in Alignment for Table
1 parent 7db88c5 commit 735dbe5

File tree

7 files changed

+151
-201
lines changed

7 files changed

+151
-201
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
- PowerPoint97 Reader : Support of Slide Note - @Progi1984 GH-226
1919
- PowerPoint2007 Reader : Support of Shape Table - @Progi1984 GH-240
2020
- PowerPoint2007 Reader : Support of Slide Note - @Progi1984 GH-226
21+
- PowerPoint2007 Reader : Support text direction in Alignment for Table - @Progi1984 GH-218
2122
- PowerPoint2007 Writer : Implement character spacing - @jvanoostrom GH-301
2223
- PowerPoint2007 Writer : Axis Bounds in Chart - @Progi1984 GH-269
23-
- PowerPoint2007 Writer : Implement Legend Key in Series for Chart - @Progi1984 GH-319
24+
- PowerPoint2007 Writer : Implement Legend Key in Series for Chart - @Progi1984 GH-319
25+
- PowerPoint2007 Writer : Support text direction in Alignment for Table - @SeregPie GH-218
2426
- Misc : Added two methods for setting Border & Fill in Legend - @Progi1984 GH-265
2527

2628
## 0.7.0 - 2016-09-12

src/PhpPresentation/Reader/PowerPoint2007.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,9 @@ protected function loadShapeTable(XMLReader $document, \DOMElement $node, Abstra
947947
if ($oElementTcPr instanceof \DOMElement) {
948948
$numParagraphs = count($oCell->getParagraphs());
949949
if ($numParagraphs > 0) {
950+
if ($oElementTcPr->hasAttribute('vert')) {
951+
$oCell->getParagraph(0)->getAlignment()->setTextDirection($oElementTcPr->getAttribute('vert'));
952+
}
950953
if ($oElementTcPr->hasAttribute('anchor')) {
951954
$oCell->getParagraph(0)->getAlignment()->setVertical($oElementTcPr->getAttribute('anchor'));
952955
}

src/PhpPresentation/Style/Alignment.php

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,27 @@
2424
*/
2525
class Alignment implements ComparableInterface
2626
{
27-
/* Horizontal alignment styles */
27+
/* Horizontal alignment */
2828
const HORIZONTAL_GENERAL = 'l';
2929
const HORIZONTAL_LEFT = 'l';
3030
const HORIZONTAL_RIGHT = 'r';
3131
const HORIZONTAL_CENTER = 'ctr';
3232
const HORIZONTAL_JUSTIFY = 'just';
3333
const HORIZONTAL_DISTRIBUTED = 'dist';
3434

35-
/* Vertical alignment styles */
35+
/* Vertical alignment */
3636
const VERTICAL_BASE = 'base';
3737
const VERTICAL_AUTO = 'auto';
3838
const VERTICAL_BOTTOM = 'b';
3939
const VERTICAL_TOP = 't';
4040
const VERTICAL_CENTER = 'ctr';
4141

42+
/* Text direction */
43+
const TEXT_DIRECTION_HORIZONTAL = 'horz';
44+
const TEXT_DIRECTION_VERTICAL_90 = 'vert';
45+
const TEXT_DIRECTION_VERTICAL_270 = 'vert270';
46+
const TEXT_DIRECTION_STACKED = 'wordArtVert';
47+
4248
private $supportedStyles = array(
4349
self::HORIZONTAL_GENERAL,
4450
self::HORIZONTAL_LEFT,
@@ -47,63 +53,60 @@ class Alignment implements ComparableInterface
4753

4854
/**
4955
* Horizontal
50-
*
5156
* @var string
5257
*/
5358
private $horizontal;
5459

5560
/**
5661
* Vertical
57-
*
5862
* @var string
5963
*/
6064
private $vertical;
6165

66+
/**
67+
* Text Direction
68+
* @var string
69+
*/
70+
private $textDirection = self::TEXT_DIRECTION_HORIZONTAL;
71+
6272
/**
6373
* Level
64-
*
6574
* @var int
6675
*/
6776
private $level = 0;
6877

6978
/**
7079
* Indent - only possible with horizontal alignment left and right
71-
*
7280
* @var int
7381
*/
7482
private $indent = 0;
7583

7684
/**
7785
* Margin left - only possible with horizontal alignment left and right
78-
*
7986
* @var int
8087
*/
8188
private $marginLeft = 0;
8289

8390
/**
8491
* Margin right - only possible with horizontal alignment left and right
85-
*
8692
* @var int
8793
*/
8894
private $marginRight = 0;
8995

9096
/**
9197
* Margin top
92-
*
9398
* @var int
9499
*/
95100
private $marginTop = 0;
96101

97102
/**
98103
* Margin bottom
99-
*
100104
* @var int
101105
*/
102106
private $marginBottom = 0;
103107

104108
/**
105109
* Hash index
106-
*
107110
* @var string
108111
*/
109112
private $hashIndex;
@@ -324,6 +327,27 @@ public function setMarginBottom($pValue = 0)
324327
return $this;
325328
}
326329

330+
/**
331+
* @return string
332+
*/
333+
public function getTextDirection()
334+
{
335+
return $this->textDirection;
336+
}
337+
338+
/**
339+
* @param string $pValue
340+
* @return Alignment
341+
*/
342+
public function setTextDirection($pValue = self::TEXT_DIRECTION_HORIZONTAL)
343+
{
344+
if (empty($pValue)) {
345+
$pValue = self::TEXT_DIRECTION_HORIZONTAL;
346+
}
347+
$this->textDirection = $pValue;
348+
return $this;
349+
}
350+
327351
/**
328352
* Get hash code
329353
*

src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php

Lines changed: 86 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
use PhpOffice\PhpPresentation\Style\Alignment;
3939
use PhpOffice\PhpPresentation\Style\Bullet;
4040
use PhpOffice\PhpPresentation\Style\Border;
41+
use PhpOffice\PhpPresentation\Style\Color;
4142
use PhpOffice\PhpPresentation\Style\Shadow;
4243
use PhpOffice\PhpPresentation\Slide\AbstractSlide as AbstractSlideAlias;
4344

@@ -433,19 +434,25 @@ protected function writeShapeTable(XMLWriter $objWriter, ShapeTable $shape, $sha
433434
$objWriter->endElement();
434435
// a:tcPr
435436
$objWriter->startElement('a:tcPr');
436-
// Alignment (horizontal)
437437
$firstParagraph = $currentCell->getParagraph(0);
438-
$verticalAlign = $firstParagraph->getAlignment()->getVertical();
438+
$firstParagraphAlignment = $firstParagraph->getAlignment();
439+
440+
// Text Direction
441+
$textDirection = $firstParagraphAlignment->getTextDirection();
442+
if ($textDirection != Alignment::TEXT_DIRECTION_HORIZONTAL) {
443+
$objWriter->writeAttribute('vert', $textDirection);
444+
}
445+
// Alignment (horizontal)
446+
$verticalAlign = $firstParagraphAlignment->getVertical();
439447
if ($verticalAlign != Alignment::VERTICAL_BASE && $verticalAlign != Alignment::VERTICAL_AUTO) {
440448
$objWriter->writeAttribute('anchor', $verticalAlign);
441449
}
442450

443451
// Margins
444-
$alignment = $firstParagraph->getAlignment();
445-
$objWriter->writeAttribute('marL', $alignment->getMarginLeft());
446-
$objWriter->writeAttribute('marR', $alignment->getMarginRight());
447-
$objWriter->writeAttribute('marT', $alignment->getMarginTop());
448-
$objWriter->writeAttribute('marB', $alignment->getMarginBottom());
452+
$objWriter->writeAttribute('marL', $firstParagraphAlignment->getMarginLeft());
453+
$objWriter->writeAttribute('marR', $firstParagraphAlignment->getMarginRight());
454+
$objWriter->writeAttribute('marT', $firstParagraphAlignment->getMarginTop());
455+
$objWriter->writeAttribute('marB', $firstParagraphAlignment->getMarginBottom());
449456

450457
// Determine borders
451458
$borderLeft = $currentCell->getBorders()->getLeft();
@@ -490,46 +497,66 @@ protected function writeShapeTable(XMLWriter $objWriter, ShapeTable $shape, $sha
490497
*
491498
* @param \PhpOffice\Common\XMLWriter $objWriter XML Writer
492499
* @param \PhpOffice\PhpPresentation\Shape\RichText\Paragraph[] $paragraphs
500+
* @param bool $bIsPlaceholder
493501
* @throws \Exception
494502
*/
495-
protected function writeParagraphs(XMLWriter $objWriter, $paragraphs)
503+
protected function writeParagraphs(XMLWriter $objWriter, $paragraphs, $bIsPlaceholder = false)
496504
{
497505
// Loop trough paragraphs
498506
foreach ($paragraphs as $paragraph) {
499507
// a:p
500508
$objWriter->startElement('a:p');
509+
501510
// a:pPr
502-
$objWriter->startElement('a:pPr');
503-
$objWriter->writeAttribute('algn', $paragraph->getAlignment()->getHorizontal());
504-
$objWriter->writeAttribute('fontAlgn', $paragraph->getAlignment()->getVertical());
505-
$objWriter->writeAttribute('marL', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginLeft()));
506-
$objWriter->writeAttribute('marR', CommonDrawing::pixelsToEmu(
507-
$paragraph->getAlignment()->getMarginRight()
508-
));
509-
$objWriter->writeAttribute('indent', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getIndent()));
510-
$objWriter->writeAttribute('lvl', $paragraph->getAlignment()->getLevel());
511-
// Bullet type specified?
512-
if ($paragraph->getBulletStyle()->getBulletType() != Bullet::TYPE_NONE) {
513-
// a:buFont
514-
$objWriter->startElement('a:buFont');
515-
$objWriter->writeAttribute('typeface', $paragraph->getBulletStyle()->getBulletFont());
511+
if (!$bIsPlaceholder) {
512+
$objWriter->startElement('a:pPr');
513+
$objWriter->writeAttribute('algn', $paragraph->getAlignment()->getHorizontal());
514+
$objWriter->writeAttribute('fontAlgn', $paragraph->getAlignment()->getVertical());
515+
$objWriter->writeAttribute('marL', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginLeft()));
516+
$objWriter->writeAttribute('marR', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginRight()));
517+
$objWriter->writeAttribute('indent', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getIndent()));
518+
$objWriter->writeAttribute('lvl', $paragraph->getAlignment()->getLevel());
519+
520+
$objWriter->startElement('a:lnSpc');
521+
$objWriter->startElement('a:spcPct');
522+
$objWriter->writeAttribute('val', $paragraph->getLineSpacing() * 1000);
516523
$objWriter->endElement();
517-
if ($paragraph->getBulletStyle()->getBulletType() == Bullet::TYPE_BULLET) {
518-
// a:buChar
519-
$objWriter->startElement('a:buChar');
520-
$objWriter->writeAttribute('char', $paragraph->getBulletStyle()->getBulletChar());
521-
$objWriter->endElement();
522-
} elseif ($paragraph->getBulletStyle()->getBulletType() == Bullet::TYPE_NUMERIC) {
523-
// a:buAutoNum
524-
$objWriter->startElement('a:buAutoNum');
525-
$objWriter->writeAttribute('type', $paragraph->getBulletStyle()->getBulletNumericStyle());
526-
if ($paragraph->getBulletStyle()->getBulletNumericStartAt() != 1) {
527-
$objWriter->writeAttribute('startAt', $paragraph->getBulletStyle()->getBulletNumericStartAt());
524+
$objWriter->endElement();
525+
526+
// Bullet type specified?
527+
if ($paragraph->getBulletStyle()->getBulletType() != Bullet::TYPE_NONE) {
528+
// Color
529+
// a:buClr must be before a:buFont (else PowerPoint crashes at launch)
530+
if ($paragraph->getBulletStyle()->getBulletColor() instanceof Color) {
531+
$objWriter->startElement('a:buClr');
532+
$this->writeColor($objWriter, $paragraph->getBulletStyle()->getBulletColor());
533+
$objWriter->endElement();
528534
}
535+
536+
// a:buFont
537+
$objWriter->startElement('a:buFont');
538+
$objWriter->writeAttribute('typeface', $paragraph->getBulletStyle()->getBulletFont());
529539
$objWriter->endElement();
540+
541+
if ($paragraph->getBulletStyle()->getBulletType() == Bullet::TYPE_BULLET) {
542+
// a:buChar
543+
$objWriter->startElement('a:buChar');
544+
$objWriter->writeAttribute('char', $paragraph->getBulletStyle()->getBulletChar());
545+
$objWriter->endElement();
546+
} elseif ($paragraph->getBulletStyle()->getBulletType() == Bullet::TYPE_NUMERIC) {
547+
// a:buAutoNum
548+
$objWriter->startElement('a:buAutoNum');
549+
$objWriter->writeAttribute('type', $paragraph->getBulletStyle()->getBulletNumericStyle());
550+
if ($paragraph->getBulletStyle()->getBulletNumericStartAt() != 1) {
551+
$objWriter->writeAttribute('startAt', $paragraph->getBulletStyle()->getBulletNumericStartAt());
552+
}
553+
$objWriter->endElement();
554+
}
530555
}
556+
557+
$objWriter->endElement();
531558
}
532-
$objWriter->endElement();
559+
533560
// Loop trough rich text elements
534561
$elements = $paragraph->getRichTextElements();
535562
foreach ($elements as $element) {
@@ -539,56 +566,57 @@ protected function writeParagraphs(XMLWriter $objWriter, $paragraphs)
539566
} elseif ($element instanceof Run || $element instanceof TextElement) {
540567
// a:r
541568
$objWriter->startElement('a:r');
569+
542570
// a:rPr
543-
if ($element instanceof Run) {
571+
if ($element instanceof Run && !$bIsPlaceholder) {
544572
// a:rPr
545573
$objWriter->startElement('a:rPr');
574+
546575
// Lang
547-
$objWriter->writeAttribute('lang', ($element->getLanguage() ?
548-
$element->getLanguage() : 'en-US'));
549-
// Bold
550-
$objWriter->writeAttribute('b', ($element->getFont()->isBold() ? '1' : '0'));
551-
// Italic
552-
$objWriter->writeAttribute('i', ($element->getFont()->isItalic() ? '1' : '0'));
553-
// Strikethrough
554-
$objWriter->writeAttribute('strike', ($element->getFont()->isStrikethrough() ?
555-
'sngStrike' : 'noStrike'));
576+
$objWriter->writeAttribute('lang', ($element->getLanguage() ? $element->getLanguage() : 'en-US'));
577+
578+
$objWriter->writeAttributeIf($element->getFont()->isBold(), 'b', '1');
579+
$objWriter->writeAttributeIf($element->getFont()->isItalic(), 'i', '1');
580+
$objWriter->writeAttributeIf($element->getFont()->isStrikethrough(), 'strike', 'sngStrike');
581+
556582
// Size
557583
$objWriter->writeAttribute('sz', ($element->getFont()->getSize() * 100));
584+
585+
// Character spacing
586+
$objWriter->writeAttribute('spc', $element->getFont()->getCharacterSpacing());
587+
558588
// Underline
559589
$objWriter->writeAttribute('u', $element->getFont()->getUnderline());
590+
560591
// Superscript / subscript
561-
if ($element->getFont()->isSuperScript() || $element->getFont()->isSubScript()) {
562-
if ($element->getFont()->isSuperScript()) {
563-
$objWriter->writeAttribute('baseline', '30000');
564-
} elseif ($element->getFont()->isSubScript()) {
565-
$objWriter->writeAttribute('baseline', '-25000');
566-
}
567-
}
592+
$objWriter->writeAttributeIf($element->getFont()->isSuperScript(), 'baseline', '30000');
593+
$objWriter->writeAttributeIf($element->getFont()->isSubScript(), 'baseline', '-25000');
594+
568595
// Color - a:solidFill
569596
$objWriter->startElement('a:solidFill');
570-
// a:srgbClr
571-
$objWriter->startElement('a:srgbClr');
572-
$objWriter->writeAttribute('val', $element->getFont()->getColor()->getRGB());
573-
$objWriter->endElement();
597+
$this->writeColor($objWriter, $element->getFont()->getColor());
574598
$objWriter->endElement();
599+
575600
// Font - a:latin
576601
$objWriter->startElement('a:latin');
577602
$objWriter->writeAttribute('typeface', $element->getFont()->getName());
578603
$objWriter->endElement();
604+
579605
// a:hlinkClick
580-
if ($element->hasHyperlink()) {
581-
$this->writeHyperlink($objWriter, $element);
582-
}
606+
$this->writeHyperlink($objWriter, $element);
607+
583608
$objWriter->endElement();
584609
}
610+
585611
// t
586612
$objWriter->startElement('a:t');
587613
$objWriter->writeCData(Text::controlCharacterPHP2OOXML($element->getText()));
588614
$objWriter->endElement();
615+
589616
$objWriter->endElement();
590617
}
591618
}
619+
592620
$objWriter->endElement();
593621
}
594622
}

0 commit comments

Comments
 (0)