tonigi's picture
Add complete Gradio interface
3c2cd23 verified
Raw History Blame Contribute Delete
2.55 kB
from __future__ import annotations
import base64
from io import BytesIO
from dataclasses import dataclass
from functools import lru_cache
from importlib.resources import files
from pathlib import Path
@dataclass(frozen=True, slots=True)
class FontFace:
family: str
weight: int
italic: bool
filename: str
@property
def path(self) -> Path:
return Path(str(files("editable_image").joinpath("fonts", self.filename)))
FACES = (
FontFace("Lato", 400, False, "Lato-Regular.ttf"),
FontFace("Lato", 400, True, "Lato-Italic.ttf"),
FontFace("Lato", 700, False, "Lato-Bold.ttf"),
FontFace("Lato", 700, True, "Lato-BoldItalic.ttf"),
FontFace("Liberation Sans", 400, False, "LiberationSans-Regular.ttf"),
FontFace("Liberation Sans", 400, True, "LiberationSans-Italic.ttf"),
FontFace("Liberation Sans", 700, False, "LiberationSans-Bold.ttf"),
FontFace("Liberation Sans", 700, True, "LiberationSans-BoldItalic.ttf"),
FontFace("Liberation Serif", 400, False, "LiberationSerif-Regular.ttf"),
FontFace("Liberation Serif", 400, True, "LiberationSerif-Italic.ttf"),
FontFace("Liberation Serif", 700, False, "LiberationSerif-Bold.ttf"),
FontFace("Liberation Serif", 700, True, "LiberationSerif-BoldItalic.ttf"),
FontFace("Liberation Mono", 400, False, "LiberationMono-Regular.ttf"),
FontFace("Liberation Mono", 400, True, "LiberationMono-Italic.ttf"),
FontFace("Liberation Mono", 700, False, "LiberationMono-Bold.ttf"),
FontFace("Liberation Mono", 700, True, "LiberationMono-BoldItalic.ttf"),
)
def families() -> list[str]:
return list(dict.fromkeys(face.family for face in FACES if face.path.exists()))
def get_face(family: str, weight: int, italic: bool) -> FontFace:
candidates = [face for face in FACES if face.family == family and face.path.exists()]
if not candidates:
candidates = [face for face in FACES if face.path.exists()]
if not candidates:
raise FileNotFoundError("No bundled fonts are installed")
return min(
candidates,
key=lambda face: abs(face.weight - weight) + (1000 if face.italic != italic else 0),
)
@lru_cache(maxsize=32)
def font_data_uri(filename: str) -> str:
path = Path(str(files("editable_image").joinpath("fonts", filename)))
from fontTools.ttLib import TTFont
font = TTFont(path)
font.flavor = "woff2"
output = BytesIO()
font.save(output)
data = base64.b64encode(output.getvalue()).decode("ascii")
return f"data:font/woff2;base64,{data}"