Skip to content

Commit 0d21ec8

Browse files
committed
add GSAVE/GRESTORE constants and expand test coverage for Draw, Gradient, and Raw
1 parent fda495e commit 0d21ec8

10 files changed

Lines changed: 105 additions & 11 deletions

File tree

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.4.23
1+
2.4.24

src/Base.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,20 @@ abstract class Base
9898
*/
9999
public const IDMATRIX = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0];
100100

101+
/**
102+
* PDF graphics state save operator.
103+
*
104+
* @var string
105+
*/
106+
protected const GSAVE = 'q' . "\n";
107+
108+
/**
109+
* PDF graphics state restore operator.
110+
*
111+
* @var string
112+
*/
113+
protected const GRESTORE = 'Q' . "\n";
114+
101115
/**
102116
* Current PDF object number
103117
*/
@@ -123,6 +137,8 @@ abstract class Base
123137
*/
124138
protected int $styleid = -1;
125139

140+
141+
126142
/**
127143
* Stack containing style data.
128144
*

src/Draw.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,10 @@ public function getBasicPolygon(
263263
array $style = [],
264264
): string {
265265
$nco = \count($points); // number of coordinates
266+
if ($nco < 4) {
267+
return ''; // need at least 2 points (4 coordinates)
268+
}
269+
266270
$out = $this->getStyleCmd($style)
267271
. $this->getRawPoint($points[0], $points[1]);
268272
for ($idx = 2; $idx < $nco; $idx += 2) {
@@ -287,10 +291,6 @@ protected function getDefaultSegStyle(array $styles = []): string
287291
$out .= $this->getStyleCmd($styles['all']);
288292
}
289293

290-
if (empty($styles[0])) {
291-
$styles[0] = [];
292-
}
293-
294294
return $out;
295295
}
296296

src/Gradient.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,10 @@ public function getCoonsPatchMesh(
621621
return '';
622622
}
623623

624+
if ($coords_max <= $coords_min) {
625+
throw new GraphException('coords_max must be greater than coords_min');
626+
}
627+
624628
$ngr = (1 + \count($this->gradients));
625629
$this->gradients[$ngr] = [
626630
'antialias' => $antialias,

src/Raw.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ public function getRawEllipticalArc(
261261
return '';
262262
}
263263

264-
$bbox = [PHP_INT_MAX, PHP_INT_MAX, 0, 0];
264+
$bbox = [PHP_INT_MAX, PHP_INT_MAX, PHP_INT_MIN, PHP_INT_MIN];
265265
if ($pie) {
266266
$out .= $this->getRawPoint($posxc, $posyc); // center of the arc
267267
}

src/Style.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,8 @@ protected function getLineModeCmd(array $style = []): string
368368
$style['dashPhase'] = 0;
369369
}
370370

371-
return $out .= \sprintf('[%s] %F d' . "\n", \implode(' ', $dash), $style['dashPhase']);
371+
$out .= \sprintf('[%s] %F d' . "\n", \implode(' ', $dash), $style['dashPhase']);
372+
return $out;
372373
}
373374

374375
return $out;

src/Transform.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public function getStartTransform(): string
7272
{
7373
$this->saveStyleStatus();
7474
$this->ctm[++$this->ctmid] = [];
75-
return 'q' . "\n";
75+
return Base::GSAVE;
7676
}
7777

7878
/**
@@ -88,7 +88,7 @@ public function getStopTransform(): string
8888
unset($this->ctm[$this->ctmid]);
8989
--$this->ctmid;
9090
$this->restoreStyleStatus();
91-
return 'Q' . "\n";
91+
return Base::GRESTORE;
9292
}
9393

9494
/**
@@ -202,7 +202,7 @@ public function getHorizMirroring(float $posx): string
202202
}
203203

204204
/**
205-
* Verical Mirroring.
205+
* Vertical Mirroring.
206206
*
207207
* @param float $posy Ordinate of the mirroring line.
208208
*
@@ -292,7 +292,7 @@ public function getVertTranslation(float $try): string
292292
public function getSkewing(float $angx, float $angy, float $posx, float $posy): string
293293
{
294294
if (($angx <= -90) || ($angx >= 90) || ($angy <= -90) || ($angy >= 90)) {
295-
throw new GraphException('Angle values must be beweeen -90 and +90 degrees.');
295+
throw new GraphException('Angle values must be between -90 and +90 degrees.');
296296
}
297297

298298
$posy = (($this->pageh - $posy) * $this->kunit);

test/DrawTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,4 +1096,13 @@ public function testGetRegistrationMarkInvalidColor(): void
10961096
$draw = $this->getTestObject();
10971097
$draw->getRegistrationMark(3, 5, 7, false, 'not-a-valid-color');
10981098
}
1099+
1100+
public function testGetBasicPolygonTooFewPoints(): void
1101+
{
1102+
$draw = $this->getTestObject();
1103+
// empty array: no points at all
1104+
$this->assertEquals('', $draw->getBasicPolygon([]));
1105+
// two coordinates = one point, not enough to draw anything
1106+
$this->assertEquals('', $draw->getBasicPolygon([3, 5]));
1107+
}
10991108
}

test/GradientTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,4 +720,40 @@ public function testGetCropMarkInvalidType(): void
720720
$res
721721
);
722722
}
723+
724+
public function testGetCoonsPatchMeshInvalidCoordsLess(): void
725+
{
726+
$this->bcExpectException('\\' . \Com\Tecnick\Pdf\Graph\Exception::class);
727+
$draw = $this->getTestObject();
728+
// coords_max < coords_min must throw
729+
$draw->getCoonsPatchMesh(3, 5, 7, 11, [], 1.0, 0.5);
730+
}
731+
732+
public function testGetCoonsPatchMeshInvalidCoordsEqual(): void
733+
{
734+
$this->bcExpectException('\\' . \Com\Tecnick\Pdf\Graph\Exception::class);
735+
$draw = $this->getTestObject();
736+
// coords_max == coords_min would cause division by zero
737+
$draw->getCoonsPatchMesh(3, 5, 7, 11, [], 1.0, 1.0);
738+
}
739+
740+
public function testGetGradientStopsDefaultsAndAutoOffset(): void
741+
{
742+
$draw = $this->getTestObject();
743+
// middle stop has no explicit offset, exponent, or opacity
744+
$stops = [
745+
['color' => 'red', 'offset' => 0.0],
746+
['color' => 'green'],
747+
['color' => 'blue', 'offset' => 1.0],
748+
];
749+
$draw->getGradient(2, [0, 0, 1, 0], $stops, '', false);
750+
$gradients = $draw->getGradientsArray();
751+
$this->assertCount(1, $gradients);
752+
$mid = $gradients[1]['colors'][1];
753+
// auto-offset for the middle stop should be 0.5
754+
$this->bcAssertEqualsWithDelta(0.5, $mid['offset'] ?? -1.0, 0.01);
755+
// default exponent and opacity should be applied
756+
$this->assertEquals(1, $mid['exponent'] ?? null);
757+
$this->assertEquals(1, $mid['opacity'] ?? null);
758+
}
723759
}

test/RawTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,32 @@ public function testGetVectorsAngle(): void
172172
$res = $draw->getVectorsAngle(1, 0, -1, 0);
173173
$this->bcAssertEqualsWithDelta(M_PI, $res);
174174
}
175+
176+
public function testGetRawEllipticalArcBboxPopulated(): void
177+
{
178+
$draw = $this->getTestObject();
179+
$bbox = [];
180+
// full circle: bbox should be fully populated (no sentinel values remaining)
181+
$draw->getRawEllipticalArc(3, 5, 7, 11, 0, 0, 360, false, 2, true, true, false, $bbox);
182+
$this->assertCount(4, $bbox);
183+
$this->assertLessThan(PHP_INT_MAX, $bbox[0]); // min-x was updated
184+
$this->assertLessThan(PHP_INT_MAX, $bbox[1]); // min-y was updated
185+
$this->assertGreaterThan(PHP_INT_MIN, $bbox[2]); // max-x was updated
186+
$this->assertGreaterThan(PHP_INT_MIN, $bbox[3]); // max-y was updated
187+
}
188+
189+
public function testGetRawEllipticalArcBboxNegativeMaxValues(): void
190+
{
191+
$draw = $this->getTestObject();
192+
// Arc from 45° to 90° with centre at (0, 0) and vertical radius 5.
193+
// In this range every cy control point is negative (cy = -rdv * sin(ang)).
194+
// The PHP_INT_MIN initialisation ensures the max values are updated correctly
195+
// even when all sampled points are negative.
196+
$bbox = [];
197+
$draw->getRawEllipticalArc(0, 0, 7, 5, 0, 45, 90, false, 2, true, true, false, $bbox);
198+
$this->assertCount(4, $bbox);
199+
$this->assertGreaterThan(PHP_INT_MIN, $bbox[2]); // max-x was updated from sentinel
200+
$this->assertGreaterThan(PHP_INT_MIN, $bbox[3]); // max-y was updated from sentinel
201+
$this->assertLessThan(0, $bbox[3]); // all cy values in this arc are < 0
202+
}
175203
}

0 commit comments

Comments
 (0)