summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--def.go11
-rw-r--r--fpdf.go37
2 files changed, 46 insertions, 2 deletions
diff --git a/def.go b/def.go
index df21e05..33eca47 100644
--- a/def.go
+++ b/def.go
@@ -18,6 +18,7 @@ package gofpdf
import (
"bytes"
+ "io"
)
// Version of FPDF from which this package is derived
@@ -132,6 +133,15 @@ type InitType struct {
FontDirStr string
}
+// FontLoader is used to read fonts (JSON font specification and zlib compressed font binaries)
+// from arbitrary locations (e.g. files, zip files, embedded font resources).
+//
+// Open provides an io.Reader for the specified font file (.json or .z). The file name
+// does never include a path. Open returns an error if the specified file cannot be opened.
+type FontLoader interface {
+ Open(name string) (io.Reader, error)
+}
+
// Fpdf is the principal structure for creating a single PDF document
type Fpdf struct {
page int // current page number
@@ -160,6 +170,7 @@ type Fpdf struct {
lasth float64 // height of last printed cell
lineWidth float64 // line width in user unit
fontpath string // path containing fonts
+ fontLoader FontLoader // used to load font files from arbitrary locations
coreFonts map[string]bool // array of core font names
fonts map[string]fontDefType // array of used fonts
fontFiles map[string]fontFileType // array of font files
diff --git a/fpdf.go b/fpdf.go
index 1508548..b2872e6 100644
--- a/fpdf.go
+++ b/fpdf.go
@@ -313,6 +313,14 @@ func (f *Fpdf) SetFontLocation(fontDirStr string) {
f.fontpath = fontDirStr
}
+// SetFontLoader sets a loader used to load font files (.json and .z) from
+// arbitrary locations. If a font loader has been specified, Fpdf first tries
+// to load files using the font loader. If the loading files Fpdf tries to
+// load the font from the configured fonts directory (see SetFontLocation).
+func (f *Fpdf) SetFontLoader(loader FontLoader) {
+ f.fontLoader = loader
+}
+
// SetHeaderFunc sets the function that lets the application render the page
// header. The specified function is automatically called by AddPage() and
// should not be called directly by the application. The implementation in Fpdf
@@ -1358,8 +1366,19 @@ func (f *Fpdf) AddFont(familyStr, styleStr, fileStr string) {
if fileStr == "" {
fileStr = strings.Replace(familyStr, " ", "", -1) + strings.ToLower(styleStr) + ".json"
}
- fileStr = path.Join(f.fontpath, fileStr)
+ if f.fontLoader != nil {
+ reader, err := f.fontLoader.Open(fileStr)
+ if err == nil {
+ f.AddFontFromReader(familyStr, styleStr, reader)
+ if closer, ok := reader.(io.Closer); ok {
+ closer.Close()
+ }
+ return
+ }
+ }
+
+ fileStr = path.Join(f.fontpath, fileStr)
file, err := os.Open(fileStr)
if err != nil {
f.err = err
@@ -2971,7 +2990,7 @@ func (f *Fpdf) putfonts() {
f.newobj()
info.n = f.n
f.fontFiles[file] = info
- font, err := ioutil.ReadFile(path.Join(f.fontpath, file))
+ font, err := f.loadFontFile(file)
if err != nil {
f.err = err
return
@@ -3071,6 +3090,20 @@ func (f *Fpdf) putfonts() {
return
}
+func (f *Fpdf) loadFontFile(name string) ([]byte, error) {
+ if f.fontLoader != nil {
+ reader, err := f.fontLoader.Open(name)
+ if err == nil {
+ data, err := ioutil.ReadAll(reader)
+ if closer, ok := reader.(io.Closer); ok {
+ closer.Close()
+ }
+ return data, err
+ }
+ }
+ return ioutil.ReadFile(path.Join(f.fontpath, name))
+}
+
func (f *Fpdf) putimages() {
for _, img := range f.images {
f.putimage(img)