Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
ViewportElement
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
3 / 3
10
100.00% covered (success)
100.00%
1 / 1
 viewBox
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
8
 widthAttribute
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 heightAttribute
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Phpdftk\Svg;
6
7/**
8 * Shared base for SVG elements that establish a viewport — currently
9 * `<svg>` (root) and `<symbol>`. Both carry a `viewBox` and optional
10 * `width` / `height`, and both apply the viewBox-to-viewport mapping
11 * described in SVG 2 §7. The two raw width/height accessors stay
12 * `string`-typed because the spec permits unit suffixes (`%`, `em`, …)
13 * that downstream code may want to round-trip.
14 */
15abstract class ViewportElement extends Element
16{
17    /**
18     * Parsed `viewBox` per SVG 2 §7.7 — `[minX, minY, width, height]`,
19     * or null if no viewBox is set. Negative width/height return null
20     * (the spec invalidates them).
21     *
22     * @return array{0: float, 1: float, 2: float, 3: float}|null
23     */
24    public function viewBox(): ?array
25    {
26        $raw = $this->getAttribute('viewBox');
27        if ($raw === null) {
28            return null;
29        }
30        $parts = preg_split('/[\s,]+/', trim($raw)) ?: [];
31        if (count($parts) !== 4) {
32            return null;
33        }
34        foreach ($parts as $p) {
35            if (!is_numeric($p)) {
36                return null;
37            }
38        }
39        $w = (float) $parts[2];
40        $h = (float) $parts[3];
41        if ($w < 0 || $h < 0) {
42            return null;
43        }
44        return [(float) $parts[0], (float) $parts[1], $w, $h];
45    }
46
47    /** Raw `width=""` attribute string (may include a unit), or null. */
48    public function widthAttribute(): ?string
49    {
50        return $this->getAttribute('width');
51    }
52
53    /** Raw `height=""` attribute string (may include a unit), or null. */
54    public function heightAttribute(): ?string
55    {
56        return $this->getAttribute('height');
57    }
58}