Initial commit

This commit is contained in:
2026-08-20 11:41:17 +00:00
commit 6949695eac
2334 changed files with 646393 additions and 0 deletions
+503
View File
@@ -0,0 +1,503 @@
<?php
/**
* BaseTest.php
*
* @since 2011-05-23
* @category Library
* @package PdfGraph
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf-graph
*
* This file is part of tc-lib-pdf-graph software library.
*/
namespace Test;
/**
* Base Test
*
* @since 2011-05-23
* @category Library
* @package PdfGraph
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf-graph
*/
class BaseTest extends TestUtil
{
protected function getTestObject(): \Com\Tecnick\Pdf\Graph\Draw
{
return new \Com\Tecnick\Pdf\Graph\Draw(
0.75,
80,
100,
new \Com\Tecnick\Color\Pdf(),
$this->getEncryptObject(),
false,
);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetOutResourcesByKeysSkipInvalidEntries(): void
{
$draw = $this->getTestObject();
$draw->getOverprint();
$draw->getGradient(
2,
[0, 0, 1, 0],
[
['color' => 'red', 'offset' => 0.0],
['color' => 'blue', 'offset' => 1.0],
],
'',
false,
);
$this->assertSame(' /ExtGState << >>' . "\n", $draw->getOutExtGStateResourcesByKeys([999]));
$this->assertSame('', $draw->getOutGradientResourcesByKeys([999]));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
* @throws \Com\Tecnick\Pdf\Encrypt\Exception
*/
public function testGradientShadersHandleMalformedStopsAndFloatExponent(): void
{
$draw = $this->getTestObject();
$draw->getGradient(
2,
[0, 0, 1, 0],
[
['color' => 'red', 'offset' => 0.0, 'opacity' => 0.5],
['color' => 'blue', 'offset' => 1.0, 'opacity' => 0.6, 'exponent' => 1.5],
],
'',
false,
);
$outFloatExponent = $draw->getOutGradientShaders($draw->getObjectNumber());
$this->assertStringContainsString('/N 1.5', $outFloatExponent);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
* @throws \Com\Tecnick\Pdf\Encrypt\Exception
*/
public function testGetOutGradientShadersSkipsMissingOpacityPattern(): void
{
$draw = new class(0.75, 80, 100, new \Com\Tecnick\Color\Pdf(), $this->getEncryptObject(), false) extends
\Com\Tecnick\Pdf\Graph\Draw {
/**
* @param array<int, array{
* antialias: bool,
* background: ?\Com\Tecnick\Color\Model,
* colors: array<int, array{color: string, exponent?: float, offset?: float, opacity?: float}>,
* colspace: string,
* coords: array<float>,
* id: int,
* pattern: int,
* stream: string,
* transparency: bool,
* type: int,
* }> $grads
*/
public function setGradientsForTest(array $grads): void
{
$this->gradients = $grads;
}
protected function getOutGradientCols(array $grad, string $type): string
{
if ($type === 'opacity') {
return '';
}
return parent::getOutGradientCols($grad, $type);
}
};
$draw->setGradientsForTest([
1 => [
'antialias' => false,
'background' => null,
'colors' => [
0 => ['color' => 'red', 'offset' => 0.0, 'opacity' => 0.5, 'exponent' => 1.0],
1 => ['color' => 'blue', 'offset' => 1.0, 'opacity' => 0.6, 'exponent' => 1.0],
],
'colspace' => 'DeviceRGB',
'coords' => [0.0, 0.0, 1.0, 0.0],
'id' => 0,
'pattern' => 0,
'stream' => '',
'transparency' => true,
'type' => 2,
],
]);
$out = $draw->getOutGradientShaders(10);
$this->assertNotSame('', $out);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetOutExtGState(): void
{
$draw = $this->getTestObject();
$res = $draw->getOutExtGState(10);
$this->assertEquals('', $res);
$draw->getOverprint();
$draw->getAlpha();
$res = $draw->getOutExtGState(10);
$this->assertEquals(
'11 0 obj'
. "\n"
. '<< /Type /ExtGState /OP true /op true /OPM 0.000000 >>'
. "\n"
. 'endobj'
. "\n"
. '12 0 obj'
. "\n"
. '<< /Type /ExtGState /CA 1.000000 /ca 1.000000 /BM /Normal /AIS false >>'
. "\n"
. 'endobj'
. "\n",
$res,
);
$this->assertEquals(12, $draw->getObjectNumber());
$this->assertEquals(2, $draw->getLastExtGStateID());
}
/**
* @SuppressWarnings("PHPMD.LongVariable")
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetOutExtGStateResourcesEmpty(): void
{
$draw = $this->getTestObject();
$outExtGStateResources = $draw->getOutExtGStateResources();
$this->assertEquals('', $outExtGStateResources);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetOutGradientResourcesEmpty(): void
{
$draw = $this->getTestObject();
$outGradientResources = $draw->getOutGradientResources();
$this->assertEquals('', $outGradientResources);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
* @throws \Com\Tecnick\Pdf\Encrypt\Exception
*/
public function testGetOutGradientShaders(): void
{
$draw = $this->getTestObject();
$res = $draw->getOutGradientShaders(10);
$this->assertEquals('', $res);
$draw->getCoonsPatchMeshWithCoords(3, 5, 7, 11);
$draw->getOutGradientShaders(11);
$this->assertEquals(13, $draw->getObjectNumber());
$res = $draw->getOutGradientResources();
$this->assertEquals(' /Pattern << /p1 13 0 R >>' . "\n" . ' /Shading << /Sh1 12 0 R >>' . "\n", $res);
$nres = $draw->getOutGradientResourcesByKeys([]);
$this->assertEmpty($nres);
$resx = $draw->getOutGradientResourcesByKeys([1]);
$this->assertEquals(' /Pattern << /p1 13 0 R >>' . "\n" . ' /Shading << /Sh1 12 0 R >>' . "\n", $resx);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
* @throws \Com\Tecnick\Pdf\Encrypt\Exception
*/
public function testGetOutShaders(): void
{
$draw = $this->getTestObject();
$stops = [
[
'color' => 'red',
'exponent' => 1,
'opacity' => 0.5,
],
[
'color' => 'blue',
'exponent' => 1,
'offset' => 0.2,
'opacity' => 0.6,
],
[
'color' => '#98fb98',
'exponent' => 1,
'opacity' => 0.7,
],
[
'color' => 'rgb(64,128,191)',
'exponent' => 1,
'offset' => 0.8,
'opacity' => 0.8,
],
[
'color' => 'skyblue',
'exponent' => 1,
'opacity' => 0.9,
],
];
$this->assertEquals('/TGS1 gs' . "\n" . '/Sh1 sh' . "\n", $draw->getGradient(
2,
[0, 0, 1, 0],
$stops,
'',
false,
));
$draw->getOverprint();
$draw->getAlpha();
$draw->getOutExtGState($draw->getObjectNumber());
$draw->getOutGradientShaders($draw->getObjectNumber());
$this->assertEquals(19, $draw->getObjectNumber());
$res = $draw->getOutExtGStateResources();
$this->assertEquals(' /ExtGState << /GS1 1 0 R /GS2 2 0 R /TGS1 19 0 R >>' . "\n", $res);
$nres = $draw->getOutExtGStateResourcesByKeys([]);
$this->assertEmpty($nres);
$resx = $draw->getOutExtGStateResourcesByKeys([1, 2]);
$this->assertEquals(' /ExtGState << /GS1 1 0 R /GS2 2 0 R >>' . "\n", $resx);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
* @throws \Com\Tecnick\Pdf\Encrypt\Exception
*/
public function testGetOutShadersRadial(): void
{
$draw = $this->getTestObject();
$out = $draw->getGradient(
3,
[0.6, 0.5, 0.4, 0.3, 1],
[
[
'color' => 'red',
'exponent' => 1,
'offset' => 0,
],
[
'color' => 'green',
'exponent' => 1,
'offset' => 1,
],
],
'white',
true,
);
$this->assertEquals('/Sh1 sh' . "\n", $out);
$this->assertEquals(0, $draw->getObjectNumber());
$draw->getOutGradientShaders($draw->getObjectNumber());
$this->assertEquals(4, $draw->getObjectNumber());
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
* @throws \Com\Tecnick\Pdf\Encrypt\Exception
*/
public function testGetOutGradientShadersInvalidColor(): void
{
$draw = $this->getTestObject();
$stops = [
[
'color' => 'red',
'exponent' => 1.0,
'opacity' => 1.0,
],
[
'color' => 'not-a-valid-color',
'exponent' => 1.0,
'opacity' => 1.0,
],
[
'color' => 'blue',
'exponent' => 1.0,
'opacity' => 1.0,
],
];
$draw->getGradient(2, [0, 0, 1, 0], $stops, '', false);
$res = $draw->getOutGradientShaders($draw->getObjectNumber());
$this->assertNotEmpty($res);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetTransparencyExtGStateNamesEmpty(): void
{
$draw = $this->getTestObject();
$this->assertSame([], $draw->getTransparencyExtGStateNames());
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetTransparencyExtGStateNamesIgnoresOpaque(): void
{
$draw = $this->getTestObject();
// Overprint carries no alpha/blend/soft-mask information.
$draw->getOverprint();
// A fully opaque alpha (CA = ca = 1, BM = Normal, no SMask) must be ignored.
$draw->getAlpha();
$this->assertSame([], $draw->getTransparencyExtGStateNames());
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetTransparencyExtGStateNamesDetectsTransparency(): void
{
$draw = $this->getTestObject();
// GS1: stroking alpha below 1 (CA).
$draw->getAlpha(0.5, 'Normal', 1.0);
// GS2: non-stroking alpha below 1 (ca).
$draw->getAlpha(1.0, 'Normal', 0.4);
// GS3: non-Normal blend mode.
$draw->getAlpha(1.0, 'Multiply', 1.0);
// GS4: an explicit soft mask.
$draw->getExtGState(['SMask' => '/Foo']);
// GS5: fully opaque, must be skipped.
$draw->getAlpha();
$this->assertSame(['GS1', 'GS2', 'GS3', 'GS4'], $draw->getTransparencyExtGStateNames());
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
* @throws \Com\Tecnick\Pdf\Encrypt\Exception
*/
public function testGetTransparencyExtGStateNamesUsesAssignedName(): void
{
$draw = new class(0.75, 80, 100, new \Com\Tecnick\Color\Pdf(), $this->getEncryptObject(), false) extends
\Com\Tecnick\Pdf\Graph\Draw {
/**
* @param array<int, array{
* 'n': int,
* 'name': string,
* 'parms': array<string, int|float|bool|string>,
* }> $extgstates
*/
public function setExtGStatesForTest(array $extgstates): void
{
$this->extgstates = $extgstates;
}
};
$draw->setExtGStatesForTest([
// Named transparent entry: the assigned name is returned verbatim.
3 => ['n' => 0, 'name' => 'NAMEDGS', 'parms' => ['ca' => 0.25]],
// Unnamed transparent entry: the name falls back to "GS" . key.
4 => ['n' => 0, 'name' => '', 'parms' => ['CA' => 0.5]],
// Named but opaque entry: must be skipped.
5 => ['n' => 0, 'name' => 'OPAQUE', 'parms' => ['ca' => 1.0]],
]);
$this->assertSame(['NAMEDGS', 'GS4'], $draw->getTransparencyExtGStateNames());
}
/**
* Axial (type 2) and radial (type 3) shading dictionaries must terminate
* with a real newline before "endobj", not a literal backslash-n.
*
* @throws \Com\Tecnick\Pdf\Graph\Exception
* @throws \Com\Tecnick\Pdf\Encrypt\Exception
*/
public function testGradientShadingDictionaryUsesRealNewline(): void
{
$draw = $this->getTestObject();
// axial shading
$draw->getGradient(
2,
[0, 0, 1, 0],
[
['color' => 'red', 'offset' => 0.0],
['color' => 'blue', 'offset' => 1.0],
],
'',
false,
);
// radial shading
$draw->getGradient(
3,
[0.5, 0.5, 0.5, 0.5, 1],
[
['color' => 'red', 'offset' => 0.0],
['color' => 'green', 'offset' => 1.0],
],
'',
false,
);
$out = $draw->getOutGradientShaders($draw->getObjectNumber());
// the shading dictionary must end with ">>" followed by a real newline and "endobj"
$this->assertStringContainsString('/Extend [true true] >>' . "\n" . 'endobj', $out);
// it must NOT contain a literal backslash-n sequence (single-quoted: backslash + n)
$this->assertStringNotContainsString('>>\n', $out);
}
/**
* A transparent gradient registers a luminosity soft-mask ExtGState that
* must be reported as carrying actual transparency.
*
* @throws \Com\Tecnick\Pdf\Graph\Exception
* @throws \Com\Tecnick\Pdf\Encrypt\Exception
*/
public function testGetTransparencyExtGStateNamesDetectsGradientSoftMask(): void
{
$draw = $this->getTestObject();
// a gradient with opacity < 1 generates a luminosity soft mask
$draw->getGradient(
2,
[0, 0, 1, 0],
[
['color' => 'red', 'offset' => 0.0, 'opacity' => 0.5],
['color' => 'blue', 'offset' => 1.0, 'opacity' => 0.5],
],
'',
false,
);
// the TGS ExtGState only exists after the shaders have been generated
$this->assertSame([], $draw->getTransparencyExtGStateNames());
$draw->getOutGradientShaders($draw->getObjectNumber());
$this->assertContains('TGS1', $draw->getTransparencyExtGStateNames());
}
}
@@ -0,0 +1,94 @@
<?php
/**
* BlendModeTest.php
*
* @since 2026-07-17
* @category Library
* @package PdfGraph
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf-graph
*
* This file is part of tc-lib-pdf-graph software library.
*/
namespace Test;
use Com\Tecnick\Pdf\Graph\BlendMode;
/**
* BlendMode enum test
*
* @since 2026-07-17
* @category Library
* @package PdfGraph
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf-graph
*/
class BlendModeTest extends TestUtil
{
protected function getTestObject(): \Com\Tecnick\Pdf\Graph\Draw
{
return new \Com\Tecnick\Pdf\Graph\Draw(1, 0, 0, new \Com\Tecnick\Color\Pdf(), $this->getEncryptObject(), false);
}
public function testCaseBackingValues(): void
{
$this->assertSame('Normal', BlendMode::Normal->value);
$this->assertSame('Multiply', BlendMode::Multiply->value);
$this->assertSame('Luminosity', BlendMode::Luminosity->value);
$this->assertCount(16, BlendMode::cases());
}
public function testFromLooseCanonical(): void
{
$this->assertSame(BlendMode::Multiply, BlendMode::fromLoose('Multiply'));
$this->assertSame(BlendMode::ColorBurn, BlendMode::fromLoose('ColorBurn'));
}
public function testFromLooseStripsLeadingSlash(): void
{
$this->assertSame(BlendMode::Screen, BlendMode::fromLoose('/Screen'));
}
public function testFromLooseFallsBackToNormal(): void
{
$this->assertSame(BlendMode::Normal, BlendMode::fromLoose('bogus'));
$this->assertSame(BlendMode::Normal, BlendMode::fromLoose(''));
// case sensitive: wrong case is unknown and falls back
$this->assertSame(BlendMode::Normal, BlendMode::fromLoose('multiply'));
}
public function testFromLoosePassesThroughEnumInstance(): void
{
$this->assertSame(BlendMode::HardLight, BlendMode::fromLoose(BlendMode::HardLight));
}
public function testFromLooseRoundTrip(): void
{
foreach (BlendMode::cases() as $case) {
$this->assertSame($case, BlendMode::fromLoose($case->value));
}
}
/**
* The widened getAlpha() accepts a BlendMode enum; equal blend modes dedupe
* to the same ExtGState reference, different ones do not.
*
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetAlphaAcceptsEnum(): void
{
$draw = $this->getTestObject();
$fromEnum = $draw->getAlpha(1.0, BlendMode::Multiply);
$this->assertSame($fromEnum, $draw->getAlpha(1.0, 'Multiply'));
$this->assertSame($fromEnum, $draw->getAlpha(1.0, '/Multiply'));
$this->assertNotSame($fromEnum, $draw->getAlpha(1.0, BlendMode::Screen));
// unknown blend mode falls back to Normal
$this->assertSame($draw->getAlpha(1.0, 'Normal'), $draw->getAlpha(1.0, 'bogus'));
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,118 @@
<?php
/**
* PathPaintOpTest.php
*
* @since 2026-07-17
* @category Library
* @package PdfGraph
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf-graph
*
* This file is part of tc-lib-pdf-graph software library.
*/
namespace Test;
use Com\Tecnick\Pdf\Graph\PathPaintOp;
/**
* PathPaintOp enum test
*
* @since 2026-07-17
* @category Library
* @package PdfGraph
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf-graph
*/
class PathPaintOpTest extends TestUtil
{
protected function getTestObject(): \Com\Tecnick\Pdf\Graph\Draw
{
return new \Com\Tecnick\Pdf\Graph\Draw(1, 0, 0, new \Com\Tecnick\Color\Pdf(), $this->getEncryptObject(), false);
}
public function testCaseBackingValues(): void
{
$this->assertSame('S', PathPaintOp::Stroke->value);
$this->assertSame('f', PathPaintOp::Fill->value);
$this->assertSame('h f', PathPaintOp::CloseFill->value);
$this->assertSame('B*', PathPaintOp::FillStrokeEvenOdd->value);
$this->assertSame('W n', PathPaintOp::Clip->value);
$this->assertSame('W* n', PathPaintOp::ClipEvenOdd->value);
$this->assertCount(14, PathPaintOp::cases());
}
public function testFromLooseCanonical(): void
{
$this->assertSame(PathPaintOp::Stroke, PathPaintOp::fromLoose('S'));
$this->assertSame(PathPaintOp::Fill, PathPaintOp::fromLoose('f'));
$this->assertSame(PathPaintOp::NoOp, PathPaintOp::fromLoose('n'));
}
public function testFromLooseResolvesAliases(): void
{
$this->assertSame(PathPaintOp::Stroke, PathPaintOp::fromLoose('D'));
$this->assertSame(PathPaintOp::CloseStroke, PathPaintOp::fromLoose('h S'));
$this->assertSame(PathPaintOp::Fill, PathPaintOp::fromLoose('F'));
$this->assertSame(PathPaintOp::FillStroke, PathPaintOp::fromLoose('FD'));
$this->assertSame(PathPaintOp::FillStroke, PathPaintOp::fromLoose('DF'));
$this->assertSame(PathPaintOp::FillStrokeEvenOdd, PathPaintOp::fromLoose('F*D'));
$this->assertSame(PathPaintOp::CloseFillStroke, PathPaintOp::fromLoose('df'));
$this->assertSame(PathPaintOp::Clip, PathPaintOp::fromLoose('CNZ'));
$this->assertSame(PathPaintOp::ClipEvenOdd, PathPaintOp::fromLoose('CEO'));
}
public function testFromLooseFallsBackToStroke(): void
{
$this->assertSame(PathPaintOp::Stroke, PathPaintOp::fromLoose('nonsense'));
$this->assertSame(PathPaintOp::Stroke, PathPaintOp::fromLoose(''));
}
public function testFromLoosePassesThroughEnumInstance(): void
{
$this->assertSame(PathPaintOp::Clip, PathPaintOp::fromLoose(PathPaintOp::Clip));
}
public function testFromLooseRoundTrip(): void
{
foreach (PathPaintOp::cases() as $case) {
$this->assertSame($case, PathPaintOp::fromLoose($case->value));
}
}
/**
* The widened getPathPaintOp() accepts a PathPaintOp enum for both $mode and
* $default, staying consistent with the legacy string call.
*
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetPathPaintOpAcceptsEnum(): void
{
$draw = $this->getTestObject();
$this->assertSame("f\n", $draw->getPathPaintOp(PathPaintOp::Fill));
$this->assertSame("B\n", $draw->getPathPaintOp(PathPaintOp::FillStroke));
$this->assertSame($draw->getPathPaintOp('CEO'), $draw->getPathPaintOp(PathPaintOp::ClipEvenOdd));
// enum used as the $default when the mode is unknown/empty
$this->assertSame("b\n", $draw->getPathPaintOp('', PathPaintOp::CloseFillStroke));
}
/**
* A drawing method that funnels $mode through the string predicates accepts
* a PathPaintOp enum too (getPolygon normalizes it once).
*
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testDrawingMethodAcceptsEnum(): void
{
$draw = $this->getTestObject();
$fromEnum = $draw->getRect(0, 0, 10, 10, PathPaintOp::Fill);
$fromString = $draw->getRect(0, 0, 10, 10, 'f');
$this->assertNotSame('', $fromEnum);
$this->assertSame($fromString, $fromEnum);
}
}
+284
View File
@@ -0,0 +1,284 @@
<?php
/**
* RawTest.php
*
* @since 2011-05-23
* @category Library
* @package PdfGraph
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf-graph
*
* This file is part of tc-lib-pdf-graph software library.
*/
namespace Test;
/**
* Raw Test
*
* @since 2011-05-23
* @category Library
* @package PdfGraph
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf-graph
*/
class RawTest extends TestUtil
{
protected function getTestObject(): \Com\Tecnick\Pdf\Graph\Draw
{
return new \Com\Tecnick\Pdf\Graph\Draw(
0.75,
80,
100,
new \Com\Tecnick\Color\Pdf(),
$this->getEncryptObject(),
false,
);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetRawPoint(): void
{
$draw = $this->getTestObject();
$this->assertEquals('2.250000 71.250000 m' . "\n", $draw->getRawPoint(3, 5));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetRawLine(): void
{
$draw = $this->getTestObject();
$this->assertEquals('2.250000 71.250000 l' . "\n", $draw->getRawLine(3, 5));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetRawRect(): void
{
$draw = $this->getTestObject();
$this->assertEquals('2.250000 71.250000 5.250000 -8.250000 re' . "\n", $draw->getRawRect(3, 5, 7, 11));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetRawCurve(): void
{
$draw = $this->getTestObject();
$this->assertEquals('2.250000 71.250000 5.250000 66.750000 9.750000 62.250000 c' . "\n", $draw->getRawCurve(
3,
5,
7,
11,
13,
17,
));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetRawCurveV(): void
{
$draw = $this->getTestObject();
$this->assertEquals('2.250000 71.250000 5.250000 66.750000 v' . "\n", $draw->getRawCurveV(3, 5, 7, 11));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetRawCurveY(): void
{
$draw = $this->getTestObject();
$this->assertEquals('2.250000 71.250000 5.250000 66.750000 y' . "\n", $draw->getRawCurveY(3, 5, 7, 11));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetRawEllipticalArc(): void
{
$draw = $this->getTestObject();
$res = $draw->getRawEllipticalArc(0, 0, 0, 0);
$this->assertEquals('', $res);
$res = $draw->getRawEllipticalArc(3, 5, 7, 11);
$this->assertEquals(
'7.500000 71.250000 m'
. "\n"
. '7.500000 73.189135 7.064930 75.067534 6.271733 76.552998 c'
. "\n"
. '5.478536 78.038462 4.376901 79.037937 3.161653 79.374664 c'
. "\n"
. '1.946405 79.711391 0.693671 79.364277 -0.375000 78.394710 c'
. "\n"
. '-1.443671 77.425142 -2.261335 75.893857 -2.683386 74.071666 c'
. "\n"
. '-3.105437 72.249475 -3.105437 70.250525 -2.683386 68.428334 c'
. "\n"
. '-2.261335 66.606143 -1.443671 65.074858 -0.375000 64.105290 c'
. "\n"
. '0.693671 63.135723 1.946405 62.788609 3.161653 63.125336 c'
. "\n"
. '4.376901 63.462063 5.478536 64.461538 6.271733 65.947002 c'
. "\n"
. '7.064930 67.432466 7.500000 69.310865 7.500000 71.250000 c'
. "\n",
$res,
);
$bbox = [];
$res = $draw->getRawEllipticalArc(3, 5, 7, 11, 0, -180, -90, true, 1.8, false, false, true, $bbox);
$this->assertEquals(
'2.250000 71.250000 m'
. "\n"
. '-3.000000 71.250000 l'
. "\n"
. '-3.000000 73.118591 -2.596009 74.932867 -1.854615 76.393791 c'
. "\n"
. '-1.113221 77.854714 -0.077525 78.877355 1.081765 79.293155 c'
. "\n"
. '2.241055 79.708956 3.456544 79.493745 4.527890 78.682993 c'
. "\n"
. '5.599235 77.872242 6.464154 76.513084 6.980087 74.829541 c'
. "\n"
. '7.496019 73.145998 7.632972 71.235944 7.368372 69.414202 c'
. "\n"
. '7.103771 67.592460 6.453000 65.964938 5.523321 64.799890 c'
. "\n"
. '4.593643 63.634843 3.439104 63.000000 2.250000 63.000000 c'
. "\n"
. '2.250000 71.250000 l'
. "\n",
$res,
);
$res = $draw->getRawEllipticalArc(3, 5, 7, 11, 0, 90, 45);
$this->assertEquals(
'2.250000 79.500000 m'
. "\n"
. '1.084822 79.500000 -0.047846 78.890447 -0.968406 77.767993 c'
. "\n"
. '-1.888967 76.645539 -2.546049 75.072821 -2.835467 73.299209 c'
. "\n"
. '-3.124884 71.525598 -3.030486 69.650067 -2.567240 67.970002 c'
. "\n"
. '-2.103993 66.289938 -1.297750 64.899093 -0.276348 64.018002 c'
. "\n"
. '0.745054 63.136911 1.924617 62.814741 3.075308 63.102576 c'
. "\n"
. '4.225999 63.390411 5.283605 64.272189 6.080433 65.608093 c'
. "\n"
. '6.877260 66.943998 7.368843 68.659482 7.477234 70.482537 c'
. "\n"
. '7.585626 72.305591 7.304778 74.134484 6.679223 75.679223 c'
. "\n",
$res,
);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetVectorsAngle(): void
{
$draw = $this->getTestObject();
$res = $draw->getVectorsAngle(0, 0, 0, 0);
$this->bcAssertEqualsWithDelta(0, $res);
$res = $draw->getVectorsAngle(0, 1, 0, 1);
$this->bcAssertEqualsWithDelta(0, $res);
$res = $draw->getVectorsAngle(1, 1, 2, 2);
$this->bcAssertEqualsWithDelta(0, $res);
$res = $draw->getVectorsAngle(1, 0, 0, 1);
$this->bcAssertEqualsWithDelta(1.57, $res);
$res = $draw->getVectorsAngle(0, 1, 1, 0);
$this->bcAssertEqualsWithDelta(-1.57, $res);
$res = $draw->getVectorsAngle(1, 0, 1, 1);
$this->bcAssertEqualsWithDelta(0.79, $res);
$res = $draw->getVectorsAngle(-1, -1, 1, 1);
$this->bcAssertEqualsWithDelta(M_PI, $res);
$res = $draw->getVectorsAngle(1, 0, -1, 0);
$this->bcAssertEqualsWithDelta(M_PI, $res);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetRawEllipticalArcBboxPopulated(): void
{
$draw = $this->getTestObject();
$bbox = [];
// full circle: bbox should be fully populated (no sentinel values remaining)
$draw->getRawEllipticalArc(3, 5, 7, 11, 0, 0, 360, false, 2, true, true, false, $bbox);
$this->assertCount(4, $bbox);
$minx = $bbox[0] ?? PHP_INT_MAX;
$miny = $bbox[1] ?? PHP_INT_MAX;
$maxx = $bbox[2] ?? PHP_INT_MIN;
$maxy = $bbox[3] ?? PHP_INT_MIN;
$this->assertLessThan(PHP_INT_MAX, $minx); // min-x was updated
$this->assertLessThan(PHP_INT_MAX, $miny); // min-y was updated
$this->assertGreaterThan(PHP_INT_MIN, $maxx); // max-x was updated
$this->assertGreaterThan(PHP_INT_MIN, $maxy); // max-y was updated
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetRawEllipticalArcBboxNegativeMaxValues(): void
{
$draw = $this->getTestObject();
// Arc from 45° to 90° with centre at (0, 0) and vertical radius 5.
// In this range every cy control point is negative (cy = -rdv * sin(ang)).
// The PHP_INT_MIN initialisation ensures the max values are updated correctly
// even when all sampled points are negative.
$bbox = [];
$draw->getRawEllipticalArc(0, 0, 7, 5, 0, 45, 90, false, 2, true, true, false, $bbox);
$this->assertCount(4, $bbox);
$maxx = $bbox[2] ?? PHP_INT_MIN;
$maxy = $bbox[3] ?? PHP_INT_MIN;
$this->assertGreaterThan(PHP_INT_MIN, $maxx); // max-x was updated from sentinel
$this->assertGreaterThan(PHP_INT_MIN, $maxy); // max-y was updated from sentinel
$this->assertLessThan(0, $maxy); // all cy values in this arc are < 0
}
/**
* A zero vertical radius means "circle" (per the docblock) and must not
* trigger a division by zero.
*
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetRawEllipticalArcZeroVerticalRadius(): void
{
$draw = $this->getTestObject();
// rdv = 0 must be treated as a circle (rdv = rdh), not crash.
$out = $draw->getRawEllipticalArc(3, 5, 7, 0);
$this->assertNotSame('', $out);
// identical to passing the horizontal radius as the vertical one
$this->assertSame($draw->getRawEllipticalArc(3, 5, 7, 7), $out);
}
}
+509
View File
@@ -0,0 +1,509 @@
<?php
/**
* StyleTest.php
*
* @since 2011-05-23
* @category Library
* @package PdfGraph
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf-graph
*
* This file is part of tc-lib-pdf-graph software library.
*/
namespace Test;
/**
* Style Test
*
* @since 2011-05-23
* @category Library
* @package PdfGraph
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf-graph
*/
class StyleTest extends TestUtil
{
protected function getTestObject(): \Com\Tecnick\Pdf\Graph\Draw
{
return new \Com\Tecnick\Pdf\Graph\Draw(1, 0, 0, new \Com\Tecnick\Color\Pdf(), $this->getEncryptObject(), false);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetStyleCmd(): void
{
$draw = $this->getTestObject();
$styleCmd = $draw->getStyleCmd();
$exp1 = '';
$this->assertEquals($exp1, $styleCmd);
$style2 = [
'lineWidth' => 3,
'lineCap' => 'round',
'lineJoin' => 'bevel',
'miterLimit' => 11,
'dashArray' => [5, 7],
'dashPhase' => 0,
'lineColor' => 'greenyellow',
'fillColor' => '["RGB",0.250000,0.500000,0.750000]',
];
$res2 = $draw->getStyleCmd($style2);
$exp2 =
'3.000000 w'
. "\n"
. '1 J'
. "\n"
. '2 j'
. "\n"
. '11.000000 M'
. "\n"
. '[5.000000 7.000000] 0.000000 d'
. "\n"
. '0.678431 1.000000 0.184314 RG'
. "\n"
. '0.250000 0.500000 0.750000 rg'
. "\n";
$this->assertEquals($exp2, $res2);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testStyle(): void
{
$draw = $this->getTestObject();
$style = [];
$res1 = $draw->add($style, true);
$exp1 =
'1.000000 w'
. "\n"
. '0 J'
. "\n"
. '0 j'
. "\n"
. '10.000000 M'
. "\n"
. '[] 0.000000 d'
. "\n"
. '/CS1 CS 1.000000 SCN'
. "\n"
. '/CS1 cs 1.000000 scn'
. "\n";
$this->assertEquals($exp1, $res1);
$style = [
'lineWidth' => 3,
'lineCap' => 'round',
'lineJoin' => 'bevel',
'miterLimit' => 11,
'dashArray' => [5, 7],
'dashPhase' => 1,
'lineColor' => 'greenyellow',
'fillColor' => '["RGB",0.250000,0.500000,0.750000]',
];
$res2 = $draw->add($style, false);
$exp2 =
'3.000000 w'
. "\n"
. '1 J'
. "\n"
. '2 j'
. "\n"
. '11.000000 M'
. "\n"
. '[5.000000 7.000000] 1.000000 d'
. "\n"
. '0.678431 1.000000 0.184314 RG'
. "\n"
. '0.250000 0.500000 0.750000 rg'
. "\n";
$this->assertEquals($exp2, $res2);
$this->assertEquals($style, $draw->getCurrentStyleArray());
$style = [
'lineCap' => 'round',
'lineJoin' => 'bevel',
'lineColor' => 'transparent',
'fillColor' => 'cmyk(67,33,0,25)',
];
$res3 = $draw->add($style, true);
$exp3 =
'3.000000 w'
. "\n"
. '1 J'
. "\n"
. '2 j'
. "\n"
. '11.000000 M'
. "\n"
. '[5.000000 7.000000] 1.000000 d'
. "\n"
. '0.670000 0.330000 0.000000 0.250000 k'
. "\n";
$this->assertEquals($exp3, $res3);
$style = [
'lineCap' => 'round',
'lineJoin' => 'bevel',
'lineColor' => 'transparent',
'fillColor' => 'cmyk(67,33,0,25)',
'dashArray' => [],
];
$res4 = $draw->add($style, true);
$exp4 =
'3.000000 w'
. "\n"
. '1 J'
. "\n"
. '2 j'
. "\n"
. '11.000000 M'
. "\n"
. '[] 1.000000 d'
. "\n"
. '0.670000 0.330000 0.000000 0.250000 k'
. "\n";
$this->assertEquals($exp4, $res4);
$style = [
'lineWidth' => 7.123,
];
$res5 = $draw->add($style, false);
$exp5 = '7.123000 w' . "\n";
$this->assertEquals($exp5, $res5);
$res = $draw->pop();
$this->assertEquals($exp5, $res);
$res = $draw->pop();
$this->assertEquals($exp4, $res);
$res = $draw->pop();
$this->assertEquals($exp3, $res);
$res = $draw->pop();
$this->assertEquals($exp2, $res);
$res = $draw->pop();
$this->assertEquals($exp1, $res);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testStyleEx(): void
{
$this->bcExpectException(\Com\Tecnick\Pdf\Graph\Exception::class);
$draw = $this->getTestObject();
$draw->pop();
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testSaveRestoreStyle(): void
{
$draw = $this->getTestObject();
$draw->add([
'lineWidth' => 1,
], false);
$draw->add([
'lineWidth' => 2,
], false);
$draw->add([
'lineWidth' => 3,
], false);
$draw->saveStyleStatus();
$draw->add([
'lineWidth' => 4,
], false);
$draw->add([
'lineWidth' => 5,
], false);
$draw->add([
'lineWidth' => 6,
], false);
$this->assertEquals(
[
'lineWidth' => 6,
],
$draw->getCurrentStyleArray(),
);
$draw->restoreStyleStatus();
$this->assertEquals(
[
'lineWidth' => 3,
],
$draw->getCurrentStyleArray(),
);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testStyleItem(): void
{
$draw = $this->getTestObject();
$this->assertEquals('butt', $draw->getCurrentStyleItem('lineCap'));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testStyleItemEx(): void
{
$this->bcExpectException(\Com\Tecnick\Pdf\Graph\Exception::class);
$draw = $this->getTestObject();
$draw->getCurrentStyleItem('wrongField');
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetLastStyleProperty(): void
{
$draw = $this->getTestObject();
$draw->add([
'lineWidth' => 1,
], false);
$draw->add([
'lineWidth' => 2,
], false);
$draw->add([
'lineWidth' => 3,
], false);
$this->assertEquals(3, $draw->getLastStyleProperty('lineWidth', 0));
$draw->add([
'lineWidth' => 4,
], false);
$this->assertEquals(4, $draw->getLastStyleProperty('lineWidth', 0));
$this->assertEquals(7, $draw->getLastStyleProperty('unknown', 7));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetPathPaintOp(): void
{
$draw = $this->getTestObject();
$res = $draw->getPathPaintOp('', '');
$this->assertEquals('', $res);
$res = $draw->getPathPaintOp('');
$this->assertEquals('S' . "\n", $res);
$res = $draw->getPathPaintOp('', 'df');
$this->assertEquals('b' . "\n", $res);
$res = $draw->getPathPaintOp('CEO');
$this->assertEquals('W* n' . "\n", $res);
$res = $draw->getPathPaintOp('F*D');
$this->assertEquals('B*' . "\n", $res);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testIsFillingMode(): void
{
$draw = $this->getTestObject();
$this->assertTrue($draw->isFillingMode('f'));
$this->assertTrue($draw->isFillingMode('f*'));
$this->assertTrue($draw->isFillingMode('B'));
$this->assertTrue($draw->isFillingMode('B*'));
$this->assertTrue($draw->isFillingMode('b'));
$this->assertTrue($draw->isFillingMode('b*'));
$this->assertFalse($draw->isFillingMode('S'));
$this->assertFalse($draw->isFillingMode('s'));
$this->assertFalse($draw->isFillingMode('n'));
$this->assertFalse($draw->isFillingMode(''));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testIsStrokingMode(): void
{
$draw = $this->getTestObject();
$this->assertTrue($draw->isStrokingMode('S'));
$this->assertTrue($draw->isStrokingMode('s'));
$this->assertTrue($draw->isStrokingMode('B'));
$this->assertTrue($draw->isStrokingMode('B*'));
$this->assertTrue($draw->isStrokingMode('b'));
$this->assertTrue($draw->isStrokingMode('b*'));
$this->assertFalse($draw->isStrokingMode('f'));
$this->assertFalse($draw->isStrokingMode('f*'));
$this->assertFalse($draw->isStrokingMode('n'));
$this->assertFalse($draw->isStrokingMode(''));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testIsClosingMode(): void
{
$draw = $this->getTestObject();
$this->assertTrue($draw->isClosingMode('s'));
$this->assertTrue($draw->isClosingMode('b'));
$this->assertTrue($draw->isClosingMode('b*'));
$this->assertFalse($draw->isClosingMode('f'));
$this->assertFalse($draw->isClosingMode('f*'));
$this->assertFalse($draw->isClosingMode('S'));
$this->assertFalse($draw->isClosingMode('B'));
$this->assertFalse($draw->isClosingMode('B*'));
$this->assertFalse($draw->isClosingMode('n'));
$this->assertFalse($draw->isClosingMode(''));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetModeWithoutClose(): void
{
$draw = $this->getTestObject();
$this->assertEquals('', $draw->getModeWithoutClose(''));
$this->assertEquals('S', $draw->getModeWithoutClose('s'));
$this->assertEquals('B', $draw->getModeWithoutClose('b'));
$this->assertEquals('B*', $draw->getModeWithoutClose('b*'));
$this->assertEquals('n', $draw->getModeWithoutClose('n'));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetModeWithoutFill(): void
{
$draw = $this->getTestObject();
$this->assertEquals('', $draw->getModeWithoutFill(''));
$this->assertEquals('', $draw->getModeWithoutFill('f'));
$this->assertEquals('', $draw->getModeWithoutFill('f*'));
$this->assertEquals('S', $draw->getModeWithoutFill('B'));
$this->assertEquals('S', $draw->getModeWithoutFill('B*'));
$this->assertEquals('s', $draw->getModeWithoutFill('b'));
$this->assertEquals('s', $draw->getModeWithoutFill('b*'));
$this->assertEquals('n', $draw->getModeWithoutFill('n'));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetModeWithoutStroke(): void
{
$draw = $this->getTestObject();
$this->assertEquals('', $draw->getModeWithoutStroke(''));
$this->assertEquals('', $draw->getModeWithoutStroke('S'));
$this->assertEquals('h', $draw->getModeWithoutStroke('s'));
$this->assertEquals('f', $draw->getModeWithoutStroke('B'));
$this->assertEquals('f*', $draw->getModeWithoutStroke('B*'));
$this->assertEquals('h f', $draw->getModeWithoutStroke('b'));
$this->assertEquals('h f*', $draw->getModeWithoutStroke('b*'));
$this->assertEquals('n', $draw->getModeWithoutStroke('n'));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetExtGState(): void
{
$draw = $this->getTestObject();
$this->assertEquals('/GS1 gs' . "\n", $draw->getExtGState([
'A' => 'B',
]));
$this->assertEquals('/GS1 gs' . "\n", $draw->getExtGState([
'A' => 'B',
]));
$this->assertEquals('/GS2 gs' . "\n", $draw->getExtGState([
'C' => 'D',
]));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetExtGStatePdfa(): void
{
$draw = new \Com\Tecnick\Pdf\Graph\Draw(1, 0, 0, new \Com\Tecnick\Color\Pdf(), $this->getEncryptObject(), true);
$this->assertEquals('', $draw->getExtGState([
'A' => 'B',
]));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testRestoreStyleStatusNull(): void
{
$draw = $this->getTestObject();
// stylemark starts as [0]; first restore pops that value
$draw->restoreStyleStatus();
// stylemark is now empty; second restore pops null and falls back to 0
$draw->restoreStyleStatus();
$this->assertEquals('butt', $draw->getCurrentStyleItem('lineCap'));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetCurrentStyleArrayDefaultFallback(): void
{
$draw = new class(1, 0, 0, new \Com\Tecnick\Color\Pdf(), $this->getEncryptObject(), false) extends
\Com\Tecnick\Pdf\Graph\Draw {
public function setStyleIdForTest(int $styleid): void
{
$this->styleid = $styleid;
}
};
$draw->setStyleIdForTest(999);
$this->assertSame('butt', $draw->getCurrentStyleArray()['lineCap'] ?? null);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testIsClippingModeInvalid(): void
{
$draw = $this->getTestObject();
$this->assertFalse($draw->isClippingMode('invalid'));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetLineModeWithDashArrayNoDashPhase(): void
{
$draw = $this->getTestObject();
$style = [
'dashArray' => [3, 5],
];
$res = $draw->getStyleCmd($style);
$this->assertEquals('[3.000000 5.000000] 0.000000 d' . "\n", $res);
}
}
+57
View File
@@ -0,0 +1,57 @@
<?php
/**
* TestUtil.php
*
* @since 2020-12-19
* @category Library
* @package file
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2015-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-file
*
* This file is part of tc-lib-file software library.
*/
namespace Test;
use PHPUnit\Framework\TestCase;
/**
* Test Util
*
* @since 2020-12-19
* @category Library
* @package file
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2015-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-file
*/
class TestUtil extends TestCase
{
public function bcAssertEqualsWithDelta(
mixed $expected,
mixed $actual,
float $delta = 0.01,
string $message = '',
): void {
parent::assertEqualsWithDelta($expected, $actual, $delta, $message);
}
/**
* @param class-string<\Throwable> $exception
*/
public function bcExpectException(string $exception): void
{
parent::expectException($exception);
}
protected function getEncryptObject(): \Com\Tecnick\Pdf\Encrypt\Encrypt
{
return new class() extends \Com\Tecnick\Pdf\Encrypt\Encrypt {
public function __construct() {}
};
}
}
@@ -0,0 +1,421 @@
<?php
/**
* TransformTest.php
*
* @since 2011-05-23
* @category Library
* @package PdfGraph
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf-graph
*
* This file is part of tc-lib-pdf-graph software library.
*/
namespace Test;
/**
* Transform Test
*
* @since 2011-05-23
* @category Library
* @package PdfGraph
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf-graph
*
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
class TransformTest extends TestUtil
{
protected function getTestObject(): \Com\Tecnick\Pdf\Graph\Draw
{
$draw = new \Com\Tecnick\Pdf\Graph\Draw(
1,
0,
0,
new \Com\Tecnick\Color\Pdf(),
$this->getEncryptObject(),
false,
);
$this->assertEquals(-1, $draw->getTransformIndex());
$this->assertEquals('q' . "\n", $draw->getStartTransform());
return $draw;
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetStartStopTransform(): void
{
$draw = new \Com\Tecnick\Pdf\Graph\Draw(
1,
0,
0,
new \Com\Tecnick\Color\Pdf(),
$this->getEncryptObject(),
false,
);
$this->assertEquals(-1, $draw->getTransformIndex());
$this->assertEquals('q' . "\n", $draw->getStartTransform());
$this->assertEquals(0, $draw->getTransformIndex());
$tmx = [0.1, 1.2, 2.3, 3.4, 4.5, 5.6];
$this->assertEquals(
'0.100000 1.200000 2.300000 3.400000 4.500000 5.600000 cm' . "\n",
$draw->getTransformation($tmx),
);
$this->bcAssertEqualsWithDelta(
[
0 => [
0 => [0.1, 1.2, 2.3, 3.4, 4.5, 5.6],
],
],
$draw->getTransformStack(),
0.0001,
'',
);
$this->assertEquals('Q' . "\n", $draw->getStopTransform());
$this->assertEquals(-1, $draw->getTransformIndex());
$this->assertEquals('', $draw->getStopTransform());
$this->assertEquals(-1, $draw->getTransformIndex());
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetTransform(): void
{
$draw = $this->getTestObject();
$tmx = [0.1, 1.2, 2.3, 3.4, 4.5, 5.6];
$this->assertEquals(
'0.100000 1.200000 2.300000 3.400000 4.500000 5.600000 cm' . "\n",
$draw->getTransformation($tmx),
);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testSetPageHeight(): void
{
$draw = new \Com\Tecnick\Pdf\Graph\Draw(
1,
0,
0,
new \Com\Tecnick\Color\Pdf(),
$this->getEncryptObject(),
false,
);
$prev = $draw->setPageHeight(100);
$this->assertEquals(0, (int) $prev);
$this->assertEquals('q' . "\n", $draw->getStartTransform());
$this->assertEquals('3.000000 0.000000 0.000000 5.000000 -14.000000 -356.000000 cm' . "\n", $draw->getScaling(
3,
5,
7,
11,
));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testSetPageWidth(): void
{
$draw = new \Com\Tecnick\Pdf\Graph\Draw(
1,
0,
0,
new \Com\Tecnick\Color\Pdf(),
$this->getEncryptObject(),
false,
);
$prev = $draw->setPageWidth(100);
$this->assertEquals(0, (int) $prev);
$this->assertEquals('q' . "\n", $draw->getStartTransform());
$this->assertEquals('3.000000 0.000000 0.000000 5.000000 -14.000000 44.000000 cm' . "\n", $draw->getScaling(
3,
5,
7,
11,
));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testSetKUnit(): void
{
$draw = new \Com\Tecnick\Pdf\Graph\Draw(
1,
0,
0,
new \Com\Tecnick\Color\Pdf(),
$this->getEncryptObject(),
false,
);
$draw->setKUnit(0.75);
$this->assertEquals('q' . "\n", $draw->getStartTransform());
$this->assertEquals('3.000000 0.000000 0.000000 5.000000 -10.500000 33.000000 cm' . "\n", $draw->getScaling(
3,
5,
7,
11,
));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetScaling(): void
{
$draw = $this->getTestObject();
$this->assertEquals('3.000000 0.000000 0.000000 5.000000 -14.000000 44.000000 cm' . "\n", $draw->getScaling(
3,
5,
7,
11,
));
$this->assertEquals('3.000000 0.000000 0.000000 3.000000 -14.000000 22.000000 cm' . "\n", $draw->getScaling(
3,
3,
7,
11,
));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetScalingEx(): void
{
$this->bcExpectException(\Com\Tecnick\Pdf\Graph\Exception::class);
$draw = $this->getTestObject();
$draw->getScaling(0, 0, 7, 11);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetHorizScaling(): void
{
$draw = $this->getTestObject();
$this->assertEquals('3.000000 0.000000 0.000000 1.000000 -14.000000 0.000000 cm' . "\n", $draw->getHorizScaling(
3,
7,
11,
));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetVertScaling(): void
{
$draw = $this->getTestObject();
$this->assertEquals('1.000000 0.000000 0.000000 5.000000 0.000000 44.000000 cm' . "\n", $draw->getVertScaling(
5,
7,
11,
));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetPropScaling(): void
{
$draw = $this->getTestObject();
$this->assertEquals('3.000000 0.000000 0.000000 3.000000 -14.000000 22.000000 cm' . "\n", $draw->getPropScaling(
3,
7,
11,
));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetRotation(): void
{
$draw = $this->getTestObject();
$this->assertEquals('0.707107 0.707107 -0.707107 0.707107 -5.727922 -8.171573 cm' . "\n", $draw->getRotation(
45,
7,
11,
));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetHorizMirroring(): void
{
$draw = $this->getTestObject();
$this->assertEquals(
'-1.000000 0.000000 0.000000 1.000000 14.000000 0.000000 cm' . "\n",
$draw->getHorizMirroring(7),
);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetVertMirroring(): void
{
$draw = $this->getTestObject();
$this->assertEquals(
'1.000000 0.000000 0.000000 -1.000000 0.000000 -22.000000 cm' . "\n",
$draw->getVertMirroring(11),
);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetPointMirroring(): void
{
$draw = $this->getTestObject();
$this->assertEquals('-1.000000 0.000000 0.000000 -1.000000 14.000000 -22.000000 cm'
. "\n", $draw->getPointMirroring(7, 11));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetReflection(): void
{
$draw = $this->getTestObject();
$this->assertEquals('-1.000000 0.000000 0.000000 1.000000 14.000000 0.000000 cm'
. "\n"
. '0.000000 1.000000 -1.000000 0.000000 -4.000000 -18.000000 cm'
. "\n", $draw->getReflection(45, 7, 11));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetTranslation(): void
{
$draw = $this->getTestObject();
$this->assertEquals('1.000000 0.000000 0.000000 1.000000 3.000000 -5.000000 cm' . "\n", $draw->getTranslation(
3,
5,
));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetHorizTranslation(): void
{
$draw = $this->getTestObject();
$this->assertEquals(
'1.000000 0.000000 0.000000 1.000000 3.000000 0.000000 cm' . "\n",
$draw->getHorizTranslation(3),
);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetVertTranslation(): void
{
$draw = $this->getTestObject();
$this->assertEquals(
'1.000000 0.000000 0.000000 1.000000 0.000000 -5.000000 cm' . "\n",
$draw->getVertTranslation(5),
);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetSkewing(): void
{
$draw = $this->getTestObject();
$this->assertEquals('1.000000 0.087489 0.052408 1.000000 0.576486 -0.612421 cm' . "\n", $draw->getSkewing(
3,
5,
7,
11,
));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetSkewingEx(): void
{
$draw = $this->getTestObject();
$this->bcExpectException(\Com\Tecnick\Pdf\Graph\Exception::class);
$draw->getSkewing(90, -90, 7, 11);
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetHorizSkewing(): void
{
$draw = $this->getTestObject();
$this->assertEquals('1.000000 0.000000 0.052408 1.000000 0.576486 0.000000 cm' . "\n", $draw->getHorizSkewing(
3,
7,
11,
));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetVertSkewing(): void
{
$draw = $this->getTestObject();
$this->assertEquals('1.000000 0.087489 0.000000 1.000000 0.000000 -0.612421 cm' . "\n", $draw->getVertSkewing(
5,
7,
11,
));
}
/**
* @throws \Com\Tecnick\Pdf\Graph\Exception
*/
public function testGetCtmProduct(): void
{
$draw = $this->getTestObject();
$tma = [3.1, 5.2, 7.3, 11.4, 13.5, 17.6];
$tmb = [19.1, 23.2, 29.3, 31.4, 37.5, 41.6];
$ctm = $draw->getCtmProduct($tma, $tmb);
$this->bcAssertEqualsWithDelta([228.570, 363.800, 320.050, 510.320, 433.430, 686.840], $ctm, 0.001);
}
}