Merge branch 'master' into NumberFormat_Improved-Docblocks

This commit is contained in:
Mark Baker
2023-02-05 09:48:46 +01:00
committed by GitHub
32 changed files with 199 additions and 7 deletions
+45 -7
View File
@@ -200,6 +200,23 @@ class Font
],
];
/**
* Array that can be used to supplement FONT_FILE_NAMES for calculating exact width.
*
* @var array
*/
private static $extraFontArray = [];
public static function setExtraFontArray(array $extraFontArray): void
{
self::$extraFontArray = $extraFontArray;
}
public static function getExtraFontArray(): array
{
return self::$extraFontArray;
}
/**
* AutoSize method.
*
@@ -403,10 +420,6 @@ class Font
*/
public static function getTextWidthPixelsExact(string $text, FontStyle $font, int $rotation = 0): int
{
if (!function_exists('imagettfbbox')) {
throw new PhpSpreadsheetException('GD library needs to be enabled');
}
// font size should really be supplied in pixels in GD2,
// but since GD2 seems to assume 72dpi, pixels and points are the same
$fontFile = self::getTrueTypeFontFileFromFont($font);
@@ -532,7 +545,8 @@ class Font
}
$name = $font->getName();
if (!isset(self::FONT_FILE_NAMES[$name])) {
$fontArray = array_merge(self::FONT_FILE_NAMES, self::$extraFontArray);
if (!isset($fontArray[$name])) {
throw new PhpSpreadsheetException('Unknown font name "' . $name . '". Cannot map to TrueType font file');
}
$bold = $font->getBold();
@@ -544,7 +558,7 @@ class Font
if ($italic) {
$index .= 'i';
}
$fontFile = self::FONT_FILE_NAMES[$name][$index];
$fontFile = $fontArray[$name][$index];
$separator = '';
if (mb_strlen(self::$trueTypeFontPath) > 1 && mb_substr(self::$trueTypeFontPath, -1) !== '/' && mb_substr(self::$trueTypeFontPath, -1) !== '\\') {
@@ -554,7 +568,31 @@ class Font
// Check if file actually exists
if ($checkPath && !file_exists($fontFile)) {
throw new PhpSpreadsheetException('TrueType Font file not found');
$alternateName = $name;
if ($index !== 'x' && $fontArray[$name][$index] !== $fontArray[$name]['x']) {
// Bold but no italic:
// Comic Sans
// Tahoma
// Neither bold nor italic:
// Impact
// Lucida Console
// Lucida Sans Unicode
// Microsoft Sans Serif
// Symbol
if ($index === 'xb') {
$alternateName .= ' Bold';
} elseif ($index === 'xi') {
$alternateName .= ' Italic';
} elseif ($fontArray[$name]['xb'] === $fontArray[$name]['xbi']) {
$alternateName .= ' Bold';
} else {
$alternateName .= ' Bold Italic';
}
}
$fontFile = self::$trueTypeFontPath . $separator . $alternateName . '.ttf';
if (!file_exists($fontFile)) {
throw new PhpSpreadsheetException('TrueType Font file not found');
}
}
return $fontFile;
@@ -0,0 +1,154 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Shared;
use PhpOffice\PhpSpreadsheet\Exception as SSException;
use PhpOffice\PhpSpreadsheet\Shared\Font;
use PhpOffice\PhpSpreadsheet\Style\Font as StyleFont;
use PHPUnit\Framework\TestCase;
class FontFileNameTest extends TestCase
{
private const DEFAULT_DIRECTORY = 'tests/data/Shared/FakeFonts/Default';
private const MAC_DIRECTORY = 'tests/data/Shared/FakeFonts/Mac';
/** @var string */
private $holdDirectory;
/** @var array */
private $holdExtraFontArray;
protected function setUp(): void
{
$this->holdDirectory = Font::getTrueTypeFontPath();
$this->holdExtraFontArray = Font::getExtraFontArray();
Font::setExtraFontArray([
'Extra Font' => [
'x' => 'extrafont.ttf',
'xb' => 'extrafontbd.ttf',
'xi' => 'extrafonti.ttf',
'xbi' => 'extrafontbi.ttf',
],
]);
}
protected function tearDown(): void
{
Font::setTrueTypeFontPath($this->holdDirectory);
Font::setExtraFontArray($this->holdExtraFontArray);
}
/**
* @dataProvider providerDefault
*/
public function testDefaultFilenames(string $expected, array $fontArray): void
{
if ($expected === 'exception') {
$this->expectException(SSException::class);
$this->expectExceptionMessage('TrueType Font file not found');
}
Font::setTrueTypeFontPath(self::DEFAULT_DIRECTORY);
$font = (new StyleFont())->applyFromArray($fontArray);
$result = Font::getTrueTypeFontFileFromFont($font);
self::assertSame($expected, basename($result));
}
public function providerDefault(): array
{
return [
['arial.ttf', ['name' => 'Arial']],
['arialbd.ttf', ['name' => 'Arial', 'bold' => true]],
['ariali.ttf', ['name' => 'Arial', 'italic' => true]],
['arialbi.ttf', ['name' => 'Arial', 'bold' => true, 'italic' => true]],
['cour.ttf', ['name' => 'Courier New']],
['courbd.ttf', ['name' => 'Courier New', 'bold' => true]],
['couri.ttf', ['name' => 'Courier New', 'italic' => true]],
['courbi.ttf', ['name' => 'Courier New', 'bold' => true, 'italic' => true]],
['impact.ttf', ['name' => 'Impact']],
'no bold impact' => ['impact.ttf', ['name' => 'Impact', 'bold' => true]],
'no italic impact' => ['impact.ttf', ['name' => 'Impact', 'italic' => true]],
'no bold italic impact' => ['impact.ttf', ['name' => 'Impact', 'bold' => true, 'italic' => true]],
['tahoma.ttf', ['name' => 'Tahoma']],
['tahomabd.ttf', ['name' => 'Tahoma', 'bold' => true]],
'no italic tahoma' => ['tahoma.ttf', ['name' => 'Tahoma', 'italic' => true]],
'no bold italic tahoma' => ['tahomabd.ttf', ['name' => 'Tahoma', 'bold' => true, 'italic' => true]],
'Times New Roman not in directory for this test' => ['exception', ['name' => 'Times New Roman']],
['extrafont.ttf', ['name' => 'Extra Font']],
['extrafontbd.ttf', ['name' => 'Extra Font', 'bold' => true]],
['extrafonti.ttf', ['name' => 'Extra Font', 'italic' => true]],
['extrafontbi.ttf', ['name' => 'Extra Font', 'bold' => true, 'italic' => true]],
];
}
/**
* @dataProvider providerMac
*/
public function testMacFilenames(string $expected, array $fontArray): void
{
if ($expected === 'exception') {
$this->expectException(SSException::class);
$this->expectExceptionMessage('TrueType Font file not found');
}
Font::setTrueTypeFontPath(self::MAC_DIRECTORY);
$font = (new StyleFont())->applyFromArray($fontArray);
$result = Font::getTrueTypeFontFileFromFont($font);
self::assertSame($expected, ucfirst(basename($result))); // allow for Windows case-insensitivity
}
public function providerMac(): array
{
return [
['Arial.ttf', ['name' => 'Arial']],
['Arial Bold.ttf', ['name' => 'Arial', 'bold' => true]],
['Arial Italic.ttf', ['name' => 'Arial', 'italic' => true]],
['Arial Bold Italic.ttf', ['name' => 'Arial', 'bold' => true, 'italic' => true]],
['Courier New.ttf', ['name' => 'Courier New']],
['Courier New Bold.ttf', ['name' => 'Courier New', 'bold' => true]],
['Courier New Italic.ttf', ['name' => 'Courier New', 'italic' => true]],
['Courier New Bold Italic.ttf', ['name' => 'Courier New', 'bold' => true, 'italic' => true]],
['Impact.ttf', ['name' => 'Impact']],
'no bold impact' => ['Impact.ttf', ['name' => 'Impact', 'bold' => true]],
'no italic impact' => ['Impact.ttf', ['name' => 'Impact', 'italic' => true]],
'no bold italic impact' => ['Impact.ttf', ['name' => 'Impact', 'bold' => true, 'italic' => true]],
['Tahoma.ttf', ['name' => 'Tahoma']],
['Tahoma Bold.ttf', ['name' => 'Tahoma', 'bold' => true]],
'no italic tahoma' => ['Tahoma.ttf', ['name' => 'Tahoma', 'italic' => true]],
'no bold italic tahoma' => ['Tahoma Bold.ttf', ['name' => 'Tahoma', 'bold' => true, 'italic' => true]],
'Times New Roman not in directory for this test' => ['exception', ['name' => 'Times New Roman']],
['Extra Font.ttf', ['name' => 'Extra Font']],
['Extra Font Bold.ttf', ['name' => 'Extra Font', 'bold' => true]],
['Extra Font Italic.ttf', ['name' => 'Extra Font', 'italic' => true]],
['Extra Font Bold Italic.ttf', ['name' => 'Extra Font', 'bold' => true, 'italic' => true]],
];
}
/**
* @dataProvider providerOverride
*/
public function testOverrideFilenames(string $expected, array $fontArray): void
{
Font::setTrueTypeFontPath(self::DEFAULT_DIRECTORY);
Font::setExtraFontArray([
'Arial' => [
'x' => 'extrafont.ttf',
'xb' => 'extrafontbd.ttf',
'xi' => 'extrafonti.ttf',
'xbi' => 'extrafontbi.ttf',
],
]);
$font = (new StyleFont())->applyFromArray($fontArray);
$result = Font::getTrueTypeFontFileFromFont($font);
self::assertSame($expected, basename($result));
}
public function providerOverride(): array
{
return [
['extrafont.ttf', ['name' => 'Arial']],
['extrafontbd.ttf', ['name' => 'Arial', 'bold' => true]],
['extrafonti.ttf', ['name' => 'Arial', 'italic' => true]],
['extrafontbi.ttf', ['name' => 'Arial', 'bold' => true, 'italic' => true]],
['cour.ttf', ['name' => 'Courier New']],
];
}
}