Files
bssapp/svc/routes/pdf_assets.go

96 lines
2.0 KiB
Go

package routes
import (
"fmt"
"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 == "" {
base = "/opt/bssapp/svc/fonts"
}
p := filepath.Join(base, name)
if _, err := os.Stat(p); err != nil {
return "", fmt.Errorf("font not found: %s", p)
}
return p, 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, 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
}