Asset Packer: Fix edge cases for animated icons

- FBT allows animated icons with any frame naming scheme
- Flipper needs precise naming
- This will ensure correct parsing and correct output
- If .bm and .png input for packer is mixed, could have issues due to inconsistent naming between input and output (duplicated frames)
This commit is contained in:
Willy-JL
2024-07-16 17:32:48 +01:00
parent e61e23a627
commit a953d0dfd4
3 changed files with 31 additions and 9 deletions

View File

@@ -116,7 +116,7 @@
- FBT:
- Consistent version/branch info, fix gitorigin (by @Willy-JL)
- OFW: Fixed starting apps with spaces in path (by @hedger)
- AssetPacker: Pack pre-compiled icons and fonts too (by @Willy-JL)
- AssetPacker: Pack pre-compiled icons and fonts too, fix animated icons edge cases (by @Willy-JL)
- GUI: Return user-provided index from `menu_set_selected_item()` like `submenu` equivalent (by @Willy-JL)
- JS:
- Fix `subghz` RAW files, fix memory leaks, deinit correctly, better error handling (by @Willy-JL)

View File

@@ -69,22 +69,24 @@ def pack_icon_animated(src: pathlib.Path, dst: pathlib.Path):
frame_count = 0
frame_rate = None
size = None
for frame in src.iterdir():
files = [file for file in src.iterdir() if file.is_file()]
for frame in sorted(files, key=lambda x: x.name):
if not frame.is_file():
continue
if frame.name == "frame_rate":
frame_rate = int(frame.read_text())
frame_rate = int(frame.read_text().strip())
elif frame.name == "meta":
shutil.copyfile(frame, dst / frame.name)
elif frame.name.startswith("frame_"):
else:
dst_frame = dst / f"frame_{frame_count:02}.bm"
if frame.suffix == ".png":
if not size:
size = Image.open(frame).size
(dst / frame.with_suffix(".bm").name).write_bytes(convert_bm(frame))
dst_frame.write_bytes(convert_bm(frame))
frame_count += 1
elif frame.suffix == ".bm":
if not (dst / frame.name).is_file():
shutil.copyfile(frame, dst / frame.name)
if frame.with_suffix(".png") not in files:
shutil.copyfile(frame, dst_frame)
frame_count += 1
if size is not None and frame_rate is not None:
(dst / "meta").write_bytes(struct.pack("<IIII", *size, frame_rate, frame_count))

View File

@@ -74,6 +74,7 @@ def _packs_emitter(target, source, env):
env.Replace(_PACKS_SRC_DIR=source_dir)
target = set()
# Animations
target.update(
source_dir.rel_path(node)
for node in env.GlobRecursive("*/Anims/manifest.txt", source_dir.srcnode())
@@ -86,14 +87,33 @@ def _packs_emitter(target, source, env):
source_dir.rel_path(node).removesuffix(".png") + ".bm"
for node in env.GlobRecursive("*/Anims/**/*.png", source_dir.srcnode())
)
# Animated icons
target.update(
source_dir.rel_path(node)
for node in env.GlobRecursive("*/Icons/**/*.bmx", source_dir.srcnode())
for node in env.GlobRecursive("*/Icons/*/*/meta", source_dir.srcnode())
)
target.update(
source_dir.rel_path(node).removesuffix("frame_rate") + "meta"
for node in env.GlobRecursive("*/Icons/*/*/frame_rate", source_dir.srcnode())
)
target.update(
source_dir.rel_path(node)
for node in env.GlobRecursive("*/Icons/*/*/*.bm", source_dir.srcnode())
)
target.update(
source_dir.rel_path(node).removesuffix(".png") + ".bm"
for node in env.GlobRecursive("*/Icons/*/*/*.png", source_dir.srcnode())
)
# Static icons
target.update(
source_dir.rel_path(node)
for node in env.GlobRecursive("*/Icons/*/*.bmx", source_dir.srcnode())
)
target.update(
source_dir.rel_path(node).removesuffix(".png") + ".bmx"
for node in env.GlobRecursive("*/Icons/**/*.png", source_dir.srcnode())
for node in env.GlobRecursive("*/Icons/*/*.png", source_dir.srcnode())
)
# Fonts
target.update(
source_dir.rel_path(node)
for node in env.GlobRecursive("*/Fonts/*.u8f", source_dir.srcnode())