| 1 | #!/usr/bin/env python3 |
| 2 | """Recolour the xfwm4 PNGs that have no SVG source. |
| 3 | |
| 4 | Nine frame pieces -- the thin edge strips and the menu button states -- ship |
| 5 | only as PNGs upstream, with no SVG to re-render from. They are flat fills with |
| 6 | at most a pixel of antialiasing at the corners, so they are remapped in place: |
| 7 | no resampling, no rendering, and nothing to install. Upstream stores them as |
| 8 | indexed images at 1x but as RGBA at some of the hidpi sizes, so both are |
| 9 | handled. Everything else in xfwm4/ comes from render-xfwm4.sh. |
| 10 | """ |
| 11 | |
| 12 | import os |
| 13 | import sys |
| 14 | |
| 15 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "lib")) |
| 16 | |
| 17 | import darkmatter as dm |
| 18 | from png import Png |
| 19 | from remap import Remapper |
| 20 | |
| 21 | NO_SVG = [ |
| 22 | "bottom-inactive", "bottom-left-inactive", "bottom-right-active", |
| 23 | "left-active", "left-inactive", "menu-inactive", "menu-prelight", |
| 24 | "menu-pressed", "right-inactive", |
| 25 | ] |
| 26 | |
| 27 | # Black and white are anchored to themselves so the corner antialiasing, which |
| 28 | # blends the frame colour toward the window's outer outline, follows along. |
| 29 | # |
| 30 | # The Darkmatter targets are anchored to themselves as well, which makes this |
| 31 | # script idempotent: an already-converted file matches those exactly and maps |
| 32 | # to itself, instead of being re-read as a Nordic blend and drifting a little |
| 33 | # darker on every run. render-xfwm4.sh calls this after rendering, so it does |
| 34 | # get run more than once. |
| 35 | HOVER_TINT = "#131214" |
| 36 | |
| 37 | ANCHORS = [ |
| 38 | (dm.rgb("#353c4a"), dm.rgb(dm.DARK)), |
| 39 | (dm.rgb("#363d4b"), dm.rgb(HOVER_TINT)), # the menu button's hover tint |
| 40 | (dm.rgb("#000000"), dm.rgb("#000000")), |
| 41 | (dm.rgb("#ffffff"), dm.rgb("#ffffff")), |
| 42 | (dm.rgb(dm.DARK), dm.rgb(dm.DARK)), |
| 43 | (dm.rgb(HOVER_TINT), dm.rgb(HOVER_TINT)), |
| 44 | ] |
| 45 | |
| 46 | DIRS = [ |
| 47 | "xfwm4", |
| 48 | "xfwm4/Darkmatter-hdpi/xfwm4", |
| 49 | "xfwm4/Darkmatter-xhdpi/xfwm4", |
| 50 | ] |
| 51 | |
| 52 | |
| 53 | def main(): |
| 54 | remap = Remapper(ANCHORS) |
| 55 | done = 0 |
| 56 | for d in DIRS: |
| 57 | for name in NO_SVG: |
| 58 | path = os.path.join(d, name + ".png") |
| 59 | if not os.path.exists(path): |
| 60 | continue |
| 61 | img = Png(path) |
| 62 | if img.color_type == 3: |
| 63 | img.set_palette([remap(c) for c in img.palette()]) |
| 64 | elif img.color_type == 6: |
| 65 | img.set_rgba([remap(p[:3]) + (p[3],) for p in img.rgba()]) |
| 66 | else: |
| 67 | print(" skipped (colour type %d): %s" % (img.color_type, path)) |
| 68 | continue |
| 69 | img.save() |
| 70 | done += 1 |
| 71 | print("recoloured %d frame PNGs" % done) |
| 72 | |
| 73 | |
| 74 | if __name__ == "__main__": |
| 75 | main() |