diff --git a/composer.json b/composer.json index 37e8c75f..faf538c6 100644 --- a/composer.json +++ b/composer.json @@ -5,8 +5,7 @@ "homepage": "https://github.com/Bacon/BaconQrCode", "require": { "php": "^8.1", - "ext-iconv": "*", - "dasprid/enum": "^1.0.3" + "ext-iconv": "*" }, "suggest": { "ext-imagick": "to generate QR code images" diff --git a/src/Common/CharacterSetEci.php b/src/Common/CharacterSetEci.php index 8b62b8cf..61013639 100644 --- a/src/Common/CharacterSetEci.php +++ b/src/Common/CharacterSetEci.php @@ -4,100 +4,124 @@ namespace BaconQrCode\Common; use BaconQrCode\Exception\InvalidArgumentException; -use DASPRiD\Enum\AbstractEnum; /** * Encapsulates a Character Set ECI, according to "Extended Channel Interpretations" 5.3.1.1 of ISO 18004. - * - * @method static self CP437() - * @method static self ISO8859_1() - * @method static self ISO8859_2() - * @method static self ISO8859_3() - * @method static self ISO8859_4() - * @method static self ISO8859_5() - * @method static self ISO8859_6() - * @method static self ISO8859_7() - * @method static self ISO8859_8() - * @method static self ISO8859_9() - * @method static self ISO8859_10() - * @method static self ISO8859_11() - * @method static self ISO8859_12() - * @method static self ISO8859_13() - * @method static self ISO8859_14() - * @method static self ISO8859_15() - * @method static self ISO8859_16() - * @method static self SJIS() - * @method static self CP1250() - * @method static self CP1251() - * @method static self CP1252() - * @method static self CP1256() - * @method static self UNICODE_BIG_UNMARKED() - * @method static self UTF8() - * @method static self ASCII() - * @method static self BIG5() - * @method static self GB18030() - * @method static self EUC_KR() */ -final class CharacterSetEci extends AbstractEnum +enum CharacterSetEci { - protected const CP437 = [[0, 2]]; - protected const ISO8859_1 = [[1, 3], 'ISO-8859-1']; - protected const ISO8859_2 = [[4], 'ISO-8859-2']; - protected const ISO8859_3 = [[5], 'ISO-8859-3']; - protected const ISO8859_4 = [[6], 'ISO-8859-4']; - protected const ISO8859_5 = [[7], 'ISO-8859-5']; - protected const ISO8859_6 = [[8], 'ISO-8859-6']; - protected const ISO8859_7 = [[9], 'ISO-8859-7']; - protected const ISO8859_8 = [[10], 'ISO-8859-8']; - protected const ISO8859_9 = [[11], 'ISO-8859-9']; - protected const ISO8859_10 = [[12], 'ISO-8859-10']; - protected const ISO8859_11 = [[13], 'ISO-8859-11']; - protected const ISO8859_12 = [[14], 'ISO-8859-12']; - protected const ISO8859_13 = [[15], 'ISO-8859-13']; - protected const ISO8859_14 = [[16], 'ISO-8859-14']; - protected const ISO8859_15 = [[17], 'ISO-8859-15']; - protected const ISO8859_16 = [[18], 'ISO-8859-16']; - protected const SJIS = [[20], 'Shift_JIS']; - protected const CP1250 = [[21], 'windows-1250']; - protected const CP1251 = [[22], 'windows-1251']; - protected const CP1252 = [[23], 'windows-1252']; - protected const CP1256 = [[24], 'windows-1256']; - protected const UNICODE_BIG_UNMARKED = [[25], 'UTF-16BE', 'UnicodeBig']; - protected const UTF8 = [[26], 'UTF-8']; - protected const ASCII = [[27, 170], 'US-ASCII']; - protected const BIG5 = [[28]]; - protected const GB18030 = [[29], 'GB2312', 'EUC_CN', 'GBK']; - protected const EUC_KR = [[30], 'EUC-KR']; + case CP437; + case ISO8859_1; + case ISO8859_2; + case ISO8859_3; + case ISO8859_4; + case ISO8859_5; + case ISO8859_6; + case ISO8859_7; + case ISO8859_8; + case ISO8859_9; + case ISO8859_10; + case ISO8859_11; + case ISO8859_12; + case ISO8859_13; + case ISO8859_14; + case ISO8859_15; + case ISO8859_16; + case SJIS; + case CP1250; + case CP1251; + case CP1252; + case CP1256; + case UNICODE_BIG_UNMARKED; + case UTF8; + case ASCII; + case BIG5; + case GB18030; + case EUC_KR; /** - * @var string[] - */ - private array $otherEncodingNames; - - /** - * @var array|null - */ - private static ?array $valueToEci; - - /** - * @var array|null + * Returns the ECI values for this character set. + * + * @return int[] */ - private static ?array $nameToEci = null; + public function getValues() : array + { + return match ($this) { + self::CP437 => [0, 2], + self::ISO8859_1 => [1, 3], + self::ISO8859_2 => [4], + self::ISO8859_3 => [5], + self::ISO8859_4 => [6], + self::ISO8859_5 => [7], + self::ISO8859_6 => [8], + self::ISO8859_7 => [9], + self::ISO8859_8 => [10], + self::ISO8859_9 => [11], + self::ISO8859_10 => [12], + self::ISO8859_11 => [13], + self::ISO8859_12 => [14], + self::ISO8859_13 => [15], + self::ISO8859_14 => [16], + self::ISO8859_15 => [17], + self::ISO8859_16 => [18], + self::SJIS => [20], + self::CP1250 => [21], + self::CP1251 => [22], + self::CP1252 => [23], + self::CP1256 => [24], + self::UNICODE_BIG_UNMARKED => [25], + self::UTF8 => [26], + self::ASCII => [27, 170], + self::BIG5 => [28], + self::GB18030 => [29], + self::EUC_KR => [30], + }; + } /** - * @param int[] $values + * Returns the primary value. */ - public function __construct(private readonly array $values, string ...$otherEncodingNames) + public function getValue() : int { - $this->otherEncodingNames = $otherEncodingNames; + return $this->getValues()[0]; } /** - * Returns the primary value. + * Returns the other encoding names for this character set. + * + * @return string[] */ - public function getValue() : int + public function getOtherEncodingNames() : array { - return $this->values[0]; + return match ($this) { + self::ISO8859_1 => ['ISO-8859-1'], + self::ISO8859_2 => ['ISO-8859-2'], + self::ISO8859_3 => ['ISO-8859-3'], + self::ISO8859_4 => ['ISO-8859-4'], + self::ISO8859_5 => ['ISO-8859-5'], + self::ISO8859_6 => ['ISO-8859-6'], + self::ISO8859_7 => ['ISO-8859-7'], + self::ISO8859_8 => ['ISO-8859-8'], + self::ISO8859_9 => ['ISO-8859-9'], + self::ISO8859_10 => ['ISO-8859-10'], + self::ISO8859_11 => ['ISO-8859-11'], + self::ISO8859_12 => ['ISO-8859-12'], + self::ISO8859_13 => ['ISO-8859-13'], + self::ISO8859_14 => ['ISO-8859-14'], + self::ISO8859_15 => ['ISO-8859-15'], + self::ISO8859_16 => ['ISO-8859-16'], + self::SJIS => ['Shift_JIS'], + self::CP1250 => ['windows-1250'], + self::CP1251 => ['windows-1251'], + self::CP1252 => ['windows-1252'], + self::CP1256 => ['windows-1256'], + self::UNICODE_BIG_UNMARKED => ['UTF-16BE', 'UnicodeBig'], + self::UTF8 => ['UTF-8'], + self::ASCII => ['US-ASCII'], + self::GB18030 => ['GB2312', 'EUC_CN', 'GBK'], + self::EUC_KR => ['EUC-KR'], + default => [], + }; } /** @@ -141,37 +165,41 @@ public static function getCharacterSetEciByName(string $name) : ?self private static function valueToEci() : array { - if (null !== self::$valueToEci) { - return self::$valueToEci; + static $cache = null; + + if (null !== $cache) { + return $cache; } - self::$valueToEci = []; + $cache = []; - foreach (self::values() as $eci) { - foreach ($eci->values as $value) { - self::$valueToEci[$value] = $eci; + foreach (self::cases() as $eci) { + foreach ($eci->getValues() as $value) { + $cache[$value] = $eci; } } - return self::$valueToEci; + return $cache; } private static function nameToEci() : array { - if (null !== self::$nameToEci) { - return self::$nameToEci; + static $cache = null; + + if (null !== $cache) { + return $cache; } - self::$nameToEci = []; + $cache = []; - foreach (self::values() as $eci) { - self::$nameToEci[strtolower($eci->name())] = $eci; + foreach (self::cases() as $eci) { + $cache[strtolower($eci->name)] = $eci; - foreach ($eci->otherEncodingNames as $name) { - self::$nameToEci[strtolower($name)] = $eci; + foreach ($eci->getOtherEncodingNames() as $name) { + $cache[strtolower($name)] = $eci; } } - return self::$nameToEci; + return $cache; } } diff --git a/src/Common/ErrorCorrectionLevel.php b/src/Common/ErrorCorrectionLevel.php index ac84d66f..123cf8c2 100644 --- a/src/Common/ErrorCorrectionLevel.php +++ b/src/Common/ErrorCorrectionLevel.php @@ -4,47 +4,33 @@ namespace BaconQrCode\Common; use BaconQrCode\Exception\OutOfBoundsException; -use DASPRiD\Enum\AbstractEnum; /** * Enum representing the four error correction levels. - * - * @method static self L() ~7% correction - * @method static self M() ~15% correction - * @method static self Q() ~25% correction - * @method static self H() ~30% correction */ -final class ErrorCorrectionLevel extends AbstractEnum +enum ErrorCorrectionLevel { - protected const L = [0x01]; - protected const M = [0x00]; - protected const Q = [0x03]; - protected const H = [0x02]; - - protected function __construct(private readonly int $bits) - { - } + /** ~7% correction */ + case L; + /** ~15% correction */ + case M; + /** ~25% correction */ + case Q; + /** ~30% correction */ + case H; /** * @throws OutOfBoundsException if number of bits is invalid */ public static function forBits(int $bits) : self { - switch ($bits) { - case 0: - return self::M(); - - case 1: - return self::L(); - - case 2: - return self::H(); - - case 3: - return self::Q(); - } - - throw new OutOfBoundsException('Invalid number of bits'); + return match ($bits) { + 0 => self::M, + 1 => self::L, + 2 => self::H, + 3 => self::Q, + default => throw new OutOfBoundsException('Invalid number of bits'), + }; } /** @@ -52,6 +38,26 @@ public static function forBits(int $bits) : self */ public function getBits() : int { - return $this->bits; + return match ($this) { + self::L => 0x01, + self::M => 0x00, + self::Q => 0x03, + self::H => 0x02, + }; + } + + /** + * Returns the ordinal index of this error correction level. + * + * The order matches the order in which EC blocks are stored in Version: L=0, M=1, Q=2, H=3. + */ + public function ordinal() : int + { + return match ($this) { + self::L => 0, + self::M => 1, + self::Q => 2, + self::H => 3, + }; } } diff --git a/src/Common/Mode.php b/src/Common/Mode.php index f5fb1537..17d8af11 100644 --- a/src/Common/Mode.php +++ b/src/Common/Mode.php @@ -3,43 +3,21 @@ namespace BaconQrCode\Common; -use DASPRiD\Enum\AbstractEnum; - /** * Enum representing various modes in which data can be encoded to bits. - * - * @method static self TERMINATOR() - * @method static self NUMERIC() - * @method static self ALPHANUMERIC() - * @method static self STRUCTURED_APPEND() - * @method static self BYTE() - * @method static self ECI() - * @method static self KANJI() - * @method static self FNC1_FIRST_POSITION() - * @method static self FNC1_SECOND_POSITION() - * @method static self HANZI() */ -final class Mode extends AbstractEnum +enum Mode { - protected const TERMINATOR = [[0, 0, 0], 0x00]; - protected const NUMERIC = [[10, 12, 14], 0x01]; - protected const ALPHANUMERIC = [[9, 11, 13], 0x02]; - protected const STRUCTURED_APPEND = [[0, 0, 0], 0x03]; - protected const BYTE = [[8, 16, 16], 0x04]; - protected const ECI = [[0, 0, 0], 0x07]; - protected const KANJI = [[8, 10, 12], 0x08]; - protected const FNC1_FIRST_POSITION = [[0, 0, 0], 0x05]; - protected const FNC1_SECOND_POSITION = [[0, 0, 0], 0x09]; - protected const HANZI = [[8, 10, 12], 0x0d]; - - /** - * @param int[] $characterCountBitsForVersions - */ - protected function __construct( - private readonly array $characterCountBitsForVersions, - private readonly int $bits - ) { - } + case TERMINATOR; + case NUMERIC; + case ALPHANUMERIC; + case STRUCTURED_APPEND; + case BYTE; + case ECI; + case KANJI; + case FNC1_FIRST_POSITION; + case FNC1_SECOND_POSITION; + case HANZI; /** * Returns the number of bits used in a specific QR code version. @@ -56,7 +34,14 @@ public function getCharacterCountBits(Version $version) : int $offset = 2; } - return $this->characterCountBitsForVersions[$offset]; + return match ($this) { + self::TERMINATOR, self::STRUCTURED_APPEND, self::ECI, + self::FNC1_FIRST_POSITION, self::FNC1_SECOND_POSITION => [0, 0, 0][$offset], + self::NUMERIC => [10, 12, 14][$offset], + self::ALPHANUMERIC => [9, 11, 13][$offset], + self::BYTE => [8, 16, 16][$offset], + self::KANJI, self::HANZI => [8, 10, 12][$offset], + }; } /** @@ -64,6 +49,17 @@ public function getCharacterCountBits(Version $version) : int */ public function getBits() : int { - return $this->bits; + return match ($this) { + self::TERMINATOR => 0x00, + self::NUMERIC => 0x01, + self::ALPHANUMERIC => 0x02, + self::STRUCTURED_APPEND => 0x03, + self::BYTE => 0x04, + self::FNC1_FIRST_POSITION => 0x05, + self::ECI => 0x07, + self::KANJI => 0x08, + self::FNC1_SECOND_POSITION => 0x09, + self::HANZI => 0x0d, + }; } } diff --git a/src/Encoder/Encoder.php b/src/Encoder/Encoder.php index a7e00ff2..787257bc 100644 --- a/src/Encoder/Encoder.php +++ b/src/Encoder/Encoder.php @@ -70,7 +70,7 @@ public static function encode( $headerBits = new BitArray(); // Append ECI segment if applicable - if ($prefixEci && Mode::BYTE() === $mode && self::DEFAULT_BYTE_MODE_ENCODING !== $encoding) { + if ($prefixEci && Mode::BYTE === $mode && self::DEFAULT_BYTE_MODE_ENCODING !== $encoding) { $eci = CharacterSetEci::getCharacterSetEciByName($encoding); if (null !== $eci) { @@ -121,9 +121,9 @@ public static function encode( // Find "length" of main segment and write it. $numLetters = match ($mode) { - Mode::BYTE() => $dataBits->getSizeInBytes(), - Mode::NUMERIC(), Mode::ALPHANUMERIC() => strlen($content), - Mode::KANJI() => iconv_strlen($content, 'utf-8'), + Mode::BYTE => $dataBits->getSizeInBytes(), + Mode::NUMERIC, Mode::ALPHANUMERIC => strlen($content), + Mode::KANJI => iconv_strlen($content, 'utf-8'), }; self::appendLengthInfo($numLetters, $version, $mode, $headerAndDataBits); @@ -168,22 +168,22 @@ private static function getAlphanumericCode(int $byte) : int private static function chooseMode(string $content, ?string $encoding = null) : Mode { if ('' === $content) { - return Mode::BYTE(); + return Mode::BYTE; } if (null !== $encoding && 0 === strcasecmp($encoding, 'SHIFT-JIS')) { - return self::isOnlyDoubleByteKanji($content) ? Mode::KANJI() : Mode::BYTE(); + return self::isOnlyDoubleByteKanji($content) ? Mode::KANJI : Mode::BYTE; } if (ctype_digit($content)) { - return Mode::NUMERIC(); + return Mode::NUMERIC; } if (self::isOnlyAlphanumeric($content)) { - return Mode::ALPHANUMERIC(); + return Mode::ALPHANUMERIC; } - return Mode::BYTE(); + return Mode::BYTE; } /** @@ -521,10 +521,10 @@ private static function appendLengthInfo(int $numLetters, Version $version, Mode private static function appendBytes(string $content, Mode $mode, BitArray $bits, string $encoding) : void { match ($mode) { - Mode::NUMERIC() => self::appendNumericBytes($content, $bits), - Mode::ALPHANUMERIC() => self::appendAlphanumericBytes($content, $bits), - Mode::BYTE() => self::append8BitBytes($content, $bits, $encoding), - Mode::KANJI() => self::appendKanjiBytes($content, $bits), + Mode::NUMERIC => self::appendNumericBytes($content, $bits), + Mode::ALPHANUMERIC => self::appendAlphanumericBytes($content, $bits), + Mode::BYTE => self::append8BitBytes($content, $bits, $encoding), + Mode::KANJI => self::appendKanjiBytes($content, $bits), }; } @@ -659,7 +659,7 @@ private static function appendKanjiBytes(string $content, BitArray $bits) : void */ private static function appendEci(CharacterSetEci $eci, BitArray $bits) : void { - $mode = Mode::ECI(); + $mode = Mode::ECI; $bits->appendBits($mode->getBits(), 4); $bits->appendBits($eci->getValue(), 8); } diff --git a/src/Encoder/QrCode.php b/src/Encoder/QrCode.php index c3398f40..61febe10 100644 --- a/src/Encoder/QrCode.php +++ b/src/Encoder/QrCode.php @@ -89,8 +89,8 @@ public static function isValidMaskPattern(int $maskPattern) : bool public function __toString() : string { $result = "<<\n" - . ' mode: ' . $this->mode . "\n" - . ' ecLevel: ' . $this->errorCorrectionLevel . "\n" + . ' mode: ' . $this->mode->name . "\n" + . ' ecLevel: ' . $this->errorCorrectionLevel->name . "\n" . ' version: ' . $this->version . "\n" . ' maskPattern: ' . $this->maskPattern . "\n"; diff --git a/src/Renderer/Image/EpsImageBackEnd.php b/src/Renderer/Image/EpsImageBackEnd.php index 42694561..d1e6f8d3 100644 --- a/src/Renderer/Image/EpsImageBackEnd.php +++ b/src/Renderer/Image/EpsImageBackEnd.php @@ -242,7 +242,7 @@ private function createGradientFill(Gradient $gradient, float $x, float $y, floa $this->eps .= "eoclip\n<<\n"; - if ($gradient->getType() === GradientType::RADIAL()) { + if ($gradient->getType() === GradientType::RADIAL) { $this->eps .= " /ShadingType 3\n"; } else { $this->eps .= " /ShadingType 2\n"; @@ -251,75 +251,53 @@ private function createGradientFill(Gradient $gradient, float $x, float $y, floa $this->eps .= " /Extend [ true true ]\n" . " /AntiAlias true\n"; - switch ($startColorType) { - case Cmyk::class: - $this->eps .= " /ColorSpace /DeviceCMYK\n"; - break; - - case Rgb::class: - $this->eps .= " /ColorSpace /DeviceRGB\n"; - break; - - case Gray::class: - $this->eps .= " /ColorSpace /DeviceGray\n"; - break; - } - - switch ($gradient->getType()) { - case GradientType::HORIZONTAL(): - $this->eps .= sprintf( - " /Coords [ %s %s %s %s ]\n", - round($x, self::PRECISION), - round($y, self::PRECISION), - round($x + $width, self::PRECISION), - round($y, self::PRECISION) - ); - break; - - case GradientType::VERTICAL(): - $this->eps .= sprintf( - " /Coords [ %s %s %s %s ]\n", - round($x, self::PRECISION), - round($y, self::PRECISION), - round($x, self::PRECISION), - round($y + $height, self::PRECISION) - ); - break; - - case GradientType::DIAGONAL(): - $this->eps .= sprintf( - " /Coords [ %s %s %s %s ]\n", - round($x, self::PRECISION), - round($y, self::PRECISION), - round($x + $width, self::PRECISION), - round($y + $height, self::PRECISION) - ); - break; - - case GradientType::INVERSE_DIAGONAL(): - $this->eps .= sprintf( - " /Coords [ %s %s %s %s ]\n", - round($x, self::PRECISION), - round($y + $height, self::PRECISION), - round($x + $width, self::PRECISION), - round($y, self::PRECISION) - ); - break; - - case GradientType::RADIAL(): - $centerX = ($x + $width) / 2; - $centerY = ($y + $height) / 2; - - $this->eps .= sprintf( - " /Coords [ %s %s 0 %s %s %s ]\n", - round($centerX, self::PRECISION), - round($centerY, self::PRECISION), - round($centerX, self::PRECISION), - round($centerY, self::PRECISION), - round(max($width, $height) / 2, self::PRECISION) - ); - break; - } + $this->eps .= match ($startColorType) { + Cmyk::class => " /ColorSpace /DeviceCMYK\n", + Rgb::class => " /ColorSpace /DeviceRGB\n", + Gray::class => " /ColorSpace /DeviceGray\n", + }; + + $centerX = ($x + $width) / 2; + $centerY = ($y + $height) / 2; + + $this->eps .= match ($gradient->getType()) { + GradientType::HORIZONTAL => sprintf( + " /Coords [ %s %s %s %s ]\n", + round($x, self::PRECISION), + round($y, self::PRECISION), + round($x + $width, self::PRECISION), + round($y, self::PRECISION) + ), + GradientType::VERTICAL => sprintf( + " /Coords [ %s %s %s %s ]\n", + round($x, self::PRECISION), + round($y, self::PRECISION), + round($x, self::PRECISION), + round($y + $height, self::PRECISION) + ), + GradientType::DIAGONAL => sprintf( + " /Coords [ %s %s %s %s ]\n", + round($x, self::PRECISION), + round($y, self::PRECISION), + round($x + $width, self::PRECISION), + round($y + $height, self::PRECISION) + ), + GradientType::INVERSE_DIAGONAL => sprintf( + " /Coords [ %s %s %s %s ]\n", + round($x, self::PRECISION), + round($y + $height, self::PRECISION), + round($x + $width, self::PRECISION), + round($y, self::PRECISION) + ), + GradientType::RADIAL => sprintf( + " /Coords [ %s %s 0 %s %s %s ]\n", + round($centerX, self::PRECISION), + round($centerY, self::PRECISION), + round($centerX, self::PRECISION), + round($centerY, self::PRECISION), + round(max($width, $height) / 2, self::PRECISION) + ), + }; $this->eps .= " /Function\n" . " <<\n" diff --git a/src/Renderer/Image/ImagickImageBackEnd.php b/src/Renderer/Image/ImagickImageBackEnd.php index a16a6638..a817c460 100644 --- a/src/Renderer/Image/ImagickImageBackEnd.php +++ b/src/Renderer/Image/ImagickImageBackEnd.php @@ -216,7 +216,7 @@ private function createGradientFill(Gradient $gradient, float $x, float $y, floa $gradientImage = new Imagick(); switch ($gradient->getType()) { - case GradientType::HORIZONTAL(): + case GradientType::HORIZONTAL: $gradientImage->newPseudoImage((int) $height, (int) $width, sprintf( 'gradient:%s-%s', $startColor, @@ -225,7 +225,7 @@ private function createGradientFill(Gradient $gradient, float $x, float $y, floa $gradientImage->rotateImage('transparent', -90); break; - case GradientType::VERTICAL(): + case GradientType::VERTICAL: $gradientImage->newPseudoImage((int) $width, (int) $height, sprintf( 'gradient:%s-%s', $startColor, @@ -233,15 +233,15 @@ private function createGradientFill(Gradient $gradient, float $x, float $y, floa )); break; - case GradientType::DIAGONAL(): - case GradientType::INVERSE_DIAGONAL(): + case GradientType::DIAGONAL: + case GradientType::INVERSE_DIAGONAL: $gradientImage->newPseudoImage((int) ($width * sqrt(2)), (int) ($height * sqrt(2)), sprintf( 'gradient:%s-%s', $startColor, $endColor )); - if (GradientType::DIAGONAL() === $gradient->getType()) { + if (GradientType::DIAGONAL === $gradient->getType()) { $gradientImage->rotateImage('transparent', -45); } else { $gradientImage->rotateImage('transparent', -135); @@ -259,7 +259,7 @@ private function createGradientFill(Gradient $gradient, float $x, float $y, floa ); break; - case GradientType::RADIAL(): + case GradientType::RADIAL: $gradientImage->newPseudoImage((int) $width, (int) $height, sprintf( 'radial-gradient:%s-%s', $startColor, diff --git a/src/Renderer/Image/SvgImageBackEnd.php b/src/Renderer/Image/SvgImageBackEnd.php index dfcd5bdd..457b433b 100644 --- a/src/Renderer/Image/SvgImageBackEnd.php +++ b/src/Renderer/Image/SvgImageBackEnd.php @@ -270,7 +270,7 @@ private function createGradientFill(Gradient $gradient, float $x, float $y, floa $startColor = $gradient->getStartColor(); $endColor = $gradient->getEndColor(); - if ($gradient->getType() === GradientType::RADIAL()) { + if ($gradient->getType() === GradientType::RADIAL) { $this->xmlWriter->startElement('radialGradient'); } else { $this->xmlWriter->startElement('linearGradient'); @@ -278,43 +278,36 @@ private function createGradientFill(Gradient $gradient, float $x, float $y, floa $this->xmlWriter->writeAttribute('gradientUnits', 'userSpaceOnUse'); - switch ($gradient->getType()) { - case GradientType::HORIZONTAL(): - $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION)); - $this->xmlWriter->writeAttribute('y1', (string) round($y, self::PRECISION)); - $this->xmlWriter->writeAttribute('x2', (string) round($x + $width, self::PRECISION)); - $this->xmlWriter->writeAttribute('y2', (string) round($y, self::PRECISION)); - break; - - case GradientType::VERTICAL(): - $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION)); - $this->xmlWriter->writeAttribute('y1', (string) round($y, self::PRECISION)); - $this->xmlWriter->writeAttribute('x2', (string) round($x, self::PRECISION)); - $this->xmlWriter->writeAttribute('y2', (string) round($y + $height, self::PRECISION)); - break; - - case GradientType::DIAGONAL(): - $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION)); - $this->xmlWriter->writeAttribute('y1', (string) round($y, self::PRECISION)); - $this->xmlWriter->writeAttribute('x2', (string) round($x + $width, self::PRECISION)); - $this->xmlWriter->writeAttribute('y2', (string) round($y + $height, self::PRECISION)); - break; - - case GradientType::INVERSE_DIAGONAL(): - $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION)); - $this->xmlWriter->writeAttribute('y1', (string) round($y + $height, self::PRECISION)); - $this->xmlWriter->writeAttribute('x2', (string) round($x + $width, self::PRECISION)); - $this->xmlWriter->writeAttribute('y2', (string) round($y, self::PRECISION)); - break; - - case GradientType::RADIAL(): - $this->xmlWriter->writeAttribute('cx', (string) round(($x + $width) / 2, self::PRECISION)); - $this->xmlWriter->writeAttribute('cy', (string) round(($y + $height) / 2, self::PRECISION)); - $this->xmlWriter->writeAttribute('r', (string) round(max($width, $height) / 2, self::PRECISION)); - break; + $attributes = match ($gradient->getType()) { + GradientType::HORIZONTAL => [ + 'x1' => $x, 'y1' => $y, + 'x2' => $x + $width, 'y2' => $y, + ], + GradientType::VERTICAL => [ + 'x1' => $x, 'y1' => $y, + 'x2' => $x, 'y2' => $y + $height, + ], + GradientType::DIAGONAL => [ + 'x1' => $x, 'y1' => $y, + 'x2' => $x + $width, 'y2' => $y + $height, + ], + GradientType::INVERSE_DIAGONAL => [ + 'x1' => $x, 'y1' => $y + $height, + 'x2' => $x + $width, 'y2' => $y, + ], + GradientType::RADIAL => [ + 'cx' => ($x + $width) / 2, 'cy' => ($y + $height) / 2, + 'r' => max($width, $height) / 2, + ], + }; + + foreach ($attributes as $name => $value) { + $this->xmlWriter->writeAttribute($name, (string) round($value, self::PRECISION)); } - $toBeHashed = $this->getColorString($startColor) . $this->getColorString($endColor) . $gradient->getType(); + $toBeHashed = $this->getColorString($startColor) + . $this->getColorString($endColor) + . $gradient->getType()->name; if ($startColor instanceof Alpha) { $toBeHashed .= (string) $startColor->getAlpha(); } diff --git a/src/Renderer/RendererStyle/GradientType.php b/src/Renderer/RendererStyle/GradientType.php index c1ca7547..bfa9afdb 100644 --- a/src/Renderer/RendererStyle/GradientType.php +++ b/src/Renderer/RendererStyle/GradientType.php @@ -3,20 +3,11 @@ namespace BaconQrCode\Renderer\RendererStyle; -use DASPRiD\Enum\AbstractEnum; - -/** - * @method static self VERTICAL() - * @method static self HORIZONTAL() - * @method static self DIAGONAL() - * @method static self INVERSE_DIAGONAL() - * @method static self RADIAL() - */ -final class GradientType extends AbstractEnum +enum GradientType { - protected const VERTICAL = null; - protected const HORIZONTAL = null; - protected const DIAGONAL = null; - protected const INVERSE_DIAGONAL = null; - protected const RADIAL = null; + case VERTICAL; + case HORIZONTAL; + case DIAGONAL; + case INVERSE_DIAGONAL; + case RADIAL; } diff --git a/src/Writer.php b/src/Writer.php index d7f7ebb6..35f644a7 100644 --- a/src/Writer.php +++ b/src/Writer.php @@ -40,7 +40,7 @@ public function writeString( } if (null === $ecLevel) { - $ecLevel = ErrorCorrectionLevel::L(); + $ecLevel = ErrorCorrectionLevel::L; } return $this->renderer->render(Encoder::encode($content, $ecLevel, $encoding, $forcedVersion)); diff --git a/test/Common/ErrorCorrectionLevelTest.php b/test/Common/ErrorCorrectionLevelTest.php index 369b5d91..9692055e 100644 --- a/test/Common/ErrorCorrectionLevelTest.php +++ b/test/Common/ErrorCorrectionLevelTest.php @@ -11,10 +11,10 @@ class ErrorCorrectionLevelTest extends TestCase { public function testBitsMatchConstants() : void { - $this->assertSame(0x0, ErrorCorrectionLevel::M()->getBits()); - $this->assertSame(0x1, ErrorCorrectionLevel::L()->getBits()); - $this->assertSame(0x2, ErrorCorrectionLevel::H()->getBits()); - $this->assertSame(0x3, ErrorCorrectionLevel::Q()->getBits()); + $this->assertSame(0x0, ErrorCorrectionLevel::M->getBits()); + $this->assertSame(0x1, ErrorCorrectionLevel::L->getBits()); + $this->assertSame(0x2, ErrorCorrectionLevel::H->getBits()); + $this->assertSame(0x3, ErrorCorrectionLevel::Q->getBits()); } public function testInvalidErrorCorrectionLevelThrowsException() : void diff --git a/test/Common/FormatInformationTest.php b/test/Common/FormatInformationTest.php index 39534a24..8724671f 100644 --- a/test/Common/FormatInformationTest.php +++ b/test/Common/FormatInformationTest.php @@ -29,7 +29,7 @@ public function testDecode() : void $this->assertNotNull($expected); $this->assertSame(7, $expected->getDataMask()); - $this->assertSame(ErrorCorrectionLevel::Q(), $expected->getErrorCorrectionLevel()); + $this->assertSame(ErrorCorrectionLevel::Q, $expected->getErrorCorrectionLevel()); $this->assertEquals( $expected, diff --git a/test/Common/ModeTest.php b/test/Common/ModeTest.php index 51fcb3eb..09324b88 100644 --- a/test/Common/ModeTest.php +++ b/test/Common/ModeTest.php @@ -10,10 +10,10 @@ class ModeTest extends TestCase { public function testBitsMatchConstants() : void { - $this->assertSame(0x0, Mode::TERMINATOR()->getBits()); - $this->assertSame(0x1, Mode::NUMERIC()->getBits()); - $this->assertSame(0x2, Mode::ALPHANUMERIC()->getBits()); - $this->assertSame(0x4, Mode::BYTE()->getBits()); - $this->assertSame(0x8, Mode::KANJI()->getBits()); + $this->assertSame(0x0, Mode::TERMINATOR->getBits()); + $this->assertSame(0x1, Mode::NUMERIC->getBits()); + $this->assertSame(0x2, Mode::ALPHANUMERIC->getBits()); + $this->assertSame(0x4, Mode::BYTE->getBits()); + $this->assertSame(0x8, Mode::KANJI->getBits()); } } diff --git a/test/Common/VersionTest.php b/test/Common/VersionTest.php index 23e03704..878d7495 100644 --- a/test/Common/VersionTest.php +++ b/test/Common/VersionTest.php @@ -47,10 +47,10 @@ public function testVersionForNumber(int $versionNumber, int $dimension) : void } $this->assertEquals($dimension, $version->getDimensionForVersion()); - $this->assertNotNull($version->getEcBlocksForLevel(ErrorCorrectionLevel::H())); - $this->assertNotNull($version->getEcBlocksForLevel(ErrorCorrectionLevel::L())); - $this->assertNotNull($version->getEcBlocksForLevel(ErrorCorrectionLevel::M())); - $this->assertNotNull($version->getEcBlocksForLevel(ErrorCorrectionLevel::Q())); + $this->assertNotNull($version->getEcBlocksForLevel(ErrorCorrectionLevel::H)); + $this->assertNotNull($version->getEcBlocksForLevel(ErrorCorrectionLevel::L)); + $this->assertNotNull($version->getEcBlocksForLevel(ErrorCorrectionLevel::M)); + $this->assertNotNull($version->getEcBlocksForLevel(ErrorCorrectionLevel::Q)); $this->assertNotNull($version->buildFunctionPattern()); } diff --git a/test/Encoder/EncoderTest.php b/test/Encoder/EncoderTest.php index b3bc1eda..66228659 100644 --- a/test/Encoder/EncoderTest.php +++ b/test/Encoder/EncoderTest.php @@ -64,43 +64,43 @@ public function testGetAlphanumericCode() : void public function testChooseMode() : void { // Empty string - $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, '')); - $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, '', 'SHIFT-JIS')); + $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, '')); + $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, '', 'SHIFT-JIS')); // Numeric mode - $this->assertSame(Mode::NUMERIC(), $this->methods['chooseMode']->invoke(null, '0')); - $this->assertSame(Mode::NUMERIC(), $this->methods['chooseMode']->invoke(null, '0123456789')); + $this->assertSame(Mode::NUMERIC, $this->methods['chooseMode']->invoke(null, '0')); + $this->assertSame(Mode::NUMERIC, $this->methods['chooseMode']->invoke(null, '0123456789')); // Alphanumeric mode - $this->assertSame(Mode::ALPHANUMERIC(), $this->methods['chooseMode']->invoke(null, 'A')); + $this->assertSame(Mode::ALPHANUMERIC, $this->methods['chooseMode']->invoke(null, 'A')); $this->assertSame( - Mode::ALPHANUMERIC(), + Mode::ALPHANUMERIC, $this->methods['chooseMode']->invoke(null, '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:') ); // 8-bit byte mode - $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, 'a')); - $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, '#')); + $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, 'a')); + $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, '#')); // AIUE in Hiragana in SHIFT-JIS - $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, "\x8\xa\x8\xa\x8\xa\x8\xa6")); + $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, "\x8\xa\x8\xa\x8\xa\x8\xa6")); // Nihon in Kanji in SHIFT-JIS - $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, "\x9\xf\x9\x7b")); + $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, "\x9\xf\x9\x7b")); // Sou-Utso-Byou in Kanji in SHIFT-JIS - $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, "\xe\x4\x9\x5\x9\x61")); + $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, "\xe\x4\x9\x5\x9\x61")); // SHIFT-JIS encoding, content only consists of double-byte kanji characters - $this->assertSame(Mode::KANJI(), $this->methods['chooseMode']->invoke(null, 'あいうえお', 'SHIFT-JIS')); + $this->assertSame(Mode::KANJI, $this->methods['chooseMode']->invoke(null, 'あいうえお', 'SHIFT-JIS')); // SHIFT-JIS encoding, but content doesn't exclusively consist of kanji characters - $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, 'あいうえお123', 'SHIFT-JIS')); + $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, 'あいうえお123', 'SHIFT-JIS')); } public function testEncode() : void { - $qrCode = Encoder::encode('ABCDEF', ErrorCorrectionLevel::H()); + $qrCode = Encoder::encode('ABCDEF', ErrorCorrectionLevel::H); $expected = "<<\n" . " mode: ALPHANUMERIC\n" . " ecLevel: H\n" @@ -135,7 +135,7 @@ public function testEncode() : void public function testSimpleUtf8Eci() : void { - $qrCode = Encoder::encode('hello', ErrorCorrectionLevel::H(), 'utf-8'); + $qrCode = Encoder::encode('hello', ErrorCorrectionLevel::H, 'utf-8'); $expected = "<<\n" . " mode: BYTE\n" . " ecLevel: H\n" @@ -170,7 +170,7 @@ public function testSimpleUtf8Eci() : void public function testSimpleUtf8WithoutEci() : void { - $qrCode = Encoder::encode('hello', ErrorCorrectionLevel::H(), 'utf-8', null, false); + $qrCode = Encoder::encode('hello', ErrorCorrectionLevel::H, 'utf-8', null, false); $expected = "<<\n" . " mode: BYTE\n" . " ecLevel: H\n" @@ -206,7 +206,7 @@ public function testSimpleUtf8WithoutEci() : void public function testAppendModeInfo() : void { $bits = new BitArray(); - $this->methods['appendModeInfo']->invoke(null, Mode::NUMERIC(), $bits); + $this->methods['appendModeInfo']->invoke(null, Mode::NUMERIC, $bits); $this->assertSame(' ...X', (string) $bits); } @@ -218,7 +218,7 @@ public function testAppendLengthInfo() : void null, 1, Version::getVersionForNumber(1), - Mode::NUMERIC(), + Mode::NUMERIC, $bits ); $this->assertSame(' ........ .X', (string) $bits); @@ -229,7 +229,7 @@ public function testAppendLengthInfo() : void null, 2, Version::getVersionForNumber(10), - Mode::ALPHANUMERIC(), + Mode::ALPHANUMERIC, $bits ); $this->assertSame(' ........ .X.', (string) $bits); @@ -240,7 +240,7 @@ public function testAppendLengthInfo() : void null, 255, Version::getVersionForNumber(27), - Mode::BYTE(), + Mode::BYTE, $bits ); $this->assertSame(' ........ XXXXXXXX', (string) $bits); @@ -251,7 +251,7 @@ public function testAppendLengthInfo() : void null, 512, Version::getVersionForNumber(40), - Mode::KANJI(), + Mode::KANJI, $bits ); $this->assertSame(' ..X..... ....', (string) $bits); @@ -265,7 +265,7 @@ public function testAppendBytes() : void $this->methods['appendBytes']->invoke( null, '1', - Mode::NUMERIC(), + Mode::NUMERIC, $bits, Encoder::DEFAULT_BYTE_MODE_ENCODING ); @@ -277,7 +277,7 @@ public function testAppendBytes() : void $this->methods['appendBytes']->invoke( null, 'A', - Mode::ALPHANUMERIC(), + Mode::ALPHANUMERIC, $bits, Encoder::DEFAULT_BYTE_MODE_ENCODING ); @@ -289,7 +289,7 @@ public function testAppendBytes() : void $this->methods['appendBytes']->invoke( null, 'abc', - Mode::BYTE(), + Mode::BYTE, $bits, Encoder::DEFAULT_BYTE_MODE_ENCODING ); @@ -301,7 +301,7 @@ public function testAppendBytes() : void $this->methods['appendBytes']->invoke( null, '点', - Mode::KANJI(), + Mode::KANJI, $bits, Encoder::DEFAULT_BYTE_MODE_ENCODING ); @@ -312,7 +312,7 @@ public function testAppendBytes() : void $this->methods['appendBytes']->invoke( null, 'a', - Mode::ALPHANUMERIC(), + Mode::ALPHANUMERIC, $bits, Encoder::DEFAULT_BYTE_MODE_ENCODING ); diff --git a/test/Encoder/MatrixUtilTest.php b/test/Encoder/MatrixUtilTest.php index a0fcc63d..67f05ca3 100644 --- a/test/Encoder/MatrixUtilTest.php +++ b/test/Encoder/MatrixUtilTest.php @@ -135,7 +135,7 @@ public function testEmbedTypeInfo() : void MatrixUtil::clearMatrix($matrix); $this->methods['embedTypeInfo']->invoke( null, - ErrorCorrectionLevel::M(), + ErrorCorrectionLevel::M, 5, $matrix ); @@ -256,7 +256,7 @@ public function testBuildMatrix() : void $matrix = new ByteMatrix(21, 21); MatrixUtil::buildMatrix( $bits, - ErrorCorrectionLevel::H(), + ErrorCorrectionLevel::H, Version::getVersionForNumber(1), 3, $matrix @@ -328,7 +328,7 @@ public function testMakeTypeInfoBits() : void { // From Appendix D in JISX0510:2004 (p 68) $bits = new BitArray(); - $this->methods['makeTypeInfoBits']->invoke(null, ErrorCorrectionLevel::M(), 5, $bits); + $this->methods['makeTypeInfoBits']->invoke(null, ErrorCorrectionLevel::M, 5, $bits); $this->assertSame(' X......X X..XXX.', (string) $bits); } } diff --git a/test/Integration/GDLibRenderingTest.php b/test/Integration/GDLibRenderingTest.php index 8e78e6da..aced6f4d 100644 --- a/test/Integration/GDLibRenderingTest.php +++ b/test/Integration/GDLibRenderingTest.php @@ -74,7 +74,7 @@ public function testFailsOnGradient(): void 9, Fill::withForegroundGradient( new Alpha(25, new Rgb(0, 0, 0)), - new Gradient(new Rgb(255, 255, 0), new Rgb(255, 0, 255), GradientType::DIAGONAL()), + new Gradient(new Rgb(255, 255, 0), new Rgb(255, 0, 255), GradientType::DIAGONAL), new EyeFill(new Rgb(220, 50, 50), new Alpha(50, new Rgb(220, 50, 50))), new EyeFill(new Rgb(50, 220, 50), new Alpha(50, new Rgb(50, 220, 50))), new EyeFill(new Rgb(50, 50, 220), new Alpha(50, new Rgb(50, 50, 220))), diff --git a/test/Integration/ImagickRenderingTest.php b/test/Integration/ImagickRenderingTest.php index f51e7ebd..e67e4546 100644 --- a/test/Integration/ImagickRenderingTest.php +++ b/test/Integration/ImagickRenderingTest.php @@ -47,7 +47,7 @@ public function testIssue79() : void $squareModule = SquareModule::instance(); $eyeFill = new EyeFill(new Rgb(100, 100, 55), new Rgb(100, 100, 255)); - $gradient = new Gradient(new Rgb(100, 100, 55), new Rgb(100, 100, 255), GradientType::HORIZONTAL()); + $gradient = new Gradient(new Rgb(100, 100, 55), new Rgb(100, 100, 255), GradientType::HORIZONTAL); $renderer = new ImageRenderer( new RendererStyle( diff --git a/test/Integration/SVGRenderingTest.php b/test/Integration/SVGRenderingTest.php index 16559508..c776de36 100644 --- a/test/Integration/SVGRenderingTest.php +++ b/test/Integration/SVGRenderingTest.php @@ -36,13 +36,13 @@ public function testGenericQrCode(): void public function testQrWithGradientGeneratesDifferentIdsForDifferentGradients() { - $types = ['HORIZONTAL', 'VERTICAL']; + $types = [GradientType::HORIZONTAL, GradientType::VERTICAL]; foreach ($types as $type) { $gradient = new Gradient( new Rgb(0, 0, 0), new Rgb(255, 0, 0), - GradientType::$type() + $type ); $renderer = new ImageRenderer( new RendererStyle(