vendor/endroid/qr-code/src/Writer/PdfWriter.php line 21

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