diff --git a/examples/MyCustomOutput.php b/examples/MyCustomOutput.php
index 4690b8528..4e4e5bcb4 100644
--- a/examples/MyCustomOutput.php
+++ b/examples/MyCustomOutput.php
@@ -18,6 +18,10 @@ use chillerlan\QRCode\Output\QROutputAbstract;
*/
class MyCustomOutput extends QROutputAbstract{
+ protected function setModuleValues():void{
+ // TODO: Implement setModuleValues() method.
+ }
+
public function dump(string $file = null){
$output = '';
diff --git a/src/Output/QRImage.php b/src/Output/QRImage.php
index 51c89604b..a183e9a3e 100644
--- a/src/Output/QRImage.php
+++ b/src/Output/QRImage.php
@@ -12,85 +12,71 @@
namespace chillerlan\QRCode\Output;
-use chillerlan\QRCode\{QRCode, Data\QRMatrix};
+use chillerlan\QRCode\QRCode;
/**
* Converts the matrix into images, raw or base64 output
*/
class QRImage extends QROutputAbstract{
- const transparencyTypes = [
+ const TRANSPARENCY_TYPES = [
QRCode::OUTPUT_IMAGE_PNG,
QRCode::OUTPUT_IMAGE_GIF,
];
protected $defaultMode = QRCode::OUTPUT_IMAGE_PNG;
- protected $moduleValues = [
- // light
- QRMatrix::M_DATA => [255, 255, 255],
- QRMatrix::M_FINDER => [255, 255, 255],
- QRMatrix::M_SEPARATOR => [255, 255, 255],
- QRMatrix::M_ALIGNMENT => [255, 255, 255],
- QRMatrix::M_TIMING => [255, 255, 255],
- QRMatrix::M_FORMAT => [255, 255, 255],
- QRMatrix::M_VERSION => [255, 255, 255],
- QRMatrix::M_QUIETZONE => [255, 255, 255],
- QRMatrix::M_TEST => [255, 255, 255],
- // dark
- QRMatrix::M_DARKMODULE << 8 => [0, 0, 0],
- QRMatrix::M_DATA << 8 => [0, 0, 0],
- QRMatrix::M_FINDER << 8 => [0, 0, 0],
- QRMatrix::M_ALIGNMENT << 8 => [0, 0, 0],
- QRMatrix::M_TIMING << 8 => [0, 0, 0],
- QRMatrix::M_FORMAT << 8 => [0, 0, 0],
- QRMatrix::M_VERSION << 8 => [0, 0, 0],
- QRMatrix::M_TEST << 8 => [0, 0, 0],
- ];
-
/**
* @see imagecreatetruecolor()
* @var resource
*/
protected $image;
- /**
- * @var int
- */
- protected $scale;
-
- /**
- * @var int
- */
- protected $length;
-
/**
* @see imagecolorallocate()
* @var int
*/
protected $background;
+ /**
+ * @return void
+ */
+ 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);
+ }
+
+ }
+
+ }
+
/**
* @param string|null $file
*
* @return string
- * @throws \chillerlan\QRCode\Output\QRCodeOutputException
*/
public function dump(string $file = null):string{
+ $this->image = imagecreatetruecolor($this->length, $this->length);
+ $this->background = imagecolorallocate($this->image, ...array_values($this->options->imageTransparencyBG));
- if($this->options->cachefile !== null && !is_writable(dirname($this->options->cachefile))){
- throw new QRCodeOutputException('Could not write data to cache file: '.$this->options->cachefile);
+ if((bool)$this->options->imageTransparent && in_array($this->options->outputType, $this::TRANSPARENCY_TYPES, true)){
+ imagecolortransparent($this->image, $this->background);
}
- $this->setImage();
-
- $moduleValues = is_array($this->options->moduleValues[$this->matrix::M_DATA])
- ? $this->options->moduleValues // @codeCoverageIgnore
- : $this->moduleValues;
+ imagefilledrectangle($this->image, 0, 0, $this->length, $this->length, $this->background);
foreach($this->matrix->matrix() as $y => $row){
- foreach($row as $x => $pixel){
- $this->setPixel($x, $y, imagecolorallocate($this->image, ...$moduleValues[$pixel]));
+ foreach($row as $x => $M_TYPE){
+ $this->setPixel($x, $y, $this->moduleValues[$M_TYPE]);
}
}
@@ -104,35 +90,20 @@ class QRImage extends QROutputAbstract{
}
/**
+ * @param int $x
+ * @param int $y
+ * @param array $rgb
+ *
* @return void
*/
- protected function setImage(){
- $this->scale = $this->options->scale;
- $this->length = $this->moduleCount * $this->scale;
- $this->image = imagecreatetruecolor($this->length, $this->length);
- $this->background = imagecolorallocate($this->image, ...$this->options->imageTransparencyBG);
-
- if((bool)$this->options->imageTransparent && in_array($this->options->outputType, $this::transparencyTypes, true)){
- imagecolortransparent($this->image, $this->background);
- }
-
- imagefilledrectangle($this->image, 0, 0, $this->length, $this->length, $this->background);
- }
-
- /**
- * @param int $x
- * @param int $y
- * @param int $color
- * @return void
- */
- protected function setPixel(int $x, int $y, int $color){
+ protected function setPixel(int $x, int $y, array $rgb):void{
imagefilledrectangle(
$this->image,
$x * $this->scale,
$y * $this->scale,
- ($x + 1) * $this->scale - 1,
- ($y + 1) * $this->scale - 1,
- $color
+ ($x + 1) * $this->scale,
+ ($y + 1) * $this->scale,
+ imagecolorallocate($this->image, ...$rgb)
);
}
diff --git a/src/Output/QRMarkup.php b/src/Output/QRMarkup.php
index 7e8aa4373..84bf1837d 100644
--- a/src/Output/QRMarkup.php
+++ b/src/Output/QRMarkup.php
@@ -21,6 +21,27 @@ class QRMarkup extends QROutputAbstract{
protected $defaultMode = QRCode::OUTPUT_MARKUP_SVG;
+ /**
+ * @return void
+ */
+ protected function setModuleValues():void{
+
+ foreach($this::DEFAULT_MODULE_VALUES as $M_TYPE => $defaultValue){
+ $v = $this->options->moduleValues[$M_TYPE] ?? null;
+
+ if(!is_string($v)){
+ $this->moduleValues[$M_TYPE] = $defaultValue
+ ? $this->options->markupDark
+ : $this->options->markupLight;
+ }
+ else{
+ $this->moduleValues[$M_TYPE] = trim(strip_tags($v), '\'"');
+ }
+
+ }
+
+ }
+
/**
* @return string|bool
*/
@@ -30,8 +51,8 @@ class QRMarkup extends QROutputAbstract{
foreach($this->matrix->matrix() as $row){
$html .= '
';
- foreach($row as $pixel){
- $html .= '';
+ foreach($row as $M_TYPE){
+ $html .= '';
}
$html .= '
'.$this->options->eol;
@@ -59,13 +80,7 @@ class QRMarkup extends QROutputAbstract{
.''.$this->options->svgDefs.''
.$this->options->eol;
- foreach($this->options->moduleValues as $M_TYPE => $value){
-
- // fallback
- if(is_bool($value)){
- $value = $value ? '#000' : '#fff';
- }
-
+ foreach($this->moduleValues as $M_TYPE => $value){
$path = '';
foreach($matrix as $y => $row){
diff --git a/src/Output/QROutputAbstract.php b/src/Output/QROutputAbstract.php
index 57d803d07..d9e656ee5 100644
--- a/src/Output/QROutputAbstract.php
+++ b/src/Output/QROutputAbstract.php
@@ -16,7 +16,7 @@ use chillerlan\QRCode\{Data\QRMatrix, QRCode};
use chillerlan\Settings\SettingsContainerInterface;
/**
- *
+ * common output abstract
*/
abstract class QROutputAbstract implements QROutputInterface{
@@ -45,6 +45,21 @@ abstract class QROutputAbstract implements QROutputInterface{
*/
protected $defaultMode;
+ /**
+ * @var int
+ */
+ protected $scale;
+
+ /**
+ * @var int
+ */
+ protected $length;
+
+ /**
+ * @var array
+ */
+ protected $moduleValues;
+
/**
* QROutputAbstract constructor.
*
@@ -55,6 +70,8 @@ abstract class QROutputAbstract implements QROutputInterface{
$this->options = $options;
$this->matrix = $matrix;
$this->moduleCount = $this->matrix->size();
+ $this->scale = $this->options->scale;
+ $this->length = $this->moduleCount * $this->scale;
$class = get_called_class();
@@ -62,8 +79,16 @@ abstract class QROutputAbstract implements QROutputInterface{
$this->outputMode = $this->options->outputType;
}
+ $this->setModuleValues();
}
+ /**
+ * Sets the initial module values (clean-up & defaults)
+ *
+ * @return void
+ */
+ abstract protected function setModuleValues():void;
+
/**
* @see file_put_contents()
*
diff --git a/src/Output/QROutputInterface.php b/src/Output/QROutputInterface.php
index 8ddc738c3..3cff7001b 100644
--- a/src/Output/QROutputInterface.php
+++ b/src/Output/QROutputInterface.php
@@ -12,11 +12,35 @@
namespace chillerlan\QRCode\Output;
+use chillerlan\QRCode\Data\QRMatrix;
+
/**
* Converts the data matrix into readable output
*/
interface QROutputInterface{
+ const DEFAULT_MODULE_VALUES = [
+ // light
+ QRMatrix::M_DATA => false, // 4
+ QRMatrix::M_FINDER => false, // 6
+ QRMatrix::M_SEPARATOR => false, // 8
+ QRMatrix::M_ALIGNMENT => false, // 10
+ QRMatrix::M_TIMING => false, // 12
+ QRMatrix::M_FORMAT => false, // 14
+ QRMatrix::M_VERSION => false, // 16
+ QRMatrix::M_QUIETZONE => false, // 18
+ QRMatrix::M_TEST => false, // 255
+ // dark
+ QRMatrix::M_DARKMODULE << 8 => true, // 512
+ QRMatrix::M_DATA << 8 => true, // 1024
+ QRMatrix::M_FINDER << 8 => true, // 1536
+ QRMatrix::M_ALIGNMENT << 8 => true, // 2560
+ QRMatrix::M_TIMING << 8 => true, // 3072
+ QRMatrix::M_FORMAT << 8 => true, // 3584
+ QRMatrix::M_VERSION << 8 => true, // 4096
+ QRMatrix::M_TEST << 8 => true, // 65280
+ ];
+
/**
* @param string|null $file
*
diff --git a/src/Output/QRString.php b/src/Output/QRString.php
index 231dfb5ff..dd7418804 100644
--- a/src/Output/QRString.php
+++ b/src/Output/QRString.php
@@ -21,6 +21,27 @@ class QRString extends QROutputAbstract{
protected $defaultMode = QRCode::OUTPUT_STRING_TEXT;
+ /**
+ * @return void
+ */
+ protected function setModuleValues():void{
+
+ foreach($this::DEFAULT_MODULE_VALUES as $M_TYPE => $defaultValue){
+ $v = $this->options->moduleValues[$M_TYPE] ?? null;
+
+ if(!is_string($v)){
+ $this->moduleValues[$M_TYPE] = $defaultValue
+ ? $this->options->textDark
+ : $this->options->textLight;
+ }
+ else{
+ $this->moduleValues[$M_TYPE] = $v;
+ }
+
+ }
+
+ }
+
/**
* @return string
*/
@@ -30,17 +51,8 @@ class QRString extends QROutputAbstract{
foreach($this->matrix->matrix() as $row){
$r = [];
- foreach($row as $col){
- $col = $this->options->moduleValues[$col];
-
- // fallback
- if(is_bool($col) || !is_string($col)){
- $col = $col
- ? $this->options->textDark
- : $this->options->textLight;
- }
-
- $r[] = $col;
+ foreach($row as $M_TYPE){
+ $r[] = $this->moduleValues[$M_TYPE];
}
$str[] = implode('', $r);
diff --git a/src/QROptions.php b/src/QROptions.php
index 02b905ecb..f19b7a1f4 100644
--- a/src/QROptions.php
+++ b/src/QROptions.php
@@ -37,6 +37,9 @@ use chillerlan\Settings\SettingsContainerAbstract;
* @property string $textDark
* @property string $textLight
*
+ * @property string $markupDark
+ * @property string $markupLight
+ *
* @property bool $imageBase64
* @property bool $imageTransparent
* @property array $imageTransparencyBG
diff --git a/src/QROptionsTrait.php b/src/QROptionsTrait.php
index 3346987cf..8994eb247 100644
--- a/src/QROptionsTrait.php
+++ b/src/QROptionsTrait.php
@@ -12,8 +12,6 @@
namespace chillerlan\QRCode;
-use chillerlan\QRCode\Data\QRMatrix;
-
trait QROptionsTrait{
/**
@@ -153,6 +151,20 @@ trait QROptionsTrait{
*/
protected $textLight = '⭕';
+ /**
+ * markup substitute for dark (CSS value)
+ *
+ * @var string
+ */
+ protected $markupDark = '#000';
+
+ /**
+ * markup substitute for light (CSS value)
+ *
+ * @var string
+ */
+ protected $markupLight = '#fff';
+
/**
* toggle base64 or raw image data
*
@@ -196,27 +208,7 @@ trait QROptionsTrait{
*
* @var array
*/
- protected $moduleValues = [
- // light
- QRMatrix::M_DATA => false, // 4
- QRMatrix::M_FINDER => false, // 6
- QRMatrix::M_SEPARATOR => false, // 8
- QRMatrix::M_ALIGNMENT => false, // 10
- QRMatrix::M_TIMING => false, // 12
- QRMatrix::M_FORMAT => false, // 14
- QRMatrix::M_VERSION => false, // 16
- QRMatrix::M_QUIETZONE => false, // 18
- QRMatrix::M_TEST => false, // 255
- // dark
- QRMatrix::M_DARKMODULE << 8 => true, // 512
- QRMatrix::M_DATA << 8 => true, // 1024
- QRMatrix::M_FINDER << 8 => true, // 1536
- QRMatrix::M_ALIGNMENT << 8 => true, // 2560
- QRMatrix::M_TIMING << 8 => true, // 3072
- QRMatrix::M_FORMAT << 8 => true, // 3584
- QRMatrix::M_VERSION << 8 => true, // 4096
- QRMatrix::M_TEST << 8 => true, // 65280
- ];
+ protected $moduleValues;
/**
* Sets the options, called internally by the constructor
diff --git a/tests/Output/QRImageTest.php b/tests/Output/QRImageTest.php
index 1ef0a9f48..f27be9df7 100644
--- a/tests/Output/QRImageTest.php
+++ b/tests/Output/QRImageTest.php
@@ -35,11 +35,7 @@ class QRImageTest extends QROutputTestAbstract{
$this->options->outputType = $type;
$this->options->cachefile = $this::cachefile.$type;
$this->setOutputInterface();
- $this->outputInterface->dump();
-
- $this->options->cachefile = null;
- $this->options->imageBase64 = false;
- $this->setOutputInterface();
+ $this->outputInterface->dump($this::cachefile.$type);
$img = $this->outputInterface->dump();
if($type === QRCode::OUTPUT_IMAGE_JPG){ // jpeg encoding may cause different results