package routes import ( "fmt" "os" "path/filepath" "strings" "github.com/jung-kurt/gofpdf" ) func resolvePdfAssetPath(fileName string) (string, error) { return resolveAssetPath(fileName, []string{ "fonts", filepath.Join("svc", "fonts"), }) } 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, regularFamily, boldFamily string) error { regularFont, err := resolvePdfAssetPath("DejaVuSans.ttf") if err != nil { return err } boldFont, err := resolvePdfAssetPath("DejaVuSans-Bold.ttf") if err != nil { return err } pdf.AddUTF8Font(regularFamily, "", regularFont) pdf.AddUTF8Font(boldFamily, "", boldFont) if err := pdf.Error(); err != nil { return fmt.Errorf("font init failed: %w", err) } return nil }