129 lines
2.5 KiB
Go
129 lines
2.5 KiB
Go
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
|
|
}
|