Skip to content

Commit 7258567

Browse files
committed
Support ECI values above 127
1 parent 0552841 commit 7258567

5 files changed

Lines changed: 50 additions & 12 deletions

File tree

docs/integrity.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
index.mjs: sha384-t+Srr58g0YdXYGilymfaxMFvFMy3OMPIuKCEo67AZhCKKYzbZqqucoONAzov+InR
2-
index.js: sha384-891dmJ3O6EdTEMN6Evag5DoSXKE2KDyKeN39Hab3a6Gilh3TGzGxr+y08FHuyE3h
1+
index.mjs: sha384-m4b9mo8rku6/YQbV1e52UTglSzniaJVeyuq4NnpxRZtq9UrxWXKj+/Mx9MvtPRhK
2+
index.js: sha384-jh47I3nzhofHfyfvgZFdmqUk4CYrsTIaq9LwhVmsWOFiX88x2h46P06/aDeaEtXp
33
nano.mjs: sha384-avNlMHLjqxeTtXysYm13MNj05YYIEl5Fg3itpc7p/JdjS3ULukmDYKaqUMtBj6tT
44
extras/svg.mjs: sha384-Gk8g8nmt6RvyscmK2SxGhYHjrlr8PGRa9CD96IKO9EfLBGE1Wpj/pT8TgbuUXYXM
55
extras/svg.js: sha384-VYnYxwUAQvjDtTiso2ihlfJcfZY60ZgYYdd5YKEO1B4BtZ3P7fxQ5WNuPPG/i8Np
@@ -11,4 +11,4 @@ extras/vue.mjs: sha384-Q4U/qU20x7la3XGJDH1okfzFYN5r+AahC/KAu3xJi5vmOj0GP
1111
extras/vue.js: sha384-lkJRxa/w/MmxmQCuZWCv3qKGlSyuRD86eaGUWktxjO/n7pcUstsLUW2COHlYDYQ4
1212
extras/errors.mjs: sha384-LaUpr3MpI+ZWjDG8L54lwBzgymdm+C1fijP3Z3HukZOFOn3nmRUtgK5aTmOSVm/q
1313
extras/errors.js: sha384-lpwl8zlB1GwhvS1ftgUv4mCvOhlixuRa8fRag2aZ2PEEPKQ++l+IjhZL8lhbZMVe
14-
webcomponent.mjs: sha384-0KyuK0e9WoUF8CmQRrkMY8YIjB8m7PsWKqgPPtJYATOjsmo7LYLfzkaBMts/cj7Y
14+
webcomponent.mjs: sha384-qEnJ44o+q4U5Coy2oSQk+VUSujAopoS0ehKAHURdzOOyw8J+YtxqhAnOwmwV8zlo

docs/stats.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
index.mjs: 6843 bytes / 3636 bytes (compressed)
2-
index.js: 6859 bytes / 3627 bytes (compressed)
1+
index.mjs: 6898 bytes / 3670 bytes (compressed)
2+
index.js: 6914 bytes / 3661 bytes (compressed)
33
nano.mjs: 3763 bytes / 2159 bytes (compressed)
44
extras/svg.mjs: 1333 bytes / 945 bytes (compressed)
55
extras/svg.js: 1350 bytes / 942 bytes (compressed)
@@ -11,4 +11,4 @@ extras/vue.mjs: 1059 bytes / 686 bytes (compressed)
1111
extras/vue.js: 1066 bytes / 684 bytes (compressed)
1212
extras/errors.mjs: 287 bytes / 342 bytes (compressed)
1313
extras/errors.js: 287 bytes / 340 bytes (compressed)
14-
webcomponent.mjs: 8550 bytes / 4396 bytes (compressed)
14+
webcomponent.mjs: 8605 bytes / 4431 bytes (compressed)

src/qr/options/modes.mjs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ const multi =
1111
const eci = (id) => (data) => {
1212
if (data.eci !== id) {
1313
data.push(0b0111, 4);
14-
data.push(id, 8);
14+
if (id < 0x80) {
15+
data.push(id, 8);
16+
} else if (id < 0x4000) {
17+
data.push(0x8000 | id, 16);
18+
} else {
19+
data.push(0xc00000 | id, 24);
20+
}
1521
data.eci = id;
1622
}
1723
};

src/qr/options/modes.test.mjs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,35 @@ describe('mode.utf8', () => {
392392
});
393393
});
394394

395+
describe('mode.eci', () => {
396+
it('stores the ECI ID', () => {
397+
const data = Bitmap1D();
398+
mode.eci(26)(data, 1);
399+
expect(data).toMatchBits(`
400+
0111
401+
0 0011010
402+
`);
403+
});
404+
405+
it('uses 2 bytes for larger ECI IDs', () => {
406+
const data = Bitmap1D();
407+
mode.eci(899)(data, 1);
408+
expect(data).toMatchBits(`
409+
0111
410+
10 000011 10000011
411+
`);
412+
});
413+
414+
it('uses 3 bytes for very large ECI IDs', () => {
415+
const data = Bitmap1D();
416+
mode.eci(16384)(data, 1);
417+
expect(data).toMatchBits(`
418+
0111
419+
110 00000 01000000 00000000
420+
`);
421+
});
422+
});
423+
395424
describe('mode.multi', () => {
396425
it('appends multiple modes in succession', () => {
397426
const data = Bitmap1D();

web/docs/index.html

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -681,10 +681,9 @@ <h5><code>multi(...modes)</code></h5>
681681
<h5><code>eci(value)</code> / <code>bytes(data)</code></h5>
682682
<a id="mode_eci"></a>
683683
<p>
684-
<code>mode.eci</code> lets you switch the Extended Channel Interpretation of the message (<a
685-
href="https://en.wikipedia.org/wiki/Extended_Channel_Interpretation"
686-
target="_blank"
687-
rel="noopener"
684+
<code>mode.eci</code> lets you switch the Extended Channel Interpretation of the message (accepts
685+
integer IDs from 0 to 999999;
686+
<a href="https://en.wikipedia.org/wiki/Extended_Channel_Interpretation" target="_blank" rel="noopener"
688687
>Wikipedia includes a list of recognised values</a
689688
>). After setting this, subsequent <code>mode.bytes</code> will be interpreted in the specified
690689
character set.
@@ -703,6 +702,10 @@ <h5><code>eci(value)</code> / <code>bytes(data)</code></h5>
703702
3 (and even though some default to ECI 26 instead, these share the same codepoints for all ASCII
704703
values).
705704
</p>
705+
<p>
706+
If you wish to use ECI values other than 3 and 26 (which are widely recognised by common QR code
707+
readers), ensure you test your QR code with the readers you want to support.
708+
</p>
706709
<p>
707710
If you set an ECI which is not compatible with ASCII, do not follow it with a
708711
<code>mode.ascii</code> section (prefer <code>mode.iso8859_1</code> or <code>mode.utf8</code>, as these
@@ -1588,7 +1591,7 @@ <h2>Comparison With Other Libraries</h2>
15881591
<a href="https://www.npmjs.com/package/lean-qr" target="_blank" rel="noopener">lean-qr</a>
15891592
<small>(<a href="https://qr.davidje13.com/" target="_blank" rel="noopener">demo</a>)</small>
15901593
</td>
1591-
<td class="R">6.9kB / 3.6kB</td>
1594+
<td class="R">6.9kB / 3.7kB</td>
15921595
<td>2900 / 51 / 21</td>
15931596
<td class="C" title="yes">&#x2705;</td>
15941597
<td class="C" title="yes">&#x2705;</td>

0 commit comments

Comments
 (0)