@@ -0,0 +1,109 @@
|
||||
"""Регистрация 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()
|
||||
Reference in New Issue
Block a user