-
-
Notifications
You must be signed in to change notification settings - Fork 766
Expand file tree
/
Copy pathPdfWriter.php
More file actions
140 lines (116 loc) · 5.27 KB
/
PdfWriter.php
File metadata and controls
140 lines (116 loc) · 5.27 KB
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
134
135
136
137
138
139
140
<?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 readonly class PdfWriter implements WriterInterface
{
public const string WRITER_OPTION_UNIT = 'unit';
public const string WRITER_OPTION_PDF = 'fpdf';
public const string WRITER_OPTION_X = 'x';
public const string WRITER_OPTION_Y = 'y';
public const string WRITER_OPTION_LINK = 'link';
#[\Override]
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');
}
if (isset($options[self::WRITER_OPTION_LINK])) {
$link = $options[self::WRITER_OPTION_LINK];
$fpdf->Link($x, $y, $x + $matrix->getOuterSize(), $y + $matrix->getOuterSize(), $link);
}
return new PdfResult($matrix, $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);
}
}