rockbox/wps/template_fill.py
Marc Aarts 1183b1ab1b Rockbox for the HiBy R3 Pro II/R1
Original author Melissa Autumn (https://codeberg.org/oopsallnaps/rockbox-hibyos) with contributions from Marc Aarts.

Adaptation to Rockbox standards by Marc Aarts

Change-Id: I09e5af7ba0a75c648e4b9fd424badc2d3665c943
2025-12-27 15:44:54 -05:00

288 lines
6.6 KiB
Python

"""
Rough script to scale up the existing classic_statusbar
It will scale up by scale_pixel_size_by, and add padding specificed by
padding_x/y.
The status bar size will be determined by main_viewport_size_by.
So if you want zero padding just make sure those two numbers are the same.
This is all based on the 8px tall classic_statusbar, but this script can
be adapted for different sbs or wps file. Just need to create a template
which is just jinja template syntax on top of a sbs or wps.
The images were hacked together, you specify their real image path
from the wps folder, but it will hack off the asset folder because
rockbox automatically adds it. Oops.
"""
from jinja2 import Environment, PackageLoader, select_autoescape
from PIL import Image
import os
env = Environment(
loader=PackageLoader("template_fill"),
autoescape=select_autoescape()
)
template = env.get_template("classic_statusbar.sbs.j2")
original_pixel_size = 8
padding_x = 4
padding_y = 4
scale_pixel_size_by = 2
main_viewport_size_by = 3
scaled_pixel_size = original_pixel_size * scale_pixel_size_by
main_viewport_size = original_pixel_size * main_viewport_size_by
font_id = 0
asset_folder = 'classic_statusbar'
def upscale_element(element: dict) -> dict:
if element.get('image'):
element_img: str = element['image']
# Split off the last .bmp (and recombine if the filename contains periods)
out_element_image = (
f'{'.'.join(element_img.split('.')[0:-1])}.{scaled_pixel_size}.bmp'
)
try:
if os.path.isfile(out_element_image):
im = Image.open(out_element_image)
else:
im = Image.open(element_img)
size = im.width * scale_pixel_size_by, im.height * scale_pixel_size_by
im = im.resize(size, Image.Resampling.NEAREST)
im.save(out_element_image, "BMP")
# Bit of a hack really
element['image'] = out_element_image.replace(
f'{asset_folder}/', '')
except IOError:
print(f"cannot resize for <{element_img}>")
if element.get('source_x') and element['source_x'] != '-':
element['source_x'] *= scale_pixel_size_by
if element.get('source_y') and element['source_y'] != '-':
element['source_x'] *= scale_pixel_size_by
if element.get('viewport'):
if element['viewport']['x'] != '-':
element['viewport']['x'] *= scale_pixel_size_by
element['viewport']['x'] += padding_x
if element['viewport']['y'] != '-':
element['viewport']['y'] *= scale_pixel_size_by
element['viewport']['y'] += padding_x
if element['viewport']['width'] != '-':
element['viewport']['width'] *= scale_pixel_size_by
if element['viewport']['height'] != '-':
element['viewport']['height'] *= scale_pixel_size_by
return element
# These are based on the original resolution, they're upscaled later
battery = upscale_element({
'image': 'classic_statusbar/battery.bmp',
'source_x': 0,
'source_y': 0,
'sub_image_count': 16,
'viewport': {
'x': 0,
'y': 0,
'width': 17,
'height': 7,
'font_id': font_id
}
})
battery_cap = upscale_element({
'image': 'classic_statusbar/batter-y.bmp',
'source_x': 0,
'source_y': 0,
'sub_image_count': 0,
'viewport': {
'x': 17,
'y': 0,
'width': 3,
'height': 7,
'font_id': font_id
}
})
battery_no_icon = upscale_element({
'viewport': {
'x': 0,
'y': 0,
'width': 18,
'height': 8,
'font_id': font_id
}
})
volume = upscale_element({
'image': 'classic_statusbar/volume.bmp',
'source_x': 1,
'source_y': 0,
'sub_image_count': 17,
'viewport': {
'x': 28,
'y': 0,
'width': 19,
'height': 8,
'font_id': font_id
}
})
status = upscale_element({
'image': 'classic_statusbar/status.bmp',
'source_x': 0,
'source_y': 0,
'sub_image_count': 15,
'viewport': {
'x': 47,
'y': 0,
'width': 8,
'height': 8,
'font_id': font_id
}
})
power = upscale_element({
'viewport': {
'x': 20,
'y': 0,
'width': 8,
'height': 8,
'font_id': font_id
}
})
playback = upscale_element({
'viewport': {
'x': 47,
'y': 0,
'width': 9,
'height': 8,
'font_id': font_id
}
})
repeat = upscale_element({
'viewport': {
'x': 56,
'y': 0,
'width': 9,
'height': 8,
'font_id': font_id
}
})
shuffle = upscale_element({
'viewport': {
'x': 65,
'y': 0,
'width': '-',
'height': 8,
'font_id': font_id
}
})
access_disk = upscale_element({
'image': 'classic_statusbar/access_disk.bmp',
'source_x': 0,
'source_y': 0,
'sub_image_count': 0,
'viewport': {
'x': -12,
'y': 0,
'width': '-',
'height': 8,
'font_id': font_id
}
})
rec_bitrate = upscale_element({
'image': 'classic_statusbar/rec_mpegbitrates.bmp',
'source_x': 1,
'source_y': 0,
'sub_image_count': 18,
'viewport': {
'x': 28,
'y': 0,
'width': 19,
'height': 8,
'font_id': font_id
}
})
rec_freq = upscale_element({
'image': 'classic_statusbar/rec_frequencies.bmp',
'source_x': 0,
'source_y': 0,
'sub_image_count': 12,
'viewport': {
'x': 55,
'y': 0,
'width': '-',
'height': 8,
'font_id': font_id
}
})
rec_encoders = upscale_element({
'image': 'classic_statusbar/rec_encoders.bmp',
'source_x': 0,
'source_y': 0,
'sub_image_count': 3,
})
rec_channels = upscale_element({
'image': 'classic_statusbar/rec_channels.bmp',
'source_x': 13,
'source_y': 0,
'sub_image_count': 2,
})
rtc = upscale_element({
'viewport': {
'x': -43,
'y': 0,
'width': 31,
'height': 8,
'font_id': font_id
}
})
rendered = template.render(
viewport={
'width': 0,
'height': main_viewport_size,
'font_id': 1
},
options={},
battery=battery,
battery_cap=battery_cap,
battery_no_icon=battery_no_icon,
volume=volume,
status=status,
access_disk=access_disk,
rec_bitrate=rec_bitrate,
rec_freq=rec_freq,
rec_encoders=rec_encoders,
rec_channels=rec_channels,
power=power,
playback=playback,
repeat=repeat,
shuffle=shuffle,
rtc=rtc,
)
print(rendered)
with open('./classic_statusbar.sbs', 'w') as fh:
fh.write(rendered)