61 lines
1.9 KiB
Python
61 lines
1.9 KiB
Python
"""CJK font registration helper for reportlab using WenQuanYi Micro Hei TTF."""
|
|
|
|
from reportlab.pdfbase import pdfmetrics
|
|
from reportlab.pdfbase.ttfonts import TTFont
|
|
|
|
_REGISTERED = False
|
|
CJK_FONT = "Helvetica" # fallback
|
|
|
|
|
|
def register_cjk_font():
|
|
"""Register a CJK font with reportlab. Returns the font name to use."""
|
|
global _REGISTERED, CJK_FONT
|
|
if _REGISTERED:
|
|
return CJK_FONT
|
|
|
|
# WenQuanYi Micro Hei: TTC with TrueType outlines (reportlab compatible)
|
|
# subfontIndex 0 = regular
|
|
candidates = [
|
|
"/usr/share/fonts/wenquanyi/wqy-microhei/wqy-microhei.ttc",
|
|
"/usr/share/fonts/wqy-microhei/wqy-microhei.ttc",
|
|
]
|
|
|
|
for path in candidates:
|
|
try:
|
|
pdfmetrics.registerFont(TTFont("WenQuanYi", path, subfontIndex=0))
|
|
CJK_FONT = "WenQuanYi"
|
|
_REGISTERED = True
|
|
return CJK_FONT
|
|
except Exception:
|
|
continue
|
|
|
|
print("WARNING: No CJK font available, Chinese text may not render correctly")
|
|
_REGISTERED = True
|
|
return CJK_FONT
|
|
|
|
|
|
def _has_cjk(text: str) -> bool:
|
|
"""Check if text contains CJK characters."""
|
|
for ch in text:
|
|
cp = ord(ch)
|
|
if (
|
|
0x4E00 <= cp <= 0x9FFF # CJK Unified Ideographs
|
|
or 0x3400 <= cp <= 0x4DBF # CJK Extension A
|
|
or 0x3000 <= cp <= 0x303F # CJK Symbols
|
|
or 0xFF00 <= cp <= 0xFFEF # Fullwidth Forms
|
|
or 0x2E80 <= cp <= 0x2EFF # CJK Radicals
|
|
or 0xF900 <= cp <= 0xFAFF # CJK Compatibility
|
|
):
|
|
return True
|
|
return False
|
|
|
|
|
|
def draw_cjk_text(c, x, y, text, font_name="Helvetica", font_size=10):
|
|
"""Draw text, switching to CJK font if needed."""
|
|
cjk_font = register_cjk_font()
|
|
if _has_cjk(text) and cjk_font != "Helvetica":
|
|
c.setFont(cjk_font, font_size)
|
|
else:
|
|
c.setFont(font_name, font_size)
|
|
c.drawString(x, y, text)
|