Changelog ********* 0.17 — 2026-07-13 ================= * Data Matrix: new "symbol_shape" option (""square"" default, ""rectangular"", ""auto"", also "--symbol-shape" in the CLI) adds the six rectangular ECC-200 sizes; ""auto"" picks the smallest-area symbol. * Substantial performance improvements across all four 2D symbologies. Compared to 0.16 on a realistic payload corpus: typically ~2.7× faster for QR Code, ~2.2× for PDF417, ~1.3× for Data Matrix (rising to ~2.1× on large payloads), and ~4.7× for Aztec Code — where large payloads, which previously scaled poorly, are up to ~200× faster. * QR Code: the frame, module-placement, mask and error-correction- block data is now constructed at encode time instead of being shipped as 200 pre-computed data files, shrinking the installed package by about 6 MB. * PDF417: automatic column selection now minimises physical symbol area within a scanner-friendly aspect band instead of targeting a square symbol, producing markedly smaller, wider symbols for small and medium payloads. 0.16 — 2026-07-03 ================= * New "ITFEncoder" for plain Interleaved 2 of 5 and "ITF14Encoder" for ITF-14 (GTIN-14), with PNG / SVG / EPS output and a "pystrich itf14" CLI subcommand. See ITF-14. * pyStrich now imports Pillow only when producing PNGs, and PNG support is offered through a "pyStrich[png]" extra; SVG, EPS, DXF and terminal output no longer need it at import time. Pillow remains installed by default in this version. * All encoders: render methods gain "dark_hex" and "light_hex" keywords that recolour the modules or bars and the background consistently across PNG, SVG and EPS. Can also be used in the CLI " --dark-hex" / "--light-hex". * Code 39, Code 128 and ITF: new "quiet_width_multiplier" keyword scales the quiet-zone width. 0.15 — 2026-06-26 ================= * All encoders gain "svg_dataurl" and "png_dataurl" methods that return the symbol as a "data:" URL string. * QR Code: the encoder now mixes Numeric, Alphanumeric and Byte segments per input to shrink symbols carrying digits or uppercase runs. * QR Code: "QRCodeData(encoding="shift_jis")" now triggers Kanji-mode segmentation under ECI 20, packing JIS X 0208 characters into 13 bits each. * QR Code: new "wifi_network()" classmethod helps build WiFi network joining QR codes. * Data Matrix: the encoder now mixes ASCII, C40, Text and X12 segments per input to shrink symbols carrying uppercase, lowercase or CR- delimited X12 records. Payloads built with "FNC1" stay in single- mode ASCII as the GS1 Data Matrix spec requires. * Data Matrix: new "force_byte_mode" keyword on "DataMatrixEncoder" pins the encoder to the byte-by-byte path, skipping the C40/Text/X12 optimiser. * Data Matrix: "iso-8859-1" payloads now emit an explicit ECI 3 designator so heuristic decoders don't misinterpret short Upper- Shift sequences as another charset. * Code 128: new "Code128Data" accepts typed "FNC1", "FNC2" and "FNC3" markers (GS1-128 etc.), plus "encoding="iso-8859-1"" for Latin-1 input. * GS1: new "GS1Fixed" / "GS1Variable" field wrappers consumed by "Code128Data.gs1" and "DataMatrixData.gs1" to build GS1-128 and GS1 Data Matrix payloads without managing FNC1 separator placement by hand. 0.14 — 2026-05-18 ================= * New "AztecEncoder" for Aztec Code (compact and full-range), with PNG / SVG / EPS / DXF / terminal output and a "pystrich aztec" CLI subcommand. See Aztec-Code. * New "PDF417Encoder" for the PDF417 stacked 2D symbology, with PNG / SVG / EPS / DXF / terminal output and a "pystrich pdf417" CLI subcommand. See PDF417. 0.13 — 2026-05-14 ================= * QR Code: accepts any Unicode string and picks the best encoding automatically (ASCII, Latin-1 or UTF-8). New "QRCodeData" exposes explicit charset control when you need it. * QR Code: internal refactor to improve the encoder's spec compliance and to share Reed-Solomon and encoding-selection code with the Data Matrix module. * Data Matrix: "TextEncoder.encode()" returns "list[int]" instead of a "str" of "chr()"-packed bytes. * Data Matrix: support all 24 ECC200 square symbol sizes up to 144x144 (1558 data codewords), with interleaved Reed-Solomon blocks for the larger symbols. Previously capped at 48x48 (174 codewords). * Data Matrix: fix the bottom-right corner-module pattern for sizes where it was previously emitted as four zero cells, and fix pad- codeword randomisation to produce the correct value at the position-28 boundary. * Code 128: unencodable characters now raise "PyStrichInvalidInput" instead of being logged and failing later with "KeyError". * Code 39: non-ASCII input under "full_ascii=True" now raises "PyStrichInvalidInput" instead of an unwrapped "UnicodeEncodeError". * Typing: the entire "pystrich" package is now checked with mypy; the remaining per-module "ignore_errors" overrides have been removed. 0.12 — 2026-05-09 ================= * New "pystrich" console script with a subcommand per format and PNG / SVG / EPS / ASCII / terminal / DXF output. See Kommandozeilen- Schnittstelle. * Data Matrix: "DataMatrixData" now expects either an "encoding=" argument or "auto_encoding=True" to be set on construction. The new "auto_encoding=True" flag picks the narrowest encoding. * SVG output for QR Code and Data Matrix via new "save_svg" / "get_svg" methods on "QRCodeEncoder" and "DataMatrixEncoder". * SVG output for the 1D barcodes via the same "save_svg" / "get_svg" methods on "Code39Encoder", "Code128Encoder" and "EAN13Encoder". * EPS output for QR Code and Data Matrix via new "save_eps" / "get_eps" methods on the same classes. * EPS output for the 1D barcodes via the same "save_eps" / "get_eps" methods on "Code39Encoder", "Code128Encoder" and "EAN13Encoder". * The human-readable labels for 1D barcodes are rendered with bundled Courier Prime glyph outlines (SIL Open Font License). * DXF: "get_dxf()" on "QRCodeEncoder" and "DataMatrixEncoder" now writes the correct "$INSUNITS" value for ""in"", ""ft"", ""mi"", ""cm"" and ""m"" (previously any value other than ""mm"" was silently treated as unspecified); you should now pass "units=None" if unspecified is desired. * All vector outputs accept a "mark_shape" keyword argument ("MarkShape") selecting how matched cells are grouped and drawn: horizontal runs (the SVG / EPS default), one square mark per cell (the DXF default), or one filled circle per cell. * Tests: round-trip DXF coverage for QR Code and Data Matrix -- the rendered DXF is read with "ezdxf", rasterised, and decoded back to the original string. * New "get_terminal_art" method on "QRCodeEncoder" and "DataMatrixEncoder", rendering the symbol with Unicode half-block characters so it scans on screen. ANSI background/foreground codes are applied by default for readability on any terminal theme; pass "ansi_bg=False" for plain output. 0.11 — 2026-05-07 ================= Bemerkung: Erratum: the "get_dxf()" docstrings on "QRCodeEncoder" and "DataMatrixEncoder" stated that "inverse=True" (the default) draws dark modules as filled cells. In fact "inverse=True" draws the *light* modules; "inverse=False" draws the dark ones. Behaviour is unchanged -- only the description was wrong. Corrected in 0.12. * Documentation: full Sphinx-built docs are now published at https://www.method-b.uk/pyStrich/docs/, covering each symbology, recipes and printing guidance, exception hierarchy and a reference index. * DataMatrix: add explicit ""iso-8859-1"" and ""utf-8"" encodings for non-ASCII payloads, selectable via "DataMatrixData". * DataMatrix: saner handling of non-ASCII input under the legacy ""compat"" encoding, with deprecation in favour of explicit encodings. * DataMatrix: proper FNC1 support via the "FNC1" marker constant. The long-accepted "chr(231)" workaround for GS1 still works behind a "Fnc1WorkaroundCompatWarning" (see issue #13). * QR Code: fix issue #8; certain valid strings could not generate a QR code. * EAN-13 quiet zone is now 11 modules left, 7 modules right (per the GS1 General Specifications); previously 9 modules each side, which was below spec on the left. * EAN-13: the leading digit's vertical position is now configurable via an "options" dict ("first_digit_y_offset"); pass "0" for a level baseline across all three digit groups (issue #18). The default preserves the classic look where the first digit is slightly higher. * Errors: unified exception hierarchy. All pyStrich-raised errors now inherit from "PyStrichError". * Public "get_pilimage" method on every encoder, returning a "PIL.Image.Image" directly. * Typing: encoders and renderers now have type hints and are checked with mypy. * Tests: refactored test suite to make better use of pytest, and extended encode/decode round-trip test coverage to Code 39, Code 128, EAN-13 and QR Code (previously DataMatrix only). * Confirmed compatibility with newer Pillow versions and Python 3.13. * Drop support for Python 3.8 and 3.9. Supported versions are now Python 3.10 to 3.14. 0.10 — 2025-09-24 ================= * Make the DataMatrix quiet zone configurable (issue #17). * Add Python 3.13 to the supported and tested versions (Python 3.8 to 3.13). 0.9 — 2024-10-02 ================ * Released as "Modernise". * Add DXF rendering for 2D barcodes (Data Matrix and QR Code), contributed by Mike Jones (PR #7). * Pillow >9.5 compatibility: replace deprecated "ImageFont.getsize" with "ImageFont.getlength". * Drop the "distutils" dependency so pyStrich installs on Python 3.12+. * Switch the build system to Poetry; add a GitHub Action that builds and publishes releases. * Add a CI GitHub Action that runs the test suite with "dmtx-utils" available. * First automated test for Code 39: output comparison plus known-good examples verified with "zbarimg". * Supported and tested on Python 3.8 to 3.12. 0.8 — 2016-07-06 ================ * Fix issue #5. 0.7 — 2015-07-26 ================ * Raise the Data Matrix payload limit from 44 characters to 174 characters (or 348 digits) by supporting larger symbol sizes (issue #2). 0.6 — 2015-07-21 ================ * Released as "This time with fonts and data". * Remove test relying on "dmtxwrite" due to issues in the previous commit. 0.4 — 2015-07-19 ================ * Released as "First working version on PyPI". * Fix "setup.py" so the PyPI package is no longer broken.