forked from endroid/qr-code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PdfWriter.php
133 lines (110 loc) · 4.93 KB
/
PdfWriter.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
declare(strict_types=1);
namespace Endroid\QrCode\Writer;
use Endroid\QrCode\Bacon\MatrixFactory;
use Endroid\QrCode\Label\LabelInterface;
use Endroid\QrCode\Logo\LogoInterface;
use Endroid\QrCode\QrCodeInterface;
use Endroid\QrCode\Writer\Result\PdfResult;
use Endroid\QrCode\Writer\Result\ResultInterface;
final class PdfWriter implements WriterInterface
{
public const WRITER_OPTION_UNIT = 'unit';
public const WRITER_OPTION_PDF = 'fpdf';
public const WRITER_OPTION_X = 'x';
public const WRITER_OPTION_Y = 'y';
public function write(QrCodeInterface $qrCode, LogoInterface $logo = null, LabelInterface $label = null, array $options = []): ResultInterface
{
$matrixFactory = new MatrixFactory();
$matrix = $matrixFactory->create($qrCode);
$unit = 'mm';
if (isset($options[self::WRITER_OPTION_UNIT])) {
$unit = $options[self::WRITER_OPTION_UNIT];
}
$allowedUnits = ['mm', 'pt', 'cm', 'in'];
if (!in_array($unit, $allowedUnits)) {
throw new \Exception(sprintf('PDF Measure unit should be one of [%s]', implode(', ', $allowedUnits)));
}
$labelSpace = 0;
if ($label instanceof LabelInterface) {
$labelSpace = 30;
}
if (!class_exists(\FPDF::class)) {
throw new \Exception('Unable to find FPDF: check your installation');
}
$foregroundColor = $qrCode->getForegroundColor();
if ($foregroundColor->getAlpha() > 0) {
throw new \Exception('PDF Writer does not support alpha channels');
}
$backgroundColor = $qrCode->getBackgroundColor();
if ($backgroundColor->getAlpha() > 0) {
throw new \Exception('PDF Writer does not support alpha channels');
}
if (isset($options[self::WRITER_OPTION_PDF])) {
$fpdf = $options[self::WRITER_OPTION_PDF];
if (!$fpdf instanceof \FPDF) {
throw new \Exception('pdf option must be an instance of FPDF');
}
} else {
// @todo Check how to add label height later
$fpdf = new \FPDF('P', $unit, [$matrix->getOuterSize(), $matrix->getOuterSize() + $labelSpace]);
$fpdf->AddPage();
}
$x = 0;
if (isset($options[self::WRITER_OPTION_X])) {
$x = $options[self::WRITER_OPTION_X];
}
$y = 0;
if (isset($options[self::WRITER_OPTION_Y])) {
$y = $options[self::WRITER_OPTION_Y];
}
$fpdf->SetFillColor($backgroundColor->getRed(), $backgroundColor->getGreen(), $backgroundColor->getBlue());
$fpdf->Rect($x, $y, $matrix->getOuterSize(), $matrix->getOuterSize(), 'F');
$fpdf->SetFillColor($foregroundColor->getRed(), $foregroundColor->getGreen(), $foregroundColor->getBlue());
for ($rowIndex = 0; $rowIndex < $matrix->getBlockCount(); ++$rowIndex) {
for ($columnIndex = 0; $columnIndex < $matrix->getBlockCount(); ++$columnIndex) {
if (1 === $matrix->getBlockValue($rowIndex, $columnIndex)) {
$fpdf->Rect(
$x + $matrix->getMarginLeft() + ($columnIndex * $matrix->getBlockSize()),
$y + $matrix->getMarginLeft() + ($rowIndex * $matrix->getBlockSize()),
$matrix->getBlockSize(),
$matrix->getBlockSize(),
'F'
);
}
}
}
if ($logo instanceof LogoInterface) {
$this->addLogo($logo, $fpdf, $x, $y, $matrix->getOuterSize());
}
if ($label instanceof LabelInterface) {
$fpdf->SetXY($x, $y + $matrix->getOuterSize() + $labelSpace - 25);
$fpdf->SetFont('Helvetica', '', $label->getFont()->getSize());
$fpdf->Cell($matrix->getOuterSize(), 0, $label->getText(), 0, 0, 'C');
}
return new PdfResult($fpdf);
}
private function addLogo(LogoInterface $logo, \FPDF $fpdf, float $x, float $y, float $size): void
{
$logoPath = $logo->getPath();
$logoHeight = $logo->getResizeToHeight();
$logoWidth = $logo->getResizeToWidth();
if (null === $logoHeight || null === $logoWidth) {
$imageSize = \getimagesize($logoPath);
if (!$imageSize) {
throw new \Exception(sprintf('Unable to read image size for logo "%s"', $logoPath));
}
[$logoSourceWidth, $logoSourceHeight] = $imageSize;
if (null === $logoWidth) {
$logoWidth = (int) $logoSourceWidth;
}
if (null === $logoHeight) {
$aspectRatio = $logoWidth / $logoSourceWidth;
$logoHeight = (int) ($logoSourceHeight * $aspectRatio);
}
}
$logoX = $x + $size / 2 - $logoWidth / 2;
$logoY = $y + $size / 2 - $logoHeight / 2;
$fpdf->Image($logoPath, $logoX, $logoY, $logoWidth, $logoHeight);
}
}