Releases: harfbuzz/packtab
1.8.0
packtab 1.7.0
packtab 1.7.0
Highlights:
-
Conditional Rust unused_unsafe suppression: safe output stays free of any unsafe text, while unsafe output silences redundant warnings.
-
No algorithm changes in this release; this is a small Rust-codegen quality release.
1.6.0
1.5.0
packtab 1.5.0 adds packtab shape comments to generated lookup functions.
Highlights:
- Generated top-level lookup functions now include a compact
packtab:comment describing the selected solution shape. - The annotation reports the split structure, including the leaf term, and includes base offset, palette size, and outer arithmetic when present.
- This makes it easier to inspect and compare generated tables without reverse-engineering the lookup expression by hand.
Validation:
pytest -q packTab/test.pypassed before release (206 passed).
1.4.0
packTab 1.4.0 focuses on better sparse-prefix compression, clearer compression modes, and simpler generation logic.
Highlights
- Added explicit compression endpoints.
--compression 0now selects a flat / unsplit encoding.--compression 10now minimizes raw table bytes.--compression 1..9keep the historical heuristic behavior.
- Added aligned leading-default culling.
- Tables with large power-of-two-aligned default prefixes can now be rebased to the smallest dyadic interval covering the live range.
- This preserves the recursive split structure while avoiding storage for removable all-default left branches.
- Added exact leading-default culling for inlineable spans.
- When trimming to the first non-default index makes the remaining flat span small enough to inline as a constant, packTab now tries that exact rebase too.
- Removed the identity optimization.
- This simplifies the model and code generation, and makes rebased sparse-prefix handling easier to reason about.
- Improved generated C and Rust lookups for rebased spans.
- Rebased lookups use a single unsigned range check, including safe wrapping arithmetic on Rust.
Other changes
- Updated documentation for the new compression semantics and sparse-prefix behavior.
- Expanded tests for compression endpoint selection, aligned prefix culling, and exact-inline prefix culling.
Validation
- Full test suite passes: 204 tests.
v1.3.0
Full Changelog: v1.2.0...v1.3.0
Release 1.2.0
New Features
Array Overlap Optimization
When extending arrays, packtab now automatically detects and merges common boundary runs where all overlapping elements share the same value, reducing total array size.
Example:
Existing: [1, 2, 7, 7, 7] (3 trailing 7s)
New: [7, 7, 8, 9] (2 leading 7s)
Result: [1, 2, 7, 7, 7, 8, 9] (saved 2 elements)
Improvements
- ~60 bytes saved on HarfBuzz UCD tables
- O(N+M) linear scan - very cheap overhead
- Automatic - only triggers when beneficial (matching boundary values)
- Universal - works across all generated arrays
Technical Details
The optimization performs two linear scans from array boundaries:
- Count trailing run of value V in existing array
- Count leading run of value V in new data
- Overlap by min(trailing, leading) elements
Since the operation is done during array extension anyway, the overhead is negligible while providing measurable space savings on real-world data.
Installation
pip install --upgrade packtab1.0.0
packtab 1.0.0
This is the first stable release of packtab! 🎉
What's New
Bug Fixes
- Fixed mapping parameter to accept bidirectional mappings: The
mappingparameter inpack_table()now correctly accepts
bidirectional dictionaries (e.g.,{0: "Cc", "Cc": 0}), which are commonly used in Unicode table generation. Previously, this would
incorrectly raise aTypeError.
Recent Improvements (since 0.4.0)
- Implemented frequency-based chunk sorting for better cache optimization
- Fixed constant data optimization with comprehensive edge case tests
- Implemented dual compression with
#ifdef __OPTIMIZE_SIZE__ - Fixed tests and enabled mapping validation
- Removed black and flake8 linting in favor of simpler tooling
Development Status
- Updated from Beta to Production/Stable
Installation
pip install packtab==1.0.0Links
- https://github.com/harfbuzz/packtab/blob/master/README.md
- https://pypi.org/project/packtab/1.0.0/
- https://github.com/harfbuzz/packtab/issues
Full Changelog: 0.4.0...1.0.0
0.4.0
Optimizations
- Identity subtraction: When data is near-linear (
data[i] ≈ i), store compact residuals instead of full values - Inline small arrays: Arrays ≤ 64 bits are emitted as integer constants with bit extraction, eliminating array storage entirely
- Bake in bias/multiplier: When bias or GCD multiplier can be folded into stored values without enlarging the data type, the runtime arithmetic is eliminated
- Bake in shift: When pre-shifted block offsets fit in the same sub-byte bucket, the runtime shift is eliminated
- O(N log N) Pareto pruning: Solution selection uses sort + scan instead of O(N²) pairwise dominance check
Rust code generation
- Improved Rust output:
pub(crate),staticarrays, clippy-clean, properusizeliterals wrapping_add()/wrapping_sub()for identity subtraction (Rust panics on unsigned overflow in debug)--unsafeflag forget_uncheckedarray access- End-to-end Rust compilation tests alongside C tests
CLI
- Rewritten with
argparse:--language,--default,--compression,--name,--help --rustkept as shorthand for--language=rust
Bug fixes
- Fix handling of constant and all-default data
- Fix string/identifier data to store verbatim values
- Fix negative unsigned literals from identity + bias interaction
- Fix parentheses in generated expressions
Code quality
- Drop Python 2 compatibility
- Proper exceptions (
ValueError,TypeError) instead ofassert - Comprehensive test suite (172 tests) with C and Rust end-to-end compilation
- Extracted
_best_reduction()helper for bias+GCD logic - Extensive design comments throughout