From 6d3c17d19d1aa9ba933c538852457f774fcec584 Mon Sep 17 00:00:00 2001 From: asepharyana Date: Wed, 16 Sep 2026 16:48:27 +0700 Subject: [PATCH] =?UTF-8?q?fix:=20PDF=20export=20kini=20Unicode=20?= =?UTF-8?q?=E2=80=94=20ganti=20core=20font=20Helvetica=20(latin1=20?= =?UTF-8?q?=E2=86=92=20'=3F')=20dengan=20DejaVuSans=20ter-embed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/reports/render.go | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/backend/internal/reports/render.go b/backend/internal/reports/render.go index 943ff0d..130d690 100644 --- a/backend/internal/reports/render.go +++ b/backend/internal/reports/render.go @@ -54,25 +54,31 @@ func (r Report) ToHTML() string { } // ToPDF renders the report server-side (pure Go, no system deps). +// Font: DejaVuSans (Unicode) instead of core Helvetica so Indonesian text +// (Em-dash, quotes, Rp, accents) renders correctly — latin1() was turning +// every non-Latin rune into '?'. func (r Report) ToPDF() ([]byte, error) { pdf := gofpdf.New("P", "mm", "A4", "") + pdf.SetFontLocation("/usr/share/fonts/truetype/dejavu/") + pdf.AddUTF8Font("DejaVu", "", "DejaVuSans.ttf") + pdf.AddUTF8Font("DejaVu", "B", "DejaVuSans-Bold.ttf") pdf.AddPage() - pdf.SetFont("Helvetica", "B", 16) + pdf.SetFont("DejaVu", "B", 14) pdf.Cell(0, 10, r.Ticker+" — FlowSight Report") pdf.Ln(12) - pdf.SetFont("Helvetica", "", 10) + pdf.SetFont("DejaVu", "", 10) pdf.Cell(0, 6, "Generated "+r.GeneratedAt) pdf.Ln(8) for _, s := range r.Sections { - pdf.SetFont("Helvetica", "B", 12) + pdf.SetFont("DejaVu", "B", 12) pdf.Cell(0, 8, s.Name) pdf.Ln(8) - pdf.SetFont("Helvetica", "", 10) - pdf.MultiCell(0, 5, latin1(s.Body), "", "", false) + pdf.SetFont("DejaVu", "", 10) + pdf.MultiCell(0, 5, s.Body, "", "", false) if len(s.Citations) > 0 { - pdf.SetFont("Helvetica", "I", 8) + pdf.SetFont("DejaVu", "", 8) for _, c := range s.Citations { - pdf.MultiCell(0, 4, latin1(c.Endpoint+" "+c.Ticker+" @ "+c.SnapshotAt), "", "", false) + pdf.MultiCell(0, 4, c.Endpoint+" "+c.Ticker+" @ "+c.SnapshotAt, "", "", false) } } pdf.Ln(4) @@ -83,13 +89,3 @@ func (r Report) ToPDF() ([]byte, error) { } return buf.Bytes(), nil } - -// latin1 drops non-latin runes gofpdf core fonts cannot render. -func latin1(s string) string { - return strings.Map(func(r rune) rune { - if r > 255 { - return '?' - } - return r - }, s) -}