diff options
| -rw-r--r-- | def.go | 11 | ||||
| -rw-r--r-- | fpdf.go | 37 | 
2 files changed, 46 insertions, 2 deletions
| @@ -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 @@ -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) | 
