Skip to content

Commit af5a271

Browse files
authored
Line spacing is wrong when using "exact" line spacing rule (#1509)
* Only add 240 twips when in auto lineRule * don't add 1 line when using EXACT line spacing rule * fix style & scrutinizer warning
1 parent c15d4d1 commit af5a271

File tree

9 files changed

+53
-16
lines changed

9 files changed

+53
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ Change Log
33
All notable changes to this project will be documented in this file.
44
This project adheres to [Semantic Versioning](http://semver.org/).
55

6-
v0.16.0 (xx xxx 2018)
6+
v0.16.0 (xx dec 2018)
77
----------------------
88
### Added
99
- Add setting Chart Title and Legend visibility @Tom-Magill #1433
1010

1111
### Fixed
1212
- Fix regex in `cloneBlock` function @nicoder #1269
1313
- HTML Title Writer loses text when Title contains a TextRun instead a string. @begnini #1436
14+
- 240 twips are being added to line spacing, should not happen when using lineRule fixed @troosan #1509 #1505
1415
- Adding table layout to the generated HTML @aarangara #1441
1516
- Fix loading of Sharepoint document @Garrcomm #1498
1617
- RTF writer: Round getPageSizeW and getPageSizeH to avoid decimals @Patrick64 #1493

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ $objWriter->save('helloWorld.html');
161161
```
162162

163163
More examples are provided in the [samples folder](samples/). For an easy access to those samples launch `php -S localhost:8000` in the samples directory then browse to [http://localhost:8000](http://localhost:8000) to view the samples.
164-
You can also read the [Developers' Documentation](http://phpword.readthedocs.org/) and the [API Documentation](http://phpoffice.github.io/PHPWord/docs/master/) for more detail.
164+
You can also read the [Developers' Documentation](http://phpword.readthedocs.org/) for more detail.
165165

166166
## Contributing
167167

docs/styles.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ Available Paragraph style options:
8181
- ``pageBreakBefore``. Start paragraph on next page, *true* or *false*.
8282
- ``spaceBefore``. Space before paragraph in *twip*.
8383
- ``spaceAfter``. Space after paragraph in *twip*.
84-
- ``spacing``. Space between lines.
84+
- ``spacing``. Space between lines in *twip*. If spacingLineRule is auto, 240 (height of 1 line) will be added, so if you want a double line height, set this to 240.
8585
- ``spacingLineRule``. Line Spacing Rule. *auto*, *exact*, *atLeast*
8686
See ``\PhpOffice\PhpWord\SimpleType\LineSpacingRule`` class constants for possible values.
8787
- ``suppressAutoHyphens``. Hyphenation for paragraph, *true* or *false*.

src/PhpWord/Shared/Html.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use PhpOffice\PhpWord\Settings;
2424
use PhpOffice\PhpWord\SimpleType\Jc;
2525
use PhpOffice\PhpWord\SimpleType\NumberFormat;
26+
use PhpOffice\PhpWord\Style\Paragraph;
2627

2728
/**
2829
* Common Html functions
@@ -533,17 +534,25 @@ private static function parseStyle($attribute, $styles)
533534
case 'line-height':
534535
$matches = array();
535536
if (preg_match('/([0-9]+\.?[0-9]*[a-z]+)/', $cValue, $matches)) {
537+
//matches number with a unit, e.g. 12px, 15pt, 20mm, ...
536538
$spacingLineRule = \PhpOffice\PhpWord\SimpleType\LineSpacingRule::EXACT;
537-
$spacing = Converter::cssToTwip($matches[1]) / \PhpOffice\PhpWord\Style\Paragraph::LINE_HEIGHT;
539+
$spacing = Converter::cssToTwip($matches[1]);
538540
} elseif (preg_match('/([0-9]+)%/', $cValue, $matches)) {
541+
//matches percentages
539542
$spacingLineRule = \PhpOffice\PhpWord\SimpleType\LineSpacingRule::AUTO;
540-
$spacing = ((int) $matches[1]) / 100;
543+
//we are subtracting 1 line height because the Spacing writer is adding one line
544+
$spacing = ((((int) $matches[1]) / 100) * Paragraph::LINE_HEIGHT) - Paragraph::LINE_HEIGHT;
541545
} else {
546+
//any other, wich is a multiplier. E.g. 1.2
542547
$spacingLineRule = \PhpOffice\PhpWord\SimpleType\LineSpacingRule::AUTO;
543-
$spacing = $cValue;
548+
//we are subtracting 1 line height because the Spacing writer is adding one line
549+
$spacing = ($cValue * Paragraph::LINE_HEIGHT) - Paragraph::LINE_HEIGHT;
544550
}
545551
$styles['spacingLineRule'] = $spacingLineRule;
546-
$styles['lineHeight'] = $spacing;
552+
$styles['line-spacing'] = $spacing;
553+
break;
554+
case 'letter-spacing':
555+
$styles['letter-spacing'] = Converter::cssToTwip($cValue);
547556
break;
548557
case 'text-indent':
549558
$styles['indentation']['firstLine'] = Converter::cssToTwip($cValue);

src/PhpWord/Style/Font.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class Font extends AbstractStyle
8080
*
8181
* @var array
8282
*/
83-
protected $aliases = array('line-height' => 'lineHeight');
83+
protected $aliases = array('line-height' => 'lineHeight', 'letter-spacing' => 'spacing');
8484

8585
/**
8686
* Font style type

src/PhpWord/Style/Paragraph.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class Paragraph extends Border
6161
*
6262
* @var array
6363
*/
64-
protected $aliases = array('line-height' => 'lineHeight');
64+
protected $aliases = array('line-height' => 'lineHeight', 'line-spacing' => 'spacing');
6565

6666
/**
6767
* Parent style
@@ -199,8 +199,6 @@ public function setStyleValue($key, $value)
199199
$key = Text::removeUnderscorePrefix($key);
200200
if ('indent' == $key || 'hanging' == $key) {
201201
$value = $value * 720;
202-
} elseif ('spacing' == $key) {
203-
$value += 240; // because line height of 1 matches 240 twips
204202
}
205203

206204
return parent::setStyleValue($key, $value);
@@ -479,7 +477,7 @@ public function setSpaceAfter($value = null)
479477
/**
480478
* Get spacing between lines
481479
*
482-
* @return int
480+
* @return int|float
483481
*/
484482
public function getSpacing()
485483
{
@@ -489,7 +487,7 @@ public function getSpacing()
489487
/**
490488
* Set spacing between lines
491489
*
492-
* @param int $value
490+
* @param int|float $value
493491
* @return self
494492
*/
495493
public function setSpacing($value = null)
@@ -547,7 +545,8 @@ public function setLineHeight($lineHeight)
547545
}
548546

549547
$this->lineHeight = $lineHeight;
550-
$this->setSpacing($lineHeight * self::LINE_HEIGHT);
548+
$this->setSpacing(($lineHeight - 1) * self::LINE_HEIGHT);
549+
$this->setSpacingLineRule(\PhpOffice\PhpWord\SimpleType\LineSpacingRule::AUTO);
551550

552551
return $this;
553552
}

src/PhpWord/Writer/Word2007/Style/Spacing.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ public function write()
4444
$xmlWriter->writeAttributeIf(!is_null($after), 'w:after', $this->convertTwip($after));
4545

4646
$line = $style->getLine();
47+
//if linerule is auto, the spacing is supposed to include the height of the line itself, which is 240 twips
48+
if (null !== $line && 'auto' === $style->getLineRule()) {
49+
$line += \PhpOffice\PhpWord\Style\Paragraph::LINE_HEIGHT;
50+
}
4751
$xmlWriter->writeAttributeIf(!is_null($line), 'w:line', $line);
4852

4953
$xmlWriter->writeAttributeIf(!is_null($line), 'w:lineRule', $style->getLineRule());

tests/PhpWord/Style/ParagraphTest.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,6 @@ public function testSetStyleValueNormal()
9191
$object->setStyleValue("$key", $value);
9292
if ('indent' == $key || 'hanging' == $key) {
9393
$value = $value * 720;
94-
} elseif ('spacing' == $key) {
95-
$value += 240;
9694
}
9795
$this->assertEquals($value, $object->$get());
9896
}

tests/PhpWord/Writer/Word2007/Style/ParagraphTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,32 @@ public function testParagraphNumbering()
5151
$this->assertTrue($doc->elementExists($path));
5252
}
5353

54+
public function testLineSpacingExact()
55+
{
56+
$phpWord = new \PhpOffice\PhpWord\PhpWord();
57+
$section = $phpWord->addSection();
58+
$section->addText('test', null, array('spacing' => 240, 'spacingLineRule' => 'exact'));
59+
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
60+
61+
$path = '/w:document/w:body/w:p/w:pPr/w:spacing';
62+
$this->assertTrue($doc->elementExists($path));
63+
$this->assertEquals('exact', $doc->getElementAttribute($path, 'w:lineRule'));
64+
$this->assertEquals('240', $doc->getElementAttribute($path, 'w:line'));
65+
}
66+
67+
public function testLineSpacingAuto()
68+
{
69+
$phpWord = new \PhpOffice\PhpWord\PhpWord();
70+
$section = $phpWord->addSection();
71+
$section->addText('test', null, array('spacing' => 240, 'spacingLineRule' => 'auto'));
72+
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
73+
74+
$path = '/w:document/w:body/w:p/w:pPr/w:spacing';
75+
$this->assertTrue($doc->elementExists($path));
76+
$this->assertEquals('auto', $doc->getElementAttribute($path, 'w:lineRule'));
77+
$this->assertEquals('480', $doc->getElementAttribute($path, 'w:line'));
78+
}
79+
5480
public function testSuppressAutoHyphens()
5581
{
5682
$paragraphStyle = new ParagraphStyle();

0 commit comments

Comments
 (0)