Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
10.00% covered (danger)
10.00%
1 / 10
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ImageSetOption
10.00% covered (danger)
10.00%
1 / 10
33.33% covered (danger)
33.33%
1 / 3
32.24
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toCss
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 formatResolution
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3declare(strict_types=1);
4
5namespace Phpdftk\Css\Value;
6
7/**
8 * One `<image> [<resolution>]? [type(<mime>)]?` entry inside an
9 * `image-set()`.
10 *
11 *   - `image` is either a {@see Url} or a {@see StringValue}
12 *     (the parser accepts both `url(foo.png)` and `"foo.png"`).
13 *   - `resolutionDppx` carries the entry's resolution in dppx
14 *     (dots-per-pixel) — `1x` = 1.0, `2x` = 2.0, `192dpi` = 2.0,
15 *     etc. Null when the author omitted a resolution.
16 *   - `mimeType` is the entry's `type(<string>)` MIME hint
17 *     (e.g. `image/svg+xml`). Null when omitted.
18 */
19final readonly class ImageSetOption
20{
21    public function __construct(
22        public Value $image,
23        public ?float $resolutionDppx = null,
24        public ?string $mimeType = null,
25    ) {}
26
27    public function toCss(): string
28    {
29        $parts = [$this->image->toCss()];
30        if ($this->resolutionDppx !== null) {
31            $parts[] = self::formatResolution($this->resolutionDppx);
32        }
33        if ($this->mimeType !== null) {
34            $parts[] = 'type("' . $this->mimeType . '")';
35        }
36        return implode(' ', $parts);
37    }
38
39    private static function formatResolution(float $dppx): string
40    {
41        return fmod($dppx, 1.0) === 0.0
42            ? ((int) $dppx) . 'x'
43            : $dppx . 'x';
44    }
45}