mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-11 22:36:38 +00:00

This allows much better compression (-60%) than gziping them individually and also allows us to build the capsule UX images as part of the build stage. Also add more popular screen resolutions for laptops you can buy in 2021.
192 lines
6.6 KiB
Python
Executable File
192 lines
6.6 KiB
Python
Executable File
#!/usr/bin/python3
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
# Copyright (C) 2017 Peter Jones <pjones@redhat.com>
|
|
# Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
|
#
|
|
# SPDX-License-Identifier: LGPL-2.1+
|
|
#
|
|
# pylint: disable=wrong-import-position,too-many-locals,unused-argument,too-many-statements
|
|
# pylint: disable=invalid-name,too-many-instance-attributes,missing-module-docstring
|
|
# pylint: disable=missing-function-docstring,missing-class-docstring,too-few-public-methods
|
|
|
|
import os
|
|
import sys
|
|
import argparse
|
|
import tarfile
|
|
import math
|
|
import io
|
|
from typing import Dict, Optional, Any
|
|
|
|
import cairo
|
|
import gi
|
|
|
|
gi.require_version("Pango", "1.0")
|
|
gi.require_version("PangoCairo", "1.0")
|
|
from gi.repository import Pango, PangoCairo
|
|
from PIL import Image
|
|
|
|
|
|
def languages(podir: str):
|
|
for x in open(os.path.join(podir, "LINGUAS"), "r").readlines():
|
|
yield x.strip()
|
|
yield "en"
|
|
|
|
|
|
class PotFile:
|
|
def __init__(self, fn=None):
|
|
self.msgs: Dict[str, str] = {}
|
|
if fn:
|
|
self.parse(fn)
|
|
|
|
def parse(self, fn: str) -> None:
|
|
with open(fn, "r") as f:
|
|
lang_en: Optional[str] = None
|
|
for line in f.read().split("\n"):
|
|
if not line:
|
|
continue
|
|
if line[0] == "#":
|
|
continue
|
|
try:
|
|
key, value = line.split(" ", maxsplit=1)
|
|
except ValueError as _:
|
|
continue
|
|
if key == "msgid":
|
|
lang_en = value[1:-1]
|
|
continue
|
|
if key == "msgstr" and lang_en:
|
|
self.msgs[lang_en] = value[1:-1]
|
|
lang_en = None
|
|
continue
|
|
|
|
|
|
def main(args) -> int:
|
|
|
|
# open output archive
|
|
with tarfile.open(args.out, "w:xz") as tar:
|
|
|
|
for lang in languages(args.podir):
|
|
# these are the 1.6:1 of some common(ish) screen widths
|
|
if lang == "en":
|
|
label_translated: str = args.label
|
|
else:
|
|
potfile = PotFile(os.path.join(args.podir, "{}.po".format(lang)))
|
|
try:
|
|
label_translated = potfile.msgs[args.label]
|
|
except KeyError as _:
|
|
continue
|
|
if label_translated == args.label:
|
|
continue
|
|
for width, height in (
|
|
(640, 480),
|
|
(800, 600),
|
|
(1024, 768),
|
|
(1280, 720),
|
|
(1280, 800),
|
|
(1366, 768),
|
|
(1536, 864),
|
|
(1600, 900),
|
|
(1920, 1080),
|
|
(1920, 1200),
|
|
(2160, 1350),
|
|
(2560, 1440),
|
|
(3840, 2160),
|
|
(5120, 2880),
|
|
(5688, 3200),
|
|
(7680, 4320),
|
|
):
|
|
|
|
# generate PangoLanguage
|
|
font_desc = "Sans %.2fpx" % (height / 32,)
|
|
fd = Pango.FontDescription(font_desc)
|
|
font_option = cairo.FontOptions()
|
|
font_option.set_antialias(cairo.ANTIALIAS_SUBPIXEL)
|
|
l = Pango.Language.from_string(lang)
|
|
|
|
# create surface
|
|
img = cairo.ImageSurface(cairo.FORMAT_RGB24, 1, 1)
|
|
cctx = cairo.Context(img)
|
|
layout = PangoCairo.create_layout(cctx)
|
|
pctx = layout.get_context()
|
|
pctx.set_font_description(fd)
|
|
pctx.set_language(l)
|
|
fs = pctx.load_fontset(fd, l)
|
|
PangoCairo.context_set_font_options(pctx, font_option)
|
|
|
|
attrs = Pango.AttrList()
|
|
length = len(bytes(label_translated, "utf8"))
|
|
items = Pango.itemize(pctx, label_translated, 0, length, attrs, None)
|
|
gs = Pango.GlyphString()
|
|
Pango.shape(label_translated, length, items[0].analysis, gs)
|
|
del img, cctx, pctx, layout
|
|
|
|
def find_size(fs, f, data):
|
|
""" find our size, I hope... """
|
|
(ink, log) = gs.extents(f)
|
|
if ink.height == 0 or ink.width == 0:
|
|
return False
|
|
data.update({"log": log, "ink": ink})
|
|
return True
|
|
|
|
data: Dict[str, Any] = {}
|
|
fs.foreach(find_size, data)
|
|
if len(data) == 0:
|
|
print("Missing sans fonts")
|
|
return 2
|
|
log = data["log"]
|
|
ink = data["ink"]
|
|
|
|
surface_height = math.ceil(max(ink.height, log.height) / Pango.SCALE)
|
|
surface_width = math.ceil(max(ink.width, log.width) / Pango.SCALE)
|
|
|
|
x = -math.ceil(log.x / Pango.SCALE)
|
|
y = -math.ceil(log.y / Pango.SCALE)
|
|
|
|
img = cairo.ImageSurface(
|
|
cairo.FORMAT_RGB24, surface_width, surface_height
|
|
)
|
|
cctx = cairo.Context(img)
|
|
layout = PangoCairo.create_layout(cctx)
|
|
pctx = layout.get_context()
|
|
PangoCairo.context_set_font_options(pctx, font_option)
|
|
|
|
cctx.set_source_rgb(1, 1, 1)
|
|
cctx.move_to(x, y)
|
|
|
|
def do_write(fs, f, data):
|
|
""" write out glyphs """
|
|
ink = gs.extents(f)[0]
|
|
if ink.height == 0 or ink.width == 0:
|
|
return False
|
|
PangoCairo.show_glyph_string(cctx, f, gs)
|
|
return True
|
|
|
|
fs.foreach(do_write, None)
|
|
img.flush()
|
|
|
|
# write PNG
|
|
with io.BytesIO() as io_png:
|
|
img.write_to_png(io_png)
|
|
io_png.seek(0)
|
|
|
|
# convert to BMP and add to archive
|
|
with io.BytesIO() as io_bmp:
|
|
pimg = Image.open(io_png)
|
|
pimg.save(io_bmp, format="BMP")
|
|
filename = "fwupd-{}-{}-{}.bmp".format(lang, width, height)
|
|
tarinfo = tarfile.TarInfo(filename)
|
|
tarinfo.size = io_bmp.tell()
|
|
io_bmp.seek(0)
|
|
tar.addfile(tarinfo, fileobj=io_bmp)
|
|
|
|
# success
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(description="Make UX images")
|
|
parser.add_argument("--label", help="Update text", required=True)
|
|
parser.add_argument("--podir", help="Po location", required=True)
|
|
parser.add_argument("--out", help="Output archive", required=True)
|
|
sys.exit(main(parser.parse_args()))
|