119 lines
3.9 KiB
Python
119 lines
3.9 KiB
Python
"""UCD SolidColor 码值刻度(与 UniTAP ``SolidColorParams`` 一致,0–65535)。"""
|
||
from __future__ import annotations
|
||
|
||
SOLID_COLOR_MIN = 0
|
||
SOLID_COLOR_MAX = 65535
|
||
# 官方 work_with_solid_color.py:65535 刻度需 bpc>=10
|
||
SOLID_COLOR_MIN_BPC = 10
|
||
|
||
# Limited Range 在 SolidColor 刻度下的端点(等价于 8bit 的 16 / 235)
|
||
_LIMITED_8BIT_BLACK = 16
|
||
_LIMITED_8BIT_WHITE = 235
|
||
LIMITED_SOLID_COLOR_BLACK = round(_LIMITED_8BIT_BLACK / 255 * SOLID_COLOR_MAX)
|
||
LIMITED_SOLID_COLOR_WHITE = round(_LIMITED_8BIT_WHITE / 255 * SOLID_COLOR_MAX)
|
||
|
||
|
||
def clamp_solid_color(value: int | float) -> int:
|
||
"""将码值限制在 SolidColor 合法范围内。"""
|
||
return max(SOLID_COLOR_MIN, min(SOLID_COLOR_MAX, int(round(value))))
|
||
|
||
|
||
def pct_to_solid_color(pct: float) -> int:
|
||
"""灰阶/亮度百分比 (0–100) → SolidColor 码值。"""
|
||
pct = max(0.0, min(100.0, float(pct)))
|
||
return int(round(pct / 100.0 * SOLID_COLOR_MAX))
|
||
|
||
|
||
def solid_color_to_pct(value: int | float) -> float:
|
||
"""SolidColor 码值 → 百分比 (0–100)。"""
|
||
if SOLID_COLOR_MAX <= 0:
|
||
return 0.0
|
||
return clamp_solid_color(value) / SOLID_COLOR_MAX * 100.0
|
||
|
||
|
||
def solid_color_to_byte(value: int | float) -> int:
|
||
"""SolidColor 码值 → 8bit(UI 色块 / HEX 显示用)。"""
|
||
return int(round(clamp_solid_color(value) / SOLID_COLOR_MAX * 255))
|
||
|
||
|
||
def byte_to_solid_color(value: int | float) -> int:
|
||
"""旧 8bit 码值 (0–255) → SolidColor 刻度。"""
|
||
byte = max(0, min(255, int(round(value))))
|
||
return int(round(byte / 255.0 * SOLID_COLOR_MAX))
|
||
|
||
|
||
def solid_color_rgb(r: int, g: int, b: int) -> list[int]:
|
||
"""将旧 8bit RGB 三元组转为 SolidColor 刻度。"""
|
||
return [byte_to_solid_color(r), byte_to_solid_color(g), byte_to_solid_color(b)]
|
||
|
||
|
||
def is_legacy_8bit_pattern_params(params: list) -> bool:
|
||
"""判断 ``pattern_params`` 是否仍为旧 0–255 刻度。"""
|
||
if not params:
|
||
return False
|
||
max_val = 0
|
||
for row in params:
|
||
if not row:
|
||
continue
|
||
for channel in row[:3]:
|
||
try:
|
||
max_val = max(max_val, int(channel))
|
||
except (TypeError, ValueError):
|
||
pass
|
||
return max_val <= 255
|
||
|
||
|
||
def migrate_pattern_params(params: list) -> list:
|
||
"""将 0–255 刻度的 pattern 参数迁移到 SolidColor 刻度。"""
|
||
if not is_legacy_8bit_pattern_params(params):
|
||
return params
|
||
migrated: list = []
|
||
for row in params:
|
||
head = [byte_to_solid_color(v) for v in row[:3]]
|
||
migrated.append(head + list(row[3:]))
|
||
return migrated
|
||
|
||
|
||
def ensure_solid_color_pattern(pattern: dict) -> dict:
|
||
"""确保 pattern 字典中的 ``pattern_params`` 使用 SolidColor 刻度。"""
|
||
params = pattern.get("pattern_params")
|
||
if params:
|
||
pattern["pattern_params"] = migrate_pattern_params(params)
|
||
return pattern
|
||
|
||
|
||
def pack_solid_color_hw_registers(
|
||
rgb: tuple[int, int, int] | list[int],
|
||
) -> tuple[int, int]:
|
||
"""将 65535 刻度 RGB 打包为 PG 硬件寄存器值(``shifter=0``,新版 UCD API)。
|
||
|
||
旧版 UniTAP SDK 在 ``set_pattern_params`` 内还会按 ``16-bpc`` 左移;
|
||
65535 刻度下左移会导致 32 位溢出(30%/50%/80% 灰阶发暗)。
|
||
新版 UCD 直接接受 0–65535,须绕过 SDK 移位。
|
||
"""
|
||
r = clamp_solid_color(rgb[0])
|
||
g = clamp_solid_color(rgb[1])
|
||
b = clamp_solid_color(rgb[2])
|
||
param0 = ((r << 16) | g) & 0xFFFFFFFF
|
||
param1 = b & 0xFFFFFFFF
|
||
return param0, param1
|
||
|
||
|
||
__all__ = [
|
||
"SOLID_COLOR_MIN",
|
||
"SOLID_COLOR_MAX",
|
||
"SOLID_COLOR_MIN_BPC",
|
||
"LIMITED_SOLID_COLOR_BLACK",
|
||
"LIMITED_SOLID_COLOR_WHITE",
|
||
"clamp_solid_color",
|
||
"pct_to_solid_color",
|
||
"solid_color_to_pct",
|
||
"solid_color_to_byte",
|
||
"byte_to_solid_color",
|
||
"solid_color_rgb",
|
||
"is_legacy_8bit_pattern_params",
|
||
"migrate_pattern_params",
|
||
"ensure_solid_color_pattern",
|
||
"pack_solid_color_hw_registers",
|
||
]
|