summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compare.go149
-rw-r--r--contrib/barcode/barcode_test.go7
-rw-r--r--contrib/httpimg/httpimg_test.go7
-rw-r--r--def.go7
-rw-r--r--fpdf.go300
-rw-r--r--fpdf_test.go14
-rw-r--r--internal/example/example.go25
-rw-r--r--template.go6
8 files changed, 403 insertions, 112 deletions
diff --git a/compare.go b/compare.go
new file mode 100644
index 0000000..64cad1f
--- /dev/null
+++ b/compare.go
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2015 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package gofpdf
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "sort"
+)
+
+type sortType struct {
+ length int
+ less func(int, int) bool
+ swap func(int, int)
+}
+
+func (s *sortType) Len() int {
+ return s.length
+}
+
+func (s *sortType) Less(i, j int) bool {
+ return s.less(i, j)
+}
+
+func (s *sortType) Swap(i, j int) {
+ s.swap(i, j)
+}
+
+func gensort(Len int, Less func(int, int) bool, Swap func(int, int)) {
+ sort.Sort(&sortType{length: Len, less: Less, swap: Swap})
+}
+
+func writeBytes(leadStr string, startPos int, sl []byte) {
+ var pos, max int
+ var b byte
+ fmt.Printf("%s %07x", leadStr, startPos)
+ max = len(sl)
+ for pos < max {
+ fmt.Printf(" ")
+ for k := 0; k < 8; k++ {
+ if pos < max {
+ fmt.Printf(" %02x", sl[pos])
+ } else {
+ fmt.Printf(" ")
+ }
+ pos++
+ }
+ }
+ fmt.Printf(" |")
+ pos = 0
+ for pos < max {
+ b = sl[pos]
+ if b < 32 || b >= 128 {
+ b = '.'
+ }
+ fmt.Printf("%c", b)
+ pos++
+ }
+ fmt.Printf("|\n")
+}
+
+func checkBytes(pos int, sl1, sl2 []byte) (eq bool) {
+ eq = bytes.Equal(sl1, sl2)
+ if !eq {
+ writeBytes("<", pos, sl1)
+ writeBytes(">", pos, sl2)
+ }
+ return
+}
+
+// compareBytes compares the bytes referred to by sl1 with those referred to by
+// sl2. Nil is returned if the buffers are equal, otherwise an error.
+func compareBytes(sl1, sl2 []byte) (err error) {
+ var posStart, posEnd, len1, len2, length int
+ var diffs bool
+
+ len1 = len(sl1)
+ len2 = len(sl2)
+ length = len1
+ if length > len2 {
+ length = len2
+ }
+ for posStart < length-1 {
+ posEnd = posStart + 16
+ if posEnd > length {
+ posEnd = length
+ }
+ if !checkBytes(posStart, sl1[posStart:posEnd], sl2[posStart:posEnd]) {
+ diffs = true
+ }
+ posStart = posEnd
+ }
+ if diffs {
+ err = fmt.Errorf("documents are different")
+ }
+ return
+}
+
+// ComparePDFs reads and compares the full contents of the two specified
+// readers. The comparison is done byte-for-byte with the exception of the
+// CreationDate fields which are effectively ignored. Nil is returned if the
+// buffers are equal, otherwise an error.
+func ComparePDFs(rdr1, rdr2 io.Reader) (err error) {
+ var b1, b2 *bytes.Buffer
+ _, err = b1.ReadFrom(rdr1)
+ if err == nil {
+ _, err = b2.ReadFrom(rdr2)
+ if err == nil {
+ err = compareBytes(b1.Bytes(), b2.Bytes())
+ }
+ }
+ return
+}
+
+// ComparePDFFiles reads and compares the full contents of the two specified
+// files. The comparison is done byte-for-byte with the exception of the
+// CreationDate fields which are effectively ignored. Nil is returned if the
+// file contents are equal, or if the second file is missing, otherwise an
+// error.
+func ComparePDFFiles(file1Str, file2Str string) (err error) {
+ var sl1, sl2 []byte
+ sl1, err = ioutil.ReadFile(file1Str)
+ if err == nil {
+ sl2, err = ioutil.ReadFile(file2Str)
+ if err == nil {
+ err = compareBytes(sl1, sl2)
+ } else {
+ // Second file is missing; treat this as success
+ err = nil
+ }
+ }
+ return
+}
diff --git a/contrib/barcode/barcode_test.go b/contrib/barcode/barcode_test.go
index c12ff12..86aafcc 100644
--- a/contrib/barcode/barcode_test.go
+++ b/contrib/barcode/barcode_test.go
@@ -1,6 +1,8 @@
package barcode_test
import (
+ "time"
+
"github.com/boombuler/barcode/code128"
"github.com/boombuler/barcode/qr"
"github.com/jung-kurt/gofpdf"
@@ -8,6 +10,11 @@ import (
"github.com/jung-kurt/gofpdf/internal/example"
)
+func init() {
+ gofpdf.SetDefaultCatalogSort(true)
+ gofpdf.SetDefaultCreationDate(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC))
+}
+
func createPdf() (pdf *gofpdf.Fpdf) {
pdf = gofpdf.New("L", "mm", "A4", "")
pdf.SetFont("Helvetica", "", 12)
diff --git a/contrib/httpimg/httpimg_test.go b/contrib/httpimg/httpimg_test.go
index bf13492..6390f09 100644
--- a/contrib/httpimg/httpimg_test.go
+++ b/contrib/httpimg/httpimg_test.go
@@ -1,11 +1,18 @@
package httpimg_test
import (
+ "time"
+
"github.com/jung-kurt/gofpdf"
"github.com/jung-kurt/gofpdf/contrib/httpimg"
"github.com/jung-kurt/gofpdf/internal/example"
)
+func init() {
+ gofpdf.SetDefaultCatalogSort(true)
+ gofpdf.SetDefaultCreationDate(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC))
+}
+
func ExampleRegister() {
pdf := gofpdf.New("L", "mm", "A4", "")
pdf.SetFont("Helvetica", "", 12)
diff --git a/def.go b/def.go
index f1c8d7b..4c99733 100644
--- a/def.go
+++ b/def.go
@@ -19,6 +19,7 @@ package gofpdf
import (
"bytes"
"io"
+ "time"
)
// Version of FPDF from which this package is derived
@@ -150,7 +151,7 @@ type InitType struct {
// 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.
+// never includes a path. Open returns an error if the specified file cannot be opened.
type FontLoader interface {
Open(name string) (io.Reader, error)
}
@@ -161,7 +162,7 @@ type Fpdf struct {
n int // current object number
offsets []int // array of object offsets
templates map[int64]Template // templates used in this document
- templateObjects map[int64]int //template object IDs within this document
+ templateObjects map[int64]int // template object IDs within this document
buffer fmtBuffer // buffer holding in-memory PDF
pages []*bytes.Buffer // slice[page] of page content; 1-based
state int // current document state
@@ -216,6 +217,7 @@ type Fpdf struct {
author string // author
keywords string // keywords
creator string // creator
+ creationDate time.Time // override for dcoument CreationDate value
aliasNbPagesStr string // alias for total number of pages
pdfVersion string // PDF version number
fontDirStr string // location of font definition files
@@ -233,6 +235,7 @@ type Fpdf struct {
err error // Set if error occurs during life cycle of instance
protect protectType // document protection structure
layer layerRecType // manages optional layers in document
+ catalogSort bool // sort resource catalogs in document
colorFlag bool // indicates whether fill and text colors are different
color struct { // Composite values of colors
draw, fill, text clrType
diff --git a/fpdf.go b/fpdf.go
index f1c6b58..b5ed8e6 100644
--- a/fpdf.go
+++ b/fpdf.go
@@ -36,11 +36,17 @@ import (
"math"
"os"
"path"
+ "sort"
"strconv"
"strings"
"time"
)
+var gl struct {
+ catalogSort bool
+ creationDate time.Time
+}
+
type fmtBuffer struct {
bytes.Buffer
}
@@ -179,6 +185,8 @@ func fpdfNew(orientationStr, unitStr, sizeStr, fontDirStr string, size SizeType)
// Set default PDF version number
f.pdfVersion = "1.3"
f.layerInit()
+ f.catalogSort = gl.catalogSort
+ f.creationDate = gl.creationDate
return
}
@@ -2986,6 +2994,35 @@ func (f *Fpdf) outf(fmtStr string, args ...interface{}) {
f.out(sprintf(fmtStr, args...))
}
+// SetDefaultCatalogSort sets the default value of the catalog sort flag that
+// will be used when initializing a new Fpdf instance. See SetCatalogSort() for
+// more details.
+func SetDefaultCatalogSort(flag bool) {
+ gl.catalogSort = flag
+}
+
+// SetCatalogSort sets a flag that will be used, if true, to consistently order
+// the document's internal resource catalogs. This method is typically only
+// used for test purposes.
+func (f *Fpdf) SetCatalogSort(flag bool) {
+ f.catalogSort = flag
+}
+
+// SetDefaultCreationDate sets the default value of the document creation date
+// that will be used when initializing a new Fpdf instance. See
+// SetCreationDate() for more details.
+func SetDefaultCreationDate(tm time.Time) {
+ gl.creationDate = tm
+}
+
+// SetCreationDate fixes the document's internal CreationDate value. By
+// default, the time when the document is generated is used for this value.
+// This method is typically only used for testing purposes. Specify a
+// zero-value time to revert to the default behavior.
+func (f *Fpdf) SetCreationDate(tm time.Time) {
+ f.creationDate = tm
+}
+
func (f *Fpdf) putpages() {
var wPt, hPt float64
var pageSize SizeType
@@ -3092,107 +3129,130 @@ func (f *Fpdf) putfonts() {
f.outf("<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [%s]>>", diff)
f.out("endobj")
}
- for file, info := range f.fontFiles {
- // foreach($this->fontFiles as $file=>$info)
- // Font file embedding
- f.newobj()
- info.n = f.n
- f.fontFiles[file] = info
- font, err := f.loadFontFile(file)
- if err != nil {
- f.err = err
- return
- }
- // dbg("font file [%s], ext [%s]", file, file[len(file)-2:])
- compressed := file[len(file)-2:] == ".z"
- if !compressed && info.length2 > 0 {
- buf := font[6:info.length1]
- buf = append(buf, font[6+info.length1+6:info.length2]...)
- font = buf
+ {
+ var fileList []string
+ var info fontFileType
+ var file string
+ for file = range f.fontFiles {
+ fileList = append(fileList, file)
}
- f.outf("<</Length %d", len(font))
- if compressed {
- f.out("/Filter /FlateDecode")
+ if f.catalogSort {
+ sort.Strings(fileList)
}
- f.outf("/Length1 %d", info.length1)
- if info.length2 > 0 {
- f.outf("/Length2 %d /Length3 0", info.length2)
- }
- f.out(">>")
- f.putstream(font)
- f.out("endobj")
- }
- for k, font := range f.fonts {
- // Font objects
- font.N = f.n + 1
- f.fonts[k] = font
- tp := font.Tp
- name := font.Name
- if tp == "Core" {
- // Core font
+ for _, file = range fileList {
+ info = f.fontFiles[file]
+ // Font file embedding
f.newobj()
- f.out("<</Type /Font")
- f.outf("/BaseFont /%s", name)
- f.out("/Subtype /Type1")
- if name != "Symbol" && name != "ZapfDingbats" {
- f.out("/Encoding /WinAnsiEncoding")
+ info.n = f.n
+ f.fontFiles[file] = info
+ font, err := f.loadFontFile(file)
+ if err != nil {
+ f.err = err
+ return
}
- f.out(">>")
- f.out("endobj")
- } else if tp == "Type1" || tp == "TrueType" {
- // Additional Type1 or TrueType/OpenType font
- f.newobj()
- f.out("<</Type /Font")
- f.outf("/BaseFont /%s", name)
- f.outf("/Subtype /%s", tp)
- f.out("/FirstChar 32 /LastChar 255")
- f.outf("/Widths %d 0 R", f.n+1)
- f.outf("/FontDescriptor %d 0 R", f.n+2)
- if font.DiffN > 0 {
- f.outf("/Encoding %d 0 R", nf+font.DiffN)
- } else {
- f.out("/Encoding /WinAnsiEncoding")
+ // dbg("font file [%s], ext [%s]", file, file[len(file)-2:])
+ compressed := file[len(file)-2:] == ".z"
+ if !compressed && info.length2 > 0 {
+ buf := font[6:info.length1]
+ buf = append(buf, font[6+info.length1+6:info.length2]...)
+ font = buf
}
- f.out(">>")
- f.out("endobj")
- // Widths
- f.newobj()
- var s fmtBuffer
- s.WriteString("[")
- for j := 32; j < 256; j++ {
- s.printf("%d ", font.Cw[j])
+ f.outf("<</Length %d", len(font))
+ if compressed {
+ f.out("/Filter /FlateDecode")
}
- s.WriteString("]")
- f.out(s.String())
- f.out("endobj")
- // Descriptor
- f.newobj()
- s.Truncate(0)
- s.printf("<</Type /FontDescriptor /FontName /%s ", name)
- s.printf("/Ascent %d ", font.Desc.Ascent)
- s.printf("/Descent %d ", font.Desc.Descent)
- s.printf("/CapHeight %d ", font.Desc.CapHeight)
- s.printf("/Flags %d ", font.Desc.Flags)
- s.printf("/FontBBox [%d %d %d %d] ", font.Desc.FontBBox.Xmin, font.Desc.FontBBox.Ymin,
- font.Desc.FontBBox.Xmax, font.Desc.FontBBox.Ymax)
- s.printf("/ItalicAngle %d ", font.Desc.ItalicAngle)
- s.printf("/StemV %d ", font.Desc.StemV)
- s.printf("/MissingWidth %d ", font.Desc.MissingWidth)
- var suffix string
- if tp != "Type1" {
- suffix = "2"
+ f.outf("/Length1 %d", info.length1)
+ if info.length2 > 0 {
+ f.outf("/Length2 %d /Length3 0", info.length2)
}
- s.printf("/FontFile%s %d 0 R>>", suffix, f.fontFiles[font.File].n)
- f.out(s.String())
+ f.out(">>")
+ f.putstream(font)
f.out("endobj")
- } else {
- f.err = fmt.Errorf("unsupported font type: %s", tp)
- return
- // Allow for additional types
- // $mtd = 'put'.strtolower($type);
- // if(!method_exists($this,$mtd))
- // $this->Error('Unsupported font type: '.$type);
- // $this->$mtd($font);
+ }
+ }
+ {
+ var keyList []string
+ var font fontDefType
+ var key string
+ for key = range f.fonts {
+ keyList = append(keyList, key)
+ }
+ if f.catalogSort {
+ sort.Strings(keyList)
+ }
+ for _, key = range keyList {
+ font = f.fonts[key]
+ // Font objects
+ font.N = f.n + 1
+ f.fonts[key] = font
+ tp := font.Tp
+ name := font.Name
+ if tp == "Core" {
+ // Core font
+ f.newobj()
+ f.out("<</Type /Font")
+ f.outf("/BaseFont /%s", name)
+ f.out("/Subtype /Type1")
+ if name != "Symbol" && name != "ZapfDingbats" {
+ f.out("/Encoding /WinAnsiEncoding")
+ }
+ f.out(">>")
+ f.out("endobj")
+ } else if tp == "Type1" || tp == "TrueType" {
+ // Additional Type1 or TrueType/OpenType font
+ f.newobj()
+ f.out("<</Type /Font")
+ f.outf("/BaseFont /%s", name)
+ f.outf("/Subtype /%s", tp)
+ f.out("/FirstChar 32 /LastChar 255")
+ f.outf("/Widths %d 0 R", f.n+1)
+ f.outf("/FontDescriptor %d 0 R", f.n+2)
+ if font.DiffN > 0 {
+ f.outf("/Encoding %d 0 R", nf+font.DiffN)
+ } else {
+ f.out("/Encoding /WinAnsiEncoding")
+ }
+ f.out(">>")
+ f.out("endobj")
+ // Widths
+ f.newobj()
+ var s fmtBuffer
+ s.WriteString("[")
+ for j := 32; j < 256; j++ {
+ s.printf("%d ", font.Cw[j])
+ }
+ s.WriteString("]")
+ f.out(s.String())
+ f.out("endobj")
+ // Descriptor
+ f.newobj()
+ s.Truncate(0)
+ s.printf("<</Type /FontDescriptor /FontName /%s ", name)
+ s.printf("/Ascent %d ", font.Desc.Ascent)
+ s.printf("/Descent %d ", font.Desc.Descent)
+ s.printf("/CapHeight %d ", font.Desc.CapHeight)
+ s.printf("/Flags %d ", font.Desc.Flags)
+ s.printf("/FontBBox [%d %d %d %d] ", font.Desc.FontBBox.Xmin, font.Desc.FontBBox.Ymin,
+ font.Desc.FontBBox.Xmax, font.Desc.FontBBox.Ymax)
+ s.printf("/ItalicAngle %d ", font.Desc.ItalicAngle)
+ s.printf("/StemV %d ", font.Desc.StemV)
+ s.printf("/MissingWidth %d ", font.Desc.MissingWidth)
+ var suffix string
+ if tp != "Type1" {
+ suffix = "2"
+ }
+ s.printf("/FontFile%s %d 0 R>>", suffix, f.fontFiles[font.File].n)
+ f.out(s.String())
+ f.out("endobj")
+ } else {
+ f.err = fmt.Errorf("unsupported font type: %s", tp)
+ return
+ // Allow for additional types
+ // $mtd = 'put'.strtolower($type);
+ // if(!method_exists($this,$mtd))
+ // $this->Error('Unsupported font type: '.$type);
+ // $this->$mtd($font);
+ }
}
}
return
@@ -3213,8 +3273,16 @@ func (f *Fpdf) loadFontFile(name string) ([]byte, error) {
}
func (f *Fpdf) putimages() {
- for _, img := range f.images {
- f.putimage(img)
+ var keyList []string
+ var key string
+ for key = range f.images {
+ keyList = append(keyList, key)
+ }
+ if f.catalogSort {
+ sort.Strings(keyList)
+ }
+ for _, key = range keyList {
+ f.putimage(f.images[key])
}
}
@@ -3283,9 +3351,20 @@ func (f *Fpdf) putimage(info *ImageInfoType) {
}
func (f *Fpdf) putxobjectdict() {
- for _, image := range f.images {
- // foreach($this->images as $image)
- f.outf("/I%d %d 0 R", image.i, image.n)
+ {
+ var image *ImageInfoType
+ var key string
+ var keyList []string
+ for key = range f.images {
+ keyList = append(keyList, key)
+ }
+ if f.catalogSort {
+ sort.Strings(keyList)
+ }
+ for _, key = range keyList {
+ image = f.images[key]
+ f.outf("/I%d %d 0 R", image.i, image.n)
+ }
}
for _, tpl := range f.templates {
id := tpl.ID()
@@ -3298,9 +3377,20 @@ func (f *Fpdf) putxobjectdict() {
func (f *Fpdf) putresourcedict() {
f.out("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]")
f.out("/Font <<")
- for _, font := range f.fonts {
- // foreach($this->fonts as $font)
- f.outf("/F%d %d 0 R", font.I, font.N)
+ {
+ var keyList []string
+ var font fontDefType
+ var key string
+ for key = range f.fonts {
+ keyList = append(keyList, key)
+ }
+ if f.catalogSort {
+ sort.Strings(keyList)
+ }
+ for _, key = range keyList {
+ font = f.fonts[key]
+ f.outf("/F%d %d 0 R", font.I, font.N)
+ }
}
f.out(">>")
f.out("/XObject <<")
@@ -3400,6 +3490,7 @@ func (f *Fpdf) putresources() {
}
func (f *Fpdf) putinfo() {
+ var tm time.Time
f.outf("/Producer %s", f.textstring("FPDF "+cnFpdfVersion))
if len(f.title) > 0 {
f.outf("/Title %s", f.textstring(f.title))
@@ -3416,7 +3507,12 @@ func (f *Fpdf) putinfo() {
if len(f.creator) > 0 {
f.outf("/Creator %s", f.textstring(f.creator))
}
- f.outf("/CreationDate %s", f.textstring("D:"+time.Now().Format("20060102150405")))
+ if f.creationDate.IsZero() {
+ tm = time.Now()
+ } else {
+ tm = f.creationDate
+ }
+ f.outf("/CreationDate %s", f.textstring("D:"+tm.Format("20060102150405")))
}
func (f *Fpdf) putcatalog() {
diff --git a/fpdf_test.go b/fpdf_test.go
index 966767f..2238ccd 100644
--- a/fpdf_test.go
+++ b/fpdf_test.go
@@ -28,6 +28,7 @@ import (
"path/filepath"
"strconv"
"strings"
+ "time"
"github.com/jung-kurt/gofpdf"
"github.com/jung-kurt/gofpdf/internal/example"
@@ -35,14 +36,21 @@ import (
func init() {
cleanup()
+ gofpdf.SetDefaultCatalogSort(true)
+ gofpdf.SetDefaultCreationDate(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC))
}
func cleanup() {
filepath.Walk(example.PdfDir(),
func(path string, info os.FileInfo, err error) (reterr error) {
- if len(path) > 3 {
- if path[len(path)-4:] == ".pdf" {
- os.Remove(path)
+ if info.Mode().IsRegular() {
+ dir, _ := filepath.Split(path)
+ if "reference" != filepath.Base(dir) {
+ if len(path) > 3 {
+ if path[len(path)-4:] == ".pdf" {
+ os.Remove(path)
+ }
+ }
}
}
return
diff --git a/internal/example/example.go b/internal/example/example.go
index d6a114c..b29561c 100644
--- a/internal/example/example.go
+++ b/internal/example/example.go
@@ -22,6 +22,8 @@ import (
"os"
"path/filepath"
"strings"
+
+ "github.com/jung-kurt/gofpdf"
)
var gofpdfDir string
@@ -36,8 +38,7 @@ func setRoot() {
wdStr, err := os.Getwd()
if err == nil {
gofpdfDir = ""
- sepStr := string(os.PathSeparator)
- list := strings.Split(wdStr, sepStr)
+ list := strings.Split(filepath.ToSlash(wdStr), "/")
for j := len(list) - 1; j >= 0 && list[j] != "gofpdf"; j-- {
gofpdfDir = filepath.Join(gofpdfDir, "..")
}
@@ -87,12 +88,32 @@ func Filename(baseStr string) string {
return PdfFile(baseStr + ".pdf")
}
+// referenceCompare compares the specified file with the file's reference copy
+// located in the 'reference' subdirectory. All bytes of the two files are
+// compared except for the value of the /CreationDate field in the PDF. This
+// function succeeds if both files are equivalent except for their
+// /CreationDate values or if the reference file does not exist.
+func referenceCompare(fileStr string) (err error) {
+ var refFileStr, refDirStr, dirStr, baseFileStr string
+ dirStr, baseFileStr = filepath.Split(fileStr)
+ refDirStr = filepath.Join(dirStr, "reference")
+ err = os.MkdirAll(refDirStr, 0755)
+ if err == nil {
+ refFileStr = filepath.Join(refDirStr, baseFileStr)
+ err = gofpdf.ComparePDFFiles(fileStr, refFileStr)
+ }
+ return
+}
+
// Summary generates a predictable report for use by test examples. If the
// specified error is nil, the filename delimiters are normalized and the
// filename printed to standard output with a success message. If the specified
// error is not nil, its String() value is printed to standard output.
func Summary(err error, fileStr string) {
if err == nil {
+ err = referenceCompare(fileStr)
+ }
+ if err == nil {
fileStr = filepath.ToSlash(fileStr)
fmt.Printf("Successfully generated %s\n", fileStr)
} else {
diff --git a/template.go b/template.go
index 7561ae1..342032e 100644
--- a/template.go
+++ b/template.go
@@ -36,7 +36,7 @@ func CreateTemplate(corner PointType, size SizeType, unitStr, fontDirStr string,
// using the size and position at which it was originally written.
func (f *Fpdf) UseTemplate(t Template) {
if t == nil {
- f.SetErrorf("Template is nil")
+ f.SetErrorf("template is nil")
return
}
corner, size := t.Size()
@@ -47,13 +47,13 @@ func (f *Fpdf) UseTemplate(t Template) {
// using the given page coordinates.
func (f *Fpdf) UseTemplateScaled(t Template, corner PointType, size SizeType) {
if t == nil {
- f.SetErrorf("Template is nil")
+ f.SetErrorf("template is nil")
return
}
// You have to add at least a page first
if f.page <= 0 {
- f.SetErrorf("Cannot use a template without first adding a page")
+ f.SetErrorf("cannot use a template without first adding a page")
return
}