Spaces:
Build error
Build error
File size: 2,545 Bytes
3c2cd23 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | 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}"
|