Files
site/WESP_REL/app/services/pdf_cyrillic_fonts.py
2026-07-17 12:57:18 +03:00

110 lines
3.3 KiB
Python

"""Регистрация TTF с кириллицей для reportlab (Linux / macOS / Windows)."""
from __future__ import annotations
import os
from pathlib import Path
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
_FONT_REGISTERED = False
_FONT_BOLD_REGISTERED = False
_PROJECT_ROOT = Path(__file__).resolve().parents[2]
def _windows_fonts_dir() -> Path:
windir = os.environ.get("WINDIR", r"C:\Windows")
return Path(windir) / "Fonts"
def _cyrillic_font_candidates(*, bold: bool = False) -> list[Path]:
bundled = (
_PROJECT_ROOT / "vendor" / "fonts" / ("DejaVuSans-Bold.ttf" if bold else "DejaVuSans.ttf")
)
candidates: list[Path] = [bundled]
if os.name == "nt":
win = _windows_fonts_dir()
if bold:
candidates.extend(
[
win / "arialbd.ttf",
win / "segoeuib.ttf",
win / "calibrib.ttf",
win / "timesbd.ttf",
]
)
else:
candidates.extend(
[
win / "arial.ttf",
win / "segoeui.ttf",
win / "calibri.ttf",
win / "times.ttf",
]
)
if bold:
candidates.extend(
[
Path("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf"),
Path("/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf"),
Path("/System/Library/Fonts/Supplemental/Arial Bold.ttf"),
Path("/Library/Fonts/Arial Bold.ttf"),
]
)
else:
candidates.extend(
[
Path("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"),
Path("/usr/share/fonts/dejavu/DejaVuSans.ttf"),
Path("/System/Library/Fonts/Supplemental/Arial Unicode.ttf"),
Path("/Library/Fonts/Arial Unicode.ttf"),
Path("/System/Library/Fonts/Supplemental/Arial.ttf"),
]
)
seen: set[str] = set()
unique: list[Path] = []
for path in candidates:
key = str(path).lower()
if key in seen:
continue
seen.add(key)
unique.append(path)
return unique
def register_cyrillic_font() -> str:
"""Возвращает имя зарегистрированного шрифта reportlab или Helvetica (без кириллицы)."""
global _FONT_REGISTERED
if _FONT_REGISTERED:
return "WespCyr"
for path in _cyrillic_font_candidates(bold=False):
if not path.is_file():
continue
try:
pdfmetrics.registerFont(TTFont("WespCyr", str(path)))
_FONT_REGISTERED = True
return "WespCyr"
except Exception:
continue
return "Helvetica"
def register_cyrillic_font_bold() -> str:
global _FONT_BOLD_REGISTERED
if _FONT_BOLD_REGISTERED:
return "WespCyrBold"
for path in _cyrillic_font_candidates(bold=True):
if not path.is_file():
continue
try:
pdfmetrics.registerFont(TTFont("WespCyrBold", str(path)))
_FONT_BOLD_REGISTERED = True
return "WespCyrBold"
except Exception:
continue
return register_cyrillic_font()