Skip to content

Commit 38e92ca

Browse files
committed
Prepare hashavatar 0.13.0
Add patterned backgrounds and integer frame mask hardening.
1 parent 6305106 commit 38e92ca

12 files changed

Lines changed: 494 additions & 92 deletions

File tree

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
# Changelog
22

3+
## 0.13.0
4+
5+
- Bumped the crate to `0.13.0`.
6+
- Added seven `AvatarBackground` variants: `polka-dot`, `striped`,
7+
`checkerboard`, `grid`, `sunrise`, `ocean`, and `starry`.
8+
- Implemented the new backgrounds for raster and SVG output with bounded,
9+
asset-free drawing paths.
10+
- Added parser/display/`ALL` coverage, raster distinctness tests, and
11+
parser-backed SVG well-formedness coverage for the expanded background
12+
catalog.
13+
- Replaced raster frame-shape hit-testing with integer arithmetic for circle,
14+
squircle, hexagon, and octagon masks, reducing floating-point sensitivity in
15+
shape clipping.
16+
- Updated automatic visual golden fingerprints because the expanded
17+
`AvatarBackground::ALL` list changes automatic background distribution.
18+
- Fixed documentation that still referenced `cargo test --all-features`; the
19+
`blake3` and `xxh3` feature modes are intentionally mutually exclusive.
20+
- Refreshed README wording for feature-gated encoder testing and the expanded
21+
background catalog.
22+
323
## 0.12.0
424

525
- Bumped the crate to `0.12.0`.

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
[package]
22
name = "hashavatar"
3-
version = "0.12.0"
3+
version = "0.13.0"
44
edition = "2024"
55
rust-version = "1.95"
6-
description = "Deterministic procedural avatars in Rust with configurable identity hashing and WebP, optional PNG/JPEG/GIF, and SVG export"
6+
description = "Deterministic procedural avatars in Rust with configurable identity hashing, patterned backgrounds, WebP, optional PNG/JPEG/GIF, and SVG export"
77
license = "MIT OR Apache-2.0"
88
repository = "https://github.com/valkyoth/hashavatar"
99
homepage = "https://github.com/valkyoth/hashavatar"

README.md

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ The crate starts conservative: validated avatar dimensions, bounded identity inp
66

77
## Current Status
88

9-
The current crate version is `0.12.0`.
9+
The current crate version is `0.13.0`.
1010

1111
Implemented now:
1212

@@ -25,8 +25,8 @@ Implemented now:
2525
- Avatar families through `AvatarKind`: animals, characters, fantasy/sci-fi
2626
faces, playful objects, and symbols. Current labels are listed in the public
2727
option catalog below.
28-
- Background modes through `AvatarBackground`: `themed`, `white`, `black`,
29-
`dark`, `light`, and `transparent`.
28+
- Background modes through `AvatarBackground`: fixed, transparent, patterned,
29+
gradient, and star-field canvas treatments.
3030
- Visual layers through `AvatarAccessory`, `AvatarColor`,
3131
`AvatarExpression`, and `AvatarShape`.
3232
- In-memory `WebP` encoding through `AvatarOutputFormat`; `PNG`, `JPEG`, and
@@ -37,7 +37,8 @@ Implemented now:
3737
- No public path-writing helpers; callers own their storage and filesystem boundary.
3838
- `#![forbid(unsafe_code)]` in library code.
3939
- Golden visual regression fingerprints.
40-
- Isolated fuzz harness for avatar identities, families, backgrounds, SVG rendering, and PNG encoding.
40+
- Isolated fuzz harness for avatar identities, families, backgrounds, SVG
41+
rendering, default WebP encoding, and feature-gated encoder paths.
4142
- Local release gates for formatting, clippy, tests, docs, dependency policy, RustSec advisories, package contents, SBOM generation, reproducible build checks, and crates.io publish dry runs.
4243

4344
Planned or intentionally external:
@@ -74,29 +75,29 @@ future release has a concrete image-generation reason to split it.
7475

7576
```toml
7677
[dependencies]
77-
hashavatar = "0.12.0"
78+
hashavatar = "0.13.0"
7879
```
7980

8081
Optional identity hash modes and extra raster encoders are disabled by default.
8182
Hash modes are mutually exclusive, so enable at most one of `blake3` or `xxh3`:
8283

8384
```toml
8485
[dependencies]
85-
hashavatar = { version = "0.12.0", features = ["blake3"] }
86+
hashavatar = { version = "0.13.0", features = ["blake3"] }
8687
```
8788

8889
Enable additional raster formats explicitly:
8990

9091
```toml
9192
[dependencies]
92-
hashavatar = { version = "0.12.0", features = ["png", "jpeg", "gif"] }
93+
hashavatar = { version = "0.13.0", features = ["png", "jpeg", "gif"] }
9394
```
9495

9596
Or enable every optional raster encoder at once:
9697

