Skip to content

Commit

Permalink
Added column spacing in RichText & line spacing mode & spacing before…
Browse files Browse the repository at this point in the history
…/after for Paragraph
  • Loading branch information
Progi1984 committed Aug 2, 2021
1 parent 7932eb1 commit a33bd2e
Show file tree
Hide file tree
Showing 19 changed files with 726 additions and 215 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"php": "^7.1|^8.0",
"ext-xml": "*",
"ext-zip": "*",
"phpoffice/common": "0.2.*",
"phpoffice/common": "dev-develop",
"phpoffice/phpspreadsheet": "^1.9.0"
},
"require-dev": {
Expand Down
8 changes: 8 additions & 0 deletions docs/changes/1.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@
- Support for line smooth for line and scatter chart - @ksmeeks0001 GH-626 & @Progi1984 GH-662
- ODPresentation Writer
- PowerPoint2007 Writer
- Support for column spacing for RichText - @zoff83 GH-617 & @Progi1984 GH-663
- PowerPoint2007 Reader
- PowerPoint2007 Writer
- Support for line spacing mode & spacing before/after for Paragraph - @zoff83 GH-617 & @Progi1984 GH-663
- ODPresentation Reader
- ODPresentation Writer
- PowerPoint2007 Reader
- PowerPoint2007 Writer

## Project Management
- Migrated from Travis CI to Github Actions - @Progi1984 GH-635
Expand Down
52 changes: 49 additions & 3 deletions docs/usage/shapes/richtext.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Rich text shapes contain paragraphs of texts. To create a rich text shape, use `createRichTextShape` method of slide.

Each rich text can contain multiples paragraphs.
Each paragraph can contain:
- a `TextElement`
- a `BreakElement`
- a `Run`

Below are the properties that you can set for a rich text shape.

- `wrap`
Expand All @@ -19,15 +25,33 @@ Below are the properties that you can set for a rich text shape.
- `topInset` in pixels
- `autoShrinkHorizontal` (boolean)
- `autoShrinkVertical` (boolean)
- `columnSpacing` see *Column Spacing*

Properties that can be set for each paragraphs are as follow.

- `alignment` <!-- see *[Alignment](#alignment)*-->
- `bulletStyle` see *[Bullet](#bullet)*
- `lineSpacing` see *[LineSpacing](#linespacing)*
- `lineSpacing` see *Line Spacing*
- `font` <!-- see *[Font](#font)*-->

## Bullet
## Column Spacing

For a paragraph, you can define the column spacing.

Example:

``` php
<?php

use PhpOffice\PhpPresentation\Shape\RichText;

$richText = new RichText();
$richText->setColumnSpacing(200);
$columnSpacing = $richText->getColumnSpacing();
```

## Paragraph
### Bullet

For a paragraph, you can define the bullet style.

Expand Down Expand Up @@ -58,9 +82,10 @@ $paragraph->getBulletStyle()->setBulletType(Bullet::TYPE_BULLET);
$paragraph->getBulletStyle()->setBulletColor(new Color(Color::COLOR_RED));
```

## LineSpacing
### Line Spacing

For a paragraph, you can define the line spacing.
By default, mode is in percent (`Paragraph::LINE_SPACING_MODE_PERCENT`), but you can use the point mode (`Paragraph::LINE_SPACING_MODE_POINT`).

Example:

Expand All @@ -72,6 +97,27 @@ use PhpOffice\PhpPresentation\Shape\RichText\Paragraph;
$paragraph = new Paragraph();
$paragraph->setLineSpacing(200);
$lineSpacing = $paragraph->getLineSpacing();

$paragraph->setLineSpacingMode(Paragraph::LINE_SPACING_MODE_POINT);
$lineSpacingMode = $paragraph->getLineSpacingMode();
```

### Spacing

For a paragraph, you can define the spacing before and after the paragraph in point
Example:

``` php
<?php

use PhpOffice\PhpPresentation\Shape\RichText\Paragraph;

$paragraph = new Paragraph();
$paragraph->setSpacingAfter(12);
$spacingAfter = $paragraph->getSpacingAfter();

$paragraph->setSpacingBefore(34);
$spacingBefore = $paragraph->getSpacingBefore();
```

## Run
Expand Down
2 changes: 1 addition & 1 deletion samples/Sample_01_Simple.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
$shape = $currentSlide->createDrawingShape();
$shape->setName('PHPPresentation logo')
->setDescription('PHPPresentation logo')
->setPath('./resources/phppowerpoint_logo.gif')
->setPath(__DIR__ . '/resources/phppowerpoint_logo.gif')
->setHeight(36)
->setOffsetX(10)
->setOffsetY(10);
Expand Down
74 changes: 68 additions & 6 deletions src/PhpPresentation/Reader/ODPresentation.php
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,19 @@ protected function loadStyle(DOMElement $nodeStyle)

$nodeParagraphProps = $this->oXMLReader->getElement('style:paragraph-properties', $nodeStyle);
if ($nodeParagraphProps instanceof DOMElement) {
if ($nodeParagraphProps->hasAttribute('fo:line-height')) {
$lineHeightUnit = $this->getExpressionUnit($nodeParagraphProps->getAttribute('fo:margin-bottom'));
$lineSpacingMode = $lineHeightUnit == '%' ? Paragraph::LINE_SPACING_MODE_PERCENT : Paragraph::LINE_SPACING_MODE_POINT;
$lineSpacing = $this->getExpressionValue($nodeParagraphProps->getAttribute('fo:margin-bottom'));
}
if ($nodeParagraphProps->hasAttribute('fo:margin-bottom')) {
$spacingAfter = (float) substr($nodeParagraphProps->getAttribute('fo:margin-bottom'), 0, -2);
$spacingAfter = CommonDrawing::centimetersToPoints($spacingAfter);
}
if ($nodeParagraphProps->hasAttribute('fo:margin-top')) {
$spacingBefore = (float) substr($nodeParagraphProps->getAttribute('fo:margin-top'), 0, -2);
$spacingBefore = CommonDrawing::centimetersToPoints($spacingBefore);
}
$oAlignment = new Alignment();
if ($nodeParagraphProps->hasAttribute('fo:text-align')) {
$oAlignment->setHorizontal($nodeParagraphProps->getAttribute('fo:text-align'));
Expand Down Expand Up @@ -432,12 +445,16 @@ protected function loadStyle(DOMElement $nodeStyle)
}

$this->arrayStyles[$keyStyle] = [
'alignment' => isset($oAlignment) ? $oAlignment : null,
'background' => isset($oBackground) ? $oBackground : null,
'fill' => isset($oFill) ? $oFill : null,
'font' => isset($oFont) ? $oFont : null,
'shadow' => isset($oShadow) ? $oShadow : null,
'listStyle' => isset($arrayListStyle) ? $arrayListStyle : null,
'alignment' => $oAlignment ?? null,
'background' => $oBackground ?? null,
'fill' => $oFill ?? null,
'font' => $oFont ?? null,
'shadow' => $oShadow ?? null,
'listStyle' => $arrayListStyle ?? null,
'spacingAfter' => $spacingAfter ?? null,
'spacingBefore' => $spacingBefore ?? null,
'lineSpacingMode' => $lineSpacingMode ?? null,
'lineSpacing' => $lineSpacing ?? null,
];

return true;
Expand Down Expand Up @@ -565,6 +582,23 @@ protected function loadShapeRichText(DOMElement $oNodeFrame): void
protected function readParagraph(RichText $oShape, DOMElement $oNodeParent): void
{
$oParagraph = $oShape->createParagraph();
if ($oNodeParent->hasAttribute('text:style-name')) {
$keyStyle = $oNodeParent->getAttribute('text:style-name');
if (isset($this->arrayStyles[$keyStyle])) {
if (!empty($this->arrayStyles[$keyStyle]['spacingAfter'])) {
$oParagraph->setSpacingAfter($this->arrayStyles[$keyStyle]['spacingAfter']);
}
if (!empty($this->arrayStyles[$keyStyle]['spacingBefore'])) {
$oParagraph->setSpacingBefore($this->arrayStyles[$keyStyle]['spacingBefore']);
}
if (!empty($this->arrayStyles[$keyStyle]['lineSpacingMode'])) {
$oParagraph->setLineSpacingMode($this->arrayStyles[$keyStyle]['lineSpacingMode']);
}
if (!empty($this->arrayStyles[$keyStyle]['lineSpacing'])) {
$oParagraph->setLineSpacing($this->arrayStyles[$keyStyle]['lineSpacing']);
}
}
}
$oDomList = $this->oXMLReader->getElements('text:span', $oNodeParent);
$oDomTextNodes = $this->oXMLReader->getElements('text()', $oNodeParent);
foreach ($oDomTextNodes as $oDomTextNode) {
Expand Down Expand Up @@ -666,4 +700,32 @@ protected function loadStylesFile(): void
}
}
}

/**
* @param string $expr
*
* @return string
*/
private function getExpressionUnit(string $expr): string
{
if (substr($expr, -1) == '%') {
return '%';
}

return substr($expr, -2);
}

/**
* @param string $expr
*
* @return string
*/
private function getExpressionValue(string $expr): string
{
if (substr($expr, -1) == '%') {
return substr($expr, 0, -1);
}

return substr($expr, 0, -2);
}
}
57 changes: 38 additions & 19 deletions src/PhpPresentation/Reader/PowerPoint2007.php
Original file line number Diff line number Diff line change
Expand Up @@ -798,27 +798,27 @@ protected function loadShapeDrawing(XMLReader $document, DOMElement $node, Abstr
$oElement = $document->getElement('p:spPr/a:xfrm', $node);
if ($oElement instanceof DOMElement) {
if ($oElement->hasAttribute('rot')) {
$oShape->setRotation(CommonDrawing::angleToDegrees($oElement->getAttribute('rot')));
$oShape->setRotation((int) CommonDrawing::angleToDegrees($oElement->getAttribute('rot')));
}
}

$oElement = $document->getElement('p:spPr/a:xfrm/a:off', $node);
if ($oElement instanceof DOMElement) {
if ($oElement->hasAttribute('x')) {
$oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
$oShape->setOffsetX((int) CommonDrawing::emuToPixels($oElement->getAttribute('x')));
}
if ($oElement->hasAttribute('y')) {
$oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
$oShape->setOffsetY((int) CommonDrawing::emuToPixels($oElement->getAttribute('y')));
}
}

$oElement = $document->getElement('p:spPr/a:xfrm/a:ext', $node);
if ($oElement instanceof DOMElement) {
if ($oElement->hasAttribute('cx')) {
$oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
$oShape->setWidth((int) CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
}
if ($oElement->hasAttribute('cy')) {
$oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
$oShape->setHeight((int) CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
}
}

Expand All @@ -829,13 +829,13 @@ protected function loadShapeDrawing(XMLReader $document, DOMElement $node, Abstr
$oSubElement = $document->getElement('a:outerShdw', $oElement);
if ($oSubElement instanceof DOMElement) {
if ($oSubElement->hasAttribute('blurRad')) {
$oShape->getShadow()->setBlurRadius(CommonDrawing::emuToPixels($oSubElement->getAttribute('blurRad')));
$oShape->getShadow()->setBlurRadius((int) CommonDrawing::emuToPixels($oSubElement->getAttribute('blurRad')));
}
if ($oSubElement->hasAttribute('dist')) {
$oShape->getShadow()->setDistance(CommonDrawing::emuToPixels($oSubElement->getAttribute('dist')));
$oShape->getShadow()->setDistance((int) CommonDrawing::emuToPixels($oSubElement->getAttribute('dist')));
}
if ($oSubElement->hasAttribute('dir')) {
$oShape->getShadow()->setDirection(CommonDrawing::angleToDegrees($oSubElement->getAttribute('dir')));
$oShape->getShadow()->setDirection((int) CommonDrawing::angleToDegrees($oSubElement->getAttribute('dir')));
}
if ($oSubElement->hasAttribute('algn')) {
$oShape->getShadow()->setAlignment($oSubElement->getAttribute('algn'));
Expand Down Expand Up @@ -880,26 +880,26 @@ protected function loadShapeRichText(XMLReader $document, DOMElement $node, Abst

$oElement = $document->getElement('p:spPr/a:xfrm', $node);
if ($oElement instanceof DOMElement && $oElement->hasAttribute('rot')) {
$oShape->setRotation(CommonDrawing::angleToDegrees($oElement->getAttribute('rot')));
$oShape->setRotation((int) CommonDrawing::angleToDegrees($oElement->getAttribute('rot')));
}

$oElement = $document->getElement('p:spPr/a:xfrm/a:off', $node);
if ($oElement instanceof DOMElement) {
if ($oElement->hasAttribute('x')) {
$oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
$oShape->setOffsetX((int) CommonDrawing::emuToPixels($oElement->getAttribute('x')));
}
if ($oElement->hasAttribute('y')) {
$oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
$oShape->setOffsetY((int) CommonDrawing::emuToPixels($oElement->getAttribute('y')));
}
}

$oElement = $document->getElement('p:spPr/a:xfrm/a:ext', $node);
if ($oElement instanceof DOMElement) {
if ($oElement->hasAttribute('cx')) {
$oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
$oShape->setWidth((int) CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
}
if ($oElement->hasAttribute('cy')) {
$oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
$oShape->setHeight((int) CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
}
}

Expand Down Expand Up @@ -945,20 +945,20 @@ protected function loadShapeTable(XMLReader $document, DOMElement $node, Abstrac
$oElement = $document->getElement('p:xfrm/a:off', $node);
if ($oElement instanceof DOMElement) {
if ($oElement->hasAttribute('x')) {
$oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
$oShape->setOffsetX((int) CommonDrawing::emuToPixels($oElement->getAttribute('x')));
}
if ($oElement->hasAttribute('y')) {
$oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
$oShape->setOffsetY((int) CommonDrawing::emuToPixels($oElement->getAttribute('y')));
}
}

$oElement = $document->getElement('p:xfrm/a:ext', $node);
if ($oElement instanceof DOMElement) {
if ($oElement->hasAttribute('cx')) {
$oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
$oShape->setWidth((int) CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
}
if ($oElement->hasAttribute('cy')) {
$oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
$oShape->setHeight((int) CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
}
}

Expand All @@ -967,7 +967,7 @@ protected function loadShapeTable(XMLReader $document, DOMElement $node, Abstrac
$oShape->createRow();
foreach ($arrayElements as $key => $oElement) {
if ($oElement instanceof DOMElement && $oElement->getAttribute('w')) {
$oShape->getRow(0)->getCell($key)->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('w')));
$oShape->getRow(0)->getCell($key)->setWidth((int) CommonDrawing::emuToPixels($oElement->getAttribute('w')));
}
}

Expand All @@ -981,7 +981,7 @@ protected function loadShapeTable(XMLReader $document, DOMElement $node, Abstrac
$oRow = $oShape->createRow();
}
if ($oElementRow->hasAttribute('h')) {
$oRow->setHeight(CommonDrawing::emuToPixels($oElementRow->getAttribute('h')));
$oRow->setHeight((int) CommonDrawing::emuToPixels($oElementRow->getAttribute('h')));
}
$arrayElementsCell = $document->getElements('a:tc', $oElementRow);
foreach ($arrayElementsCell as $keyCell => $oElementCell) {
Expand Down Expand Up @@ -1098,6 +1098,25 @@ protected function loadParagraph(XMLReader $document, DOMElement $oElement, $oSh
$oParagraph->getAlignment()->setIsRTL((bool) $oSubElement->getAttribute('rtl'));
}

$oElementLineSpacingPoints = $document->getElement('a:lnSpc/a:spcPts', $oSubElement);
if ($oElementLineSpacingPoints instanceof DOMElement) {
$oParagraph->setLineSpacingMode(Paragraph::LINE_SPACING_MODE_POINT);
$oParagraph->setLineSpacing($oElementLineSpacingPoints->getAttribute('val') / 100);
}
$oElementLineSpacingPercent = $document->getElement('a:lnSpc/a:spcPct', $oSubElement);
if ($oElementLineSpacingPercent instanceof DOMElement) {
$oParagraph->setLineSpacingMode(Paragraph::LINE_SPACING_MODE_PERCENT);
$oParagraph->setLineSpacing($oElementLineSpacingPercent->getAttribute('val') / 1000);
}
$oElementSpacingBefore = $document->getElement('a:spcBef/a:spcPts', $oSubElement);
if ($oElementSpacingBefore instanceof DOMElement) {
$oParagraph->setSpacingBefore($oElementSpacingBefore->getAttribute('val') / 100);
}
$oElementSpacingAfter = $document->getElement('a:spcAft/a:spcPts', $oSubElement);
if ($oElementSpacingAfter instanceof DOMElement) {
$oParagraph->setSpacingAfter($oElementSpacingAfter->getAttribute('val') / 100);
}

$oParagraph->getBulletStyle()->setBulletType(Bullet::TYPE_NONE);

$oElementBuFont = $document->getElement('a:buFont', $oSubElement);
Expand Down
Loading

0 comments on commit a33bd2e

Please sign in to comment.