package routes import ( "fmt" "log" "os" "path/filepath" "strings" "github.com/jung-kurt/gofpdf" ) func resolvePdfAssetPath(name string) (string, error) { base := strings.TrimSpace(os.Getenv("PDF_FONT_DIR")) if base == "" { return "", fmt.Errorf("env PDF_FONT_DIR not set") } if !strings.HasPrefix(base, "/") { base = "/" + base } name = strings.TrimSpace(name) name = strings.TrimPrefix(name, "/") name = strings.TrimPrefix(name, "\\") full := filepath.Join(base, name) full = filepath.Clean(full) log.Printf("📄 PDF FONT PATH = %s", full) if _, err := os.Stat(full); err != nil { return "", fmt.Errorf("font not found: %s (%v)", full, err) } return full, nil } func resolvePdfImagePath(fileName string) (string, error) { return resolveAssetPath(fileName, []string{ "public", filepath.Join("svc", "public"), }) } func resolveAssetPath(fileName string, relativeDirs []string) (string, error) { candidates := make([]string, 0, len(relativeDirs)*3) for _, dir := range relativeDirs { candidates = append(candidates, filepath.Join(dir, fileName), filepath.Join(".", dir, fileName), filepath.Join("..", dir, fileName), ) } if exePath, err := os.Executable(); err == nil { exeDir := filepath.Dir(exePath) for _, dir := range relativeDirs { candidates = append(candidates, filepath.Join(exeDir, dir, fileName), filepath.Join(exeDir, "..", dir, fileName), ) } } seen := map[string]struct{}{} tried := make([]string, 0, len(candidates)) for _, p := range candidates { if abs, err := filepath.Abs(p); err == nil { p = abs } if _, ok := seen[p]; ok { continue } seen[p] = struct{}{} tried = append(tried, p) if fi, err := os.Stat(p); err == nil && !fi.IsDir() { return p, nil } } return "", fmt.Errorf("asset not found: %s (tried: %s)", fileName, strings.Join(tried, ", ")) } func registerDejavuFonts(pdf *gofpdf.Fpdf, s string, s2 string) error { regPath, err := resolvePdfAssetPath("DejaVuSans.ttf") if err != nil { return err } boldPath, err := resolvePdfAssetPath("DejaVuSans-Bold.ttf") if err != nil { return err } // SAME FAMILY: "dejavu" pdf.AddUTF8FontFromBytes( "dejavu", "", mustReadFile(regPath), ) pdf.AddUTF8FontFromBytes( "dejavu", "B", mustReadFile(boldPath), ) if pdf.Error() != nil { return fmt.Errorf("font init failed: %w", pdf.Error()) } return nil } func mustReadFile(path string) []byte { b, err := os.ReadFile(path) if err != nil { panic("FONT READ ERROR: " + err.Error()) } return b }