Skip to content

Commit 4280dab

Browse files
authored
Merge branch 'master' into wordunimplemented2
2 parents 5084642 + 337dc27 commit 4280dab

File tree

9 files changed

+151
-44
lines changed

9 files changed

+151
-44
lines changed

docs/changes/1.x/1.4.0.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
## Enhancements
66

7+
- Default Font: Allow specify Asisn font and Latin font separately
8+
79
- Writer ODText: Support for ListItemRun by [@Progi1984](https://github.com/Progi1984) fixing [#2159](https://github.com/PHPOffice/PHPWord/issues/2159), [#2620](https://github.com/PHPOffice/PHPWord/issues/2620) in [#2669](https://github.com/PHPOffice/PHPWord/pull/2669)
810
- Writer HTML: Support for vAlign in Tables by [@SpraxDev](https://github.com/SpraxDev) in [#2675](https://github.com/PHPOffice/PHPWord/pull/2675)
911
- Added support for PHP 8.4 by [@Progi1984](https://github.com/Progi1984) in [#2660](https://github.com/PHPOffice/PHPWord/pull/2660)
@@ -13,6 +15,7 @@
1315

1416
- Writer ODText: Support for images inside a textRun by [@Progi1984](https://github.com/Progi1984) fixing [#2240](https://github.com/PHPOffice/PHPWord/issues/2240) in [#2668](https://github.com/PHPOffice/PHPWord/pull/2668)
1517
- Allow vAlign and vMerge on Style\Cell to be set to null by [@SpraxDev](https://github.com/SpraxDev) fixing [#2673](https://github.com/PHPOffice/PHPWord/issues/2673) in [#2676](https://github.com/PHPOffice/PHPWord/pull/2676)
18+
- Reader HTML: Support for differents size units for table by [@Progi1984](https://github.com/Progi1984) fixing [#2384](https://github.com/PHPOffice/PHPWord/issues/2384), [#2701](https://github.com/PHPOffice/PHPWord/issues/2701) in [#2725](https://github.com/PHPOffice/PHPWord/pull/2725)
1619

1720
### Miscellaneous
1821

docs/usage/introduction.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,14 @@ $phpWord->setDefaultFontName('Times New Roman');
137137
$phpWord->setDefaultFontSize(12);
138138
```
139139

140+
Or you can specify Asian Font
141+
142+
``` php
143+
<?php
144+
145+
$phpWord->setDefaultAsianFontName('標楷體');
146+
```
147+
140148
## Document settings
141149

142150
Settings for the generated document can be set using ``$phpWord->getSettings()``
@@ -380,4 +388,4 @@ To control whether or not words in all capital letters shall be hyphenated use t
380388
<?php
381389

382390
$phpWord->getSettings()->setDoNotHyphenateCaps(true);
383-
```
391+
```

src/PhpWord/PhpWord.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,24 @@ public function setDefaultFontName($fontName): void
258258
Settings::setDefaultFontName($fontName);
259259
}
260260

261+
/**
262+
* Get default asian font name.
263+
*/
264+
public function getDefaultAsianFontName(): string
265+
{
266+
return Settings::getDefaultAsianFontName();
267+
}
268+
269+
/**
270+
* Set default font name.
271+
*
272+
* @param string $fontName
273+
*/
274+
public function setDefaultAsianFontName($fontName): void
275+
{
276+
Settings::setDefaultAsianFontName($fontName);
277+
}
278+
261279
/**
262280
* Get default font size.
263281
*

src/PhpWord/Settings.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ class Settings
120120
*/
121121
private static $defaultFontName = self::DEFAULT_FONT_NAME;
122122

123+
/**
124+
* Default font name.
125+
*
126+
* @var string
127+
*/
128+
private static $defaultAsianFontName = self::DEFAULT_FONT_NAME;
129+
123130
/**
124131
* Default font size.
125132
*
@@ -357,6 +364,14 @@ public static function getDefaultFontName(): string
357364
return self::$defaultFontName;
358365
}
359366

367+
/**
368+
* Get default font name.
369+
*/
370+
public static function getDefaultAsianFontName(): string
371+
{
372+
return self::$defaultAsianFontName;
373+
}
374+
360375
/**
361376
* Set default font name.
362377
*/
@@ -371,6 +386,17 @@ public static function setDefaultFontName(string $value): bool
371386
return false;
372387
}
373388

389+
public static function setDefaultAsianFontName(string $value): bool
390+
{
391+
if (trim($value) !== '') {
392+
self::$defaultAsianFontName = $value;
393+
394+
return true;
395+
}
396+
397+
return false;
398+
}
399+
374400
/**
375401
* Get default font size.
376402
*

src/PhpWord/Shared/Html.php

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -203,21 +203,21 @@ protected static function parseInlineStyle($node, &$styles)
203203
break;
204204
case 'width':
205205
// tables, cells
206+
$val = $val === 'auto' ? '100%' : $val;
206207
if (false !== strpos($val, '%')) {
207208
// e.g. <table width="100%"> or <td width="50%">
208209
$styles['width'] = (int) $val * 50;
209210
$styles['unit'] = \PhpOffice\PhpWord\SimpleType\TblWidth::PERCENT;
210211
} else {
211212
// e.g. <table width="250> where "250" = 250px (always pixels)
212-
$styles['width'] = Converter::pixelToTwip($val);
213+
$styles['width'] = Converter::pixelToTwip(self::convertHtmlSize($val));
213214
$styles['unit'] = \PhpOffice\PhpWord\SimpleType\TblWidth::TWIP;
214215
}
215216

216217
break;
217218
case 'cellspacing':
218219
// tables e.g. <table cellspacing="2">, where "2" = 2px (always pixels)
219-
$val = (int) $val . 'px';
220-
$styles['cellSpacing'] = Converter::cssToTwip($val);
220+
$styles['cellSpacing'] = Converter::pixelToTwip(self::convertHtmlSize($val));
221221

222222
break;
223223
case 'bgcolor':
@@ -1046,36 +1046,12 @@ protected static function parseImage($node, $element)
10461046

10471047
break;
10481048
case 'width':
1049-
$width = $attribute->value;
1050-
1051-
// pt
1052-
if (false !== strpos($width, 'pt')) {
1053-
$width = Converter::pointToPixel((float) str_replace('pt', '', $width));
1054-
}
1055-
1056-
// px
1057-
if (false !== strpos($width, 'px')) {
1058-
$width = str_replace('px', '', $width);
1059-
}
1060-
1061-
$style['width'] = $width;
1049+
$style['width'] = self::convertHtmlSize($attribute->value);
10621050
$style['unit'] = \PhpOffice\PhpWord\Style\Image::UNIT_PX;
10631051

10641052
break;
10651053
case 'height':
1066-
$height = $attribute->value;
1067-
1068-
// pt
1069-
if (false !== strpos($height, 'pt')) {
1070-
$height = Converter::pointToPixel((float) str_replace('pt', '', $height));
1071-
}
1072-
1073-
// px
1074-
if (false !== strpos($height, 'px')) {
1075-
$height = str_replace('px', '', $height);
1076-
}
1077-
1078-
$style['height'] = $height;
1054+
$style['height'] = self::convertHtmlSize($attribute->value);
10791055
$style['unit'] = \PhpOffice\PhpWord\Style\Image::UNIT_PX;
10801056

10811057
break;
@@ -1358,4 +1334,22 @@ private static function convertRgb(string $rgb): string
13581334

13591335
return trim($rgb, '# ');
13601336
}
1337+
1338+
/**
1339+
* Transform HTML sizes (pt, px) in pixels.
1340+
*/
1341+
protected static function convertHtmlSize(string $size): float
1342+
{
1343+
// pt
1344+
if (false !== strpos($size, 'pt')) {
1345+
return Converter::pointToPixel((float) str_replace('pt', '', $size));
1346+
}
1347+
1348+
// px
1349+
if (false !== strpos($size, 'px')) {
1350+
return (float) str_replace('px', '', $size);
1351+
}
1352+
1353+
return (float) $size;
1354+
}
13611355
}

src/PhpWord/Writer/Word2007/Part/Styles.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ private function writeDefaultStyles(XMLWriter $xmlWriter, $styles): void
8585
{
8686
$phpWord = $this->getParentWriter()->getPhpWord();
8787
$fontName = $phpWord->getDefaultFontName();
88+
$asianFontName = $phpWord->getDefaultAsianFontName();
8889
$fontSize = $phpWord->getDefaultFontSize();
8990
$language = $phpWord->getSettings()->getThemeFontLang();
9091
$latinLanguage = ($language == null || $language->getLatin() === null) ? 'en-US' : $language->getLatin();
@@ -96,7 +97,7 @@ private function writeDefaultStyles(XMLWriter $xmlWriter, $styles): void
9697
$xmlWriter->startElement('w:rFonts');
9798
$xmlWriter->writeAttribute('w:ascii', $fontName);
9899
$xmlWriter->writeAttribute('w:hAnsi', $fontName);
99-
$xmlWriter->writeAttribute('w:eastAsia', $fontName);
100+
$xmlWriter->writeAttribute('w:eastAsia', $asianFontName);
100101
$xmlWriter->writeAttribute('w:cs', $fontName);
101102
$xmlWriter->endElement(); // w:rFonts
102103
$xmlWriter->startElement('w:sz');

tests/PhpWordTests/PhpWordTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,18 @@ public function testSetGetDefaultFontSize(): void
8383
self::assertEquals($fontSize, $phpWord->getDefaultFontSize());
8484
}
8585

86+
/**
87+
* Test set/get default asian font name.
88+
*/
89+
public function testSetGetDefaultAsianFontName(): void
90+
{
91+
$phpWord = new PhpWord();
92+
$fontName = 'Times New Roman';
93+
self::assertEquals(Settings::DEFAULT_FONT_NAME, $phpWord->getDefaultAsianFontName());
94+
$phpWord->setDefaultAsianFontName($fontName);
95+
self::assertEquals($fontName, $phpWord->getDefaultAsianFontName());
96+
}
97+
8698
/**
8799
* Test set default paragraph style.
88100
*/

tests/PhpWordTests/SettingsTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,20 @@ public function testSetGetDefaultFontName(): void
201201
self::assertEquals('Times New Roman', Settings::getDefaultFontName());
202202
}
203203

204+
/**
205+
* Test set/get default font name.
206+
*/
207+
public function testSetGetDefaultAsianFontName(): void
208+
{
209+
self::assertEquals(Settings::DEFAULT_FONT_NAME, Settings::getDefaultAsianFontName());
210+
self::assertFalse(Settings::setDefaultAsianFontName(' '));
211+
self::assertEquals(Settings::DEFAULT_FONT_NAME, Settings::getDefaultAsianFontName());
212+
self::assertTrue(Settings::setDefaultAsianFontName('Times New Roman'));
213+
self::assertEquals('Times New Roman', Settings::getDefaultAsianFontName());
214+
self::assertFalse(Settings::setDefaultAsianFontName(' '));
215+
self::assertEquals('Times New Roman', Settings::getDefaultAsianFontName());
216+
}
217+
204218
/**
205219
* Test set/get default font size.
206220
*/

tests/PhpWordTests/Shared/HtmlTest.php

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use PhpOffice\PhpWord\SimpleType\LineSpacingRule;
3131
use PhpOffice\PhpWord\Style;
3232
use PhpOffice\PhpWord\Style\Font;
33+
use PhpOffice\PhpWord\SimpleType\TblWidth;
3334
use PhpOffice\PhpWord\Style\Paragraph;
3435
use PhpOffice\PhpWordTests\AbstractWebServerEmbedded;
3536
use PhpOffice\PhpWordTests\TestHelperDOCX;
@@ -209,11 +210,11 @@ public function testSpanClassName(): void
209210
}
210211

211212
/**
212-
* Test underline.
213+
* Test text-decoration style.
213214
*/
214-
public function testParseUnderline(): void
215+
public function testParseTextDecoration(): void
215216
{
216-
$html = '<u>test</u>';
217+
$html = '<span style="text-decoration: underline;">test</span>';
217218
$phpWord = new PhpWord();
218219
$section = $phpWord->addSection();
219220
Html::addHtml($section, $html);
@@ -224,11 +225,11 @@ public function testParseUnderline(): void
224225
}
225226

226227
/**
227-
* Test text-decoration style.
228+
* Test underline.
228229
*/
229-
public function testParseTextDecoration(): void
230+
public function testParseUnderline(): void
230231
{
231-
$html = '<span style="text-decoration: underline;">test</span>';
232+
$html = '<u>test</u>';
232233
$phpWord = new PhpWord();
233234
$section = $phpWord->addSection();
234235
Html::addHtml($section, $html);
@@ -238,6 +239,25 @@ public function testParseTextDecoration(): void
238239
self::assertEquals('single', $doc->getElementAttribute('/w:document/w:body/w:p/w:r/w:rPr/w:u', 'w:val'));
239240
}
240241

242+
/**
243+
* Test width.
244+
*
245+
* @dataProvider providerParseWidth
246+
*/
247+
public function testParseWidth(string $htmlSize, float $docxSize, string $docxUnit): void
248+
{
249+
$html = '<table width="' . $htmlSize . '"><tr><td>A</td></tr></table>';
250+
$phpWord = new PhpWord();
251+
$section = $phpWord->addSection();
252+
253+
Html::addHtml($section, $html);
254+
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
255+
$xpath = '/w:document/w:body/w:tbl/w:tblPr/w:tblW';
256+
self::assertTrue($doc->elementExists($xpath));
257+
self::assertEquals($docxSize, $doc->getElement($xpath)->getAttribute('w:w'));
258+
self::assertEquals($docxUnit, $doc->getElement($xpath)->getAttribute('w:type'));
259+
}
260+
241261
/**
242262
* Test font-variant style.
243263
*/
@@ -514,31 +534,31 @@ public function testParseTableAndCellWidth(): void
514534
$xpath = '/w:document/w:body/w:tbl/w:tblGrid/w:gridCol';
515535
self::assertTrue($doc->elementExists($xpath));
516536
self::assertEquals(25 * 50, $doc->getElement($xpath)->getAttribute('w:w'));
517-
self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type'));
537+
self::assertEquals(TblWidth::TWIP, $doc->getElement($xpath)->getAttribute('w:type'));
518538

519539
// <td style="width: 25%; ...
520540
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc/w:tcPr/w:tcW';
521541
self::assertTrue($doc->elementExists($xpath));
522542
self::assertEquals(25 * 50, $doc->getElement($xpath)->getAttribute('w:w'));
523-
self::assertEquals('pct', $doc->getElement($xpath)->getAttribute('w:type'));
543+
self::assertEquals(TblWidth::PERCENT, $doc->getElement($xpath)->getAttribute('w:type'));
524544

525545
// <table width="400" .. 400px = 6000 twips (400 / 96 * 1440)
526546
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc/w:tbl/w:tr/w:tc/w:tcPr/w:tcW';
527547
self::assertTrue($doc->elementExists($xpath));
528548
self::assertEquals(6000, $doc->getElement($xpath)->getAttribute('w:w'));
529-
self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type'));
549+
self::assertEquals(TblWidth::TWIP, $doc->getElement($xpath)->getAttribute('w:type'));
530550

531551
// <th style="width: 50pt; .. 50pt = 750 twips (50 / 72 * 1440)
532552
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc/w:tbl/w:tr[2]/w:tc[2]/w:tcPr/w:tcW';
533553
self::assertTrue($doc->elementExists($xpath));
534554
self::assertEquals(1000, $doc->getElement($xpath)->getAttribute('w:w'));
535-
self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type'));
555+
self::assertEquals(TblWidth::TWIP, $doc->getElement($xpath)->getAttribute('w:type'));
536556

537557
// <th width="300" .. 300px = 4500 twips (300 / 96 * 1440)
538558
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc/w:tbl/w:tr[3]/w:tc/w:tcPr/w:tcW';
539559
self::assertTrue($doc->elementExists($xpath));
540560
self::assertEquals(4500, $doc->getElement($xpath)->getAttribute('w:w'));
541-
self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type'));
561+
self::assertEquals(TblWidth::TWIP, $doc->getElement($xpath)->getAttribute('w:type'));
542562
}
543563

544564
/**
@@ -652,7 +672,7 @@ public function testParseTableCellspacingRowBgColor(): void
652672
$xpath = '/w:document/w:body/w:tbl/w:tblPr/w:tblCellSpacing';
653673
self::assertTrue($doc->elementExists($xpath));
654674
self::assertEquals(3 * 15, $doc->getElement($xpath)->getAttribute('w:w'));
655-
self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type'));
675+
self::assertEquals(TblWidth::TWIP, $doc->getElement($xpath)->getAttribute('w:type'));
656676

657677
$xpath = '/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:shd';
658678
self::assertTrue($doc->elementExists($xpath));
@@ -685,7 +705,7 @@ public function testParseTableStyleAttributeInlineStyle(): void
685705
$xpath = '/w:document/w:body/w:tbl/w:tblPr/w:tblW';
686706
self::assertTrue($doc->elementExists($xpath));
687707
self::assertEquals(100 * 50, $doc->getElement($xpath)->getAttribute('w:w'));
688-
self::assertEquals('pct', $doc->getElement($xpath)->getAttribute('w:type'));
708+
self::assertEquals(TblWidth::PERCENT, $doc->getElement($xpath)->getAttribute('w:type'));
689709

690710
$xpath = '/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:shd';
691711
self::assertTrue($doc->elementExists($xpath));
@@ -1278,4 +1298,15 @@ public function testDontDecodeAlreadyEncodedDoubleQuotes(): void
12781298
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
12791299
self::assertIsObject($doc);
12801300
}
1301+
1302+
public static function providerParseWidth(): array
1303+
{
1304+
return [
1305+
['auto', 5000, TblWidth::PERCENT],
1306+
['100%', 5000, TblWidth::PERCENT],
1307+
['200pt', 3999.999999999999, TblWidth::TWIP],
1308+
['300px', 4500, TblWidth::TWIP],
1309+
['400', 6000, TblWidth::TWIP],
1310+
];
1311+
}
12811312
}

0 commit comments

Comments
 (0)