@@ -6,7 +6,6 @@ from pathlib import Path
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont, features
|
||||
|
||||
|
||||
REPO = Path(__file__).resolve().parents[1]
|
||||
FONT_PATH = REPO / "package/assets/fonts/petaluma/PetalumaScript.otf"
|
||||
FONT_SIZE = 32
|
||||
@@ -15,7 +14,6 @@ FONT_MAX_WIDTH = 28
|
||||
FIRST_CODEPOINT = 32
|
||||
LAST_CODEPOINT = 126
|
||||
|
||||
|
||||
def cpp_char_literal(value: str) -> str:
|
||||
if value == "'":
|
||||
return "'\\''"
|
||||
@@ -23,30 +21,26 @@ def cpp_char_literal(value: str) -> str:
|
||||
return "'\\\\'"
|
||||
return f"'{value}'"
|
||||
|
||||
|
||||
def render_glyph(font: ImageFont.FreeTypeFont, value: str, y_offset: int) -> tuple[list[int], int, int]:
|
||||
image = Image.new("L", (FONT_MAX_WIDTH, FONT_HEIGHT), 0)
|
||||
draw = ImageDraw.Draw(image)
|
||||
bbox = font.getbbox(value)
|
||||
x = max(0, -bbox[0])
|
||||
draw.text((x, y_offset), value, font=font, fill=255)
|
||||
|
||||
pixels = [min(15, max(0, round(pixel / 17))) for pixel in image.get_flattened_data()]
|
||||
visible = image.getbbox()
|
||||
width = 0 if visible is None else min(FONT_MAX_WIDTH, visible[2])
|
||||
advance = min(255, max(0, round(font.getlength(value))))
|
||||
return pixels, width, advance
|
||||
|
||||
|
||||
def render_alpha_rows(values: list[int]) -> list[str]:
|
||||
lines = []
|
||||
for row in range(FONT_HEIGHT):
|
||||
start = row * FONT_MAX_WIDTH
|
||||
row_values = values[start : start + FONT_MAX_WIDTH]
|
||||
row_values = values[start: start + FONT_MAX_WIDTH]
|
||||
lines.append(" " + ", ".join(f"0x{value:02x}" for value in row_values) + ",")
|
||||
return lines
|
||||
|
||||
|
||||
def pair_adjustments(font: ImageFont.FreeTypeFont) -> list[tuple[int, int]]:
|
||||
chars = [chr(value) for value in range(FIRST_CODEPOINT, LAST_CODEPOINT + 1)]
|
||||
adjustments = []
|
||||
@@ -60,7 +54,6 @@ def pair_adjustments(font: ImageFont.FreeTypeFont) -> list[tuple[int, int]]:
|
||||
adjustments.append((key, int(adjustment)))
|
||||
return sorted(adjustments)
|
||||
|
||||
|
||||
def generate() -> str:
|
||||
if not features.check_feature("raqm"):
|
||||
raise RuntimeError("Font generation requires Pillow with Raqm support; install libfribidi0 on Debian/Ubuntu.")
|
||||
@@ -68,7 +61,6 @@ def generate() -> str:
|
||||
min_top = min(font.getbbox(chr(value))[1] for value in range(FIRST_CODEPOINT, LAST_CODEPOINT + 1))
|
||||
y_offset = max(0, -min_top)
|
||||
adjustments = pair_adjustments(font)
|
||||
|
||||
lines = [
|
||||
"#include <vamp_style/font.hpp>",
|
||||
"",
|
||||
@@ -112,7 +104,6 @@ def generate() -> str:
|
||||
" switch (value) {",
|
||||
]
|
||||
)
|
||||
|
||||
for codepoint in range(FIRST_CODEPOINT, LAST_CODEPOINT + 1):
|
||||
value = chr(codepoint)
|
||||
alpha, width, advance = render_glyph(font, value, y_offset)
|
||||
@@ -132,7 +123,6 @@ def generate() -> str:
|
||||
" };",
|
||||
]
|
||||
)
|
||||
|
||||
lines.extend(
|
||||
[
|
||||
" default:",
|
||||
@@ -171,13 +161,11 @@ def generate() -> str:
|
||||
)
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--output", type=Path, required=True)
|
||||
parser.add_argument("--check", action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
generated = generate()
|
||||
if args.check:
|
||||
if not args.output.is_file():
|
||||
@@ -195,12 +183,10 @@ def main() -> int:
|
||||
)
|
||||
print("\n".join(diff))
|
||||
return 1
|
||||
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_text(generated, encoding="utf-8")
|
||||
print(f"generated {args.output}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
|
||||
Reference in New Issue
Block a user