First commit
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
"""Generate PDF: IPD Filing Receipt (native text PDF, bilingual)."""
|
||||
|
||||
from pathlib import Path
|
||||
from reportlab.lib.pagesizes import A4
|
||||
from reportlab.lib.units import mm
|
||||
from reportlab.pdfgen import canvas
|
||||
from reportlab.lib.colors import HexColor
|
||||
from generators.cjk_font import register_cjk_font
|
||||
|
||||
|
||||
def _set_font(c, bold=False, size=10):
|
||||
"""Set font with CJK support."""
|
||||
cjk = register_cjk_font()
|
||||
if cjk != "Helvetica":
|
||||
c.setFont(cjk, size)
|
||||
else:
|
||||
c.setFont("Helvetica-Bold" if bold else "Helvetica", size)
|
||||
|
||||
|
||||
def _has_cjk(text):
|
||||
"""Check if text contains CJK characters."""
|
||||
return any(ord(ch) > 0x2E80 for ch in text)
|
||||
|
||||
|
||||
def generate(
|
||||
output_path: Path,
|
||||
ipd: dict,
|
||||
tm_number: str,
|
||||
tm_text: str,
|
||||
applicant: str,
|
||||
applicant_address: str,
|
||||
agent: str,
|
||||
agent_address: str,
|
||||
filing_date: str,
|
||||
response_deadline: str,
|
||||
nice_class: str,
|
||||
class_description: str,
|
||||
):
|
||||
"""Generate an IPD filing receipt PDF."""
|
||||
cjk = register_cjk_font()
|
||||
c = canvas.Canvas(str(output_path), pagesize=A4)
|
||||
w, h = A4
|
||||
|
||||
def draw_text(x, y_pos, text, size=10, bold=False, centered=False):
|
||||
"""Draw text, auto-switching to CJK font if needed."""
|
||||
if _has_cjk(text) and cjk != "Helvetica":
|
||||
c.setFont(cjk, size)
|
||||
else:
|
||||
c.setFont("Helvetica-Bold" if bold else "Helvetica", size)
|
||||
if centered:
|
||||
c.drawCentredString(x, y_pos, text)
|
||||
else:
|
||||
c.drawString(x, y_pos, text)
|
||||
|
||||
# Header
|
||||
draw_text(w / 2, h - 50, ipd["name"], 12, bold=True, centered=True)
|
||||
draw_text(w / 2, h - 66, ipd["chinese_name"], 10, centered=True)
|
||||
draw_text(
|
||||
w / 2,
|
||||
h - 82,
|
||||
"The Government of the Hong Kong Special Administrative Region",
|
||||
10,
|
||||
centered=True,
|
||||
)
|
||||
|
||||
# Divider
|
||||
c.setStrokeColor(HexColor("#333333"))
|
||||
c.setLineWidth(1)
|
||||
c.line(50, h - 95, w - 50, h - 95)
|
||||
|
||||
# Title
|
||||
draw_text(
|
||||
w / 2,
|
||||
h - 120,
|
||||
"E-Filing Receipt / Acknowledgment",
|
||||
14,
|
||||
bold=True,
|
||||
centered=True,
|
||||
)
|
||||
|
||||
# Receipt details
|
||||
y = h - 160
|
||||
fields = [
|
||||
("Receipt No.:", f"EF-{tm_number[-6:]}"),
|
||||
("Application No. / 申請編號:", tm_number),
|
||||
("Trade Mark Text / 商標文字:", tm_text),
|
||||
("Mark Type / 商標種類:", "Ordinary"),
|
||||
("Class No. / 類別編號:", nice_class),
|
||||
("Specification / 貨品/服務說明:", class_description),
|
||||
("", ""),
|
||||
("Applicant / 申請人:", applicant),
|
||||
("Address / 地址:", applicant_address),
|
||||
("", ""),
|
||||
("Agent / 代理人:", agent),
|
||||
("Agent Address / 代理人地址:", agent_address),
|
||||
("", ""),
|
||||
("Date of Filing / 提交日期:", filing_date),
|
||||
("Date of Receipt / 確認日期:", filing_date),
|
||||
]
|
||||
|
||||
for label, value in fields:
|
||||
if not label and not value:
|
||||
y -= 10
|
||||
continue
|
||||
draw_text(50, y, label, 10, bold=True)
|
||||
# Wrap long values
|
||||
if len(value) > 60:
|
||||
draw_text(250, y, value[:60], 10)
|
||||
y -= 16
|
||||
draw_text(250, y, value[60:120], 10)
|
||||
else:
|
||||
draw_text(250, y, value, 10)
|
||||
y -= 18
|
||||
|
||||
# Response deadline (highlighted)
|
||||
y -= 15
|
||||
c.setStrokeColor(HexColor("#cc0000"))
|
||||
c.setLineWidth(0.5)
|
||||
c.rect(40, y - 10, w - 80, 40, stroke=1, fill=0)
|
||||
|
||||
c.setFillColor(HexColor("#cc0000"))
|
||||
draw_text(50, y + 12, "IMPORTANT / 重要通知:", 11, bold=True)
|
||||
c.setFillColor(HexColor("#000000"))
|
||||
draw_text(50, y - 4, f"Response deadline / 回覆限期: {response_deadline}", 10)
|
||||
|
||||
# Footer
|
||||
y -= 50
|
||||
c.setFillColor(HexColor("#666666"))
|
||||
draw_text(
|
||||
w / 2,
|
||||
y,
|
||||
"This is a computer-generated receipt. No signature is required.",
|
||||
8,
|
||||
centered=True,
|
||||
)
|
||||
draw_text(w / 2, y - 14, "此為電腦自動產生之收據,毋須簽署。", 8, centered=True)
|
||||
|
||||
c.save()
|
||||
Reference in New Issue
Block a user