Skip to content

Commit d09330a

Browse files
authored
Merge pull request #2 from PHPOffice/wmf
Refactored WMF Reader
2 parents 854cc57 + 59f639a commit d09330a

File tree

11 files changed

+131
-55
lines changed

11 files changed

+131
-55
lines changed

src/WMF/Reader/ReaderInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77

88
interface ReaderInterface
99
{
10-
public function isWMF(string $filename): bool;
11-
1210
public function load(string $filename): bool;
1311

1412
public function save(string $filename, string $format): bool;
1513

14+
public function getMediaType(): string;
15+
1616
/**
1717
* @phpstan-ignore-next-line
1818
*
Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace PhpOffice\WMF\Reader;
5+
namespace PhpOffice\WMF\Reader\WMF;
66

77
use GdImage;
88
use PhpOffice\WMF\Exception\WMFException;
@@ -72,6 +72,9 @@ public function isWMF(string $filename): bool
7272
return $key == (int) 0x9AC6CDD7;
7373
}
7474

75+
/**
76+
* @see https://github.com/affinitybridge/mpdf/blob/master/src/Image/Wmf.php
77+
*/
7578
public function load(string $filename): bool
7679
{
7780
$this->content = file_get_contents($filename);
@@ -252,13 +255,31 @@ public function load(string $filename): bool
252255
}
253256
break;
254257
default:
255-
// throw new WMFException('Reader : Function not implemented : 0x' . str_pad(dechex($recordType), 4, '0', STR_PAD_LEFT));
258+
throw new WMFException('Reader : Function not implemented : 0x' . str_pad(dechex($recordType), 4, '0', STR_PAD_LEFT));
256259
}
257260
}
258261

259262
return true;
260263
}
261264

265+
protected function readHeader(): void
266+
{
267+
list(, $key) = unpack('L', substr($this->content, 0, 4));
268+
list(, $handle) = unpack('S', substr($this->content, 4, 2));
269+
list(, $left) = unpack('S', substr($this->content, 6, 2));
270+
list(, $top) = unpack('S', substr($this->content, 8, 2));
271+
list(, $right) = unpack('S', substr($this->content, 10, 2));
272+
list(, $bottom) = unpack('S', substr($this->content, 12, 2));
273+
list(, $this->unitPerInch) = unpack('S', substr($this->content, 14, 2));
274+
list(, $reserved) = unpack('L', substr($this->content, 16, 4));
275+
list(, $checksum) = unpack('S', substr($this->content, 18, 2));
276+
277+
$this->pos = 18;
278+
if ($key == (int) 0x9AC6CDD7) {
279+
$this->pos += 22;
280+
}
281+
}
282+
262283
/**
263284
* @return array<int, int>
264285
*/
@@ -280,19 +301,21 @@ protected function resetCoordinates(int $x, int $y): array
280301
/**
281302
* @param array<string, string> $gdiObject
282303
*/
283-
protected function addGDIObject(array $gdiObject): void
304+
protected function addGDIObject(array $gdiObject, ?int $idx = null): void
284305
{
285-
// Find next available slot
286-
$idx = 0;
287-
288-
if (!empty($this->gdiObjects)) {
289-
$empty = false;
290-
$i = 0;
291-
while (!$empty) {
292-
$empty = !isset($this->gdiObjects[$i]);
293-
++$i;
306+
if (!$idx) {
307+
// Find next available slot
308+
$idx = 0;
309+
310+
if (!empty($this->gdiObjects)) {
311+
$empty = false;
312+
$i = 0;
313+
while (!$empty) {
314+
$empty = !isset($this->gdiObjects[$i]);
315+
++$i;
316+
}
317+
$idx = $i - 1;
294318
}
295-
$idx = $i - 1;
296319
}
297320

298321
$this->gdiObjects[$idx] = $gdiObject;
@@ -301,7 +324,7 @@ protected function addGDIObject(array $gdiObject): void
301324
/**
302325
* @phpstan-ignore-next-line
303326
*
304-
* @return GDImage|resource
327+
* @return GdImage|resource
305328
*/
306329
public function getResource()
307330
{
@@ -337,21 +360,8 @@ public function save(string $filename, string $format): bool
337360
}
338361
}
339362

340-
protected function readHeader(): void
363+
public function getMediaType(): string
341364
{
342-
list(, $key) = unpack('L', substr($this->content, 0, 4));
343-
list(, $handle) = unpack('S', substr($this->content, 4, 2));
344-
list(, $left) = unpack('S', substr($this->content, 6, 2));
345-
list(, $top) = unpack('S', substr($this->content, 8, 2));
346-
list(, $right) = unpack('S', substr($this->content, 10, 2));
347-
list(, $bottom) = unpack('S', substr($this->content, 12, 2));
348-
list(, $this->unitPerInch) = unpack('S', substr($this->content, 14, 2));
349-
list(, $reserved) = unpack('L', substr($this->content, 16, 4));
350-
list(, $checksum) = unpack('S', substr($this->content, 18, 2));
351-
352-
$this->pos = 18;
353-
if ($key == (int) 0x9AC6CDD7) {
354-
$this->pos += 22;
355-
}
365+
return 'image/wmf';
356366
}
357367
}
Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
declare(strict_types=1);
44

5-
namespace PhpOffice\WMF\Reader;
5+
namespace PhpOffice\WMF\Reader\WMF;
66

77
use Imagick as ImagickBase;
8+
use ImagickException;
89
use PhpOffice\WMF\Exception\WMFException;
910

1011
class Imagick implements ReaderInterface
@@ -16,9 +17,15 @@ class Imagick implements ReaderInterface
1617

1718
public function load(string $filename): bool
1819
{
19-
$this->im = new ImagickBase();
20+
try {
21+
$this->im = new ImagickBase();
2022

21-
return $this->im->readImage($filename);
23+
return $this->im->readImage($filename);
24+
} catch (ImagickException $e) {
25+
$this->im->clear();
26+
27+
throw new WMFException('Cannot load WMG File from Imagick');
28+
}
2229
}
2330

2431
public function isWMF(string $filename): bool
@@ -34,6 +41,11 @@ public function getResource(): ImagickBase
3441
return $this->im;
3542
}
3643