9798
```toml
9899
[dependencies]
99-
hashavatar = { version = "0.12.0", features = ["all-formats"] }
100+
hashavatar = { version = "0.13.0", features = ["all-formats"] }
100101
```
101102

102103
Combine these as needed, for example `features = ["blake3", "png"]`.
@@ -143,7 +144,7 @@ in caller code.
143144
| Enum | Controls | Values |
144145
| --- | --- | --- |
145146
| `AvatarKind` | Base avatar family | `cat`, `dog`, `robot`, `fox`, `alien`, `monster`, `ghost`, `slime`, `bird`, `wizard`, `skull`, `paws`, `planet`, `rocket`, `mushroom`, `cactus`, `frog`, `panda`, `cupcake`, `pizza`, `icecream`, `octopus`, `knight`, `bear`, `penguin`, `dragon`, `ninja`, `astronaut`, `diamond`, `coffee-cup`, `shield` |
146-
| `AvatarBackground` | Canvas/background treatment | `themed`, `white`, `black`, `dark`, `light`, `transparent` |
147+
| `AvatarBackground` | Canvas/background treatment | `themed`, `white`, `black`, `dark`, `light`, `transparent`, `polka-dot`, `striped`, `checkerboard`, `grid`, `sunrise`, `ocean`, `starry` |
147148
| `AvatarAccessory` | Optional accessory layer | `none`, `glasses`, `hat`, `headphones`, `crown`, `bowtie`, `eyepatch`, `scarf`, `halo`, `horns` |
148149
| `AvatarColor` | Optional accent palette | `default`, `neon-mint`, `pastel-pink`, `crimson`, `gold`, `deep-sea-blue` |
149150
| `AvatarExpression` | Optional expression overlay | `default`, `happy`, `grumpy`, `surprised`, `sleepy`, `winking`, `cool`, `crying` |
@@ -380,7 +381,7 @@ your namespace style version when intentionally migrating output.
380381

381382
```toml
382383
[dependencies]
383-
hashavatar = { version = "0.12.0", features = ["blake3"] }
384+
hashavatar = { version = "0.13.0", features = ["blake3"] }
384385
```
385386

386387
```rust
@@ -408,7 +409,7 @@ assert!(svg.contains("alien avatar"));
408409

409410
```toml
410411
[dependencies]
411-
hashavatar = { version = "0.12.0", features = ["xxh3"] }
412+
hashavatar = { version = "0.13.0", features = ["xxh3"] }
412413
```
413414

414415
```rust
@@ -625,23 +626,24 @@ For style-aware rendering, the deterministic tuple also includes
625626
`accessory`, `color`, `expression`, and `shape`. Existing `AvatarOptions`
626627
entry points keep those extra layer choices at `none`, `default`, `default`,
627628
and `square`, so explicitly selected `AvatarOptions` output remains stable
628-
unless the selected family renderer changes. `0.12.0` adds new `AvatarKind`
629-
values, so automatic style derivation can map some identities to different
630-
families than `0.11.0`; services that need the old automatic distribution
631-
should keep their existing namespace style version until they intentionally
632-
migrate. Some family/layer combinations are deterministic no-ops when the
633-
layer has no sensible anchor for that family.
629+
unless the selected family renderer changes. `0.13.0` adds new
630+
`AvatarBackground` values, so automatic style derivation can map some
631+
identities to different backgrounds than `0.12.0`; services that need the old
632+
automatic distribution should keep their existing namespace style version until
633+
they intentionally migrate. Some family/layer combinations are deterministic
634+
no-ops when the layer has no sensible anchor for that family.
634635

635636
Frame shapes are applied as masks in raster output and as SVG clip paths in SVG
636637
output. Non-square shapes therefore trim the background, avatar body, color
637638
accent, accessory layer, and expression layer consistently before drawing the
638639
frame border.
639640

640-
The renderer uses floating-point geometry internally. The project tests golden
641-
fingerprints on the release platform, but it does not yet claim formal
641+
The renderer still uses floating-point geometry in family-specific drawing
642+
paths. Frame-shape raster hit-testing uses integer arithmetic as of `0.13.0`,
643+
which reduces one source of platform rounding variance. The project tests
644+
golden fingerprints on the release platform, but it does not yet claim formal
642645
bit-identical raster output across every CPU architecture, compiler backend,
643-
and optimization mode. Future core-boundary work tracks fixed-point geometry
644-
as the path to a stricter cross-platform determinism contract.
646+
and optimization mode.
645647

646648
The procedural cat renderer seeds its internal RNG from bytes `32..64` of the
647649
identity digest and uses the lower digest bytes for direct visual parameters.

docs/DEPENDENCIES.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ Dependency changes should be reviewed for:
6464
identity hash, and do not recommend it for user-controlled identifiers unless
6565
the application first maps those identifiers through its own cryptographic
6666
boundary.
67-
- Optional dependency features must be tested with `cargo test --all-features`
68-
before release.
67+
- Optional dependency features must be tested in valid feature combinations
68+
before release. Do not use `cargo test --all-features` because the `blake3`
69+
and `xxh3` identity-hash modes are intentionally mutually exclusive.
6970

