diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml new file mode 100644 index 0000000..b9c99de --- /dev/null +++ b/.github/workflows/php.yml @@ -0,0 +1,116 @@ +name: PHP +on: + push: + branches: + - master + pull_request: + +jobs: + php-cs-fixer: + name: PHP CS Fixer + runs-on: ubuntu-latest + steps: + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '7.4' + extensions: xml + + - uses: actions/checkout@v4 + + - name: Validate composer config + run: composer validate --strict + + - name: Composer Install + run: composer global require friendsofphp/php-cs-fixer + + - name: Add environment path + run: export PATH="$PATH:$HOME/.composer/vendor/bin" + + - name: Run PHPCSFixer + run: php-cs-fixer fix --dry-run --diff + + phpstan: + name: PHP Static Analysis + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: + - '7.1' + - '7.2' + - '7.3' + - '7.4' + - '8.0' + - '8.1' + - '8.2' + - '8.3' + steps: + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: xml + + - uses: actions/checkout@v4 + + - name: Composer Install + run: composer install --ansi --prefer-dist --no-interaction --no-progress + + - name: Run phpstan + run: ./vendor/bin/phpstan analyse -c phpstan.neon.dist + + phpunit: + name: PHPUnit + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: + - '7.1' + - '7.2' + - '7.3' + - '7.4' + - '8.0' + - '8.1' + - '8.2' + - '8.3' + steps: + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: xml + coverage: ${{ (matrix.php == '8.1') && 'xdebug' || 'none' }} + + - uses: actions/checkout@v4 + + - name: Install dependencies + run: composer install --ansi --prefer-dist --no-interaction --no-progress + + - name: Run PHPUnit + if: matrix.php != '8.1' + run: ./vendor/bin/phpunit -c phpunit.xml.dist + + - name: Run PHPUnit (w CodeCoverage) + if: matrix.php == '8.1' + run: XDEBUG_MODE=coverage ./vendor/bin/phpunit -c phpunit.xml.dist --coverage-clover build/clover.xml + + - name: Upload coverage results to Coveralls + if: matrix.php == '8.1' + env: + COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.4.3/php-coveralls.phar + chmod +x php-coveralls.phar + php php-coveralls.phar --coverage_clover=build/clover.xml --json_path=build/coveralls-upload.json -vvv + + #roave-backwards-compatibility-check: + # name: Roave Backwards Compatibility Check + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # with: + # fetch-depth: 0 + # - name: "Check for BC breaks" + # run: docker run -u $(id -u) -v $(pwd):/app nyholm/roave-bc-check-ga \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2b91b07..d45292a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .phpunit.cache .phpunit.result.cache +.php-cs-fixer.cache composer.lock vendor/ \ No newline at end of file diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..aaa5016 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,45 @@ +setUsingCache(true) + ->setRiskyAllowed(true) + ->setRules([ + '@Symfony' => true, + 'array_indentation' => true, + 'cast_spaces' => [ + 'space' => 'single', + ], + 'combine_consecutive_issets' => true, + 'concat_space' => [ + 'spacing' => 'one', + ], + 'error_suppression' => [ + 'mute_deprecation_error' => false, + 'noise_remaining_usages' => false, + 'noise_remaining_usages_exclude' => [], + ], + 'function_to_constant' => false, + 'global_namespace_import' => true, + 'method_chaining_indentation' => true, + 'no_alias_functions' => false, + 'no_superfluous_phpdoc_tags' => false, + 'non_printable_character' => [ + 'use_escape_sequences_in_strings' => true, + ], + 'phpdoc_align' => [ + 'align' => 'left', + ], + 'phpdoc_summary' => false, + 'protected_to_private' => false, + 'self_accessor' => false, + 'yoda_style' => false, + 'single_line_throw' => false, + 'no_alias_language_construct_call' => false, + ]) + ->getFinder() + ->in(__DIR__) + ->exclude('vendor'); + +return $config; \ No newline at end of file diff --git a/composer.json b/composer.json index 4a3fac2..a1fa1eb 100644 --- a/composer.json +++ b/composer.json @@ -1,9 +1,9 @@ { "name": "phpoffice/wmf", + "description": "WMF - Manipulate WMF Images", + "keywords": ["PHP", "wmf", "emf", "image"], + "homepage": "https://phpoffice.github.io/WMF/", "type": "library", - "require-dev": { - "phpunit/phpunit": "10" - }, "license": "MIT", "autoload": { "psr-4": { @@ -20,5 +20,13 @@ "name": "Progi1984", "homepage": "https://lefevre.dev" } - ] + ], + "require": { + "php": "^7.1|^8.0", + "ext-gd": "*" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^9.0", + "phpstan/phpstan": "^0.12.88 || ^1.0.0" + } } diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..cd5eabf --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,9 @@ +parameters: + level: 6 + bootstrapFiles: + - vendor/autoload.php + paths: + - src + - tests + reportUnmatchedIgnoredErrors: false + ignoreErrors: \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml.dist similarity index 100% rename from phpunit.xml rename to phpunit.xml.dist diff --git a/src/WMF/Exception/WMFException.php b/src/WMF/Exception/WMFException.php index ab4635b..662df2d 100644 --- a/src/WMF/Exception/WMFException.php +++ b/src/WMF/Exception/WMFException.php @@ -8,4 +8,4 @@ class WMFException extends Exception { -} \ No newline at end of file +} diff --git a/src/WMF/Reader/GD.php b/src/WMF/Reader/GD.php index 6e4463c..82af6af 100644 --- a/src/WMF/Reader/GD.php +++ b/src/WMF/Reader/GD.php @@ -4,13 +4,15 @@ namespace PhpOffice\WMF\Reader; +use GdImage; use PhpOffice\WMF\Exception\WMFException; -use function imagedestroy; class GD implements ReaderInterface { /** - * @var resource + * @phpstan-ignore-next-line + * + * @var GdImage|resource|false */ protected $gd; /** @@ -41,22 +43,24 @@ class GD implements ReaderInterface * @var int */ protected $unitPerInch; - - const META_EOF = 0x0000; - const META_SETPOLYFILLMODE = 0x0106; - const META_SELECTOBJECT = 0x012D; - const META_DELETEOBJECT = 0x01F0; - const META_SETWINDOWORG = 0x020B; - const META_SETWINDOWEXT = 0x020C; - const META_CREATEPENINDIRECT = 0x02FA; - const META_CREATEBRUSHINDIRECT = 0x02FC; - const META_POLYGON = 0x0324; - + /** + * @var array> + */ protected $gdiObjects = []; + public const META_EOF = 0x0000; + public const META_SETPOLYFILLMODE = 0x0106; + public const META_SELECTOBJECT = 0x012D; + public const META_DELETEOBJECT = 0x01F0; + public const META_SETWINDOWORG = 0x020B; + public const META_SETWINDOWEXT = 0x020C; + public const META_CREATEPENINDIRECT = 0x02FA; + public const META_CREATEBRUSHINDIRECT = 0x02FC; + public const META_POLYGON = 0x0324; + public function __destruct() { - if ($this->gd){ + if ($this->gd) { imagedestroy($this->gd); } } @@ -82,84 +86,86 @@ public function load(string $filename): bool $recordEnd = false; $dataFillColor = $dataDrawColor = null; + $nullPen = $nullBrush = false; + $dashArray = []; $modePolyFill = 0; - + while ($this->pos < $contentLen && !$recordEnd) { - list(,$size) = unpack('L', substr($this->content, $this->pos, 4)); - $this->pos += 4; - - list(,$recordType) = unpack('S', substr($this->content, $this->pos, 2)); - $this->pos += 2; - - if ($size > 3) { - $params = substr($this->content, $this->pos, 2 * ($size - 3)); - $this->pos += 2 * ($size - 3); - } - - switch ($recordType) { - case self::META_EOF: - $recordEnd = true; - break; + list(, $size) = unpack('L', substr($this->content, $this->pos, 4)); + $this->pos += 4; + + list(, $recordType) = unpack('S', substr($this->content, $this->pos, 2)); + $this->pos += 2; + + $params = []; + if ($size > 3) { + $params = substr($this->content, $this->pos, 2 * ($size - 3)); + $this->pos += 2 * ($size - 3); + } + + switch ($recordType) { + case self::META_EOF: + $recordEnd = true; + break; case self::META_SETPOLYFILLMODE: list(, $modePolyFill) = unpack('s', $params); break; case self::META_SELECTOBJECT: - list(, $idx) = unpack('S', $params); - $object = $this->gdiObjects[$idx]; - switch ($object['type']) { - case 'B': - $nullBrush = false; - if ($object['style'] == 1) { - $nullBrush = true; - } else { - $dataFillColor = imagecolorallocate($this->gd, $object['r'], $object['g'], $object['b']); - } - break; - case 'P': - $nullPen = false; - $dashArray = []; - // dash parameters are custom - switch ($object['style']) { - case 0: // PS_SOLID - break; - case 1: // PS_DASH - $dashArray = [3, 1]; - break; - case 2: // PS_DOT - $dashArray = [0.5, 0.5]; - break; - case 3: // PS_DASHDOT - $dashArray = [2, 1, 0.5, 1]; - break; - case 4: // PS_DASHDOTDOT - $dashArray = [2, 1, 0.5, 1, 0.5, 1]; - break; - case 5: // PS_NULL - $nullPen = true; - break; - } - if (!$nullPen) { - $dataDrawColor = imagecolorallocate($this->gd, $object['r'], $object['g'], $object['b']); - //@todo - //$wmfdata .= sprintf("%.3F w\n", $object['width'] * $k); - } - if (!empty($dashArray)) { - $s = '['; - for ($i = 0; $i < count($dashArray); $i++) { - $s .= $dashArray[$i] * $k; - if ($i != count($dashArray) - 1) { - $s .= ' '; - } - } - $s .= '] 0 d'; - //$wmfdata .= $s . "\n"; - } - break; - } - break; + list(, $idx) = unpack('S', $params); + $object = $this->gdiObjects[$idx]; + switch ($object['type']) { + case 'B': + $nullBrush = false; + if ($object['style'] == 1) { + $nullBrush = true; + } else { + $dataFillColor = imagecolorallocate($this->gd, (int) $object['r'], (int) $object['g'], (int) $object['b']); + } + break; + case 'P': + $nullPen = false; + $dashArray = []; + // dash parameters are custom + switch ($object['style']) { + case 0: // PS_SOLID + break; + case 1: // PS_DASH + $dashArray = [3, 1]; + break; + case 2: // PS_DOT + $dashArray = [0.5, 0.5]; + break; + case 3: // PS_DASHDOT + $dashArray = [2, 1, 0.5, 1]; + break; + case 4: // PS_DASHDOTDOT + $dashArray = [2, 1, 0.5, 1, 0.5, 1]; + break; + case 5: // PS_NULL + $nullPen = true; + break; + } + if (!$nullPen) { + $dataDrawColor = imagecolorallocate($this->gd, (int) $object['r'], (int) $object['g'], (int) $object['b']); + // @todo + // $wmfdata .= sprintf("%.3F w\n", $object['width'] * $k); + } + if (!empty($dashArray)) { + $s = '['; + for ($i = 0; $i < count($dashArray); ++$i) { + $s .= $dashArray[$i] * $k; + if ($i != count($dashArray) - 1) { + $s .= ' '; + } + } + $s .= '] 0 d'; + } + break; + } + break; case self::META_DELETEOBJECT: - list(, $idx) = unpack('S', $params); - unset($this->gdiObjects[$idx]); + list(, $idx) = unpack('S', $params); + unset($this->gdiObjects[$idx]); break; case self::META_SETWINDOWORG: // Do not allow window origin to be changed after drawing has begun @@ -171,87 +177,99 @@ public function load(string $filename): bool break; case self::META_SETWINDOWEXT: // Do not allow window extent to be changed after drawing has begun - var_dump('META_SETWINDOWEXT'); if (!$this->windowWidth) { $windowExtent = array_reverse(unpack('s2', $params)); $this->windowWidth = (int) $windowExtent[0]; $this->windowHeight = (int) ($windowExtent[1] > 0 ? $windowExtent[1] : $windowExtent[1] * -1); - + $this->gd = imagecreatetruecolor($this->windowWidth, $this->windowHeight); imagefilledrectangle($this->gd, 0, 0, $this->windowWidth, $this->windowHeight, imagecolorallocate($this->gd, 255, 255, 255)); } break; case self::META_CREATEPENINDIRECT: - $pen = unpack('Sstyle/swidth/sdummy/Cr/Cg/Cb/Ca', $params); - // convert width from twips to user unit - $pen['width'] /= (20 * $k); - $pen['type'] = 'P'; - $this->addGDIObject($pen); + $pen = unpack('Sstyle/swidth/sdummy/Cr/Cg/Cb/Ca', $params); + // convert width from twips to user unit + $pen['width'] /= (20 * $k); + $pen['type'] = 'P'; + $this->addGDIObject($pen); break; case self::META_CREATEBRUSHINDIRECT: - $brush = unpack('sstyle/Cr/Cg/Cb/Ca/Shatch', $params); - $brush['type'] = 'B'; - $this->addGDIObject($brush); + $brush = unpack('sstyle/Cr/Cg/Cb/Ca/Shatch', $params); + $brush['type'] = 'B'; + $this->addGDIObject($brush); break; case self::META_POLYGON: - $coordinates = unpack('s' . ($size - 3), $params); - $numpoints = $coordinates[1]; + $coordinates = unpack('s' . ($size - 3), $params); + $numpoints = $coordinates[1]; $points = []; - for ($i = $numpoints; $i > 0; $i--) { + for ($i = $numpoints; $i > 0; --$i) { list($px, $py) = $this->resetCoordinates((int) $coordinates[2 * $i], (int) $coordinates[2 * $i + 1]); - if ($i < $numpoints) { + if ($i < $numpoints) { $points[] = $px; $points[] = $py; - } else { + } else { $points[] = $px; $points[] = $py; - } - } - if ($recordType == 0x0325) { + } + } + if ($recordType == 0x0325) { \imagepolygon($this->gd, $points, $numpoints, $dataDrawColor); - } + } if ($recordType == self::META_POLYGON) { - if ($nullPen) { - if ($nullBrush) { + if ($nullPen) { + if ($nullBrush) { // No op - $op = 'n'; - } else { + $op = 'n'; + } else { // Fill - \imagefilledpolygon($this->gd, $points, $dataFillColor); - } - } else { - if ($nullBrush) { + if (\PHP_VERSION_ID < 80000) { + imagefilledpolygon($this->gd, $points, $numpoints, $dataFillColor); + } else { + /* @phpstan-ignore-next-line */ + imagefilledpolygon($this->gd, $points, $dataFillColor); + } + } + } else { + if ($nullBrush) { // Stroke - \imagepolygon($this->gd, $points, $numpoints, $dataDrawColor); - } else { + \imagepolygon($this->gd, $points, $numpoints, $dataDrawColor); + } else { // Stroke and Fill - \imagepolygon($this->gd, $points, $numpoints, $dataDrawColor); - \imagefilledpolygon($this->gd, $points, $dataFillColor); - } - } - if ($modePolyFill == 1 && (($nullPen && !$nullBrush) || (!$nullPen && $nullBrush))) { - // Even-odd fill - } - } - break; + \imagepolygon($this->gd, $points, $numpoints, $dataDrawColor); + if (\PHP_VERSION_ID < 80000) { + imagefilledpolygon($this->gd, $points, $numpoints, $dataFillColor); + } else { + /* @phpstan-ignore-next-line */ + imagefilledpolygon($this->gd, $points, $dataFillColor); + } + } + } + if ($modePolyFill == 1 && (($nullPen && !$nullBrush) || (!$nullPen && $nullBrush))) { + // Even-odd fill + } + } + break; default: - //throw new WMFException('Reader : Function not implemented : 0x' . str_pad(dechex($recordType), 4, '0', STR_PAD_LEFT)); + // throw new WMFException('Reader : Function not implemented : 0x' . str_pad(dechex($recordType), 4, '0', STR_PAD_LEFT)); } } return true; } + /** + * @return array + */ protected function resetCoordinates(int $x, int $y): array { $x -= $this->windowOriginX; $midHeight = $this->windowHeight / 2; - $y = $y + ($this->windowHeight - $this->windowOriginY); + $y += ($this->windowHeight - $this->windowOriginY); if ($y > $midHeight) { - $y -= ($y - $midHeight ) * 2; + $y -= ($y - $midHeight) * 2; } else { $y += ($midHeight - $y) * 2; } @@ -259,24 +277,32 @@ protected function resetCoordinates(int $x, int $y): array return [$x, $y]; } - protected function addGDIObject(array $gdiObject): void - { - // Find next available slot - $idx = 0; + /** + * @param array $gdiObject + */ + protected function addGDIObject(array $gdiObject): void + { + // Find next available slot + $idx = 0; - if (!empty($this->gdiObjects)) { - $empty = false; - $i = 0; - while (!$empty) { - $empty = !isset($this->gdiObjects[$i]); - $i++; - } - $idx = $i - 1; - } + if (!empty($this->gdiObjects)) { + $empty = false; + $i = 0; + while (!$empty) { + $empty = !isset($this->gdiObjects[$i]); + ++$i; + } + $idx = $i - 1; + } - $this->gdiObjects[$idx] = $gdiObject; - } + $this->gdiObjects[$idx] = $gdiObject; + } + /** + * @phpstan-ignore-next-line + * + * @return GDImage|resource + */ public function getResource() { // INCH_TO_POINT @@ -284,16 +310,17 @@ public function getResource() $this->gd = imagescale( $this->gd, - ceil(($this->windowWidth/$this->unitPerInch) * $inchToPoint), - ceil(($this->windowHeight/$this->unitPerInch) * $inchToPoint) + (int) ceil(($this->windowWidth / $this->unitPerInch) * $inchToPoint), + (int) ceil(($this->windowHeight / $this->unitPerInch) * $inchToPoint) ); imagesavealpha($this->gd, true); + return $this->gd; } public function save(string $filename, string $format): bool { - switch(strtolower($format)) { + switch (strtolower($format)) { case 'gif': return imagegif($this->getResource(), $filename); case 'jpg': @@ -324,7 +351,7 @@ protected function readHeader(): void $this->pos = 18; if ($key == (int) 0x9AC6CDD7) { - $this->pos += 22; - } + $this->pos += 22; + } } -} \ No newline at end of file +} diff --git a/src/WMF/Reader/Imagick.php b/src/WMF/Reader/Imagick.php index 0fd93c0..34200d0 100644 --- a/src/WMF/Reader/Imagick.php +++ b/src/WMF/Reader/Imagick.php @@ -5,6 +5,7 @@ namespace PhpOffice\WMF\Reader; use Imagick as ImagickBase; +use PhpOffice\WMF\Exception\WMFException; class Imagick implements ReaderInterface { @@ -16,7 +17,8 @@ class Imagick implements ReaderInterface public function load(string $filename): bool { $this->im = new ImagickBase(); - return $this->im->readImage($filename); + + return $this->im->readImage($filename); } public function isWMF(string $filename): bool @@ -34,7 +36,7 @@ public function getResource(): ImagickBase public function save(string $filename, string $format): bool { - switch(strtolower($format)) { + switch (strtolower($format)) { case 'gif': case 'jpg': case 'jpeg': @@ -42,9 +44,10 @@ public function save(string $filename, string $format): bool case 'webp': case 'wbmp': $this->getResource()->setImageFormat(strtolower($format)); + return $this->getResource()->writeImage($filename); default: throw new WMFException(sprintf('Format %s not supported', $format)); } } -} \ No newline at end of file +} diff --git a/src/WMF/Reader/Magic.php b/src/WMF/Reader/Magic.php index b64d103..ca83a6b 100644 --- a/src/WMF/Reader/Magic.php +++ b/src/WMF/Reader/Magic.php @@ -4,8 +4,8 @@ namespace PhpOffice\WMF\Reader; +use GDImage; use Imagick as ImagickBase; -use PhpOffice\WMF\Reader\GD; use PhpOffice\WMF\Reader\Imagick as ImagickReader; class Magic implements ReaderInterface @@ -17,22 +17,24 @@ class Magic implements ReaderInterface public function __construct() { + $reader = null; if (extension_loaded('imagick') && in_array('WMF', ImagickBase::queryformats())) { - $this->reader = new ImagickReader(); + $reader = new ImagickReader(); } - if (!$this->reader && extension_loaded('gd')) { - $this->reader = new GD(); + if (!$reader && extension_loaded('gd')) { + $reader = new GD(); } + $this->reader = $reader; } public function load(string $filename): bool { - return $this->reader->load($filename); + return $this->reader->load($filename); } public function save(string $filename, string $format): bool { - return $this->reader->save($filename, $format); + return $this->reader->save($filename, $format); } public function isWMF(string $filename): bool @@ -40,8 +42,13 @@ public function isWMF(string $filename): bool return $this->reader->isWMF($filename); } + /** + * @phpstan-ignore-next-line + * + * @return GDImage|ImagickBase + */ public function getResource() { return $this->reader->getResource(); } -} \ No newline at end of file +} diff --git a/src/WMF/Reader/ReaderInterface.php b/src/WMF/Reader/ReaderInterface.php index def0bc3..ee057c7 100644 --- a/src/WMF/Reader/ReaderInterface.php +++ b/src/WMF/Reader/ReaderInterface.php @@ -2,13 +2,21 @@ namespace PhpOffice\WMF\Reader; +use GDImage; +use Imagick; + interface ReaderInterface { public function isWMF(string $filename): bool; - + public function load(string $filename): bool; - + public function save(string $filename, string $format): bool; + /** + * @phpstan-ignore-next-line + * + * @return GDImage|Imagick + */ public function getResource(); -} \ No newline at end of file +} diff --git a/tests/WMF/Reader/AbstractTestReader.php b/tests/WMF/Reader/AbstractTestReader.php index cb3ec34..0c46578 100644 --- a/tests/WMF/Reader/AbstractTestReader.php +++ b/tests/WMF/Reader/AbstractTestReader.php @@ -7,7 +7,7 @@ use Imagick; use PHPUnit\Framework\TestCase; -class AbstractTestReader extends TestCase +class AbstractTestReader extends TestCase { public function getResourceDir(): string { @@ -23,6 +23,9 @@ public function assertImageCompare(string $expectedFile, string $outputFile, flo $this->assertLessThanOrEqual($threshold, $result[1]); } + /** + * @return array> + */ public static function dataProviderFiles(): array { return [ @@ -40,4 +43,4 @@ public static function dataProviderFiles(): array ], ]; } -} \ No newline at end of file +} diff --git a/tests/WMF/Reader/GDTest.php b/tests/WMF/Reader/GDTest.php index 8c5c488..759cb1b 100644 --- a/tests/WMF/Reader/GDTest.php +++ b/tests/WMF/Reader/GDTest.php @@ -7,7 +7,7 @@ use GdImage; use PhpOffice\WMF\Reader\GD; -class GDTest extends AbstractTestReader +class GDTest extends AbstractTestReader { /** * @dataProvider dataProviderFiles @@ -25,15 +25,21 @@ public function testGetResource(string $file): void { $reader = new GD(); $reader->load($this->getResourceDir() . $file); - $this->assertInstanceOf(GdImage::class, $reader->getResource()); + if (\PHP_VERSION_ID < 80000) { + $this->assertIsResource($reader->getResource()); + } else { + /* @phpstan-ignore-next-line */ + $this->assertInstanceOf(GdImage::class, $reader->getResource()); + } } + /** * @dataProvider dataProviderFiles */ public function testOutput(string $file): void { - $outputFile = $this->getResourceDir() . 'output_'.pathinfo($file, PATHINFO_FILENAME).'.png'; - $similarFile = $this->getResourceDir() . pathinfo($file, PATHINFO_FILENAME).'.png'; + $outputFile = $this->getResourceDir() . 'output_' . pathinfo($file, PATHINFO_FILENAME) . '.png'; + $similarFile = $this->getResourceDir() . pathinfo($file, PATHINFO_FILENAME) . '.png'; $reader = new GD(); $reader->load($this->getResourceDir() . $file); @@ -50,6 +56,6 @@ public function testOutput(string $file): void public function testIsWMF(string $file): void { $reader = new GD(); - $this->assertTrue($reader->isWMF($this->getResourceDir() .$file)); + $this->assertTrue($reader->isWMF($this->getResourceDir() . $file)); } -} \ No newline at end of file +} diff --git a/tests/WMF/Reader/ImagickTest.php b/tests/WMF/Reader/ImagickTest.php index 9ba93fd..a8076f2 100644 --- a/tests/WMF/Reader/ImagickTest.php +++ b/tests/WMF/Reader/ImagickTest.php @@ -7,7 +7,7 @@ use Imagick as ImagickBase; use PhpOffice\WMF\Reader\Imagick as ImagickReader; -class ImagickTest extends AbstractTestReader +class ImagickTest extends AbstractTestReader { /** * @dataProvider dataProviderFiles @@ -33,8 +33,8 @@ public function testGetResource(string $file): void */ public function testOutput(string $file): void { - $outputFile = $this->getResourceDir() . 'output_'.pathinfo($file, PATHINFO_FILENAME).'.png'; - $similarFile = $this->getResourceDir() . pathinfo($file, PATHINFO_FILENAME).'.png'; + $outputFile = $this->getResourceDir() . 'output_' . pathinfo($file, PATHINFO_FILENAME) . '.png'; + $similarFile = $this->getResourceDir() . pathinfo($file, PATHINFO_FILENAME) . '.png'; $reader = new ImagickReader(); $reader->load($this->getResourceDir() . $file); @@ -53,4 +53,4 @@ public function testIsWMF(string $file): void $reader = new ImagickReader(); $this->assertTrue($reader->isWMF($this->getResourceDir() . $file)); } -} \ No newline at end of file +} diff --git a/tests/WMF/Reader/MagicTest.php b/tests/WMF/Reader/MagicTest.php index ff87d95..831ea14 100644 --- a/tests/WMF/Reader/MagicTest.php +++ b/tests/WMF/Reader/MagicTest.php @@ -6,7 +6,7 @@ use PhpOffice\WMF\Reader\Magic; -class MagicTest extends AbstractTestReader +class MagicTest extends AbstractTestReader { /** * @dataProvider dataProviderFiles @@ -26,13 +26,14 @@ public function testGetResource(string $file): void $reader->load($this->getResourceDir() . $file); $this->assertIsObject($reader->getResource()); } + /** * @dataProvider dataProviderFiles */ public function testOutput(string $file): void { - $outputFile = $this->getResourceDir() . 'output_'.pathinfo($file, PATHINFO_FILENAME).'.png'; - $similarFile = $this->getResourceDir() . pathinfo($file, PATHINFO_FILENAME).'.png'; + $outputFile = $this->getResourceDir() . 'output_' . pathinfo($file, PATHINFO_FILENAME) . '.png'; + $similarFile = $this->getResourceDir() . pathinfo($file, PATHINFO_FILENAME) . '.png'; $reader = new Magic(); $reader->load($this->getResourceDir() . $file); @@ -49,6 +50,6 @@ public function testOutput(string $file): void public function testIsWMF(string $file): void { $reader = new Magic(); - $this->assertTrue($reader->isWMF($this->getResourceDir() .$file)); + $this->assertTrue($reader->isWMF($this->getResourceDir() . $file)); } -} \ No newline at end of file +} diff --git a/tests/resources/files.txt b/tests/resources/files.txt new file mode 100644 index 0000000..39c52eb --- /dev/null +++ b/tests/resources/files.txt @@ -0,0 +1,8 @@ +# Where to find EMF/WMF files + +## EMF +https://opengrok.libreoffice.org/xref/core/emfio/qa/cppunit/wmf/data/ + +## WMF +https://opengrok.libreoffice.org/xref/core/emfio/qa/cppunit/wmf/data/ +https://opengrok.libreoffice.org/xref/core/odk/examples/basic/forms_and_controls/ \ No newline at end of file