generated from jric11/baseProject
512 lines
16 KiB
PHP
512 lines
16 KiB
PHP
<?php
|
|
|
|
/**
|
|
* RegionTest.php
|
|
*
|
|
* @since 2011-05-23
|
|
* @category Library
|
|
* @package PdfPage
|
|
* @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-page
|
|
*
|
|
* This file is part of tc-lib-pdf-page software library.
|
|
*/
|
|
|
|
namespace Test;
|
|
|
|
use Com\Tecnick\Color\Pdf;
|
|
use Com\Tecnick\Pdf\Page\Page;
|
|
|
|
/**
|
|
* Page Test
|
|
*
|
|
* @since 2011-05-23
|
|
* @category Library
|
|
* @package PdfPage
|
|
* @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-page
|
|
*/
|
|
class RegionTest extends TestUtil
|
|
{
|
|
/**
|
|
* @throws \Com\Tecnick\Pdf\Page\Exception
|
|
*/
|
|
protected function getTestObject(): \Com\Tecnick\Pdf\Page\Page
|
|
{
|
|
$pdf = new Pdf();
|
|
$encrypt = $this->getEncryptObject();
|
|
return new Page('mm', $pdf, $encrypt, false, false);
|
|
}
|
|
|
|
/**
|
|
* @throws \Com\Tecnick\Pdf\Page\Exception
|
|
*/
|
|
public function testRegion(): void
|
|
{
|
|
$page = $this->getTestObject();
|
|
$page->add([
|
|
'columns' => 3,
|
|
]);
|
|
|
|
$res = $page->selectRegion(1);
|
|
$exp = [
|
|
'RX' => 70,
|
|
'RY' => 0,
|
|
'RW' => 70,
|
|
'RH' => 297,
|
|
'RL' => 140,
|
|
'RR' => 70,
|
|
'RT' => 297,
|
|
'RB' => 0,
|
|
'x' => 70,
|
|
'y' => 0,
|
|
];
|
|
$this->bcAssertEqualsWithDelta($exp, $res);
|
|
|
|
$res = $page->getRegion();
|
|
$this->bcAssertEqualsWithDelta($exp, $res);
|
|
|
|
$res = $page->getNextRegion();
|
|
$this->bcAssertEqualsWithDelta(2, $res['currentRegion']);
|
|
|
|
$res = $page->getNextRegion();
|
|
$this->bcAssertEqualsWithDelta(0, $res['currentRegion']);
|
|
|
|
$page->setCurrentPage(0);
|
|
$res = $page->getNextRegion();
|
|
$this->bcAssertEqualsWithDelta(0, $res['currentRegion']);
|
|
|
|
$res = $page->checkRegionBreak(1000);
|
|
$this->bcAssertEqualsWithDelta(1, $res['currentRegion']);
|
|
|
|
$res = $page->checkRegionBreak();
|
|
$this->bcAssertEqualsWithDelta(1, $res['currentRegion']);
|
|
|
|
$page->setX(13)->setY(17);
|
|
$this->bcAssertEqualsWithDelta(13, $page->getX());
|
|
$this->bcAssertEqualsWithDelta(17, $page->getY());
|
|
}
|
|
|
|
/**
|
|
* @throws \Com\Tecnick\Pdf\Page\Exception
|
|
*/
|
|
public function testRegionBoundaries(): void
|
|
{
|
|
$page = $this->getTestObject();
|
|
$page->add([
|
|
'columns' => 3,
|
|
]);
|
|
|
|
$region = $page->getRegion();
|
|
|
|
$res = $page->isYOutRegion(null, 1);
|
|
$this->assertFalse($res);
|
|
$res = $page->isYOutRegion(-1);
|
|
$this->assertTrue($res);
|
|
$res = $page->isYOutRegion($region['RY']);
|
|
$this->assertFalse($res);
|
|
$res = $page->isYOutRegion(0);
|
|
$this->assertFalse($res);
|
|
$res = $page->isYOutRegion(100);
|
|
$this->assertFalse($res);
|
|
$res = $page->isYOutRegion(297);
|
|
$this->assertFalse($res);
|
|
$res = $page->isYOutRegion($region['RT']);
|
|
$this->assertFalse($res);
|
|
$res = $page->isYOutRegion(298);
|
|
$this->assertTrue($res);
|
|
|
|
$page->getNextRegion();
|
|
$region = $page->getRegion();
|
|
|
|
$res = $page->isXOutRegion(null, 1);
|
|
$this->assertFalse($res);
|
|
$res = $page->isXOutRegion(69);
|
|
$this->assertTrue($res);
|
|
$res = $page->isXOutRegion($region['RX']);
|
|
$this->assertFalse($res);
|
|
$res = $page->isXOutRegion(70);
|
|
$this->assertFalse($res);
|
|
$res = $page->isXOutRegion(90);
|
|
$this->assertFalse($res);
|
|
$res = $page->isXOutRegion(140);
|
|
$this->assertFalse($res);
|
|
$res = $page->isXOutRegion($region['RL']);
|
|
$this->assertFalse($res);
|
|
$res = $page->isXOutRegion(141);
|
|
$this->assertTrue($res);
|
|
|
|
$pid = $page->getPageID();
|
|
$this->assertEquals(0, $pid);
|
|
}
|
|
|
|
/**
|
|
* @throws \Com\Tecnick\Pdf\Page\Exception
|
|
*/
|
|
public function testSetNoWriteRegionsSideRectangle(): void
|
|
{
|
|
$page = $this->getTestObject();
|
|
$page->add();
|
|
|
|
// Obstacle on the right side blocking x in [150, 210] for y in [100, 200].
|
|
$res = $page->setNoWriteRegions([
|
|
['xt' => 150, 'yt' => 100, 'xb' => 150, 'yb' => 200, 'side' => 'R'],
|
|
], 50.0);
|
|
|
|
$this->bcAssertEqualsWithDelta(3, $res['columns']);
|
|
|
|
$exp = [
|
|
[
|
|
'RW' => 210,
|
|
'RX' => 0,
|
|
'RL' => 210,
|
|
'RR' => 0,
|
|
'RH' => 100,
|
|
'RY' => 0,
|
|
'RT' => 100,
|
|
'RB' => 197,
|
|
'x' => 0,
|
|
'y' => 0,
|
|
],
|
|
[
|
|
'RW' => 150,
|
|
'RX' => 0,
|
|
'RL' => 150,
|
|
'RR' => 60,
|
|
'RH' => 100,
|
|
'RY' => 100,
|
|
'RT' => 200,
|
|
'RB' => 97,
|
|
'x' => 0,
|
|
'y' => 100,
|
|
],
|
|
[
|
|
'RW' => 210,
|
|
'RX' => 0,
|
|
'RL' => 210,
|
|
'RR' => 0,
|
|
'RH' => 97,
|
|
'RY' => 200,
|
|
'RT' => 297,
|
|
'RB' => 0,
|
|
'x' => 0,
|
|
'y' => 200,
|
|
],
|
|
];
|
|
$this->bcAssertEqualsWithDelta($exp, $res['region']);
|
|
}
|
|
|
|
/**
|
|
* @throws \Com\Tecnick\Pdf\Page\Exception
|
|
*/
|
|
public function testBuildWritableRegionsSlantedSegment(): void
|
|
{
|
|
$page = $this->getTestObject();
|
|
$page->add();
|
|
|
|
// Slanted right-side segment from (100,100) to (150,200): a staircase approximation.
|
|
$res = $page->buildWritableRegions([
|
|
['xt' => 100, 'yt' => 100, 'xb' => 150, 'yb' => 200, 'side' => 'R'],
|
|
], 50.0);
|
|
|
|
$exp = [
|
|
['RX' => 0, 'RY' => 0, 'RW' => 210, 'RH' => 100],
|
|
['RX' => 0, 'RY' => 100, 'RW' => 100, 'RH' => 50],
|
|
['RX' => 0, 'RY' => 150, 'RW' => 125, 'RH' => 50],
|
|
['RX' => 0, 'RY' => 200, 'RW' => 210, 'RH' => 97],
|
|
];
|
|
$this->bcAssertEqualsWithDelta($exp, $res);
|
|
}
|
|
|
|
/**
|
|
* @throws \Com\Tecnick\Pdf\Page\Exception
|
|
*/
|
|
public function testBuildWritableRegionsFloatingBoxKeepsWidestSide(): void
|
|
{
|
|
$page = $this->getTestObject();
|
|
$page->add();
|
|
|
|
// Floating obstacle blocking x in [60, 100] for y in [100, 150]:
|
|
// the band splits into [0,60] (w=60) and [100,210] (w=110); the widest is kept.
|
|
$res = $page->buildWritableRegions([
|
|
['x' => 60, 'y' => 100, 'w' => 40, 'h' => 50],
|
|
], 50.0);
|
|
|
|
$exp = [
|
|
['RX' => 0, 'RY' => 0, 'RW' => 210, 'RH' => 100],
|
|
['RX' => 100, 'RY' => 100, 'RW' => 110, 'RH' => 50],
|
|
['RX' => 0, 'RY' => 150, 'RW' => 210, 'RH' => 147],
|
|
];
|
|
$this->bcAssertEqualsWithDelta($exp, $res);
|
|
}
|
|
|
|
/**
|
|
* @throws \Com\Tecnick\Pdf\Page\Exception
|
|
*/
|
|
public function testNoWriteRegionsAddGetRemove(): void
|
|
{
|
|
$page = $this->getTestObject();
|
|
$page->add();
|
|
|
|
$page->setNoWriteRegions([
|
|
['xt' => 150, 'yt' => 100, 'xb' => 150, 'yb' => 200, 'side' => 'R'],
|
|
], 50.0);
|
|
$this->assertCount(1, $page->getNoWriteRegions());
|
|
|
|
// The added left-side obstacle pushes the bottom region's left edge to x=60.
|
|
$res = $page->addNoWriteRegion(['xt' => 60, 'yt' => 230, 'xb' => 60, 'yb' => 270, 'side' => 'L']);
|
|
$this->assertCount(2, $page->getNoWriteRegions());
|
|
$this->bcAssertEqualsWithDelta(3, $res['columns']);
|
|
$expAdded = [
|
|
[
|
|
'RW' => 210,
|
|
'RX' => 0,
|
|
'RL' => 210,
|
|
'RR' => 0,
|
|
'RH' => 100,
|
|
'RY' => 0,
|
|
'RT' => 100,
|
|
'RB' => 197,
|
|
'x' => 0,
|
|
'y' => 0,
|
|
],
|
|
[
|
|
'RW' => 150,
|
|
'RX' => 0,
|
|
'RL' => 150,
|
|
'RR' => 60,
|
|
'RH' => 100,
|
|
'RY' => 100,
|
|
'RT' => 200,
|
|
'RB' => 97,
|
|
'x' => 0,
|
|
'y' => 100,
|
|
],
|
|
[
|
|
'RW' => 150,
|
|
'RX' => 60,
|
|
'RL' => 210,
|
|
'RR' => 0,
|
|
'RH' => 97,
|
|
'RY' => 200,
|
|
'RT' => 297,
|
|
'RB' => 0,
|
|
'x' => 60,
|
|
'y' => 200,
|
|
],
|
|
];
|
|
$this->bcAssertEqualsWithDelta($expAdded, $res['region']);
|
|
|
|
// Removing the first (right) area leaves only the left-side area.
|
|
$page->removeNoWriteRegion(0);
|
|
$this->bcAssertEqualsWithDelta([[
|
|
'xt' => 60,
|
|
'yt' => 230,
|
|
'xb' => 60,
|
|
'yb' => 270,
|
|
'side' => 'L',
|
|
]], $page->getNoWriteRegions());
|
|
|
|
// Removing the last area leaves the page with a single full content region.
|
|
$res = $page->removeNoWriteRegion(0);
|
|
$this->assertCount(0, $page->getNoWriteRegions());
|
|
$this->bcAssertEqualsWithDelta(1, $res['columns']);
|
|
$this->bcAssertEqualsWithDelta([[
|
|
'RW' => 210,
|
|
'RX' => 0,
|
|
'RL' => 210,
|
|
'RR' => 0,
|
|
'RH' => 297,
|
|
'RY' => 0,
|
|
'RT' => 297,
|
|
'RB' => 0,
|
|
'x' => 0,
|
|
'y' => 0,
|
|
]], $res['region']);
|
|
}
|
|
|
|
/**
|
|
* @throws \Com\Tecnick\Pdf\Page\Exception
|
|
*/
|
|
public function testNoWriteRegionsResetOnClonedPage(): void
|
|
{
|
|
$page = $this->getTestObject();
|
|
$page->add();
|
|
|
|
$res = $page->setNoWriteRegions([
|
|
['xt' => 150, 'yt' => 100, 'xb' => 150, 'yb' => 200, 'side' => 'R'],
|
|
], 50.0);
|
|
$this->assertGreaterThan(1, $res['columns']);
|
|
|
|
// Cloning the page (e.g. an automatic page break) must NOT inherit the no-write bands:
|
|
// the new page starts with a single default full-content region.
|
|
$cloned = $page->add();
|
|
$this->bcAssertEqualsWithDelta(1, $cloned['columns']);
|
|
$this->assertCount(0, $page->getNoWriteRegions($cloned['pid']));
|
|
$this->bcAssertEqualsWithDelta([[
|
|
'RW' => 210,
|
|
'RX' => 0,
|
|
'RL' => 210,
|
|
'RR' => 0,
|
|
'RH' => 297,
|
|
'RY' => 0,
|
|
'RT' => 297,
|
|
'RB' => 0,
|
|
'x' => 0,
|
|
'y' => 0,
|
|
]], $cloned['region']);
|
|
}
|
|
|
|
/**
|
|
* @throws \Com\Tecnick\Pdf\Page\Exception
|
|
*/
|
|
public function testNoWriteRegionsValidation(): void
|
|
{
|
|
$page = $this->getTestObject();
|
|
$page->add();
|
|
|
|
try {
|
|
$page->setNoWriteRegions([], 0.0);
|
|
$this->fail('Expected exception was not thrown.');
|
|
} catch (\Com\Tecnick\Pdf\Page\Exception $e) {
|
|
$this->assertStringContainsString('band height', $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$page->buildWritableRegions([], -5.0);
|
|
$this->fail('Expected exception was not thrown.');
|
|
} catch (\Com\Tecnick\Pdf\Page\Exception $e) {
|
|
$this->assertStringContainsString('band height', $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$page->addNoWriteRegion(['x' => 10, 'y' => 10, 'w' => 10, 'h' => 10]);
|
|
$this->fail('Expected exception was not thrown.');
|
|
} catch (\Com\Tecnick\Pdf\Page\Exception $e) {
|
|
$this->assertStringContainsString('setNoWriteRegions', $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$page->removeNoWriteRegion(7);
|
|
$this->fail('Expected exception was not thrown.');
|
|
} catch (\Com\Tecnick\Pdf\Page\Exception $e) {
|
|
$this->assertStringContainsString('index 7', $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @throws \Com\Tecnick\Pdf\Page\Exception
|
|
*/
|
|
public function testDefensiveChecksOnMissingPageAfterForcedSanitizeId(): void
|
|
{
|
|
$pdf = new Pdf();
|
|
$encrypt = $this->getEncryptObject();
|
|
$page = new class('mm', $pdf, $encrypt, false, false) extends Page {
|
|
public bool $forceSanitizePageId = false;
|
|
public int $forcedPid = 0;
|
|
|
|
protected function sanitizePageID(int $pid = -1): int
|
|
{
|
|
if ($this->forceSanitizePageId) {
|
|
return $this->forcedPid;
|
|
}
|
|
|
|
return parent::sanitizePageID($pid);
|
|
}
|
|
};
|
|
$page->add();
|
|
$page->forceSanitizePageId = true;
|
|
$page->forcedPid = 99;
|
|
|
|
try {
|
|
$page->getPage(99);
|
|
$this->fail('Expected exception was not thrown.');
|
|
} catch (\Com\Tecnick\Pdf\Page\Exception $e) {
|
|
$this->assertStringContainsString('index 99', $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$page->setPagePHeight(10, 99);
|
|
$this->fail('Expected exception was not thrown.');
|
|
} catch (\Com\Tecnick\Pdf\Page\Exception $e) {
|
|
$this->assertStringContainsString('index 99', $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$page->setPagePWidth(10, 99);
|
|
$this->fail('Expected exception was not thrown.');
|
|
} catch (\Com\Tecnick\Pdf\Page\Exception $e) {
|
|
$this->assertStringContainsString('index 99', $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$page->selectRegion(0, 99);
|
|
$this->fail('Expected exception was not thrown.');
|
|
} catch (\Com\Tecnick\Pdf\Page\Exception $e) {
|
|
$this->assertStringContainsString('index 99', $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$page->getNextRegion(99);
|
|
$this->fail('Expected exception was not thrown.');
|
|
} catch (\Com\Tecnick\Pdf\Page\Exception $e) {
|
|
$this->assertStringContainsString('index 99', $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$page->isAutoPageBreakEnabled(99);
|
|
$this->fail('Expected exception was not thrown.');
|
|
} catch (\Com\Tecnick\Pdf\Page\Exception $e) {
|
|
$this->assertStringContainsString('index 99', $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$page->enableAutoPageBreak(true, 99);
|
|
$this->fail('Expected exception was not thrown.');
|
|
} catch (\Com\Tecnick\Pdf\Page\Exception $e) {
|
|
$this->assertStringContainsString('index 99', $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$page->setX(1, 99);
|
|
$this->fail('Expected exception was not thrown.');
|
|
} catch (\Com\Tecnick\Pdf\Page\Exception $e) {
|
|
$this->assertStringContainsString('index 99', $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$page->setY(1, 99);
|
|
$this->fail('Expected exception was not thrown.');
|
|
} catch (\Com\Tecnick\Pdf\Page\Exception $e) {
|
|
$this->assertStringContainsString('index 99', $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An out-of-range region index must clamp to the nearest valid region instead
|
|
* of selecting a non-existent index (which previously threw).
|
|
*
|
|
* @throws \Com\Tecnick\Pdf\Page\Exception
|
|
*/
|
|
public function testSelectRegionClampsOutOfRangeIndex(): void
|
|
{
|
|
$page = $this->getTestObject();
|
|
$page->add([
|
|
'columns' => 3,
|
|
]);
|
|
|
|
// Index beyond the last region (valid: 0..2) clamps to the last region.
|
|
$res = $page->selectRegion(99);
|
|
$this->bcAssertEqualsWithDelta(2, $page->getPage()['currentRegion']);
|
|
$this->bcAssertEqualsWithDelta($res, $page->getRegion());
|
|
|
|
// Negative index clamps to the first region.
|
|
$page->selectRegion(-5);
|
|
$this->bcAssertEqualsWithDelta(0, $page->getPage()['currentRegion']);
|
|
}
|
|
}
|