44+
public function getMediaType(): string
45+
{
46+
return 'image/wmf';
47+
}
48+
3749
public function save(string $filename, string $format): bool
3850
{
3951
switch (strtolower($format)) {
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
declare(strict_types=1);
44

5-
namespace PhpOffice\WMF\Reader;
5+
namespace PhpOffice\WMF\Reader\WMF;
66

77
use GDImage;
88
use Imagick as ImagickBase;
9-
use PhpOffice\WMF\Reader\Imagick as ImagickReader;
9+
use PhpOffice\WMF\Reader\WMF\Imagick as ImagickReader;
1010

1111
class Magic implements ReaderInterface
1212
{
@@ -37,6 +37,11 @@ public function save(string $filename, string $format): bool
3737
return $this->reader->save($filename, $format);
3838
}
3939

40+
public function getMediaType(): string
41+
{
42+
return $this->reader->getMediaType();
43+
}
44+
4045
public function isWMF(string $filename): bool
4146
{
4247
return $this->reader->isWMF($filename);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace PhpOffice\WMF\Reader\WMF;
4+
5+
use PhpOffice\WMF\Reader\ReaderInterface as ReaderInterfaceBase;
6+
7+
interface ReaderInterface extends ReaderInterfaceBase
8+
{
9+
public function isWMF(string $filename): bool;
10+
}

tests/WMF/Reader/AbstractTestReader.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function assertImageCompare(string $expectedFile, string $outputFile, flo
2626
/**
2727
* @return array<array<string>>
2828
*/
29-
public static function dataProviderFiles(): array
29+
public static function dataProviderFilesWMF(): array
3030
{
3131
return [
3232
[
@@ -43,4 +43,16 @@ public static function dataProviderFiles(): array
4343
],
4444
];
4545
}
46+
47+
/**
48+
* @return array<array<string>>
49+
*/
50+
public static function dataProviderFilesWMFNotImplemented(): array
51+
{
52+
return [
53+
[
54+
'test_libuemf.wmf',
55+
],
56+
];
57+
}
4658
}
Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
22

33
declare(strict_types=1);
44

5-
namespace Tests\PhpOffice\WMF\Reader;
5+
namespace Tests\PhpOffice\WMF\Reader\WMF;
66

77
use GdImage;
8-
use PhpOffice\WMF\Reader\GD;
8+
use PhpOffice\WMF\Exception\WMFException;
9+
use PhpOffice\WMF\Reader\WMF\GD;
10+
use Tests\PhpOffice\WMF\Reader\AbstractTestReader;
911

1012
class GDTest extends AbstractTestReader
1113
{
1214
/**
13-
* @dataProvider dataProviderFiles
15+
* @dataProvider dataProviderFilesWMF
1416
*/
1517
public function testLoad(string $file): void
1618
{
@@ -19,7 +21,7 @@ public function testLoad(string $file): void
1921
}
2022

2123
/**
22-
* @dataProvider dataProviderFiles
24+
* @dataProvider dataProviderFilesWMF
2325
*/
2426
public function testGetResource(string $file): void
2527
{
@@ -34,7 +36,7 @@ public function testGetResource(string $file): void
3436
}
3537

3638
/**
37-
* @dataProvider dataProviderFiles
39+
* @dataProvider dataProviderFilesWMF
3840
*/
3941
public function testOutput(string $file): void
4042
{
@@ -51,11 +53,22 @@ public function testOutput(string $file): void
5153
}
5254

5355
/**
54-
* @dataProvider dataProviderFiles
56+
* @dataProvider dataProviderFilesWMF
5557
*/
5658
public function testIsWMF(string $file): void
5759
{
5860
$reader = new GD();
5961
$this->assertTrue($reader->isWMF($this->getResourceDir() . $file));
6062
}
63+
64+
/**
65+
* @dataProvider dataProviderFilesWMFNotImplemented
66+
*/
67+
public function testNotImplemented(string $file): void
68+
{
69+
$this->expectException(WMFException::class);
70+
71+
$reader = new GD();
72+
$reader->load($this->getResourceDir() . $file);
73+
}
6174
}
Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
22

33
declare(strict_types=1);
44

5-
namespace Tests\PhpOffice\WMF\Reader;
5+
namespace Tests\PhpOffice\WMF\Reader\WMF;
66

77
use Imagick as ImagickBase;
8-
use PhpOffice\WMF\Reader\Imagick as ImagickReader;
8+
use PhpOffice\WMF\Exception\WMFException;
9+
use PhpOffice\WMF\Reader\WMF\Imagick as ImagickReader;
10+
use Tests\PhpOffice\WMF\Reader\AbstractTestReader;
911

1012
class ImagickTest extends AbstractTestReader
1113
{
1214
/**
13-
* @dataProvider dataProviderFiles
15+
* @dataProvider dataProviderFilesWMF
1416
*/
1517
public function testLoad(string $file): void
1618
{
@@ -19,7 +21,7 @@ public function testLoad(string $file): void
1921
}
2022

2123
/**
22-
* @dataProvider dataProviderFiles
24+
* @dataProvider dataProviderFilesWMF
2325
*/
2426
public function testGetResource(string $file): void
2527
{
@@ -29,7 +31,7 @@ public function testGetResource(string $file): void
2931
}
3032

3133
/**
32-
* @dataProvider dataProviderFiles
34+
* @dataProvider dataProviderFilesWMF
3335
*/
3436
public function testOutput(string $file): void
3537
{
@@ -46,11 +48,22 @@ public function testOutput(string $file): void
4648
}
4749

4850
/**
49-
* @dataProvider dataProviderFiles
51+
* @dataProvider dataProviderFilesWMF
5052
*/
5153
public function testIsWMF(string $file): void
5254
{
5355
$reader = new ImagickReader();
5456
$this->assertTrue($reader->isWMF($this->getResourceDir() . $file));
5557
}
58+
59+
/**
60+
* @dataProvider dataProviderFilesWMFNotImplemented
61+
*/
62+
public function testNotImplemented(string $file): void
63+
{
64+
$this->expectException(WMFException::class);
65+
66+
$reader = new ImagickReader();
67+
$reader->load($this->getResourceDir() . $file);
68+
}
5669
}

0 commit comments

Comments
 (0)