Passed
Push — master ( e7d3e1...34e870 )
by Jhao
01:48
created

Fingerprint::compilePrint()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
ccs 0
cts 6
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of PhpAidc LabelPrinter package.
5
 *
6
 * © Appwilio (https://appwilio.com)
7
 * © JhaoDa (https://github.com/jhaoda)
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
declare(strict_types=1);
14
15
namespace PhpAidc\LabelPrinter\Language;
16
17
use PhpAidc\LabelPrinter\Command\Raw;
18
use PhpAidc\LabelPrinter\Command\Clear;
19
use PhpAidc\LabelPrinter\Command\Bitmap;
20
use PhpAidc\LabelPrinter\Command\Barcode;
21
use PhpAidc\LabelPrinter\Command\TextLine;
22
use PhpAidc\LabelPrinter\Command\TextBlock;
23
use PhpAidc\LabelPrinter\Command\ExternalImage;
24
use PhpAidc\LabelPrinter\Command\InternalImage;
25
use PhpAidc\LabelPrinter\Contract\Label;
26
use PhpAidc\LabelPrinter\Contract\Command;
27
use PhpAidc\LabelPrinter\Contract\Language;
28
use PhpAidc\LabelPrinter\Enum\Unit;
29
use PhpAidc\LabelPrinter\Enum\Charset;
30
use PhpAidc\LabelPrinter\Language\Fingerprint as Handlers;
31
32
final class Fingerprint implements Language
33
{
34
    public const DEFAULT_ANCHOR = 1;
35
    public const DEFAULT_DIRECTION = 1;
36
    public const DEFAULT_BARCODE_HEIGHT = 100;
37
    public const DEFAULT_BARCODE_MAGNIFICATION = 2;
38
39
    private const EOC = "\n";
40
41
    private const HANDLERS = [
42
        Raw::class           => Handlers\FingerprintRaw::class,
43
        Clear::class         => Handlers\FingerprintClear::class,
44
        Bitmap::class        => Handlers\FingerprintBitmap::class,
45
        Barcode::class       => Handlers\FingerprintBarcode::class,
46
        TextLine::class      => Handlers\FingerprintTextLine::class,
47
        TextBlock::class     => Handlers\FingerprintTextBlock::class,
48
        ExternalImage::class => Handlers\FingerprintExternalImage::class,
49
        InternalImage::class => Handlers\FingerprintInternalImage::class,
50
    ];
51
52
    /** @var float */
53
    private $density;
54
55
    public function __construct(float $density)
56
    {
57
        $this->density = $density;
58
    }
59
60
    public function compileDeclaration(Label $label): iterable
61
    {
62
        yield from $this->translateMedia($label->getMedia());
63
        yield from $this->translateCharset($label->getCharset());
64
    }
65
66
    public function isSupport(Command $command): bool
67
    {
68
        return isset(self::HANDLERS[\get_class($command)]);
69
    }
70
71
    public function compileCommand(Command $command): iterable
72
    {
73
        if ($this->isSupport($command)) {
74
            $class = self::HANDLERS[\get_class($command)];
75
76
            $handler = new $class();
77
78
            foreach ((new $handler)->translate($command) as $instruction) {
79
                yield $instruction.self::EOC;
80
            }
81
        } else {
82
            // throw exception
83
            yield null;
84
        }
85
    }
86
87
    public function compilePrint(int $copies): iterable
88
    {
89
        if ($copies <= 0) {
90
            throw new \InvalidArgumentException('Number of copies must be greather than 0.');
91
        }
92
93
        yield "PF {$copies}".self::EOC;
94
    }
95
96
    private function translateCharset(?Charset $charset): iterable
97
    {
98
        if ($charset) {
99
            yield \sprintf('NASC "%s"', $charset->getValue()).self::EOC;
100
        }
101
    }
102
103
    private function translateMedia(array $media): iterable
104
    {
105
        ['unit' => $unit, 'width' => $width, 'height' => $height] = $media;
106
107
        if ($width) {
108
            yield \sprintf('SETUP "MEDIA,MEDIA SIZE,WIDTH,%d'.self::EOC, $this->valueToDots($width, $unit));
109
        }
110
111
        if ($height) {
112
            yield \sprintf('SETUP "MEDIA,MEDIA SIZE,HEIGHT,%d'.self::EOC, $this->valueToDots($height, $unit));
113
        }
114
    }
115
116
    private function valueToDots(float $value, Unit $unit): int
117
    {
118
        if ($unit->equals(Unit::DOT())) {
119
            return (int) $value;
120
        }
121
122
        if ($unit->equals(Unit::IN())) {
123
            return (int) \round($this->density * $value);
124
        }
125
126
        return (int) \round(($this->density / 2.54 / 10) * $value);
127
    }
128
}
129