Browse Source

Added fpdf output

Maximilian Kresse 5 years ago
parent
commit
091ea635bd
4 changed files with 130 additions and 5 deletions
  1. 4 2
      composer.json
  2. 46 0
      examples/fpdf.php
  3. 74 0
      src/Output/QRFpdf.php
  4. 6 3
      src/QRCode.php

+ 4 - 2
composer.json

@@ -30,10 +30,12 @@
 	},
 	"require-dev": {
 		"phpunit/phpunit": "^9.1",
-		"phan/phan": "^2.7"
+		"phan/phan": "^2.7",
+		"setasign/fpdf": "^1.8"
 	},
 	"suggest": {
-		"chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps."
+		"chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.",
+		"setasign/fpdf": "Required to use the QR FPDF output."
 	},
 	"autoload": {
 		"psr-4": {

+ 46 - 0
examples/fpdf.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace chillerlan\QRCodeExamples;
+
+use chillerlan\QRCode\{QRCode, QROptions};
+
+require_once __DIR__ . '/../vendor/autoload.php';
+
+$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
+
+$options = new QROptions([
+    'version'      => 7,
+    'outputType'   => QRCode::OUTPUT_FPDF,
+    'eccLevel'     => QRCode::ECC_L,
+    'scale'        => 5,
+    'moduleValues' => [
+        // finder
+        1536 => [0, 63, 255], // dark (true)
+        6    => [255, 255, 255], // light (false), white is the transparency color and is enabled by default
+        // alignment
+        2560 => [255, 0, 255],
+        10   => [255, 255, 255],
+        // timing
+        3072 => [255, 0, 0],
+        12   => [255, 255, 255],
+        // format
+        3584 => [67, 191, 84],
+        14   => [255, 255, 255],
+        // version
+        4096 => [62, 174, 190],
+        16   => [255, 255, 255],
+        // data
+        1024 => [0, 0, 0],
+        4    => [255, 255, 255],
+        // darkmodule
+        512  => [0, 0, 0],
+        // separator
+        8    => [255, 255, 255],
+        // quietzone
+        18   => [255, 255, 255],
+    ],
+]);
+
+\header('Content-type: application/pdf');
+
+echo (new QRCode($options))->render($data, 'example_fpdf.pdf');

+ 74 - 0
src/Output/QRFpdf.php

@@ -0,0 +1,74 @@
+<?php
+
+declare(strict_types=1);
+
+namespace chillerlan\QRCode\Output;
+
+use chillerlan\QRCode\Data\QRMatrix;
+use chillerlan\Settings\SettingsContainerInterface;
+
+class QRFpdf extends QROutputAbstract
+{
+    public function __construct(SettingsContainerInterface $options, QRMatrix $matrix)
+    {
+        parent::__construct($options, $matrix);
+
+        if (!\class_exists(\FPDF::class)) {
+            throw new \BadMethodCallException(
+                'The QRFpdf output requires FPDF as dependency but the class "\FPDF" couldn\'t be found.'
+            );
+        }
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function setModuleValues(): void
+    {
+        foreach ($this::DEFAULT_MODULE_VALUES as $M_TYPE => $defaultValue) {
+            $v = $this->options->moduleValues[$M_TYPE] ?? null;
+
+            if (!\is_array($v) || \count($v) < 3) {
+                $this->moduleValues[$M_TYPE] = $defaultValue
+                    ? [0, 0, 0]
+                    : [255, 255, 255];
+            } else {
+                $this->moduleValues[$M_TYPE] = \array_values($v);
+            }
+        }
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function dump(string $file = null): string
+    {
+        $file ??= $this->options->cachefile;
+
+        $fpdf = new \FPDF('P', 'pt', [$this->length, $this->length]);
+        $fpdf->AddPage();
+
+        $prevColor = null;
+        foreach ($this->matrix->matrix() as $y => $row) {
+            foreach ($row as $x => $M_TYPE) {
+                /**
+                 * @var int $M_TYPE
+                 */
+                $color = $this->moduleValues[$M_TYPE];
+                if ($prevColor === null || $prevColor !== $color) {
+                    $fpdf->SetFillColor(...$color);
+                    $prevColor = $color;
+                }
+                $fpdf->Rect($x * $this->scale, $y * $this->scale, 1 * $this->scale, 1 * $this->scale, 'F');
+            }
+        }
+
+        $pdfData = $fpdf->Output('S');
+
+        if ($file !== null) {
+            $this->saveToFile($pdfData, $file);
+        }
+
+        return $pdfData;
+    }
+}

+ 6 - 3
src/QRCode.php

@@ -15,9 +15,7 @@ namespace chillerlan\QRCode;
 use chillerlan\QRCode\Data\{
 	AlphaNum, Byte, Kanji, MaskPatternTester, Number, QRCodeDataException, QRDataInterface, QRMatrix
 };
-use chillerlan\QRCode\Output\{
-	QRCodeOutputException, QRImage, QRImagick, QRMarkup, QROutputInterface, QRString
-};
+use chillerlan\QRCode\Output\{QRCodeOutputException, QRFpdf, QRImage, QRImagick, QRMarkup, QROutputInterface, QRString};
 use chillerlan\Settings\SettingsContainerInterface;
 
 use function call_user_func_array, class_exists, in_array, mb_internal_encoding, ord, strlen, strtolower, str_split;
@@ -107,6 +105,8 @@ class QRCode{
 	/** @var string */
 	public const OUTPUT_IMAGICK     = 'imagick';
 	/** @var string */
+	public const OUTPUT_FPDF        = 'fpdf';
+	/** @var string */
 	public const OUTPUT_CUSTOM      = 'custom';
 
 	/**
@@ -131,6 +131,9 @@ class QRCode{
 		QRImagick::class => [
 			self::OUTPUT_IMAGICK,
 		],
+		QRFpdf::class => [
+			self::OUTPUT_FPDF
+		]
 	];
 
 	/**