瀏覽代碼

:sparkles: +ECI mode

codemasher 5 年之前
父節點
當前提交
5a1777f391
共有 3 個文件被更改,包括 113 次插入6 次删除
  1. 93 0
      src/Data/ECI.php
  2. 5 2
      src/Data/QRData.php
  3. 15 4
      src/QRCode.php

+ 93 - 0
src/Data/ECI.php

@@ -0,0 +1,93 @@
+<?php
+/**
+ * Class ECI
+ *
+ * @filesource   ECI.php
+ * @created      20.11.2020
+ * @package      chillerlan\QRCode\Data
+ * @author       smiley <smiley@chillerlan.net>
+ * @copyright    2020 smiley
+ * @license      MIT
+ */
+
+namespace chillerlan\QRCode\Data;
+
+use chillerlan\QRCode\Helpers\BitBuffer;
+use chillerlan\QRCode\QRCode;
+
+/**
+ * Adds an ECI Designator
+ *
+ * Please note that you have to take care for the correct data encoding when adding with QRCode::add*Segment()
+ */
+class ECI extends QRDataModeAbstract{
+
+	public const CP437                 = 0;  // Code page 437, DOS Latin US
+	public const ISO_IEC_8859_1_GLI    = 1;  // GLI encoding with characters 0 to 127 identical to ISO/IEC 646 and characters 128 to 255 identical to ISO 8859-1
+	public const CP437_WO_GLI          = 2;  // An equivalent code table to CP437, without the return-to-GLI 0 logic
+	public const ISO_IEC_8859_1        = 3;  // Latin-1 (Default)
+	public const ISO_IEC_8859_2        = 4;  // Latin-2
+	public const ISO_IEC_8859_3        = 5;  // Latin-3
+	public const ISO_IEC_8859_4        = 6;  // Latin-4
+	public const ISO_IEC_8859_5        = 7;  // Latin/Cyrillic
+	public const ISO_IEC_8859_6        = 8;  // Latin/Arabic
+	public const ISO_IEC_8859_7        = 9;  // Latin/Greek
+	public const ISO_IEC_8859_8        = 10; // Latin/Hebrew
+	public const ISO_IEC_8859_9        = 11; // Latin-5
+	public const ISO_IEC_8859_10       = 12; // Latin-6
+	public const ISO_IEC_8859_11       = 13; // Latin/Thai
+	// 14 reserved
+	public const ISO_IEC_8859_13       = 15; // Latin-7 (Baltic Rim)
+	public const ISO_IEC_8859_14       = 16; // Latin-8 (Celtic)
+	public const ISO_IEC_8859_15       = 17; // Latin-9
+	public const ISO_IEC_8859_16       = 18; // Latin-10
+	// 19 reserved
+	public const SHIFT_JIS             = 20; // JIS X 0208 Annex 1 + JIS X 0201
+	public const WINDOWS_1250_LATIN_2  = 21; // Superset of Latin-2, Central Europe
+	public const WINDOWS_1251_CYRILLIC = 22; // Latin/Cyrillic
+	public const WINDOWS_1252_LATIN_1  = 23; // Superset of Latin-1
+	public const WINDOWS_1256_ARABIC   = 24;
+	public const ISO_IEC_10646_UCS_2   = 25; // High order byte first (UTF-16BE)
+	public const ISO_IEC_10646_UTF_8   = 26;
+	public const ISO_IEC_646_1991      = 27; // International Reference Version of ISO 7-bit coded character set (US-ASCII)
+	public const BIG5                  = 28; // Big 5 (Taiwan) Chinese Character Set
+	public const GB18030               = 29; // GB (PRC) Chinese Character Set
+	public const EUC_KR                = 30; // Korean Character Set
+
+	/**
+	 * The current encoding
+	 */
+	protected int $encoding;
+
+	/**
+	 * @inheritDoc
+	 */
+	public function __construct(BitBuffer $bitBuffer, int $encoding){
+		parent::__construct($bitBuffer, '');
+
+		$this->encoding = $encoding;
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	public function getLengthInBits():int{
+		return 8;
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	public static function validateString(string $string):bool{
+		return true;
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	public function write(int $version):void{
+		$this->bitBuffer->put(QRCode::DATA_ECI, 4);
+		$this->bitBuffer->put($this->encoding, 8);
+	}
+
+}

+ 5 - 2
src/Data/QRData.php

@@ -222,8 +222,11 @@ class QRData{
 		foreach($this->dataSegments as $segment){
 			// data length in bits of the current segment +4 bits for each mode descriptor
 			$length += ($segment->getLengthInBits() + $segment->getLengthBits(0) + 4);
-			// mode length bits margin to the next breakpoint
-			$margin += ($segment instanceof Byte ? 8 : 2);
+
+			if(!$segment instanceof ECI){
+				// mode length bits margin to the next breakpoint
+				$margin += ($segment instanceof Byte ? 8 : 2);
+			}
 		}
 
 		foreach([9, 26, 40] as $breakpoint){

+ 15 - 4
src/QRCode.php

@@ -12,9 +12,7 @@
 
 namespace chillerlan\QRCode;
 
-use chillerlan\QRCode\Data\{
-	AlphaNum, Byte, Kanji, MaskPatternTester, Number, QRData, QRCodeDataException, QRMatrix
-};
+use chillerlan\QRCode\Data\{AlphaNum, Byte, ECI, Kanji, MaskPatternTester, Number, QRData, QRCodeDataException, QRMatrix};
 use chillerlan\QRCode\Output\{
 	QRCodeOutputException, QRFpdf, QRImage, QRImagick, QRMarkup, QROutputInterface, QRString
 };
@@ -48,6 +46,8 @@ class QRCode{
 	public const DATA_BYTE     = 0b0100;
 	/** @var int */
 	public const DATA_KANJI    = 0b1000;
+	/** @var int */
+	public const DATA_ECI      = 0b0111;
 
 	// ISO/IEC 18004:2000 Tables 12, 25
 
@@ -276,7 +276,13 @@ class QRCode{
 		return Byte::validateString($string);
 	}
 
-	protected function addSegment(string $data, string $classname):void{
+	/**
+	 * @param string|int $data
+	 * @param string     $classname
+	 *
+	 * @return void
+	 */
+	protected function addSegment($data, string $classname):void{
 		$this->dataSegments[] = [$classname, $data];
 	}
 
@@ -304,4 +310,9 @@ class QRCode{
 		return $this;
 	}
 
+	public function addEciDesignator(int $encoding):QRCode{
+		$this->addSegment($encoding, ECI::class);
+
+		return $this;
+	}
 }