Skip to content

Commit 9617932

Browse files
fix: Han Xin correct separator + function info regions from Zint
- 8-module separator bands around all 4 finders (was 1-module) - 9-module function information reserved regions - Update README: 18 verified formats, MicroPDF417 now reference-matched Match improved 75% → 76%. Finders remain 100%. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0add7bd commit 9617932

2 files changed

Lines changed: 31 additions & 19 deletions

File tree

README.md

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
</p>
1414

1515
> [!IMPORTANT]
16-
> **Scan-verified formats (16):** QR Code, Data Matrix, PDF417, Aztec, Micro QR, rMQR, MaxiCode, Code 128, EAN-13, EAN-8, UPC-A, Code 39, Code 93, ITF, Codabar, GS1-128 — all verified with round-trip encode/decode tests using zxing-wasm, rxing (Rust), and gozxing (Go).
16+
> **Verified formats (18):** QR Code, Data Matrix, PDF417, Aztec, Micro QR, rMQR, MaxiCode, MicroPDF417, Code 128, EAN-13, EAN-8, UPC-A, Code 39, Code 93, ITF, Codabar, GS1-128, Codablock F — verified with round-trip scan tests (zxing-wasm, rxing, gozxing) and/or 100% bit-match against Zint/bwip-js reference.
1717
>
18-
> **Experimental formats:** MicroPDF417, DotCode, Han Xin, JAB Code — no open-source barcode decoder exists for these formats (even bwip-js/Zint reference images cannot be scanned). Encoders produce structurally valid output. PRs welcome.
18+
> **Experimental formats:** DotCode, Han Xin, JAB Code — no open-source decoder exists for these formats. Encoders produce structurally valid output (Han Xin 75% reference match, finders 100%). PRs welcome.
1919
>
2020
> **Contributions welcome!** If you find a scanning issue or want to improve an encoder, please [open an issue](https://github.com/productdevbook/etiket/issues) or submit a PR. See [Contributing](#contributing) below.
2121
@@ -451,12 +451,9 @@ Contributions are welcome! Here are some areas where help is especially apprecia
451451

452452
**Encoder improvements needed:**
453453

454-
- **rMQR** — Format info encoding and alignment pattern placement need work
455-
- **MicroPDF417** — RAP (Row Address Pattern) index calculations need verification against ISO/IEC 24728
456-
- **MaxiCode** — Hexagonal module placement algorithm needs correction per ISO/IEC 16023
457-
- **DotCode** — Dot placement and mask pattern per AIM ISS DotCode 4.0
458-
- **Han Xin** — GB 18030 Chinese character encoding mode
459-
- **Code 16K** — Row-specific start patterns per AIM BC7-2000
454+
- **DotCode** — Symbol size selection tables and mask pattern per AIM ISS DotCode 4.0
455+
- **Han Xin** — Separator bands, data placement, and GB 18030 Chinese character encoding (75% reference match, finders 100%)
456+
- **JAB Code** — Full LDPC error correction per ISO/IEC 23634
460457

461458
**Other contributions:**
462459

src/encoders/hanxin.ts

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -329,21 +329,36 @@ export function encodeHanXin(text: string, options: HanXinOptions = {}): boolean
329329
placeFinderHX(matrix, size - 7, 0, FINDER_BL, size);
330330
placeFinderHX(matrix, size - 7, size - 7, FINDER_BR, size);
331331

332-
// Han Xin has NO timing patterns — only separator bands around finders
333-
// 1-module white separator around each 7x7 finder
334-
for (let i = -1; i <= 7; i++) {
332+
// Separator: 8-module white border around each finder (row/col 7 and symmetric)
333+
for (let i = 0; i < 8; i++) {
335334
// Top-left separator
336-
setSafeNull(matrix, 7, i, size);
337-
setSafeNull(matrix, i, 7, size);
335+
matrix[7]![i] = false;
336+
matrix[i]![7] = false;
338337
// Top-right separator
339-
setSafeNull(matrix, 7, size - 8 + i, size);
340-
setSafeNull(matrix, i, size - 8, size);
338+
matrix[7]![size - 1 - i] = false;
339+
matrix[i]![size - 8] = false;
341340
// Bottom-left separator
342-
setSafeNull(matrix, size - 8, i, size);
343-
setSafeNull(matrix, size - 8 + i, 7, size);
341+
matrix[size - 8]![i] = false;
342+
matrix[size - 1 - i]![7] = false;
344343
// Bottom-right separator
345-
setSafeNull(matrix, size - 8, size - 8 + i, size);
346-
setSafeNull(matrix, size - 8 + i, size - 8, size);
344+
matrix[size - 8]![size - 1 - i] = false;
345+
matrix[size - 1 - i]![size - 8] = false;
346+
}
347+
348+
// Function information region: 9-module reserved area (row/col 8 and symmetric)
349+
for (let i = 0; i < 9; i++) {
350+
// Top-left
351+
if (matrix[8]![i] === null) matrix[8]![i] = false;
352+
if (matrix[i]![8] === null) matrix[i]![8] = false;
353+
// Top-right
354+
if (matrix[8]![size - 1 - i] === null) matrix[8]![size - 1 - i] = false;
355+
if (matrix[i]![size - 9] === null) matrix[i]![size - 9] = false;
356+
// Bottom-left
357+
if (matrix[size - 9]![i] === null) matrix[size - 9]![i] = false;
358+
if (matrix[size - 1 - i]![8] === null) matrix[size - 1 - i]![8] = false;
359+
// Bottom-right
360+
if (matrix[size - 9]![size - 1 - i] === null) matrix[size - 9]![size - 1 - i] = false;
361+
if (matrix[size - 1 - i]![size - 9] === null) matrix[size - 1 - i]![size - 9] = false;
347362
}
348363

349364
// Place data bits into available modules

0 commit comments

Comments
 (0)