Merge pull request #4503 from oleibman/issue4502

AutoColor for LibreOffice Dark Mode
This commit is contained in:
oleibman
2025-06-18 04:22:45 +00:00
committed by GitHub
6 changed files with 187 additions and 7 deletions
@@ -152,6 +152,12 @@ class Styles extends BaseParserClass
$attr = $this->getStyleAttributes($fontStyleXml->scheme);
$fontStyle->setScheme((string) $attr['val']);
}
if (isset($fontStyleXml->auto)) {
$attr = $this->getStyleAttributes($fontStyleXml->auto);
if (isset($attr['val'])) {
$fontStyle->setAutoColor(self::boolean((string) $attr['val']));
}
}
}
private function readNumberFormat(NumberFormat $numfmtStyle, SimpleXMLElement $numfmtStyleXml): void
+37 -3
View File
@@ -86,6 +86,8 @@ class Font extends Supervisor
*/
protected Color $color;
protected bool $autoColor = false;
public ?int $colorIndex = null;
protected string $scheme = '';
@@ -175,7 +177,7 @@ class Font extends Supervisor
* );
* </code>
*
* @param array{name?: string, latin?: string, eastAsian?: string, complexScript?: string, bold?: bool, italic?: bool, superscript?: bool, subscript?: bool, underline?: bool|string, strikethrough?: bool, color?: string[], size?: ?int, chartColor?: ChartColor, scheme?: string, cap?: string} $styleArray Array containing style information
* @param array{name?: string, latin?: string, eastAsian?: string, complexScript?: string, bold?: bool, italic?: bool, superscript?: bool, subscript?: bool, underline?: bool|string, strikethrough?: bool, color?: string[], size?: ?int, chartColor?: ChartColor, scheme?: string, cap?: string, autoColor?: bool} $styleArray Array containing style information
*
* @return $this
*/
@@ -194,7 +196,9 @@ class Font extends Supervisor
$this->setEastAsian($styleArray['eastAsian']);
}
if (isset($styleArray['complexScript'])) {
$this->setComplexScript($styleArray['complexScript']);
$this->setComplexScript(
$styleArray['complexScript']
);
}
if (isset($styleArray['bold'])) {
$this->setBold($styleArray['bold']);
@@ -212,7 +216,9 @@ class Font extends Supervisor
$this->setUnderline($styleArray['underline']);
}
if (isset($styleArray['strikethrough'])) {
$this->setStrikethrough($styleArray['strikethrough']);
$this->setStrikethrough(
$styleArray['strikethrough']
);
}
if (isset($styleArray['color'])) {
/** @var array{rgb?: string, argb?: string, theme?: int} */
@@ -232,6 +238,9 @@ class Font extends Supervisor
if (isset($styleArray['cap'])) {
$this->setCap($styleArray['cap']);
}
if (isset($styleArray['autoColor'])) {
$this->setAutoColor($styleArray['autoColor']);
}
}
return $this;
@@ -745,6 +754,7 @@ class Font extends Supervisor
. ($this->subscript ? 't' : 'f')
. $this->underline
. ($this->strikethrough ? 't' : 'f')
. ($this->autoColor ? 't' : 'f')
. $this->color->getHashCode()
. $this->scheme
. implode(
@@ -786,6 +796,7 @@ class Font extends Supervisor
$this->exportArray2($exportedArray, 'superscript', $this->getSuperscript());
$this->exportArray2($exportedArray, 'underline', $this->getUnderline());
$this->exportArray2($exportedArray, 'underlineColor', $this->getUnderlineColor());
$this->exportArray2($exportedArray, 'autoColor', $this->getAutoColor());
return $exportedArray;
}
@@ -840,6 +851,29 @@ class Font extends Supervisor
return $this;
}
public function setAutoColor(bool $autoColor): self
{
if ($this->isSupervisor) {
$styleArray = $this->getStyleArray(['autoColor' => $autoColor]);
$this->getActiveSheet()
->getStyle($this->getSelectedCells())
->applyFromArray($styleArray);
} else {
$this->autoColor = $autoColor;
}
return $this;
}
public function getAutoColor(): bool
{
if ($this->isSupervisor) {
return $this->getSharedComponent()->getAutoColor();
}
return $this->autoColor;
}
/**
* Implement PHP __clone to create a deep clone, not just a shallow copy.
*/
+14 -3
View File
@@ -204,15 +204,26 @@ class Style
if ($font->getBold()) {
$this->writer->writeAttribute('fo:font-weight', 'bold');
$this->writer->writeAttribute('style:font-weight-complex', 'bold');
$this->writer->writeAttribute('style:font-weight-asian', 'bold');
$this->writer->writeAttribute(
'style:font-weight-complex',
'bold'
);
$this->writer->writeAttribute(
'style:font-weight-asian',
'bold'
);
}
if ($font->getItalic()) {
$this->writer->writeAttribute('fo:font-style', 'italic');
}
$this->writer->writeAttribute('fo:color', sprintf('#%s', $font->getColor()->getRGB()));
if ($font->getAutoColor()) {
$this->writer
->writeAttribute('style:use-window-font-color', 'true');
} else {
$this->writer->writeAttribute('fo:color', sprintf('#%s', $font->getColor()->getRGB()));
}
if ($family = $font->getName()) {
$this->writer->writeAttribute('fo:font-family', $family);
+6 -1
View File
@@ -347,7 +347,12 @@ class Style extends WriterPart
}
// Foreground color
if ($font->getColor()->getTheme() >= 0) {
if ($font->getAutoColor()) {
$this->startFont($objWriter, $fontStarted);
$objWriter->startElement('auto');
$objWriter->writeAttribute('val', '1');
$objWriter->endElement();
} elseif ($font->getColor()->getTheme() >= 0) {
$this->startFont($objWriter, $fontStarted);
$objWriter->startElement('color');
$objWriter->writeAttribute('theme', (string) $font->getColor()->getTheme());
@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests\Writer\ODS;
use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Ods as OdsWriter;
use PHPUnit\Framework\TestCase;
class AutoColorTest extends TestCase
{
private string $outputFile = '';
protected function tearDown(): void
{
if ($this->outputFile !== '') {
unlink($this->outputFile);
$this->outputFile = '';
}
}
public function testAutoColor(): void
{
// It's not clear to me what AutoColor does in Excel.
// However, LibreOffice Dark Mode
// can make use of a spreadsheet which uses it.
$spreadsheet = new Spreadsheet();
$spreadsheet->getDefaultStyle()->getFont()
->setAutoColor(true);
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World!');
$sheet->setCellValue('A2', 'Hello World!');
$sheet->getStyle('A2')->getFont()
->setBold(true);
$sheet->setCellValue('A3', 'Hello World!');
$sheet->getStyle('A3')->getFont()
->setItalic(true);
$sheet->setCellValue('B1', 'Hello World!');
$writer = new OdsWriter($spreadsheet);
$outputFile = $this->outputFile = File::temporaryFilename();
$writer->save($outputFile);
$spreadsheet->disconnectWorksheets();
$zipfile = "zip://$outputFile#content.xml";
$contents = file_get_contents($zipfile);
if ($contents === false) {
self::fail('Unable to open file');
} else {
self::assertStringContainsString('<style:text-properties style:use-window-font-color="true" fo:font-family="Calibri" fo:font-size="11.0pt"/>', $contents);
self::assertStringContainsString('<style:text-properties fo:font-weight="bold" style:font-weight-complex="bold" style:font-weight-asian="bold" style:use-window-font-color="true" fo:font-family="Calibri" fo:font-size="11.0pt"/>', $contents);
self::assertStringContainsString('<style:text-properties fo:font-style="italic" style:use-window-font-color="true" fo:font-family="Calibri" fo:font-size="11.0pt"/>', $contents);
}
}
}
@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
use PHPUnit\Framework\TestCase;
class AutoColorTest extends TestCase
{
private string $outputFile = '';
protected function tearDown(): void
{
if ($this->outputFile !== '') {
unlink($this->outputFile);
$this->outputFile = '';
}
}
public function testAutoColor(): void
{
// It's not clear to me what AutoColor does in Excel.
// However, LibreOffice Dark Mode
// can make use of a spreadsheet which uses it.
$spreadsheet = new Spreadsheet();
$spreadsheet->getDefaultStyle()->getFont()
->setAutoColor(true);
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World!');
$sheet->setCellValue('A2', 'Hello World!');
$sheet->getStyle('A2')->getFont()
->setBold(true);
$sheet->setCellValue('A3', 'Hello World!');
$sheet->getStyle('A3')->getFont()
->setItalic(true);
$sheet->setCellValue('B1', 'Hello World!');
$writer = new XlsxWriter($spreadsheet);
$outputFile = $this->outputFile = File::temporaryFilename();
$writer->save($outputFile);
$spreadsheet->disconnectWorksheets();
$zipfile = "zip://$outputFile#xl/styles.xml";
$contents = file_get_contents($zipfile);
if ($contents === false) {
self::fail('Unable to open file');
} else {
self::assertStringContainsString('<fonts count="3">', $contents);
self::assertStringContainsString('<font><b val="0"/><i val="0"/><strike val="0"/><u val="none"/><sz val="11"/><auto val="1"/><name val="Calibri"/></font>', $contents);
self::assertStringContainsString('<font><b val="1"/><i val="0"/><strike val="0"/><u val="none"/><sz val="11"/><auto val="1"/><name val="Calibri"/></font>', $contents);
self::assertStringContainsString('<font><b val="0"/><i val="1"/><strike val="0"/><u val="none"/><sz val="11"/><auto val="1"/><name val="Calibri"/></font>', $contents);
}
$reader = new XlsxReader();
$spreadsheet2 = $reader->load($outputFile);
$sheet2 = $spreadsheet2->getActiveSheet();
self::assertTrue(
$sheet2->getStyle('A1')
->getFont()
->getAutoColor()
);
$spreadsheet2->disconnectWorksheets();
}
}