Add support for fractional font sizes (#2363)

* Add support for fractional font sizes

Word supports fractional font sizes like 8.5pt, but PHPWord doesn't.

* Add background color support for textboxes

* Add background color support for text boxes for Word writer

* Added period to the comments to match the cs-fixer configuration

* Fixed cs-fixer issues.

* Added type hints and matching PHPDoc. Also added @return void.

* Added bgcolor unit test coverage

* Removed @return void as not compatible with projects coding standard.

* Fixed several CS-Fixer issues

* Replaced deprecated "assertRegExp" test method by assertMatchesRegularExpression.

* Address the CI coverage issue for the regex match assertion.

* Add support for fractional font sizes

Word supports fractional font sizes like 8.5pt, but PHPWord doesn't.

* The default font size method now supports int and float font sizes. Added type hinting to settings class and unit test coverage for fractional (float) font size.

* The default font size method now supports int and float font sizes. Added type hinting to settings class and unit test coverage for fractional (float) font size.

Co-authored-by: hazington <hazington@eweso.de>
Co-authored-by: Progi1984 <progi1984@gmail.com>
This commit is contained in:
Erik Hazington 2023-01-06 21:04:39 +01:00 committed by GitHub
parent ef99fac8e1
commit aac3a601e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 117 deletions

View File

@ -2,10 +2,8 @@
/** /**
* This file is part of PHPWord - A pure PHP library for reading and writing * This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents. * word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser * PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation. * General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE * For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of * file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
@ -29,48 +27,46 @@ class Settings
* *
* @const string * @const string
*/ */
const ZIPARCHIVE = 'ZipArchive'; public const ZIPARCHIVE = 'ZipArchive';
const PCLZIP = 'PclZip'; public const PCLZIP = 'PclZip';
const OLD_LIB = \PhpOffice\PhpWord\Shared\ZipArchive::class; // @deprecated 0.11 public const OLD_LIB = \PhpOffice\PhpWord\Shared\ZipArchive::class; // @deprecated 0.11
/** /**
* PDF rendering libraries. * PDF rendering libraries.
* *
* @const string * @const string
*/ */
const PDF_RENDERER_DOMPDF = 'DomPDF'; public const PDF_RENDERER_DOMPDF = 'DomPDF';
const PDF_RENDERER_TCPDF = 'TCPDF'; public const PDF_RENDERER_TCPDF = 'TCPDF';
const PDF_RENDERER_MPDF = 'MPDF'; public const PDF_RENDERER_MPDF = 'MPDF';
/** /**
* Measurement units multiplication factor. * Measurement units multiplication factor.
*
* Applied to: * Applied to:
* - Section: margins, header/footer height, gutter, column spacing * - Section: margins, header/footer height, gutter, column spacing
* - Tab: position * - Tab: position
* - Indentation: left, right, firstLine, hanging * - Indentation: left, right, firstLine, hanging
* - Spacing: before, after * - Spacing: before, after.
* *
* @const string * @const string
*/ */
const UNIT_TWIP = 'twip'; // = 1/20 point public const UNIT_TWIP = 'twip'; // = 1/20 point
const UNIT_CM = 'cm'; public const UNIT_CM = 'cm';
const UNIT_MM = 'mm'; public const UNIT_MM = 'mm';
const UNIT_INCH = 'inch'; public const UNIT_INCH = 'inch';
const UNIT_POINT = 'point'; // = 1/72 inch public const UNIT_POINT = 'point'; // = 1/72 inch
const UNIT_PICA = 'pica'; // = 1/6 inch = 12 points public const UNIT_PICA = 'pica'; // = 1/6 inch = 12 points
/** /**
* Default font settings. * Default font settings.
*
* OOXML defined font size values in halfpoints, i.e. twice of what PhpWord * OOXML defined font size values in halfpoints, i.e. twice of what PhpWord
* use, and the conversion will be conducted during XML writing. * use, and the conversion will be conducted during XML writing.
*/ */
const DEFAULT_FONT_NAME = 'Arial'; public const DEFAULT_FONT_NAME = 'Arial';
const DEFAULT_FONT_SIZE = 10; public const DEFAULT_FONT_SIZE = 10;
const DEFAULT_FONT_COLOR = '000000'; public const DEFAULT_FONT_COLOR = '000000';
const DEFAULT_FONT_CONTENT_TYPE = 'default'; // default|eastAsia|cs public const DEFAULT_FONT_CONTENT_TYPE = 'default'; // default|eastAsia|cs
const DEFAULT_PAPER = 'A4'; public const DEFAULT_PAPER = 'A4';
/** /**
* Compatibility option for XMLWriter. * Compatibility option for XMLWriter.
@ -89,21 +85,21 @@ class Settings
/** /**
* Name of the external Library used for rendering PDF files. * Name of the external Library used for rendering PDF files.
* *
* @var string * @var null|string
*/ */
private static $pdfRendererName; private static $pdfRendererName;
/** /**
* Directory Path to the external Library used for rendering PDF files. * Directory Path to the external Library used for rendering PDF files.
* *
* @var string * @var null|string
*/ */
private static $pdfRendererPath; private static $pdfRendererPath;
/** /**
* Measurement unit. * Measurement unit.
* *
* @var float|int * @var string
*/ */
private static $measurementUnit = self::UNIT_TWIP; private static $measurementUnit = self::UNIT_TWIP;
@ -117,7 +113,7 @@ class Settings
/** /**
* Default font size. * Default font size.
* *
* @var int * @var float|int
*/ */
private static $defaultFontSize = self::DEFAULT_FONT_SIZE; private static $defaultFontSize = self::DEFAULT_FONT_SIZE;
@ -148,23 +144,17 @@ class Settings
* *
* @return bool Compatibility * @return bool Compatibility
*/ */
public static function hasCompatibility() public static function hasCompatibility(): bool
{ {
return self::$xmlWriterCompatibility; return self::$xmlWriterCompatibility;
} }
/** /**
* Set the compatibility option used by the XMLWriter. * Set the compatibility option used by the XMLWriter.
* * This sets the setIndent and setIndentString for better compatibility.
* This sets the setIndent and setIndentString for better compatibility
*
* @param bool $compatibility
*
* @return bool
*/ */
public static function setCompatibility($compatibility) public static function setCompatibility(bool $compatibility): bool
{ {
$compatibility = (bool) $compatibility;
self::$xmlWriterCompatibility = $compatibility; self::$xmlWriterCompatibility = $compatibility;
return true; return true;
@ -172,22 +162,16 @@ class Settings
/** /**
* Get zip handler class. * Get zip handler class.
*
* @return string
*/ */
public static function getZipClass() public static function getZipClass(): string
{ {
return self::$zipClass; return self::$zipClass;
} }
/** /**
* Set zip handler class. * Set zip handler class.
*
* @param string $zipClass
*
* @return bool
*/ */
public static function setZipClass($zipClass) public static function setZipClass(string $zipClass): bool
{ {
if (in_array($zipClass, [self::PCLZIP, self::ZIPARCHIVE, self::OLD_LIB])) { if (in_array($zipClass, [self::PCLZIP, self::ZIPARCHIVE, self::OLD_LIB])) {
self::$zipClass = $zipClass; self::$zipClass = $zipClass;
@ -201,12 +185,9 @@ class Settings
/** /**
* Set details of the external library for rendering PDF files. * Set details of the external library for rendering PDF files.
* *
* @param string $libraryName
* @param string $libraryBaseDir
*
* @return bool Success or failure * @return bool Success or failure
*/ */
public static function setPdfRenderer($libraryName, $libraryBaseDir) public static function setPdfRenderer(string $libraryName, string $libraryBaseDir): bool
{ {
if (!self::setPdfRendererName($libraryName)) { if (!self::setPdfRendererName($libraryName)) {
return false; return false;
@ -217,22 +198,16 @@ class Settings
/** /**
* Return the PDF Rendering Library. * Return the PDF Rendering Library.
*
* @return string
*/ */
public static function getPdfRendererName() public static function getPdfRendererName(): ?string
{ {
return self::$pdfRendererName; return self::$pdfRendererName;
} }
/** /**
* Identify the external library to use for rendering PDF files. * Identify the external library to use for rendering PDF files.
*
* @param string $libraryName
*
* @return bool
*/ */
public static function setPdfRendererName($libraryName) public static function setPdfRendererName(?string $libraryName): bool
{ {
$pdfRenderers = [self::PDF_RENDERER_DOMPDF, self::PDF_RENDERER_TCPDF, self::PDF_RENDERER_MPDF]; $pdfRenderers = [self::PDF_RENDERER_DOMPDF, self::PDF_RENDERER_TCPDF, self::PDF_RENDERER_MPDF];
if (!in_array($libraryName, $pdfRenderers)) { if (!in_array($libraryName, $pdfRenderers)) {
@ -245,10 +220,8 @@ class Settings
/** /**
* Return the directory path to the PDF Rendering Library. * Return the directory path to the PDF Rendering Library.
*
* @return string
*/ */
public static function getPdfRendererPath() public static function getPdfRendererPath(): ?string
{ {
return self::$pdfRendererPath; return self::$pdfRendererPath;
} }
@ -256,11 +229,11 @@ class Settings
/** /**
* Location of external library to use for rendering PDF files. * Location of external library to use for rendering PDF files.
* *
* @param string $libraryBaseDir Directory path to the library's base folder * @param null|string $libraryBaseDir Directory path to the library's base folder
* *
* @return bool Success or failure * @return bool Success or failure
*/ */
public static function setPdfRendererPath($libraryBaseDir) public static function setPdfRendererPath(?string $libraryBaseDir): bool
{ {
if (!$libraryBaseDir || false === file_exists($libraryBaseDir) || false === is_readable($libraryBaseDir)) { if (!$libraryBaseDir || false === file_exists($libraryBaseDir) || false === is_readable($libraryBaseDir)) {
return false; return false;
@ -272,25 +245,25 @@ class Settings
/** /**
* Get measurement unit. * Get measurement unit.
*
* @return string
*/ */
public static function getMeasurementUnit() public static function getMeasurementUnit(): string
{ {
return self::$measurementUnit; return self::$measurementUnit;
} }
/** /**
* Set measurement unit. * Set measurement unit.
*
* @param string $value
*
* @return bool
*/ */
public static function setMeasurementUnit($value) public static function setMeasurementUnit(string $value): bool
{ {
$units = [self::UNIT_TWIP, self::UNIT_CM, self::UNIT_MM, self::UNIT_INCH, $units = [
self::UNIT_POINT, self::UNIT_PICA, ]; self::UNIT_TWIP,
self::UNIT_CM,
self::UNIT_MM,
self::UNIT_INCH,
self::UNIT_POINT,
self::UNIT_PICA,
];
if (!in_array($value, $units)) { if (!in_array($value, $units)) {
return false; return false;
} }
@ -302,11 +275,11 @@ class Settings
/** /**
* Sets the user defined path to temporary directory. * Sets the user defined path to temporary directory.
* *
* @since 0.12.0
*
* @param string $tempDir The user defined path to temporary directory * @param string $tempDir The user defined path to temporary directory
*
* @since 0.12.0
*/ */
public static function setTempDir($tempDir): void public static function setTempDir(string $tempDir): void
{ {
self::$tempDir = $tempDir; self::$tempDir = $tempDir;
} }
@ -315,10 +288,8 @@ class Settings
* Returns path to temporary directory. * Returns path to temporary directory.
* *
* @since 0.12.0 * @since 0.12.0
*
* @return string
*/ */
public static function getTempDir() public static function getTempDir(): string
{ {
if (!empty(self::$tempDir)) { if (!empty(self::$tempDir)) {
$tempDir = self::$tempDir; $tempDir = self::$tempDir;
@ -331,44 +302,34 @@ class Settings
/** /**
* @since 0.13.0 * @since 0.13.0
*
* @return bool
*/ */
public static function isOutputEscapingEnabled() public static function isOutputEscapingEnabled(): bool
{ {
return self::$outputEscapingEnabled; return self::$outputEscapingEnabled;
} }
/** /**
* @since 0.13.0 * @since 0.13.0
*
* @param bool $outputEscapingEnabled
*/ */
public static function setOutputEscapingEnabled($outputEscapingEnabled): void public static function setOutputEscapingEnabled(bool $outputEscapingEnabled): void
{ {
self::$outputEscapingEnabled = $outputEscapingEnabled; self::$outputEscapingEnabled = $outputEscapingEnabled;
} }
/** /**
* Get default font name. * Get default font name.
*
* @return string
*/ */
public static function getDefaultFontName() public static function getDefaultFontName(): string
{ {
return self::$defaultFontName; return self::$defaultFontName;
} }
/** /**
* Set default font name. * Set default font name.
*
* @param string $value
*
* @return bool
*/ */
public static function setDefaultFontName($value) public static function setDefaultFontName(string $value): bool
{ {
if (is_string($value) && trim($value) !== '') { if (trim($value) !== '') {
self::$defaultFontName = $value; self::$defaultFontName = $value;
return true; return true;
@ -380,7 +341,7 @@ class Settings
/** /**
* Get default font size. * Get default font size.
* *
* @return int * @return float|int
*/ */
public static function getDefaultFontSize() public static function getDefaultFontSize()
{ {
@ -390,14 +351,11 @@ class Settings
/** /**
* Set default font size. * Set default font size.
* *
* @param int $value * @param null|float|int $value
*
* @return bool
*/ */
public static function setDefaultFontSize($value) public static function setDefaultFontSize($value): bool
{ {
$value = (int) $value; if ((is_int($value) || is_float($value)) && (int) $value > 0) {
if ($value > 0) {
self::$defaultFontSize = $value; self::$defaultFontSize = $value;
return true; return true;
@ -408,12 +366,8 @@ class Settings
/** /**
* Load setting from phpword.yml or phpword.yml.dist. * Load setting from phpword.yml or phpword.yml.dist.
*
* @param string $filename
*
* @return array
*/ */
public static function loadConfig($filename = null) public static function loadConfig(?string $filename = null): array
{ {
// Get config file // Get config file
$configFile = null; $configFile = null;
@ -455,24 +409,18 @@ class Settings
/** /**
* Get default paper. * Get default paper.
*
* @return string
*/ */
public static function getDefaultPaper() public static function getDefaultPaper(): string
{ {
return self::$defaultPaper; return self::$defaultPaper;
} }
/** /**
* Set default paper. * Set default paper.
*
* @param string $value
*
* @return bool
*/ */
public static function setDefaultPaper($value) public static function setDefaultPaper(string $value): bool
{ {
if (is_string($value) && trim($value) !== '') { if (trim($value) !== '') {
self::$defaultPaper = $value; self::$defaultPaper = $value;
return true; return true;

View File

@ -2,10 +2,8 @@
/** /**
* This file is part of PHPWord - A pure PHP library for reading and writing * This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents. * word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser * PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation. * General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE * For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of * file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors. * contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
@ -19,15 +17,15 @@ namespace PhpOffice\PhpWordTests;
use PhpOffice\PhpWord\PhpWord; use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings; use PhpOffice\PhpWord\Settings;
use PHPUnit\Framework\TestCase;
/** /**
* Test class for PhpOffice\PhpWord\Settings. * Test class for PhpOffice\PhpWord\Settings.
* *
* @coversDefaultClass \PhpOffice\PhpWord\Settings * @coversDefaultClass \PhpOffice\PhpWord\Settings
*
* @runTestsInSeparateProcesses * @runTestsInSeparateProcesses
*/ */
class SettingsTest extends \PHPUnit\Framework\TestCase class SettingsTest extends TestCase
{ {
private $compatibility; private $compatibility;
@ -151,7 +149,6 @@ class SettingsTest extends \PHPUnit\Framework\TestCase
/** /**
* @covers ::getTempDir * @covers ::getTempDir
* @covers ::setTempDir * @covers ::setTempDir
*
* @depends testPhpTempDirIsUsedByDefault * @depends testPhpTempDirIsUsedByDefault
*/ */
public function testTempDirCanBeSet(): void public function testTempDirCanBeSet(): void
@ -189,6 +186,12 @@ class SettingsTest extends \PHPUnit\Framework\TestCase
self::assertEquals(12, Settings::getDefaultFontSize()); self::assertEquals(12, Settings::getDefaultFontSize());
self::assertFalse(Settings::setDefaultFontSize(null)); self::assertFalse(Settings::setDefaultFontSize(null));
self::assertEquals(12, Settings::getDefaultFontSize()); self::assertEquals(12, Settings::getDefaultFontSize());
self::assertTrue(Settings::setDefaultFontSize(12.5));
self::assertEquals(12.5, Settings::getDefaultFontSize());
self::assertFalse(Settings::setDefaultFontSize(0.5));
self::assertEquals(12.5, Settings::getDefaultFontSize());
self::assertFalse(Settings::setDefaultFontSize(0));
self::assertEquals(12.5, Settings::getDefaultFontSize());
} }
/** /**