Skip to content

fix: gray levels, half_white, and hardened hex color parsing#25

Merged
g4bri3lDev merged 2 commits into
mainfrom
fix/gray-and-hex-colors
Jul 2, 2026
Merged

fix: gray levels, half_white, and hardened hex color parsing#25
g4bri3lDev merged 2 commits into
mainfrom
fix/gray-and-hex-colors

Conversation

@g4bri3lDev

Copy link
Copy Markdown
Member

Context

From the OpenDisplay firmware-dev Discord thread (6/22/2026): users running 4-gray / 16-gray e-paper displays (reTerminal E1001, etc.) hit color problems via drawcustom — not enough gray levels, and half_white rendering as mid-gray.

Changes

Gray handling (colors.py)

  • Add darkgray/dkgray(64,64,64) and lightgray/ltgray(191,191,191), giving a clean 4-gray ramp: black → dkgray → gray (127) → ltgray → white.
  • Fix half_white/hw, which was wrongly grouped with half_black/gray and resolved to mid-gray (127); it now resolves to light gray (191).

Hex hardening (colors.py)

  • Accept 8-digit #RRGGBBAA and 4-digit #RGBA (alpha) in addition to the existing 3/6-digit forms.
  • Strip surrounding whitespace before resolving, so templated values like " #FF0000 " work.
  • 16-gray displays are addressed via hex (#888888, …); the panel driver quantizes to its nearest level. No gray0..15 constants added (avoids palette/regex bloat).

Maintainability

  • Introduce a single NAMED_COLORS mapping as the source of truth. The resolver does a dict lookup, and the inline text-markup allowlist is derived from COLOR_TOKEN_PATTERN — so a future named color is added in one place instead of being duplicated across colors.py and text.py. Accent aliases remain special-cased (they resolve dynamically from accent_color).

Tests

  • New cases for the gray names, the half_white fix, 4/8-digit + alpha + whitespace hex, and the new inline-markup tags.
  • Full suite green (399 passed); ruff + mypy clean.

Out of scope / follow-up

The original "hex replaced with null on fill:" report is a validation bug in the HA integration's drawcustom schema (OpenEPaperLink/Home_Assistant_Integration), not this library — hex parsing here always worked. That repo's color validator should accept hex for fill the same as for color.

…lors

Add named grays for 4-gray displays: darkgray/dkgray (64) and
lightgray/ltgray (191) around the existing gray (127). Fix half_white/hw,
which wrongly resolved to mid gray (127) instead of light gray (191).

Harden hex parsing for 16-gray and templated values: accept 8-digit
#RRGGBBAA and 4-digit #RGBA alpha forms, and strip surrounding whitespace.

Centralize named colors into a single NAMED_COLORS mapping. The resolver
and the inline text-markup allowlist (COLOR_TOKEN_PATTERN) are both derived
from it, so a future named color is added in exactly one place instead of
being duplicated across colors.py and text.py.
@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Cover the named gray ramp (black/dkgray/gray/ltgray/white), the hex
grayscale ramp, and inline [dkgray]/[gray]/[ltgray] markup rendered via
parse_colors.
@g4bri3lDev g4bri3lDev merged commit f92b08b into main Jul 2, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant