FpdfWriter.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4. * (c) Jeroen van den Enden <info@endroid.nl>
  5. *
  6. * This source file is subject to the MIT license that is bundled
  7. * with this source code in the file LICENSE.
  8. */
  9. namespace Endroid\QrCode\Writer;
  10. use Endroid\QrCode\Exception\ValidationException;
  11. use Endroid\QrCode\QrCodeInterface;
  12. class FpdfWriter extends AbstractWriter
  13. {
  14. /**
  15. * Defines as which unit the size is handled. Default is: "mm".
  16. *
  17. * Allowed values: 'mm', 'pt', 'cm', 'in'
  18. */
  19. public const WRITER_OPTION_MEASURE_UNIT = 'fpdf_measure_unit';
  20. public function writeString(QrCodeInterface $qrCode): string
  21. {
  22. if (!\class_exists(\FPDF::class)) {
  23. throw new \BadMethodCallException('The Fpdf writer requires FPDF as dependency but the class "\\FPDF" couldn\'t be found.');
  24. }
  25. if ($qrCode->getValidateResult()) {
  26. throw new ValidationException('Built-in validation reader can not check fpdf qr codes: please disable via setValidateResult(false)');
  27. }
  28. $foregroundColor = $qrCode->getForegroundColor();
  29. if (0 !== $foregroundColor['a']) {
  30. throw new \InvalidArgumentException('The foreground color has an alpha channel, but the fpdf qr writer doesn\'t support alpha channels.');
  31. }
  32. $backgroundColor = $qrCode->getBackgroundColor();
  33. if (0 !== $backgroundColor['a']) {
  34. throw new \InvalidArgumentException('The foreground color has an alpha channel, but the fpdf qr writer doesn\'t support alpha channels.');
  35. }
  36. $label = $qrCode->getLabel();
  37. $labelHeight = null !== $label ? 30 : 0;
  38. $data = $qrCode->getData();
  39. $options = $qrCode->getWriterOptions();
  40. $fpdf = new \FPDF(
  41. 'P',
  42. $options[self::WRITER_OPTION_MEASURE_UNIT] ?? 'mm',
  43. [$data['outer_width'], $data['outer_height'] + $labelHeight]
  44. );
  45. $fpdf->AddPage();
  46. $fpdf->SetFillColor($backgroundColor['r'], $backgroundColor['g'], $backgroundColor['b']);
  47. $fpdf->Rect(0, 0, $data['outer_width'], $data['outer_height'], 'F');
  48. $fpdf->SetFillColor($foregroundColor['r'], $foregroundColor['g'], $foregroundColor['b']);
  49. foreach ($data['matrix'] as $row => $values) {
  50. foreach ($values as $column => $value) {
  51. if (1 === $value) {
  52. $fpdf->Rect(
  53. $data['margin_left'] + ($column * $data['block_size']),
  54. $data['margin_left'] + ($row * $data['block_size']),
  55. $data['block_size'],
  56. $data['block_size'],
  57. 'F'
  58. );
  59. }
  60. }
  61. }
  62. $logoPath = $qrCode->getLogoPath();
  63. if (null !== $logoPath) {
  64. $this->addLogo(
  65. $fpdf,
  66. $logoPath,
  67. $qrCode->getLogoWidth(),
  68. $qrCode->getLogoHeight(),
  69. $data['outer_width'],
  70. $data['outer_height']
  71. );
  72. }
  73. if (null !== $label) {
  74. $fpdf->setY($data['outer_height'] + 5);
  75. $fpdf->SetFont('Helvetica', null, $qrCode->getLabelFontSize());
  76. $fpdf->Cell(0, 0, $label, 0, 0, strtoupper($qrCode->getLabelAlignment()[0]));
  77. }
  78. return $fpdf->Output('S');
  79. }
  80. protected function addLogo(\FPDF $fpdf, string $logoPath, ?int $logoWidth, ?int $logoHeight, int $imageWidth, int $imageHeight): void
  81. {
  82. if (null === $logoHeight || null === $logoWidth) {
  83. [$logoSourceWidth, $logoSourceHeight] = \getimagesize($logoPath);
  84. if (null === $logoWidth) {
  85. $logoWidth = (int) $logoSourceWidth;
  86. }
  87. if (null === $logoHeight) {
  88. $aspectRatio = $logoWidth / $logoSourceWidth;
  89. $logoHeight = (int) ($logoSourceHeight * $aspectRatio);
  90. }
  91. }
  92. $logoX = $imageWidth / 2 - (int) $logoWidth / 2;
  93. $logoY = $imageHeight / 2 - (int) $logoHeight / 2;
  94. $fpdf->Image($logoPath, $logoX, $logoY, $logoWidth, $logoHeight);
  95. }
  96. public static function getContentType(): string
  97. {
  98. return 'application/pdf';
  99. }
  100. public static function getSupportedExtensions(): array
  101. {
  102. return ['pdf'];
  103. }
  104. public function getName(): string
  105. {
  106. return 'fpdf';
  107. }
  108. }