7071
`scripts/validate-dependencies.sh` enforces the current direct dependency allowlist.
7172

docs/SECURITY_CONTROLS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@
9191
async/runtime boundary.
9292
- Internal rectangle helpers use saturating or clamping arithmetic for edge and
9393
intersection calculations.
94+
- Raster frame-shape hit-testing uses integer arithmetic for circle, squircle,
95+
hexagon, and octagon masks, reducing platform-specific floating-point
96+
rounding in clipping decisions.
9497
- Polygon rasterization returns immediately for empty polygons and zero-sized
9598
images, widens scanline interpolation math before rounding, and is covered by
9699
a dedicated fuzz harness for arbitrary image dimensions, degenerate polygons,

docs/VERSION_PLAN.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,47 @@ public API.
446446
- `scripts/stable_release_gate.sh check` passes.
447447
- crates.io publish dry run passes.
448448

449+
## 0.13.0: Background Expansion And Determinism Hardening
450+
451+
Status: implemented in `0.13.0`.
452+
453+
Goal: improve the background catalog without adding new avatar families, and
454+
reduce platform-sensitive geometry in frame-shape masking before `1.0`.
455+
456+
### Scope
457+
458+
- Add a small accepted background set:
459+
- `PolkaDot`
460+
- `Striped`
461+
- `Checkerboard`
462+
- `Grid`
463+
- `Sunrise`
464+
- `Ocean`
465+
- `Starry`
466+
- Keep background rendering deterministic, bounded, asset-free, and represented
467+
in both raster and SVG output.
468+
- Avoid admitting busier backgrounds such as `Wavy`, `Synthwave`, `Pixel`, and
469+
`Cloudy` until they have a clearer contrast and readability story.
470+
- Replace selected float-based frame-shape raster hit-testing with integer
471+
arithmetic.
472+
- Fix stale documentation around feature-combination testing and fuzz encoder
473+
coverage.
474+
475+
### Finish Line
476+
477+
`0.13.0` is done when:
478+
479+
- Every accepted background has `as_str`, `Display`, `FromStr`, and `ALL`
480+
coverage.
481+
- Raster tests prove the new background canvases are distinct and bounded.
482+
- SVG tests parse every new background as well-formed XML.
483+
- Golden fingerprints document the automatic-output impact from expanding
484+
`AvatarBackground::ALL`.
485+
- README, dependency docs, changelog, and release notes describe the new
486+
background catalog and the feature-testing policy.
487+
- `scripts/stable_release_gate.sh check` passes.
488+
- crates.io publish dry run passes.
489+
449490
## 1.0.0: Stability Contract
450491

451492
Goal: freeze a professional, security-oriented public API and rendering
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# hashavatar 0.13.0
2+
3+
`0.13.0` expands the background catalog and applies targeted determinism
4+
hardening without adding new avatar families.
5+
6+
## Added
7+
8+
- Added seven `AvatarBackground` values:
9+
- `polka-dot`
10+
- `striped`
11+
- `checkerboard`
12+
- `grid`
13+
- `sunrise`
14+
- `ocean`
15+
- `starry`
16+
- Implemented each new background in raster and SVG output.
17+
- Added tests that prove the new raster backgrounds are distinct and that the
18+
new SVG backgrounds remain well-formed XML.
19+
20+
## Changed
21+
22+
- Raster frame-shape hit-testing now uses integer arithmetic for circle,
23+
squircle, hexagon, and octagon masks. This reduces one source of
24+
platform-specific floating-point rounding in clipped output.
25+
- Automatic style derivation can now map some identities to different
26+
backgrounds because `AvatarBackground::ALL` contains more variants. Services
27+
that need old automatic output should keep their existing namespace
28+
`style_version` until they intentionally migrate.
29+
- Documentation now avoids `cargo test --all-features` guidance because
30+
`blake3` and `xxh3` are intentionally mutually exclusive crate-wide identity
31+
hash modes.
32+
- README fuzz wording now reflects default WebP coverage and feature-gated
33+
encoder paths instead of describing PNG as always available.
34+
35+
## Compatibility Notes
36+
37+
- Explicit `AvatarOptions` and `AvatarStyleOptions` selections remain
38+
deterministic for the selected kind, background, dimensions, seed, namespace,
39+
crate identity hash mode, and identity.
40+
- The new background variants are public API and therefore affect automatic
41+
background distribution.
42+
- No new avatar families were added in this release.

fuzz/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fuzz/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ publish = false
88
cargo-fuzz = true
99

1010
[dependencies]
11-
hashavatar = { path = "..", version = "0.12.0", features = ["fuzzing"] }
11+
hashavatar = { path = "..", version = "0.13.0", features = ["fuzzing"] }
1212
libfuzzer-sys = "0.4"
1313
roxmltree = "0.21.1"
1414

0 commit comments

Comments
 (0)