From fd73b28bfe68c6b20d2ce446de94819bdcfe8d36 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Thu, 8 Oct 2015 14:19:39 -0400 Subject: Compare bytes of PDFs generated as examples with reference copies. Differences in the CreationDate values are effectively ignored in the comparison. --- .gitignore | 1 + internal/example/example.go | 55 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/.gitignore b/.gitignore index e8f0fe4..8203c3c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ makefont/makefont pdf/*.pdf +pdf/reference look open pdf.txt diff --git a/internal/example/example.go b/internal/example/example.go index d6a114c..3a60a1e 100644 --- a/internal/example/example.go +++ b/internal/example/example.go @@ -18,9 +18,12 @@ package example import ( + "bytes" "fmt" + "io/ioutil" "os" "path/filepath" + "regexp" "strings" ) @@ -87,11 +90,63 @@ func Filename(baseStr string) string { return PdfFile(baseStr + ".pdf") } +var ( + // 00000230 44 46 20 31 2e 37 29 0a 2f 43 72 65 61 74 69 6f |DF 1.7)./Creatio| + // 00000240 6e 44 61 74 65 20 28 44 3a 32 30 31 35 31 30 30 |nDate (D:2015100| + // 00000250 38 31 32 33 30 34 35 29 0a 3e 3e 0a 65 6e 64 6f |8123045).>>.endo| + creationDateRe *regexp.Regexp = regexp.MustCompile("/CreationDate \\(D:\\d{14}\\)") + fixDate []byte = []byte("/CreationDate (D:20000101000000)") +) + +// 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. An +// error is returned if the two files do not match. If the file does not exist, +// a copy of the specified file is made and a non-nil error is returned only if +// this copy fails. +func referenceCompare(fileStr string) (err error) { + var fileBuf, refFileBuf []byte + 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) + fileBuf, err = ioutil.ReadFile(fileStr) + if err == nil { + // Replace the creation timestamp of this PDF with a fixed value + fileBuf = creationDateRe.ReplaceAll(fileBuf, fixDate) + refFileBuf, err = ioutil.ReadFile(refFileStr) + if err == nil { + if len(fileBuf) == len(refFileBuf) { + if bytes.Equal(fileBuf, refFileBuf) { + // Files match + } else { + err = fmt.Errorf("%s differs from %s", fileStr, refFileStr) + } + } else { + err = fmt.Errorf("size of %s (%d) does not match size of %s (%d)", + fileStr, len(fileBuf), refFileStr, len(refFileBuf)) + } + } else { + // Reference file is missing. Create it with a copy of the newly produced + // file in which the creation date has been fixed. Overwrite error with copy + // error. + err = ioutil.WriteFile(refFileStr, fileBuf, 0644) + } + } + } + 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) -- cgit v1.2.1-24-ge1ad From 4bed0d1e5b814845432a73f62b9462a27fd53bda Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Thu, 8 Oct 2015 14:52:13 -0400 Subject: Clarify a comment --- internal/example/example.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/example/example.go b/internal/example/example.go index 3a60a1e..6a3c65a 100644 --- a/internal/example/example.go +++ b/internal/example/example.go @@ -101,9 +101,9 @@ var ( // 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. An -// error is returned if the two files do not match. If the file does not exist, -// a copy of the specified file is made and a non-nil error is returned only if -// this copy fails. +// error is returned if the two files do not match. If the reference file does +// not exist, a copy of the specified file is made and a non-nil error is +// returned only if this copy fails. func referenceCompare(fileStr string) (err error) { var fileBuf, refFileBuf []byte var refFileStr, refDirStr, dirStr, baseFileStr string -- cgit v1.2.1-24-ge1ad From 47143d5c2dabe888df2ff3e586c911468881b55c Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Thu, 8 Oct 2015 15:05:15 -0400 Subject: Omit type in declaration assignment --- internal/example/example.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/example/example.go b/internal/example/example.go index 6a3c65a..9e2c736 100644 --- a/internal/example/example.go +++ b/internal/example/example.go @@ -94,8 +94,8 @@ var ( // 00000230 44 46 20 31 2e 37 29 0a 2f 43 72 65 61 74 69 6f |DF 1.7)./Creatio| // 00000240 6e 44 61 74 65 20 28 44 3a 32 30 31 35 31 30 30 |nDate (D:2015100| // 00000250 38 31 32 33 30 34 35 29 0a 3e 3e 0a 65 6e 64 6f |8123045).>>.endo| - creationDateRe *regexp.Regexp = regexp.MustCompile("/CreationDate \\(D:\\d{14}\\)") - fixDate []byte = []byte("/CreationDate (D:20000101000000)") + creationDateRe = regexp.MustCompile("/CreationDate \\(D:\\d{14}\\)") + fixDate = []byte("/CreationDate (D:20000101000000)") ) // referenceCompare compares the specified file with the file's reference copy -- cgit v1.2.1-24-ge1ad From 25d0813f8f9210fcaf3a5797d72756a332ef2dbe Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Fri, 9 Oct 2015 15:52:07 -0400 Subject: Implement PDF comparison with rudimentary byte-difference display. If a reference file exists, it will be compared with its associated example file. If the reference file is missing, the associated example file is considered to be without differences. PDF files in any subdirectory named reference are not deleted when the test begins. This commit is broken -- it illustrates how the use of maps for fonts, images and other resources lead to different dictionary tables in the PDF document. --- compare.go | 144 ++++++++++++++++++++++++++++++++++++++++++++ fpdf_test.go | 11 +++- internal/example/example.go | 52 +++++++--------- 3 files changed, 175 insertions(+), 32 deletions(-) create mode 100644 compare.go diff --git a/compare.go b/compare.go new file mode 100644 index 0000000..dadf5eb --- /dev/null +++ b/compare.go @@ -0,0 +1,144 @@ +/* + * 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" + "regexp" +) + +var ( + // 00000230 44 46 20 31 2e 37 29 0a 2f 43 72 65 61 74 69 6f |DF 1.7)./Creatio| + // 00000240 6e 44 61 74 65 20 28 44 3a 32 30 31 35 31 30 30 |nDate (D:2015100| + // 00000250 38 31 32 33 30 34 35 29 0a 3e 3e 0a 65 6e 64 6f |8123045).>>.endo| + creationDateRe = regexp.MustCompile("/CreationDate \\(D:\\d{14}\\)") + fixDate = []byte("/CreationDate (D:20000101000000)") +) + +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 { + // fmt.Printf("< %v\n", sl1) + // fmt.Printf("> %v\n", sl2) + writeBytes("<", pos, sl1) + writeBytes(">", pos, sl2) + } + return +} + +// compareBytes compares the bytes referred to by sl1 with those referred to by +// sl2. 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 compareBytes(sl1, sl2 []byte) (err error) { + var posStart, posEnd, len1, len2, length int + var diffs bool + + sl1 = creationDateRe.ReplaceAll(sl1, fixDate) + sl2 = creationDateRe.ReplaceAll(sl2, fixDate) + len1 = len(sl1) + len2 = len(sl2) + length = len1 + if length > len2 { + length = len2 + } + // fmt.Printf("Len 1 %d, Len 2 %d, Len %d\n", len1, len2, length) + for posStart < length-1 { + posEnd = posStart + 16 + if posEnd > length { + posEnd = length + } + // fmt.Printf("%d to %d\n", posStart, posEnd) + 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 + // fmt.Printf("Comparing [%s] with [%s]\n", file1Str, file2Str) + 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/fpdf_test.go b/fpdf_test.go index 966767f..e45f966 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -40,9 +40,14 @@ func init() { 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 9e2c736..b95972c 100644 --- a/internal/example/example.go +++ b/internal/example/example.go @@ -18,13 +18,14 @@ package example import ( - "bytes" "fmt" - "io/ioutil" + // "io/ioutil" "os" "path/filepath" "regexp" "strings" + + "github.com/jung-kurt/gofpdf" ) var gofpdfDir string @@ -39,8 +40,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, "..") } @@ -103,38 +103,32 @@ var ( // compared except for the value of the /CreationDate field in the PDF. An // error is returned if the two files do not match. If the reference file does // not exist, a copy of the specified file is made and a non-nil error is -// returned only if this copy fails. +// returned only if this copy fails. If the reference file exists but has zero +// length, the file will not be overwritten and will be considered to be equal +// to the example file. This is intended to facilitate initial example +// development. func referenceCompare(fileStr string) (err error) { - var fileBuf, refFileBuf []byte var refFileStr, refDirStr, dirStr, baseFileStr string + // var fileBuf []byte + // var info os.FileInfo dirStr, baseFileStr = filepath.Split(fileStr) refDirStr = filepath.Join(dirStr, "reference") err = os.MkdirAll(refDirStr, 0755) if err == nil { refFileStr = filepath.Join(refDirStr, baseFileStr) - fileBuf, err = ioutil.ReadFile(fileStr) - if err == nil { - // Replace the creation timestamp of this PDF with a fixed value - fileBuf = creationDateRe.ReplaceAll(fileBuf, fixDate) - refFileBuf, err = ioutil.ReadFile(refFileStr) - if err == nil { - if len(fileBuf) == len(refFileBuf) { - if bytes.Equal(fileBuf, refFileBuf) { - // Files match - } else { - err = fmt.Errorf("%s differs from %s", fileStr, refFileStr) - } - } else { - err = fmt.Errorf("size of %s (%d) does not match size of %s (%d)", - fileStr, len(fileBuf), refFileStr, len(refFileBuf)) - } - } else { - // Reference file is missing. Create it with a copy of the newly produced - // file in which the creation date has been fixed. Overwrite error with copy - // error. - err = ioutil.WriteFile(refFileStr, fileBuf, 0644) - } - } + // info, err = os.Stat(refFileStr) + // if err == nil { + // if info.Size() > 0 { + err = gofpdf.ComparePDFFiles(fileStr, refFileStr) + // } + // } else { + // // Reference file is missing. Create it with a copy of the example file. + // // Overwrite error with copy error. + // fileBuf, err = ioutil.ReadFile(fileStr) + // if err == nil { + // err = ioutil.WriteFile(refFileStr, fileBuf, 0644) + // } + // } } return } -- cgit v1.2.1-24-ge1ad From b0f3b60a71b8ca327da859e5f4a7cd8eb5bea4e7 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Fri, 9 Oct 2015 16:07:19 -0400 Subject: Remove some development comments --- compare.go | 5 ----- internal/example/example.go | 34 +++------------------------------- 2 files changed, 3 insertions(+), 36 deletions(-) diff --git a/compare.go b/compare.go index dadf5eb..6a79cba 100644 --- a/compare.go +++ b/compare.go @@ -64,8 +64,6 @@ func writeBytes(leadStr string, startPos int, sl []byte) { func checkBytes(pos int, sl1, sl2 []byte) (eq bool) { eq = bytes.Equal(sl1, sl2) if !eq { - // fmt.Printf("< %v\n", sl1) - // fmt.Printf("> %v\n", sl2) writeBytes("<", pos, sl1) writeBytes(">", pos, sl2) } @@ -88,13 +86,11 @@ func compareBytes(sl1, sl2 []byte) (err error) { if length > len2 { length = len2 } - // fmt.Printf("Len 1 %d, Len 2 %d, Len %d\n", len1, len2, length) for posStart < length-1 { posEnd = posStart + 16 if posEnd > length { posEnd = length } - // fmt.Printf("%d to %d\n", posStart, posEnd) if !checkBytes(posStart, sl1[posStart:posEnd], sl2[posStart:posEnd]) { diffs = true } @@ -129,7 +125,6 @@ func ComparePDFs(rdr1, rdr2 io.Reader) (err error) { // error. func ComparePDFFiles(file1Str, file2Str string) (err error) { var sl1, sl2 []byte - // fmt.Printf("Comparing [%s] with [%s]\n", file1Str, file2Str) sl1, err = ioutil.ReadFile(file1Str) if err == nil { sl2, err = ioutil.ReadFile(file2Str) diff --git a/internal/example/example.go b/internal/example/example.go index b95972c..b29561c 100644 --- a/internal/example/example.go +++ b/internal/example/example.go @@ -19,10 +19,8 @@ package example import ( "fmt" - // "io/ioutil" "os" "path/filepath" - "regexp" "strings" "github.com/jung-kurt/gofpdf" @@ -90,45 +88,19 @@ func Filename(baseStr string) string { return PdfFile(baseStr + ".pdf") } -var ( - // 00000230 44 46 20 31 2e 37 29 0a 2f 43 72 65 61 74 69 6f |DF 1.7)./Creatio| - // 00000240 6e 44 61 74 65 20 28 44 3a 32 30 31 35 31 30 30 |nDate (D:2015100| - // 00000250 38 31 32 33 30 34 35 29 0a 3e 3e 0a 65 6e 64 6f |8123045).>>.endo| - creationDateRe = regexp.MustCompile("/CreationDate \\(D:\\d{14}\\)") - fixDate = []byte("/CreationDate (D:20000101000000)") -) - // 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. An -// error is returned if the two files do not match. If the reference file does -// not exist, a copy of the specified file is made and a non-nil error is -// returned only if this copy fails. If the reference file exists but has zero -// length, the file will not be overwritten and will be considered to be equal -// to the example file. This is intended to facilitate initial example -// development. +// 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 - // var fileBuf []byte - // var info os.FileInfo dirStr, baseFileStr = filepath.Split(fileStr) refDirStr = filepath.Join(dirStr, "reference") err = os.MkdirAll(refDirStr, 0755) if err == nil { refFileStr = filepath.Join(refDirStr, baseFileStr) - // info, err = os.Stat(refFileStr) - // if err == nil { - // if info.Size() > 0 { err = gofpdf.ComparePDFFiles(fileStr, refFileStr) - // } - // } else { - // // Reference file is missing. Create it with a copy of the example file. - // // Overwrite error with copy error. - // fileBuf, err = ioutil.ReadFile(fileStr) - // if err == nil { - // err = ioutil.WriteFile(refFileStr, fileBuf, 0644) - // } - // } } return } -- cgit v1.2.1-24-ge1ad From cae789a4e309eb39bd6145f93361a3745effbb2d Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Sat, 10 Oct 2015 06:23:36 -0400 Subject: Add method to fix document creation date --- def.go | 2 ++ fpdf.go | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/def.go b/def.go index f1c8d7b..50a3f70 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 @@ -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 diff --git a/fpdf.go b/fpdf.go index f1c6b58..efe5274 100644 --- a/fpdf.go +++ b/fpdf.go @@ -2986,6 +2986,14 @@ func (f *Fpdf) outf(fmtStr string, args ...interface{}) { f.out(sprintf(fmtStr, args...)) } +// 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 @@ -3400,6 +3408,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 +3425,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() { -- cgit v1.2.1-24-ge1ad From e924055b983321336e31f556f5235ea79fe72134 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Sat, 10 Oct 2015 09:11:53 -0400 Subject: Implement conditional catalog sort feature --- def.go | 1 + fpdf.go | 230 +++++++++++++++++++++++++++++++++++------------------------ fpdf_test.go | 1 + 3 files changed, 137 insertions(+), 95 deletions(-) diff --git a/def.go b/def.go index 50a3f70..2c4d33d 100644 --- a/def.go +++ b/def.go @@ -235,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 efe5274..d501574 100644 --- a/fpdf.go +++ b/fpdf.go @@ -36,6 +36,7 @@ import ( "math" "os" "path" + "sort" "strconv" "strings" "time" @@ -2986,6 +2987,13 @@ func (f *Fpdf) outf(fmtStr string, args ...interface{}) { f.out(sprintf(fmtStr, args...)) } +// 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 +} + // 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 @@ -3100,107 +3108,131 @@ func (f *Fpdf) putfonts() { f.outf("<>", 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("< 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 { + // for file, info := range f.fontFiles { + info = f.fontFiles[file] + // Font file embedding f.newobj() - f.out("<>") - f.out("endobj") - } else if tp == "Type1" || tp == "TrueType" { - // Additional Type1 or TrueType/OpenType font - f.newobj() - f.out("< 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("< 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("<>") + f.out("endobj") + } else if tp == "Type1" || tp == "TrueType" { + // Additional Type1 or TrueType/OpenType font + f.newobj() + f.out("< 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("<>", 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 @@ -3221,8 +3253,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]) } } diff --git a/fpdf_test.go b/fpdf_test.go index e45f966..39cebc0 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -110,6 +110,7 @@ func Example() { // This example demonsrates the generation of headers, footers and page breaks. func ExampleFpdf_AddPage() { pdf := gofpdf.New("P", "mm", "A4", "") + pdf.SetCatalogSort(true) pdf.SetHeaderFunc(func() { pdf.Image(example.ImageFile("logo.png"), 10, 6, 30, 0, false, "", 0, "") pdf.SetY(5) -- cgit v1.2.1-24-ge1ad From 5847afd8a205853a7effbf749b7a388ae325eb24 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Sat, 10 Oct 2015 14:16:23 -0400 Subject: Introduce helper functions to set default catalog sort flag and creation date value. Remove regular expression scheme that effectively ignored the embedded creation date when comparing PDFs. --- compare.go | 15 +-------------- fpdf.go | 42 ++++++++++++++++++++++++++++++++++++++---- fpdf_test.go | 3 +++ 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/compare.go b/compare.go index 6a79cba..3fd7eaf 100644 --- a/compare.go +++ b/compare.go @@ -21,15 +21,6 @@ import ( "fmt" "io" "io/ioutil" - "regexp" -) - -var ( - // 00000230 44 46 20 31 2e 37 29 0a 2f 43 72 65 61 74 69 6f |DF 1.7)./Creatio| - // 00000240 6e 44 61 74 65 20 28 44 3a 32 30 31 35 31 30 30 |nDate (D:2015100| - // 00000250 38 31 32 33 30 34 35 29 0a 3e 3e 0a 65 6e 64 6f |8123045).>>.endo| - creationDateRe = regexp.MustCompile("/CreationDate \\(D:\\d{14}\\)") - fixDate = []byte("/CreationDate (D:20000101000000)") ) func writeBytes(leadStr string, startPos int, sl []byte) { @@ -71,15 +62,11 @@ func checkBytes(pos int, sl1, sl2 []byte) (eq bool) { } // compareBytes compares the bytes referred to by sl1 with those referred to by -// sl2. 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. +// 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 - sl1 = creationDateRe.ReplaceAll(sl1, fixDate) - sl2 = creationDateRe.ReplaceAll(sl2, fixDate) len1 = len(sl1) len2 = len(sl2) length = len1 diff --git a/fpdf.go b/fpdf.go index d501574..aeb0c3e 100644 --- a/fpdf.go +++ b/fpdf.go @@ -42,6 +42,11 @@ import ( "time" ) +var gl struct { + catalogSort bool + creationDate time.Time +} + type fmtBuffer struct { bytes.Buffer } @@ -180,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 } @@ -2987,6 +2994,13 @@ 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. @@ -2994,10 +3008,17 @@ 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 +// zero-value time to revert to the default behavior. func (f *Fpdf) SetCreationDate(tm time.Time) { f.creationDate = tm } @@ -3346,9 +3367,22 @@ 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] + // for _, font := range f.fonts { + // foreach($this->fonts as $font) + f.outf("/F%d %d 0 R", font.I, font.N) + } } f.out(">>") f.out("/XObject <<") diff --git a/fpdf_test.go b/fpdf_test.go index 39cebc0..cc0b91c 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,6 +36,8 @@ import ( func init() { cleanup() + gofpdf.SetDefaultCatalogSort(true) + gofpdf.SetDefaultCreationDate(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)) } func cleanup() { -- cgit v1.2.1-24-ge1ad From 92858a8b5ff04e4196597d9d517f3b2a0d651579 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Sat, 10 Oct 2015 15:24:43 -0400 Subject: Conditionally sort image catalog. Correct small typos. --- compare.go | 23 +++++++++++++++++++++++ def.go | 4 ++-- fpdf.go | 20 ++++++++++++++------ fpdf_test.go | 1 - template.go | 6 +++--- 5 files changed, 42 insertions(+), 12 deletions(-) diff --git a/compare.go b/compare.go index 3fd7eaf..64cad1f 100644 --- a/compare.go +++ b/compare.go @@ -21,8 +21,31 @@ import ( "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 diff --git a/def.go b/def.go index 2c4d33d..4c99733 100644 --- a/def.go +++ b/def.go @@ -151,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) } @@ -162,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 diff --git a/fpdf.go b/fpdf.go index aeb0c3e..b5ed8e6 100644 --- a/fpdf.go +++ b/fpdf.go @@ -3140,7 +3140,6 @@ func (f *Fpdf) putfonts() { sort.Strings(fileList) } for _, file = range fileList { - // for file, info := range f.fontFiles { info = f.fontFiles[file] // Font file embedding f.newobj() @@ -3352,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() @@ -3379,8 +3389,6 @@ func (f *Fpdf) putresourcedict() { } for _, key = range keyList { font = f.fonts[key] - // for _, font := range f.fonts { - // foreach($this->fonts as $font) f.outf("/F%d %d 0 R", font.I, font.N) } } diff --git a/fpdf_test.go b/fpdf_test.go index cc0b91c..2238ccd 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -113,7 +113,6 @@ func Example() { // This example demonsrates the generation of headers, footers and page breaks. func ExampleFpdf_AddPage() { pdf := gofpdf.New("P", "mm", "A4", "") - pdf.SetCatalogSort(true) pdf.SetHeaderFunc(func() { pdf.Image(example.ImageFile("logo.png"), 10, 6, 30, 0, false, "", 0, "") pdf.SetY(5) 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 } -- cgit v1.2.1-24-ge1ad From d51a8d74b25e9e8b342e0a620c8afdfe155c3e09 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Sun, 11 Oct 2015 07:27:08 -0400 Subject: Include catalog sort and creation date assignment so that tests of contributed packages can be run --- contrib/barcode/barcode_test.go | 7 +++++++ contrib/httpimg/httpimg_test.go | 7 +++++++ 2 files changed, 14 insertions(+) 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) -- cgit v1.2.1-24-ge1ad From eca9f96fbf9b6be62915d111546f4798ce3fac62 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Sun, 11 Oct 2015 09:16:21 -0400 Subject: Move default assignments to init function of example file from various test files. Now any package that imports the example package will generate PDFs with sorted catalogs and a fixed creation timestamp. --- contrib/barcode/barcode_test.go | 7 ------- contrib/httpimg/httpimg_test.go | 7 ------- fpdf_test.go | 3 --- internal/example/example.go | 3 +++ 4 files changed, 3 insertions(+), 17 deletions(-) diff --git a/contrib/barcode/barcode_test.go b/contrib/barcode/barcode_test.go index 86aafcc..c12ff12 100644 --- a/contrib/barcode/barcode_test.go +++ b/contrib/barcode/barcode_test.go @@ -1,8 +1,6 @@ package barcode_test import ( - "time" - "github.com/boombuler/barcode/code128" "github.com/boombuler/barcode/qr" "github.com/jung-kurt/gofpdf" @@ -10,11 +8,6 @@ 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 6390f09..bf13492 100644 --- a/contrib/httpimg/httpimg_test.go +++ b/contrib/httpimg/httpimg_test.go @@ -1,18 +1,11 @@ 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/fpdf_test.go b/fpdf_test.go index 2238ccd..e45f966 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -28,7 +28,6 @@ import ( "path/filepath" "strconv" "strings" - "time" "github.com/jung-kurt/gofpdf" "github.com/jung-kurt/gofpdf/internal/example" @@ -36,8 +35,6 @@ import ( func init() { cleanup() - gofpdf.SetDefaultCatalogSort(true) - gofpdf.SetDefaultCreationDate(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)) } func cleanup() { diff --git a/internal/example/example.go b/internal/example/example.go index b29561c..56ffb23 100644 --- a/internal/example/example.go +++ b/internal/example/example.go @@ -22,6 +22,7 @@ import ( "os" "path/filepath" "strings" + "time" "github.com/jung-kurt/gofpdf" ) @@ -30,6 +31,8 @@ var gofpdfDir string func init() { setRoot() + gofpdf.SetDefaultCatalogSort(true) + gofpdf.SetDefaultCreationDate(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)) } // Assign the relative path to the gofpdfDir directory based on current working -- cgit v1.2.1-24-ge1ad From 08c842eee7361c4d515301a5d84d246a0b0a9462 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Sun, 11 Oct 2015 09:43:23 -0400 Subject: Investigate missing spaces between words --- fpdf_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/fpdf_test.go b/fpdf_test.go index e45f966..a0eaec1 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -1140,6 +1140,7 @@ func ExampleFpdf_SVGBasicWrite() { err error ) pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0 + pdf.SetCompression(false) pdf.SetFont("Times", "", fontPtSize) lineHt := pdf.PointConvert(fontPtSize) pdf.AddPage() -- cgit v1.2.1-24-ge1ad From 13a5fda5f79f2c15eea512e6ec3de2ce60aa29ca Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Sun, 11 Oct 2015 13:23:37 -0400 Subject: Conditionally sort two map iterations in template code; more to come. --- fpdf.go | 27 +++++++++++++++++++++++---- template.go | 21 +++++++++++++++++++-- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/fpdf.go b/fpdf.go index b5ed8e6..08bcb2e 100644 --- a/fpdf.go +++ b/fpdf.go @@ -3366,10 +3366,29 @@ func (f *Fpdf) putxobjectdict() { f.outf("/I%d %d 0 R", image.i, image.n) } } - for _, tpl := range f.templates { - id := tpl.ID() - if objID, ok := f.templateObjects[id]; ok { - f.outf("/TPL%d %d 0 R", id, objID) + { + var key int64 + var keyList []int64 + var tpl Template + for key = range f.templates { + keyList = append(keyList, key) + } + if f.catalogSort { + gensort(len(keyList), + func(a, b int) bool { + return keyList[a] < keyList[b] + }, + func(a, b int) { + keyList[a], keyList[b] = keyList[b], keyList[a] + }) + } + for _, key = range keyList { + tpl = f.templates[key] + // for _, tpl := range f.templates { + id := tpl.ID() + if objID, ok := f.templateObjects[id]; ok { + f.outf("/TPL%d %d 0 R", id, objID) + } } } } diff --git a/template.go b/template.go index 342032e..bf25c9f 100644 --- a/template.go +++ b/template.go @@ -17,6 +17,10 @@ package gofpdf * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +import ( + "sort" +) + // CreateTemplate defines a new template using the current page size. func (f *Fpdf) CreateTemplate(fn func(*Tpl)) Template { return newTpl(PointType{0, 0}, f.curPageSize, f.unitStr, f.fontDirStr, fn, f) @@ -135,8 +139,21 @@ func (f *Fpdf) putTemplates() { tTemplates := t.Templates() if len(tImages) > 0 || len(tTemplates) > 0 { f.out("/XObject <<") - for _, ti := range tImages { - f.outf("/I%d %d 0 R", ti.i, ti.n) + { + var key string + var keyList []string + var ti *ImageInfoType + for key = range tImages { + keyList = append(keyList, key) + } + if gl.catalogSort { + sort.Strings(keyList) + } + for _, key = range keyList { + // for _, ti := range tImages { + ti = tImages[key] + f.outf("/I%d %d 0 R", ti.i, ti.n) + } } for _, tt := range tTemplates { id := tt.ID() -- cgit v1.2.1-24-ge1ad From d51e132c6432f2c1bbff5d9516f77375bb5252e6 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Sun, 11 Oct 2015 21:06:01 -0400 Subject: Conditionally order another map iteration. Fix 'go vet' problem with unkeyed field in composite literal. --- fpdf.go | 15 ++------------- fpdf_test.go | 4 ++-- template.go | 29 ++++++++++++++++++++++++++++- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/fpdf.go b/fpdf.go index 08bcb2e..74489de 100644 --- a/fpdf.go +++ b/fpdf.go @@ -3367,21 +3367,10 @@ func (f *Fpdf) putxobjectdict() { } } { - var key int64 var keyList []int64 + var key int64 var tpl Template - for key = range f.templates { - keyList = append(keyList, key) - } - if f.catalogSort { - gensort(len(keyList), - func(a, b int) bool { - return keyList[a] < keyList[b] - }, - func(a, b int) { - keyList[a], keyList[b] = keyList[b], keyList[a] - }) - } + keyList = templateKeyList(f.templates, f.catalogSort) for _, key = range keyList { tpl = f.templates[key] // for _, tpl := range f.templates { diff --git a/fpdf_test.go b/fpdf_test.go index a0eaec1..7b56fab 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -1734,8 +1734,8 @@ func ExampleFpdf_CreateTemplate() { pdf.AddPage() pdf.UseTemplate(template) - pdf.UseTemplateScaled(template, gofpdf.PointType{0, 30}, tplSize) - pdf.UseTemplateScaled(template, gofpdf.PointType{0, 60}, tplSize.ScaleBy(1.4)) + pdf.UseTemplateScaled(template, gofpdf.PointType{X: 0, Y: 30}, tplSize) + pdf.UseTemplateScaled(template, gofpdf.PointType{X: 0, Y: 60}, tplSize.ScaleBy(1.4)) pdf.Line(40, 210, 60, 210) pdf.Text(40, 200, "Template example page 1") diff --git a/template.go b/template.go index bf25c9f..cdb1428 100644 --- a/template.go +++ b/template.go @@ -178,12 +178,34 @@ func (f *Fpdf) putTemplates() { } } +func templateKeyList(mp map[int64]Template, sort bool) (keyList []int64) { + var key int64 + for key = range mp { + keyList = append(keyList, key) + } + if sort { + gensort(len(keyList), + func(a, b int) bool { + return keyList[a] < keyList[b] + }, + func(a, b int) { + keyList[a], keyList[b] = keyList[b], keyList[a] + }) + } + return +} + // sortTemplates puts templates in a suitable order based on dependices func sortTemplates(templates map[int64]Template) []Template { chain := make([]Template, 0, len(templates)*2) // build a full set of dependency chains - for _, t := range templates { + var keyList []int64 + var key int64 + var t Template + keyList = templateKeyList(templates, true) // FIXME + for _, key = range keyList { + t = templates[key] tlist := templateChainDependencies(t) for _, tt := range tlist { if tt != nil { @@ -219,3 +241,8 @@ func templateChainDependencies(template Template) []Template { chain = append(chain, template) return chain } + +// < 0002640 31 20 31 32 20 30 20 52 0a 2f 54 50 4c 32 20 31 |1 12 0 R./TPL2 1| +// > 0002640 31 20 31 32 20 30 20 52 0a 2f 54 50 4c 31 20 31 |1 12 0 R./TPL1 1| +// < 0002650 35 20 30 20 52 0a 2f 54 50 4c 31 20 31 34 20 30 |5 0 R./TPL1 14 0| +// > 0002650 34 20 30 20 52 0a 2f 54 50 4c 32 20 31 35 20 30 |4 0 R./TPL2 15 0| -- cgit v1.2.1-24-ge1ad From 31c1da203bd00ff9e9ba602257bab2b4282ca945 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Mon, 12 Oct 2015 10:34:43 -0400 Subject: Add reference PDFs for comparison purposes. Document comparison of example documents. --- .gitignore | 1 - README.md | 13 + doc.go | 13 + fpdf.go | 6 +- pdf/reference/Fpdf_AddFont.pdf | Bin 0 -> 27815 bytes pdf/reference/Fpdf_AddLayer.pdf | Bin 0 -> 1318 bytes pdf/reference/Fpdf_AddPage.pdf | Bin 0 -> 4690 bytes pdf/reference/Fpdf_Beziergon.pdf | Bin 0 -> 1272 bytes pdf/reference/Fpdf_Bookmark.pdf | Bin 0 -> 1992 bytes pdf/reference/Fpdf_CellFormat_1_tables.pdf | Bin 0 -> 5863 bytes pdf/reference/Fpdf_CellFormat_2_align.pdf | Bin 0 -> 31946 bytes pdf/reference/Fpdf_CellFormat_3_codepageescape.pdf | Bin 0 -> 1471 bytes pdf/reference/Fpdf_CellFormat_4_codepage.pdf | Bin 0 -> 315587 bytes pdf/reference/Fpdf_Circle_figures.pdf | Bin 0 -> 2732 bytes pdf/reference/Fpdf_ClipText.pdf | Bin 0 -> 9018 bytes pdf/reference/Fpdf_CreateTemplate.pdf | Bin 0 -> 10763 bytes pdf/reference/Fpdf_DrawPath_fill.pdf | Bin 0 -> 2150 bytes pdf/reference/Fpdf_HTMLBasicNew.pdf | Bin 0 -> 5093 bytes pdf/reference/Fpdf_Image.pdf | Bin 0 -> 23469 bytes pdf/reference/Fpdf_LinearGradient_gradient.pdf | Bin 0 -> 2545 bytes pdf/reference/Fpdf_MoveTo_path.pdf | Bin 0 -> 855 bytes pdf/reference/Fpdf_MultiCell.pdf | Bin 0 -> 11693 bytes pdf/reference/Fpdf_PageSize.pdf | Bin 0 -> 1520 bytes pdf/reference/Fpdf_Polygon.pdf | Bin 0 -> 3229 bytes pdf/reference/Fpdf_RegisterImage.pdf | Bin 0 -> 27788 bytes pdf/reference/Fpdf_RegisterImageReader_url.pdf | Bin 0 -> 10998 bytes pdf/reference/Fpdf_SVGBasicWrite.pdf | 398 +++++++++++++++++++++ .../Fpdf_SetAcceptPageBreakFunc_landscape.pdf | Bin 0 -> 139383 bytes pdf/reference/Fpdf_SetAlpha_transparency.pdf | Bin 0 -> 130413 bytes pdf/reference/Fpdf_SetFontLoader.pdf | Bin 0 -> 27815 bytes pdf/reference/Fpdf_SetKeywords.pdf | Bin 0 -> 44528 bytes pdf/reference/Fpdf_SetLeftMargin_multicolumn.pdf | Bin 0 -> 14966 bytes pdf/reference/Fpdf_SetLineJoinStyle_caps.pdf | Bin 0 -> 822 bytes pdf/reference/Fpdf_SetProtection.pdf | Bin 0 -> 1077 bytes pdf/reference/Fpdf_Splitlines.pdf | Bin 0 -> 1325 bytes pdf/reference/Fpdf_TransformBegin.pdf | Bin 0 -> 1835 bytes pdf/reference/Fpdf_WriteAligned.pdf | Bin 0 -> 967 bytes pdf/reference/basic.pdf | Bin 0 -> 895 bytes template.go | 9 +- template_impl.go | 4 +- 40 files changed, 434 insertions(+), 10 deletions(-) create mode 100644 pdf/reference/Fpdf_AddFont.pdf create mode 100644 pdf/reference/Fpdf_AddLayer.pdf create mode 100644 pdf/reference/Fpdf_AddPage.pdf create mode 100644 pdf/reference/Fpdf_Beziergon.pdf create mode 100644 pdf/reference/Fpdf_Bookmark.pdf create mode 100644 pdf/reference/Fpdf_CellFormat_1_tables.pdf create mode 100644 pdf/reference/Fpdf_CellFormat_2_align.pdf create mode 100644 pdf/reference/Fpdf_CellFormat_3_codepageescape.pdf create mode 100644 pdf/reference/Fpdf_CellFormat_4_codepage.pdf create mode 100644 pdf/reference/Fpdf_Circle_figures.pdf create mode 100644 pdf/reference/Fpdf_ClipText.pdf create mode 100644 pdf/reference/Fpdf_CreateTemplate.pdf create mode 100644 pdf/reference/Fpdf_DrawPath_fill.pdf create mode 100644 pdf/reference/Fpdf_HTMLBasicNew.pdf create mode 100644 pdf/reference/Fpdf_Image.pdf create mode 100644 pdf/reference/Fpdf_LinearGradient_gradient.pdf create mode 100644 pdf/reference/Fpdf_MoveTo_path.pdf create mode 100644 pdf/reference/Fpdf_MultiCell.pdf create mode 100644 pdf/reference/Fpdf_PageSize.pdf create mode 100644 pdf/reference/Fpdf_Polygon.pdf create mode 100644 pdf/reference/Fpdf_RegisterImage.pdf create mode 100644 pdf/reference/Fpdf_RegisterImageReader_url.pdf create mode 100644 pdf/reference/Fpdf_SVGBasicWrite.pdf create mode 100644 pdf/reference/Fpdf_SetAcceptPageBreakFunc_landscape.pdf create mode 100644 pdf/reference/Fpdf_SetAlpha_transparency.pdf create mode 100644 pdf/reference/Fpdf_SetFontLoader.pdf create mode 100644 pdf/reference/Fpdf_SetKeywords.pdf create mode 100644 pdf/reference/Fpdf_SetLeftMargin_multicolumn.pdf create mode 100644 pdf/reference/Fpdf_SetLineJoinStyle_caps.pdf create mode 100644 pdf/reference/Fpdf_SetProtection.pdf create mode 100644 pdf/reference/Fpdf_Splitlines.pdf create mode 100644 pdf/reference/Fpdf_TransformBegin.pdf create mode 100644 pdf/reference/Fpdf_WriteAligned.pdf create mode 100644 pdf/reference/basic.pdf diff --git a/.gitignore b/.gitignore index 8203c3c..e8f0fe4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ makefont/makefont pdf/*.pdf -pdf/reference look open pdf.txt diff --git a/README.md b/README.md index 95fe304..25d68c3 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,19 @@ Please note that these examples run in the context of a test. In order run an example as a standalone application, you'll need to examine [fpdf_test.go](https://github.com/jung-kurt/gofpdf/blob/master/fpdf_test.go) for some helper routines, for example exampleFilename and summary. +Example PDFs can be compared with reference copies in order to verify that they +have been generated as expected. This comparison will be performed if a PDF +with the same name as the example PDF is placed in the gofpdf/pdf/reference +directory. The routine that summarizes an example will look for this file and, +if found, will call the ComparePDFFiles() to check the example PDF for equality +with its reference PDF. If differences exist between the two files they will be +printed to standard output and the test will fail. If the reference file is +missing, the comparison is considered to succeed. In order to successfully +compare two PDFs, the placement of internal resources must be consistent and +the internal creation timestamps must be the same. To do this, the methods +SetCatalogSort() and SetCreationDate() need to be called for both files. This +is done automatically for all examples. + ##Nonstandard Fonts diff --git a/doc.go b/doc.go index 3dd09ef..1561090 100644 --- a/doc.go +++ b/doc.go @@ -120,6 +120,19 @@ Please note that these examples run in the context of a test. In order run an example as a standalone application, you'll need to examine fpdf_test.go for some helper routines, for example exampleFilename and summary. +Example PDFs can be compared with reference copies in order to verify that they +have been generated as expected. This comparison will be performed if a PDF +with the same name as the example PDF is placed in the gofpdf/pdf/reference +directory. The routine that summarizes an example will look for this file and, +if found, will call the ComparePDFFiles() to check the example PDF for equality +with its reference PDF. If differences exist between the two files they will be +printed to standard output and the test will fail. If the reference file is +missing, the comparison is considered to succeed. In order to successfully +compare two PDFs, the placement of internal resources must be consistent and +the internal creation timestamps must be the same. To do this, the methods +SetCatalogSort() and SetCreationDate() need to be called for both files. This +is done automatically for all examples. + Nonstandard Fonts Nothing special is required to use the standard PDF fonts (courier, helvetica, diff --git a/fpdf.go b/fpdf.go index 74489de..bc23674 100644 --- a/fpdf.go +++ b/fpdf.go @@ -3003,7 +3003,7 @@ func SetDefaultCatalogSort(flag bool) { // 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. +// used for test purposes to facilitate PDF comparison. func (f *Fpdf) SetCatalogSort(flag bool) { f.catalogSort = flag } @@ -3017,8 +3017,8 @@ func SetDefaultCreationDate(tm time.Time) { // 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. +// This method is typically only used for testing purposes to facilitate PDF +// comparsion. Specify a zero-value time to revert to the default behavior. func (f *Fpdf) SetCreationDate(tm time.Time) { f.creationDate = tm } diff --git a/pdf/reference/Fpdf_AddFont.pdf b/pdf/reference/Fpdf_AddFont.pdf new file mode 100644 index 0000000..e5c8266 Binary files /dev/null and b/pdf/reference/Fpdf_AddFont.pdf differ diff --git a/pdf/reference/Fpdf_AddLayer.pdf b/pdf/reference/Fpdf_AddLayer.pdf new file mode 100644 index 0000000..16b4b5b Binary files /dev/null and b/pdf/reference/Fpdf_AddLayer.pdf differ diff --git a/pdf/reference/Fpdf_AddPage.pdf b/pdf/reference/Fpdf_AddPage.pdf new file mode 100644 index 0000000..72c59eb Binary files /dev/null and b/pdf/reference/Fpdf_AddPage.pdf differ diff --git a/pdf/reference/Fpdf_Beziergon.pdf b/pdf/reference/Fpdf_Beziergon.pdf new file mode 100644 index 0000000..b33e2ee Binary files /dev/null and b/pdf/reference/Fpdf_Beziergon.pdf differ diff --git a/pdf/reference/Fpdf_Bookmark.pdf b/pdf/reference/Fpdf_Bookmark.pdf new file mode 100644 index 0000000..463d49e Binary files /dev/null and b/pdf/reference/Fpdf_Bookmark.pdf differ diff --git a/pdf/reference/Fpdf_CellFormat_1_tables.pdf b/pdf/reference/Fpdf_CellFormat_1_tables.pdf new file mode 100644 index 0000000..ef0a880 Binary files /dev/null and b/pdf/reference/Fpdf_CellFormat_1_tables.pdf differ diff --git a/pdf/reference/Fpdf_CellFormat_2_align.pdf b/pdf/reference/Fpdf_CellFormat_2_align.pdf new file mode 100644 index 0000000..5074357 Binary files /dev/null and b/pdf/reference/Fpdf_CellFormat_2_align.pdf differ diff --git a/pdf/reference/Fpdf_CellFormat_3_codepageescape.pdf b/pdf/reference/Fpdf_CellFormat_3_codepageescape.pdf new file mode 100644 index 0000000..ef3a88e Binary files /dev/null and b/pdf/reference/Fpdf_CellFormat_3_codepageescape.pdf differ diff --git a/pdf/reference/Fpdf_CellFormat_4_codepage.pdf b/pdf/reference/Fpdf_CellFormat_4_codepage.pdf new file mode 100644 index 0000000..6c11be0 Binary files /dev/null and b/pdf/reference/Fpdf_CellFormat_4_codepage.pdf differ diff --git a/pdf/reference/Fpdf_Circle_figures.pdf b/pdf/reference/Fpdf_Circle_figures.pdf new file mode 100644 index 0000000..097d53c Binary files /dev/null and b/pdf/reference/Fpdf_Circle_figures.pdf differ diff --git a/pdf/reference/Fpdf_ClipText.pdf b/pdf/reference/Fpdf_ClipText.pdf new file mode 100644 index 0000000..258ea1f Binary files /dev/null and b/pdf/reference/Fpdf_ClipText.pdf differ diff --git a/pdf/reference/Fpdf_CreateTemplate.pdf b/pdf/reference/Fpdf_CreateTemplate.pdf new file mode 100644 index 0000000..0223da9 Binary files /dev/null and b/pdf/reference/Fpdf_CreateTemplate.pdf differ diff --git a/pdf/reference/Fpdf_DrawPath_fill.pdf b/pdf/reference/Fpdf_DrawPath_fill.pdf new file mode 100644 index 0000000..fdde12c Binary files /dev/null and b/pdf/reference/Fpdf_DrawPath_fill.pdf differ diff --git a/pdf/reference/Fpdf_HTMLBasicNew.pdf b/pdf/reference/Fpdf_HTMLBasicNew.pdf new file mode 100644 index 0000000..fb5cbf4 Binary files /dev/null and b/pdf/reference/Fpdf_HTMLBasicNew.pdf differ diff --git a/pdf/reference/Fpdf_Image.pdf b/pdf/reference/Fpdf_Image.pdf new file mode 100644 index 0000000..838dd4b Binary files /dev/null and b/pdf/reference/Fpdf_Image.pdf differ diff --git a/pdf/reference/Fpdf_LinearGradient_gradient.pdf b/pdf/reference/Fpdf_LinearGradient_gradient.pdf new file mode 100644 index 0000000..cb1e3bd Binary files /dev/null and b/pdf/reference/Fpdf_LinearGradient_gradient.pdf differ diff --git a/pdf/reference/Fpdf_MoveTo_path.pdf b/pdf/reference/Fpdf_MoveTo_path.pdf new file mode 100644 index 0000000..b5dcca0 Binary files /dev/null and b/pdf/reference/Fpdf_MoveTo_path.pdf differ diff --git a/pdf/reference/Fpdf_MultiCell.pdf b/pdf/reference/Fpdf_MultiCell.pdf new file mode 100644 index 0000000..a073d75 Binary files /dev/null and b/pdf/reference/Fpdf_MultiCell.pdf differ diff --git a/pdf/reference/Fpdf_PageSize.pdf b/pdf/reference/Fpdf_PageSize.pdf new file mode 100644 index 0000000..f523782 Binary files /dev/null and b/pdf/reference/Fpdf_PageSize.pdf differ diff --git a/pdf/reference/Fpdf_Polygon.pdf b/pdf/reference/Fpdf_Polygon.pdf new file mode 100644 index 0000000..a3c04ed Binary files /dev/null and b/pdf/reference/Fpdf_Polygon.pdf differ diff --git a/pdf/reference/Fpdf_RegisterImage.pdf b/pdf/reference/Fpdf_RegisterImage.pdf new file mode 100644 index 0000000..80a14d9 Binary files /dev/null and b/pdf/reference/Fpdf_RegisterImage.pdf differ diff --git a/pdf/reference/Fpdf_RegisterImageReader_url.pdf b/pdf/reference/Fpdf_RegisterImageReader_url.pdf new file mode 100644 index 0000000..171ad32 Binary files /dev/null and b/pdf/reference/Fpdf_RegisterImageReader_url.pdf differ diff --git a/pdf/reference/Fpdf_SVGBasicWrite.pdf b/pdf/reference/Fpdf_SVGBasicWrite.pdf new file mode 100644 index 0000000..d250cb7 --- /dev/null +++ b/pdf/reference/Fpdf_SVGBasicWrite.pdf @@ -0,0 +1,398 @@ +%PDF-1.3 +3 0 obj +<>>><>>>] +/Contents 4 0 R>> +endobj +4 0 obj +<> +stream +0 J +0 j +0.57 w +BT /F0 16.00 Tf ET +0.000 G +0.000 g +BT 31.19 800.74 Td (This example renders a simple ) Tj ET +q 0.000 0.000 0.502 rg BT 230.70 800.74 Td (SVG) Tj ET 230.70 799.14 32.00 -0.80 re f Q +BT 262.70 800.74 Td ( \(scalable vector graphics\) image that contains) Tj ET +BT 31.18 784.74 Td (only basic path commands without) Tj ET +BT 254.29 784.74 Td (any styling, color fill, reflection or endpoint) Tj ET +BT 31.18 768.74 Td (closures. In particular, the type of) Tj ET +BT 246.69 768.74 Td (vector graphic returned from a ) Tj ET +q 0.000 0.000 0.502 rg BT 446.17 768.74 Td (jSignature) Tj ET 446.17 767.14 65.78 -0.80 re f Q +BT 511.95 768.74 Td ( web) Tj ET +BT 31.18 752.74 Td (control is supported and is used in this example.) Tj ET +1 J +0.71 w +0.000 0.000 0.502 RG +173.14 728.26 m +176.69201 726.39095 182.10238 728.53851 183.84896 730.80536 c S +183.85 730.81 m +185.59553 733.07220 184.58495 734.47986 182.68888 734.91049 c S +182.69 734.91 m +180.79282 735.34111 179.70744 734.16862 178.61086 732.56810 c S +178.61 732.57 m +177.51427 730.96757 177.03169 729.05904 176.76941 726.25412 c S +176.77 726.25 m +176.50713 723.44920 176.58763 718.92532 175.59231 716.02576 c S +175.59 716.03 m +174.59698 713.12621 172.70888 711.78580 169.93096 710.97133 c S +169.93 710.97 m +167.15304 710.15686 163.10183 710.49922 160.99777 712.68222 c S +161.00 712.68 m +158.89370 714.86523 159.25220 718.65958 161.04160 720.24991 c S +161.04 720.25 m +162.83099 721.84024 164.57017 721.79421 164.81549 718.92486 c S +164.82 718.92 m +165.06081 716.05552 159.34783 711.36114 157.59405 711.67243 c S +157.59 711.67 m +155.84027 711.98373 156.94420 711.67243 156.61927 711.67243 c S +194.42 717.62 m +195.55336 718.57545 196.53975 719.83734 196.71861 721.35310 c S +196.72 721.35 m +196.82446 722.07726 196.58118 722.91283 195.89534 723.27141 c S +195.90 723.27 m +194.29350 724.28299 192.26361 723.95615 190.57449 723.35079 c S +190.57 723.35 m +188.48355 722.55908 186.56863 721.33744 184.85714 719.90832 c S +184.86 719.91 m +183.75668 718.95525 182.71431 717.88298 182.01721 716.59503 c S +182.02 716.60 m +181.27049 714.82491 182.43659 712.43836 184.40396 712.18734 c S +184.40 712.19 m +185.88681 711.92596 187.32423 712.55186 188.58566 713.26658 c S +188.59 713.27 m +190.25962 714.11983 191.79288 715.22377 193.18879 716.47757 c S +193.19 716.48 m +193.60290 716.83039 194.01304 717.18786 194.42040 717.54843 c S +199.35 720.53 m +196.54236 718.91546 192.97248 716.48071 191.52980 714.77466 c S +191.53 714.77 m +190.08712 713.06861 191.65325 712.50117 193.05058 712.37366 c S +193.05 712.37 m +194.44790 712.24614 195.89422 712.78453 197.56822 713.70532 c S +197.57 713.71 m +199.24222 714.62611 201.44780 716.46597 202.73492 717.96366 c S +202.73 717.96 m +204.02203 719.46135 205.40992 720.91076 205.82992 722.02588 c S +205.83 722.03 m +206.24992 723.14099 206.31152 723.46716 205.66702 723.86598 c S +197.34 712.34 m +201.53970 715.84331 205.14769 720.18427 210.14205 722.62966 c S +210.14 722.63 m +211.66595 723.65683 215.03478 724.77732 215.41016 722.05536 c S +215.41 722.06 m +215.56246 719.73171 213.64299 718.07070 212.48553 716.26895 c S +212.49 716.27 m +211.68434 715.21492 210.02152 712.93076 209.77854 712.65527 c S +209.78 712.66 m +212.49367 716.83123 216.42339 720.09449 220.58985 722.74578 c S +220.59 722.75 m +222.11202 723.74785 225.98680 723.99924 225.05321 721.15944 c S +225.05 721.16 m +224.59796 719.01691 222.96208 717.46923 221.42602 716.06033 c S +221.43 716.06 m +219.84594 714.63332 220.58200 712.11502 222.92551 712.60418 c S +222.93 712.60 m +224.90790 712.72647 226.45016 714.14554 228.13027 715.04406 c S +228.13 715.04 m +231.73885 717.86466 234.44484 721.90966 238.75494 723.78135 c S +238.75 723.78 m +240.92664 724.63139 243.74468 725.41728 245.70339 723.68346 c S +245.70 723.68 m +247.32271 722.17600 246.40020 719.70592 245.20379 718.24469 c S +245.20 718.24 m +243.91773 716.33636 242.04581 714.92493 239.91289 714.07804 c S +239.91 714.08 m +237.50533 712.64078 234.30210 712.77113 232.08008 714.50451 c S +232.08 714.50 m +232.00346 714.55375 231.92079 714.59171 231.83970 714.63264 c S +237.53 725.94 m +236.16664 722.49110 234.75181 719.00201 232.45219 716.05907 c S +232.45 716.06 m +230.44053 712.94864 229.16906 709.39055 226.81651 706.49471 c S +226.82 706.49 m +225.13530 704.16637 223.36673 701.86107 221.16026 700.00071 c S +221.16 700.00 m +219.78331 699.56298 219.74355 701.47050 220.12388 702.32728 c S +220.12 702.33 m +221.03094 704.89014 222.75501 707.03352 224.00539 709.42369 c S +224.01 709.42 m +225.56584 712.15913 227.82633 714.34097 230.06657 716.51012 c S +232.03 714.35 m +234.97123 711.68212 239.53495 711.46073 243.00452 713.18561 c S +243.00 713.19 m +248.64064 715.57527 253.44019 719.45575 258.25868 723.14675 c S +258.26 723.15 m +260.98511 725.35221 263.61742 727.85352 265.20744 731.02457 c S +265.21 731.02 m +265.58109 732.17969 266.00169 733.72429 265.04456 734.69963 c S +265.04 734.70 m +263.28737 735.36357 261.88150 733.34147 260.61139 732.40457 c S +260.61 732.40 m +257.62787 729.49504 255.24533 726.01787 253.13898 722.43949 c S +253.14 722.44 m +251.85716 720.04012 250.56984 718.16982 249.95083 714.95719 c S +249.95 714.96 m +249.60668 713.17113 251.17742 712.12890 252.67159 712.39514 c S +252.67 712.40 m +254.59704 712.48556 256.36031 713.38919 258.13335 714.05752 c S +258.13 714.06 m +259.56564 714.74830 260.82323 715.73671 262.07316 716.70648 c S +263.25 720.83 m +266.45830 718.32194 269.24179 718.19770 272.84620 719.05054 c S +272.85 719.05 m +273.90124 719.39462 274.66655 720.32105 274.97709 721.36491 c S +274.98 721.36 m +275.41570 722.28065 274.95660 723.33824 274.06315 723.76115 c S +274.06 723.76 m +272.68466 724.63544 270.90412 724.50736 269.47476 723.82657 c S +269.47 723.83 m +267.11353 722.80474 265.27331 720.93322 263.49705 719.12908 c S +263.50 719.13 m +262.51271 717.95853 261.89445 716.43859 261.87150 714.90564 c S +261.87 714.91 m +261.92482 714.00566 262.63090 713.30406 263.46867 713.07181 c S +263.47 713.07 m +265.49308 712.22637 267.82843 711.79548 269.96169 712.48022 c S +269.96 712.48 m +271.38589 712.99418 272.77993 713.60559 274.12454 714.29924 c S +274.12 714.30 m +275.73324 715.24381 277.04723 716.59074 278.37100 717.88463 c S +282.40 711.90 m +284.42511 711.68139 286.87452 711.71014 288.24351 713.48277 c S +288.24 713.48 m +289.77356 714.89601 291.29688 716.88360 290.76238 719.09920 c S +290.76 719.10 m +290.46995 720.66673 288.38862 721.80129 287.07511 720.65649 c S +287.08 720.66 m +284.83080 719.06805 284.85744 715.69051 286.16454 713.50810 c S +286.16 713.51 m +287.83794 710.78294 291.39981 709.93746 294.37610 710.58475 c S +294.38 710.58 m +298.19476 711.31369 301.75755 714.39307 302.21808 718.37987 c S +302.22 718.38 m +302.27384 720.70131 302.27291 723.02577 302.56760 725.33335 c S +302.57 725.33 m +302.84540 728.35509 303.27076 731.63068 305.33980 734.00518 c S +305.34 734.01 m +306.54888 735.31235 308.96093 735.90837 310.24950 734.39793 c S +310.25 734.40 m +311.28815 733.04105 310.46366 731.19605 309.49016 730.05151 c S +309.49 730.05 m +308.33498 728.27449 306.04620 727.99188 304.16152 727.48991 c S +304.16 727.49 m +302.28972 727.08157 300.01717 727.29546 298.78181 728.93980 c S +298.78 728.94 m +298.09957 729.69710 297.33548 730.54928 297.31969 731.62981 c S +315.29 727.51 m +315.00973 727.44850 314.82299 727.12458 314.91766 726.85678 c S +314.92 726.86 m +315.00798 726.60006 315.22645 726.38678 315.49277 726.32089 c S +315.49 726.32 m +315.64178 726.31238 315.78365 726.43926 315.79232 726.58816 c S +315.79 726.59 m +315.84805 726.85217 315.81141 727.14788 315.64285 727.36550 c S +315.64 727.37 m +315.55476 727.46279 315.42043 727.53319 315.28659 727.50625 c S +313.47 724.12 m +311.35342 721.29454 309.30928 718.41152 307.38263 715.45503 c S +307.38 715.46 m +306.99823 714.64637 306.89333 713.52880 307.56739 712.84376 c S +307.57 712.84 m +308.38275 712.24289 309.44839 712.56426 310.33569 712.79924 c S +310.34 712.80 m +312.59541 713.39748 314.80881 714.34466 316.57502 715.90806 c S +316.58 715.91 m +317.65017 716.79085 318.63346 717.78496 319.50832 718.86643 c S +332.40 721.78 m +332.16589 723.13908 330.67278 723.93843 329.37515 723.80245 c S +329.38 723.80 m +326.61691 723.90645 324.09629 722.51390 321.87411 721.02639 c S +321.87 721.03 m +319.93298 719.66330 318.13021 717.83625 317.49119 715.49099 c S +317.49 715.49 m +317.28543 713.79420 318.81139 712.02572 320.56032 712.19858 c S +320.56 712.20 m +323.48689 712.23348 326.10902 713.86336 328.21679 715.76982 c S +328.22 715.77 m +330.09114 717.35188 331.95005 719.26950 332.40123 721.77838 c S +334.38 720.14 m +330.96442 718.38670 327.63686 716.04994 325.75985 712.60194 c S +325.76 712.60 m +323.03491 708.51169 319.74605 704.83793 316.51659 701.14850 c S +316.52 701.15 m +315.50279 700.17328 314.26549 699.11349 312.78273 699.14168 c S +312.78 699.14 m +311.19787 699.55260 311.35870 701.64714 312.51702 702.45870 c S +312.52 702.46 m +313.81397 703.91905 315.32759 705.17809 316.85560 706.38598 c S +316.86 706.39 m +319.49294 708.29575 322.10541 710.29857 325.09624 711.63306 c S +325.10 711.63 m +328.33960 713.13687 331.64025 714.56306 334.52982 716.70648 c S +337.67 723.68 m +336.84252 720.88107 335.42446 718.30079 333.84347 715.86491 c S +333.84 715.86 m +333.03995 714.64381 332.17889 713.45902 331.24079 712.33748 c S +331.29 712.48 m +334.07649 716.36828 337.24670 720.17732 341.48414 722.53221 c S +341.48 722.53 m +342.93013 723.27663 344.57172 723.46456 346.15836 723.68073 c S +346.16 723.68 m +347.24751 723.83157 348.64372 723.05150 348.52428 721.82540 c S +348.52 721.83 m +348.31569 720.66770 347.52332 719.72346 346.89869 718.76111 c S +346.90 718.76 m +345.95837 717.41785 344.73958 716.16963 344.31068 714.54926 c S +344.31 714.55 m +344.00261 713.24949 345.31058 712.08146 346.56954 712.49179 c S +346.57 712.49 m +347.75729 712.83364 348.76607 713.59466 349.84334 714.17881 c S +349.84 714.18 m +351.49437 715.18108 353.06331 716.34851 354.36212 717.78645 c S +364.77 716.61 m +366.35139 717.88369 367.85549 719.50385 368.24594 721.56699 c S +368.25 721.57 m +368.36326 722.74804 367.24454 723.80833 366.08950 723.78076 c S +366.09 723.78 m +363.36815 724.27267 360.64865 723.13638 358.45357 721.60052 c S +358.45 721.60 m +356.50210 720.25171 354.55170 718.66798 353.56001 716.45281 c S +353.56 716.45 m +353.05173 715.11390 353.41457 713.31400 354.78470 712.64113 c S +354.78 712.64 m +356.36791 711.74619 358.35987 712.10735 359.86286 712.99644 c S +359.86 713.00 m +361.65803 713.96816 363.16587 715.36503 364.76918 716.60830 c S +370.91 720.54 m +368.43366 718.81082 359.59578 713.85776 364.46275 712.67519 c S +364.46 712.68 m +367.96243 711.82485 372.99419 716.53166 377.06220 719.86793 c S +377.06 719.87 m +381.13021 723.20421 388.66532 729.50635 389.52279 734.40918 c S +389.52 734.41 m +390.38026 739.31201 386.99017 732.63924 385.44672 729.99800 c S +385.45 730.00 m +383.90327 727.35676 381.68734 721.89825 378.84260 717.57920 c S +378.84 717.58 m +374.88808 711.57520 379.84829 710.67284 384.40551 713.75693 c S +384.41 713.76 m +387.47762 715.83598 388.36739 716.53064 390.05047 718.32644 c S +377.09 724.61 m +380.71911 724.41189 384.35803 724.30792 387.98869 724.51177 c S +394.03 724.41 m +392.18491 721.66026 390.24889 718.97709 388.69800 716.01507 c S +388.70 716.02 m +388.11570 714.90294 387.78649 713.14830 389.14290 712.64677 c S +389.14 712.65 m +390.93520 712.19182 391.58604 712.85554 392.62746 713.16610 c S +392.63 713.17 m +396.02262 714.53123 398.83776 717.01922 401.31194 719.76695 c S +401.31 719.77 m +402.40197 721.24598 403.46885 722.74227 404.63016 724.16817 c S +404.78 724.22 m +402.55929 721.74558 400.57949 719.06249 398.76886 716.28285 c S +398.77 716.28 m +398.32437 715.32028 397.62621 714.21254 398.07187 713.13095 c S +398.07 713.13 m +398.57336 712.18240 399.85778 712.37483 400.73100 712.56985 c S +400.73 712.57 m +402.98443 713.25618 404.83854 714.79610 406.66011 716.22985 c S +406.66 716.23 m +408.11360 717.41183 409.36895 718.81778 410.44888 720.34308 c S +410.45 720.34 m +411.47726 721.59671 412.51414 722.88301 413.25375 724.32691 c S +413.25 724.33 m +413.60253 725.66655 411.26351 725.68421 412.00122 724.33574 c S +412.00 724.34 m +412.67563 723.07539 414.28726 723.02575 415.54291 722.95857 c S +415.54 722.96 m +416.69601 723.19698 417.19632 721.86044 416.45907 721.08440 c S +416.46 721.08 m +415.97330 720.51720 415.48724 719.96970 415.10474 719.31838 c S +415.10 719.32 m +413.91309 717.57253 412.50005 715.87703 411.94882 713.79691 c S +411.95 713.80 m +411.73164 712.43046 413.33326 711.41965 414.54890 711.86110 c S +414.55 711.86 m +417.07044 712.45069 419.35460 713.73436 421.56616 715.03742 c S +422.60 720.83 m +424.94264 719.25149 427.88660 718.31183 430.71325 718.88005 c S +430.71 718.88 m +431.82181 719.10667 432.85178 719.63723 433.76367 720.28974 c S +433.76 720.29 m +434.98835 721.29361 434.95979 723.45602 433.61045 724.33926 c S +433.61 724.34 m +432.65667 724.96769 431.44146 724.75467 430.38277 724.58403 c S +430.38 724.58 m +428.00929 724.08917 426.00610 722.58363 424.31063 720.91694 c S +424.31 720.92 m +422.51500 719.31015 421.33376 716.83779 421.70110 714.40116 c S +421.70 714.40 m +422.15276 713.11643 423.49103 712.39634 424.79016 712.29603 c S +424.79 712.30 m +426.65615 712.13320 428.52395 712.57632 430.27740 713.18297 c S +430.28 713.18 m +433.09197 714.20773 435.59332 715.92106 437.91309 717.78645 c S + +endstream +endobj +1 0 obj +<> +endobj +5 0 obj +<> +endobj +2 0 obj +<< +/ProcSet [/PDF /Text /ImageB /ImageC /ImageI] +/Font << +/F0 5 0 R +>> +/XObject << +>> +>> +endobj +6 0 obj +<< +/Producer (FPDF 1.7) +/CreationDate (D:20000101000000) +>> +endobj +7 0 obj +<< +/Type /Catalog +/Pages 1 0 R +>> +endobj +xref +0 8 +0000000000 65535 f +0000013606 00000 n +0000013791 00000 n +0000000009 00000 n +0000000384 00000 n +0000013693 00000 n +0000013895 00000 n +0000013970 00000 n +trailer +<< +/Size 8 +/Root 7 0 R +/Info 6 0 R +>> +startxref +14019 +%%EOF diff --git a/pdf/reference/Fpdf_SetAcceptPageBreakFunc_landscape.pdf b/pdf/reference/Fpdf_SetAcceptPageBreakFunc_landscape.pdf new file mode 100644 index 0000000..7997df9 Binary files /dev/null and b/pdf/reference/Fpdf_SetAcceptPageBreakFunc_landscape.pdf differ diff --git a/pdf/reference/Fpdf_SetAlpha_transparency.pdf b/pdf/reference/Fpdf_SetAlpha_transparency.pdf new file mode 100644 index 0000000..49dde6a Binary files /dev/null and b/pdf/reference/Fpdf_SetAlpha_transparency.pdf differ diff --git a/pdf/reference/Fpdf_SetFontLoader.pdf b/pdf/reference/Fpdf_SetFontLoader.pdf new file mode 100644 index 0000000..1aa2f6f Binary files /dev/null and b/pdf/reference/Fpdf_SetFontLoader.pdf differ diff --git a/pdf/reference/Fpdf_SetKeywords.pdf b/pdf/reference/Fpdf_SetKeywords.pdf new file mode 100644 index 0000000..3d3d3a5 Binary files /dev/null and b/pdf/reference/Fpdf_SetKeywords.pdf differ diff --git a/pdf/reference/Fpdf_SetLeftMargin_multicolumn.pdf b/pdf/reference/Fpdf_SetLeftMargin_multicolumn.pdf new file mode 100644 index 0000000..91b6d59 Binary files /dev/null and b/pdf/reference/Fpdf_SetLeftMargin_multicolumn.pdf differ diff --git a/pdf/reference/Fpdf_SetLineJoinStyle_caps.pdf b/pdf/reference/Fpdf_SetLineJoinStyle_caps.pdf new file mode 100644 index 0000000..9b9badb Binary files /dev/null and b/pdf/reference/Fpdf_SetLineJoinStyle_caps.pdf differ diff --git a/pdf/reference/Fpdf_SetProtection.pdf b/pdf/reference/Fpdf_SetProtection.pdf new file mode 100644 index 0000000..8d007c7 Binary files /dev/null and b/pdf/reference/Fpdf_SetProtection.pdf differ diff --git a/pdf/reference/Fpdf_Splitlines.pdf b/pdf/reference/Fpdf_Splitlines.pdf new file mode 100644 index 0000000..d8064be Binary files /dev/null and b/pdf/reference/Fpdf_Splitlines.pdf differ diff --git a/pdf/reference/Fpdf_TransformBegin.pdf b/pdf/reference/Fpdf_TransformBegin.pdf new file mode 100644 index 0000000..d1ffe34 Binary files /dev/null and b/pdf/reference/Fpdf_TransformBegin.pdf differ diff --git a/pdf/reference/Fpdf_WriteAligned.pdf b/pdf/reference/Fpdf_WriteAligned.pdf new file mode 100644 index 0000000..c173146 Binary files /dev/null and b/pdf/reference/Fpdf_WriteAligned.pdf differ diff --git a/pdf/reference/basic.pdf b/pdf/reference/basic.pdf new file mode 100644 index 0000000..80a7fbf Binary files /dev/null and b/pdf/reference/basic.pdf differ diff --git a/template.go b/template.go index cdb1428..17354fa 100644 --- a/template.go +++ b/template.go @@ -116,7 +116,7 @@ func (f *Fpdf) putTemplates() { filter = "/Filter /FlateDecode " } - templates := sortTemplates(f.templates) + templates := sortTemplates(f.templates, f.catalogSort) var t Template for _, t = range templates { corner, size := t.Size() @@ -196,14 +196,14 @@ func templateKeyList(mp map[int64]Template, sort bool) (keyList []int64) { } // sortTemplates puts templates in a suitable order based on dependices -func sortTemplates(templates map[int64]Template) []Template { +func sortTemplates(templates map[int64]Template, catalogSort bool) []Template { chain := make([]Template, 0, len(templates)*2) // build a full set of dependency chains var keyList []int64 var key int64 var t Template - keyList = templateKeyList(templates, true) // FIXME + keyList = templateKeyList(templates, catalogSort) for _, key = range keyList { t = templates[key] tlist := templateChainDependencies(t) @@ -243,6 +243,7 @@ func templateChainDependencies(template Template) []Template { } // < 0002640 31 20 31 32 20 30 20 52 0a 2f 54 50 4c 32 20 31 |1 12 0 R./TPL2 1| -// > 0002640 31 20 31 32 20 30 20 52 0a 2f 54 50 4c 31 20 31 |1 12 0 R./TPL1 1| // < 0002650 35 20 30 20 52 0a 2f 54 50 4c 31 20 31 34 20 30 |5 0 R./TPL1 14 0| + +// > 0002640 31 20 31 32 20 30 20 52 0a 2f 54 50 4c 31 20 31 |1 12 0 R./TPL1 1| // > 0002650 34 20 30 20 52 0a 2f 54 50 4c 32 20 31 35 20 30 |4 0 R./TPL2 15 0| diff --git a/template_impl.go b/template_impl.go index 093e1fd..c94f880 100644 --- a/template_impl.go +++ b/template_impl.go @@ -35,8 +35,8 @@ func newTpl(corner PointType, size SizeType, unitStr, fontDirStr string, fn func fn(&tpl) bytes := tpl.Fpdf.pages[tpl.Fpdf.page].Bytes() templates := make([]Template, 0, len(tpl.Fpdf.templates)) - for _, t := range tpl.Fpdf.templates { - templates = append(templates, t) + for _, key := range templateKeyList(tpl.Fpdf.templates, true) { + templates = append(templates, tpl.Fpdf.templates[key]) } images := tpl.Fpdf.images -- cgit v1.2.1-24-ge1ad From 0e7f14245b3a89fe3e1aa59814b080b65b58ee08 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Mon, 12 Oct 2015 11:00:21 -0400 Subject: Allow SVG example to be compressed --- fpdf_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/fpdf_test.go b/fpdf_test.go index 7b56fab..596816c 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -1140,7 +1140,6 @@ func ExampleFpdf_SVGBasicWrite() { err error ) pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0 - pdf.SetCompression(false) pdf.SetFont("Times", "", fontPtSize) lineHt := pdf.PointConvert(fontPtSize) pdf.AddPage() -- cgit v1.2.1-24-ge1ad From 212c47a0d580bfdaede6aa9c3bca15a7bab72ff6 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Mon, 12 Oct 2015 13:58:40 -0400 Subject: New reference files that changed as a result of the updated WriteAligned method. --- pdf/reference/Fpdf_CellFormat_3_codepageescape.pdf | Bin 1471 -> 1461 bytes pdf/reference/Fpdf_SVGBasicWrite.pdf | Bin 14256 -> 7375 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/pdf/reference/Fpdf_CellFormat_3_codepageescape.pdf b/pdf/reference/Fpdf_CellFormat_3_codepageescape.pdf index ef3a88e..1d31153 100644 Binary files a/pdf/reference/Fpdf_CellFormat_3_codepageescape.pdf and b/pdf/reference/Fpdf_CellFormat_3_codepageescape.pdf differ diff --git a/pdf/reference/Fpdf_SVGBasicWrite.pdf b/pdf/reference/Fpdf_SVGBasicWrite.pdf index d250cb7..bdefa65 100644 Binary files a/pdf/reference/Fpdf_SVGBasicWrite.pdf and b/pdf/reference/Fpdf_SVGBasicWrite.pdf differ -- cgit v1.2.1-24-ge1ad From 42df0bc5e661afaa5227ccd20ee852801f3bc272 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Mon, 12 Oct 2015 14:49:53 -0400 Subject: Saving files before refreshing line endings --- .gitattribute | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattribute diff --git a/.gitattribute b/.gitattribute new file mode 100644 index 0000000..d72fd52 --- /dev/null +++ b/.gitattribute @@ -0,0 +1 @@ +*.pdf binary -- cgit v1.2.1-24-ge1ad From 7b263b0aecefbf13d8295ea38e19108f121a01b2 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Mon, 12 Oct 2015 17:29:01 -0400 Subject: Reference PDFs generated by contributed packages --- pdf/reference/contrib_barcode_Register.pdf | Bin 0 -> 4954 bytes pdf/reference/contrib_barcode_RegisterCodabar.pdf | Bin 0 -> 5249 bytes pdf/reference/contrib_barcode_RegisterCode128.pdf | Bin 0 -> 5421 bytes pdf/reference/contrib_barcode_RegisterCode39.pdf | Bin 0 -> 5252 bytes pdf/reference/contrib_barcode_RegisterDataMatrix.pdf | Bin 0 -> 4592 bytes pdf/reference/contrib_barcode_RegisterEAN.pdf | Bin 0 -> 4747 bytes pdf/reference/contrib_barcode_RegisterQR.pdf | Bin 0 -> 4411 bytes pdf/reference/contrib_barcode_RegisterTwoOfFive.pdf | Bin 0 -> 5599 bytes pdf/reference/contrib_httpimg_Register.pdf | Bin 0 -> 82994 bytes 9 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 pdf/reference/contrib_barcode_Register.pdf create mode 100644 pdf/reference/contrib_barcode_RegisterCodabar.pdf create mode 100644 pdf/reference/contrib_barcode_RegisterCode128.pdf create mode 100644 pdf/reference/contrib_barcode_RegisterCode39.pdf create mode 100644 pdf/reference/contrib_barcode_RegisterDataMatrix.pdf create mode 100644 pdf/reference/contrib_barcode_RegisterEAN.pdf create mode 100644 pdf/reference/contrib_barcode_RegisterQR.pdf create mode 100644 pdf/reference/contrib_barcode_RegisterTwoOfFive.pdf create mode 100644 pdf/reference/contrib_httpimg_Register.pdf diff --git a/pdf/reference/contrib_barcode_Register.pdf b/pdf/reference/contrib_barcode_Register.pdf new file mode 100644 index 0000000..5ad12e7 Binary files /dev/null and b/pdf/reference/contrib_barcode_Register.pdf differ diff --git a/pdf/reference/contrib_barcode_RegisterCodabar.pdf b/pdf/reference/contrib_barcode_RegisterCodabar.pdf new file mode 100644 index 0000000..4ed247b Binary files /dev/null and b/pdf/reference/contrib_barcode_RegisterCodabar.pdf differ diff --git a/pdf/reference/contrib_barcode_RegisterCode128.pdf b/pdf/reference/contrib_barcode_RegisterCode128.pdf new file mode 100644 index 0000000..f76ae86 Binary files /dev/null and b/pdf/reference/contrib_barcode_RegisterCode128.pdf differ diff --git a/pdf/reference/contrib_barcode_RegisterCode39.pdf b/pdf/reference/contrib_barcode_RegisterCode39.pdf new file mode 100644 index 0000000..fee2c99 Binary files /dev/null and b/pdf/reference/contrib_barcode_RegisterCode39.pdf differ diff --git a/pdf/reference/contrib_barcode_RegisterDataMatrix.pdf b/pdf/reference/contrib_barcode_RegisterDataMatrix.pdf new file mode 100644 index 0000000..5ea011d Binary files /dev/null and b/pdf/reference/contrib_barcode_RegisterDataMatrix.pdf differ diff --git a/pdf/reference/contrib_barcode_RegisterEAN.pdf b/pdf/reference/contrib_barcode_RegisterEAN.pdf new file mode 100644 index 0000000..166090d Binary files /dev/null and b/pdf/reference/contrib_barcode_RegisterEAN.pdf differ diff --git a/pdf/reference/contrib_barcode_RegisterQR.pdf b/pdf/reference/contrib_barcode_RegisterQR.pdf new file mode 100644 index 0000000..6e989e3 Binary files /dev/null and b/pdf/reference/contrib_barcode_RegisterQR.pdf differ diff --git a/pdf/reference/contrib_barcode_RegisterTwoOfFive.pdf b/pdf/reference/contrib_barcode_RegisterTwoOfFive.pdf new file mode 100644 index 0000000..0078dc1 Binary files /dev/null and b/pdf/reference/contrib_barcode_RegisterTwoOfFive.pdf differ diff --git a/pdf/reference/contrib_httpimg_Register.pdf b/pdf/reference/contrib_httpimg_Register.pdf new file mode 100644 index 0000000..212ca93 Binary files /dev/null and b/pdf/reference/contrib_httpimg_Register.pdf differ -- cgit v1.2.1-24-ge1ad From 89173160f564ddc0a63efaadf3ae78b0dc9377d2 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Tue, 13 Oct 2015 07:42:35 -0400 Subject: Use %f rather than %F since earlier versions of Go did not support the latter. Thanks, Marcus. --- template.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/template.go b/template.go index 17354fa..c9a33d5 100644 --- a/template.go +++ b/template.go @@ -79,7 +79,7 @@ func (f *Fpdf) UseTemplateScaled(t Template, corner PointType, size SizeType) { tx := corner.X * f.k ty := (f.curPageSize.Ht - corner.Y - size.Ht) * f.k - f.outf("q %.4F 0 0 %.4F %.4F %.4F cm", scaleX, scaleY, tx, ty) // Translate + f.outf("q %.4f 0 0 %.4f %.4f %.4f cm", scaleX, scaleY, tx, ty) // Translate f.outf("/TPL%d Do Q", t.ID()) } @@ -126,9 +126,9 @@ func (f *Fpdf) putTemplates() { f.outf("<<%s/Type /XObject", filter) f.out("/Subtype /Form") f.out("/Formtype 1") - f.outf("/BBox [%.2F %.2F %.2F %.2F]", corner.X*f.k, corner.Y*f.k, (corner.X+size.Wd)*f.k, (corner.Y+size.Ht)*f.k) + f.outf("/BBox [%.2f %.2f %.2f %.2f]", corner.X*f.k, corner.Y*f.k, (corner.X+size.Wd)*f.k, (corner.Y+size.Ht)*f.k) if corner.X != 0 || corner.Y != 0 { - f.outf("/Matrix [1 0 0 1 %.5F %.5F]", -corner.X*f.k*2, corner.Y*f.k*2) + f.outf("/Matrix [1 0 0 1 %.5f %.5f]", -corner.X*f.k*2, corner.Y*f.k*2) } // Template's resource dictionary -- cgit v1.2.1-24-ge1ad From f10939e21402781b0b6223dd64110df2da085ba0 Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Tue, 13 Oct 2015 18:38:33 -0400 Subject: Include links to reference PDFs in README --- README.md | 43 +++++++++++++++++++++++++++++++++++++++++++ list/list.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mkdoc | 11 +++++++++-- 3 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 list/list.go diff --git a/README.md b/README.md index 25d68c3..8e0954a 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,49 @@ the internal creation timestamps must be the same. To do this, the methods SetCatalogSort() and SetCreationDate() need to be called for both files. This is done automatically for all examples. +[AddFont](pdf/reference/Fpdf_AddFont.pdf) +[AddLayer](pdf/reference/Fpdf_AddLayer.pdf) +[AddPage](pdf/reference/Fpdf_AddPage.pdf) +[Beziergon](pdf/reference/Fpdf_Beziergon.pdf) +[Bookmark](pdf/reference/Fpdf_Bookmark.pdf) +[CellFormat 1 tables](pdf/reference/Fpdf_CellFormat_1_tables.pdf) +[CellFormat 2 align](pdf/reference/Fpdf_CellFormat_2_align.pdf) +[CellFormat 3 codepageescape](pdf/reference/Fpdf_CellFormat_3_codepageescape.pdf) +[CellFormat 4 codepage](pdf/reference/Fpdf_CellFormat_4_codepage.pdf) +[Circle figures](pdf/reference/Fpdf_Circle_figures.pdf) +[ClipText](pdf/reference/Fpdf_ClipText.pdf) +[CreateTemplate](pdf/reference/Fpdf_CreateTemplate.pdf) +[DrawPath fill](pdf/reference/Fpdf_DrawPath_fill.pdf) +[HTMLBasicNew](pdf/reference/Fpdf_HTMLBasicNew.pdf) +[Image](pdf/reference/Fpdf_Image.pdf) +[LinearGradient gradient](pdf/reference/Fpdf_LinearGradient_gradient.pdf) +[MoveTo path](pdf/reference/Fpdf_MoveTo_path.pdf) +[MultiCell](pdf/reference/Fpdf_MultiCell.pdf) +[PageSize](pdf/reference/Fpdf_PageSize.pdf) +[Polygon](pdf/reference/Fpdf_Polygon.pdf) +[RegisterImage](pdf/reference/Fpdf_RegisterImage.pdf) +[RegisterImageReader url](pdf/reference/Fpdf_RegisterImageReader_url.pdf) +[SVGBasicWrite](pdf/reference/Fpdf_SVGBasicWrite.pdf) +[SetAcceptPageBreakFunc landscape](pdf/reference/Fpdf_SetAcceptPageBreakFunc_landscape.pdf) +[SetAlpha transparency](pdf/reference/Fpdf_SetAlpha_transparency.pdf) +[SetFontLoader](pdf/reference/Fpdf_SetFontLoader.pdf) +[SetKeywords](pdf/reference/Fpdf_SetKeywords.pdf) +[SetLeftMargin multicolumn](pdf/reference/Fpdf_SetLeftMargin_multicolumn.pdf) +[SetLineJoinStyle caps](pdf/reference/Fpdf_SetLineJoinStyle_caps.pdf) +[SetProtection](pdf/reference/Fpdf_SetProtection.pdf) +[Splitlines](pdf/reference/Fpdf_Splitlines.pdf) +[TransformBegin](pdf/reference/Fpdf_TransformBegin.pdf) +[WriteAligned](pdf/reference/Fpdf_WriteAligned.pdf) +[barcode Register](pdf/reference/contrib_barcode_Register.pdf) +[barcode RegisterCodabar](pdf/reference/contrib_barcode_RegisterCodabar.pdf) +[barcode RegisterCode128](pdf/reference/contrib_barcode_RegisterCode128.pdf) +[barcode RegisterCode39](pdf/reference/contrib_barcode_RegisterCode39.pdf) +[barcode RegisterDataMatrix](pdf/reference/contrib_barcode_RegisterDataMatrix.pdf) +[barcode RegisterEAN](pdf/reference/contrib_barcode_RegisterEAN.pdf) +[barcode RegisterQR](pdf/reference/contrib_barcode_RegisterQR.pdf) +[barcode RegisterTwoOfFive](pdf/reference/contrib_barcode_RegisterTwoOfFive.pdf) +[httpimg Register](pdf/reference/contrib_httpimg_Register.pdf) + ##Nonstandard Fonts diff --git a/list/list.go b/list/list.go new file mode 100644 index 0000000..8099404 --- /dev/null +++ b/list/list.go @@ -0,0 +1,59 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" + "strings" +) + +func matchTail(str, tailStr string) (match bool, headStr string) { + sln := len(str) + ln := len(tailStr) + if sln > ln { + match = str[sln-ln:] == tailStr + if match { + headStr = str[:sln-ln] + } + } + return +} + +func matchHead(str, headStr string) (match bool, tailStr string) { + ln := len(headStr) + if len(str) > ln { + match = str[:ln] == headStr + if match { + tailStr = str[ln:] + } + } + return +} + +func main() { + var err error + var ok bool + var showStr, name string + err = filepath.Walk("pdf/reference", func(path string, info os.FileInfo, err error) error { + if info.Mode().IsRegular() { + name = filepath.Base(path) + ok, name = matchTail(name, ".pdf") + if ok { + name = strings.Replace(name, "_", " ", -1) + ok, showStr = matchHead(name, "Fpdf ") + if ok { + fmt.Printf("[%s](%s)\n", showStr, path) + } else { + ok, showStr = matchHead(name, "contrib ") + if ok { + fmt.Printf("[%s](%s)\n", showStr, path) + } + } + } + } + return nil + }) + if err != nil { + fmt.Println(err) + } +} diff --git a/mkdoc b/mkdoc index 301c39f..213becc 100755 --- a/mkdoc +++ b/mkdoc @@ -1,3 +1,5 @@ +#!/bin/bash + # https://github.com/jimmyfrasche/autoreadme autoreadme -f -template README.md.template # Improve the appearance of the markdown document with features unavailable in godoc @@ -16,5 +18,10 @@ cat README.md | tr '\n' '\v' | sed \ -e 's/test.coverage.(\(https:\/\/blog\.golang\.org\/cover\))/[test coverage](\1)/g' \ -e 's/Pull.requests.(\(https:\/\/help\.github\.com\/articles\/using\-pull\-requests\/\))/[Pull requests](\1)/g' \ -e 's/Your change should\v/Your change should\v\v/g' \ - | tr '\v' '\n' > 0 -mv 0 README.md + -e 's/##Nonstandard Fonts/__PDFS__\v\v##Nonstandard Fonts/g' \ + | tr '\v' '\n' > _0 +sed -e '/__PDFS__/,$d' _0 > _1 +go run list/list.go >> _1 +sed -e '1,/__PDFS__/d' _0 >> _1 +rm _0 +mv _1 README.md -- cgit v1.2.1-24-ge1ad From 2efaba8cfa054408af1330401b8b7741975f77ae Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Tue, 20 Oct 2015 12:10:08 -0400 Subject: Correct typo --- README.md | 2 +- doc.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8e0954a..28d579f 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ Example PDFs can be compared with reference copies in order to verify that they have been generated as expected. This comparison will be performed if a PDF with the same name as the example PDF is placed in the gofpdf/pdf/reference directory. The routine that summarizes an example will look for this file and, -if found, will call the ComparePDFFiles() to check the example PDF for equality +if found, will call ComparePDFFiles() to check the example PDF for equality with its reference PDF. If differences exist between the two files they will be printed to standard output and the test will fail. If the reference file is missing, the comparison is considered to succeed. In order to successfully diff --git a/doc.go b/doc.go index 1561090..b05ed8e 100644 --- a/doc.go +++ b/doc.go @@ -124,7 +124,7 @@ Example PDFs can be compared with reference copies in order to verify that they have been generated as expected. This comparison will be performed if a PDF with the same name as the example PDF is placed in the gofpdf/pdf/reference directory. The routine that summarizes an example will look for this file and, -if found, will call the ComparePDFFiles() to check the example PDF for equality +if found, will call ComparePDFFiles() to check the example PDF for equality with its reference PDF. If differences exist between the two files they will be printed to standard output and the test will fail. If the reference file is missing, the comparison is considered to succeed. In order to successfully -- cgit v1.2.1-24-ge1ad From f45e5e9196bb313883f36e0ccc72f052f46aa37e Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Tue, 20 Oct 2015 12:24:07 -0400 Subject: Remove listing of reference PDFs in README --- README.md | 45 +-------------------------------------------- doc.go | 2 +- mkdoc | 7 +------ 3 files changed, 3 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 28d579f..fdcbac4 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ complete. Please note that these examples run in the context of a test. In order run an example as a standalone application, you'll need to examine [fpdf_test.go](https://github.com/jung-kurt/gofpdf/blob/master/fpdf_test.go) for -some helper routines, for example exampleFilename and summary. +some helper routines, for example exampleFilename() and summary(). Example PDFs can be compared with reference copies in order to verify that they have been generated as expected. This comparison will be performed if a PDF @@ -114,49 +114,6 @@ the internal creation timestamps must be the same. To do this, the methods SetCatalogSort() and SetCreationDate() need to be called for both files. This is done automatically for all examples. -[AddFont](pdf/reference/Fpdf_AddFont.pdf) -[AddLayer](pdf/reference/Fpdf_AddLayer.pdf) -[AddPage](pdf/reference/Fpdf_AddPage.pdf) -[Beziergon](pdf/reference/Fpdf_Beziergon.pdf) -[Bookmark](pdf/reference/Fpdf_Bookmark.pdf) -[CellFormat 1 tables](pdf/reference/Fpdf_CellFormat_1_tables.pdf) -[CellFormat 2 align](pdf/reference/Fpdf_CellFormat_2_align.pdf) -[CellFormat 3 codepageescape](pdf/reference/Fpdf_CellFormat_3_codepageescape.pdf) -[CellFormat 4 codepage](pdf/reference/Fpdf_CellFormat_4_codepage.pdf) -[Circle figures](pdf/reference/Fpdf_Circle_figures.pdf) -[ClipText](pdf/reference/Fpdf_ClipText.pdf) -[CreateTemplate](pdf/reference/Fpdf_CreateTemplate.pdf) -[DrawPath fill](pdf/reference/Fpdf_DrawPath_fill.pdf) -[HTMLBasicNew](pdf/reference/Fpdf_HTMLBasicNew.pdf) -[Image](pdf/reference/Fpdf_Image.pdf) -[LinearGradient gradient](pdf/reference/Fpdf_LinearGradient_gradient.pdf) -[MoveTo path](pdf/reference/Fpdf_MoveTo_path.pdf) -[MultiCell](pdf/reference/Fpdf_MultiCell.pdf) -[PageSize](pdf/reference/Fpdf_PageSize.pdf) -[Polygon](pdf/reference/Fpdf_Polygon.pdf) -[RegisterImage](pdf/reference/Fpdf_RegisterImage.pdf) -[RegisterImageReader url](pdf/reference/Fpdf_RegisterImageReader_url.pdf) -[SVGBasicWrite](pdf/reference/Fpdf_SVGBasicWrite.pdf) -[SetAcceptPageBreakFunc landscape](pdf/reference/Fpdf_SetAcceptPageBreakFunc_landscape.pdf) -[SetAlpha transparency](pdf/reference/Fpdf_SetAlpha_transparency.pdf) -[SetFontLoader](pdf/reference/Fpdf_SetFontLoader.pdf) -[SetKeywords](pdf/reference/Fpdf_SetKeywords.pdf) -[SetLeftMargin multicolumn](pdf/reference/Fpdf_SetLeftMargin_multicolumn.pdf) -[SetLineJoinStyle caps](pdf/reference/Fpdf_SetLineJoinStyle_caps.pdf) -[SetProtection](pdf/reference/Fpdf_SetProtection.pdf) -[Splitlines](pdf/reference/Fpdf_Splitlines.pdf) -[TransformBegin](pdf/reference/Fpdf_TransformBegin.pdf) -[WriteAligned](pdf/reference/Fpdf_WriteAligned.pdf) -[barcode Register](pdf/reference/contrib_barcode_Register.pdf) -[barcode RegisterCodabar](pdf/reference/contrib_barcode_RegisterCodabar.pdf) -[barcode RegisterCode128](pdf/reference/contrib_barcode_RegisterCode128.pdf) -[barcode RegisterCode39](pdf/reference/contrib_barcode_RegisterCode39.pdf) -[barcode RegisterDataMatrix](pdf/reference/contrib_barcode_RegisterDataMatrix.pdf) -[barcode RegisterEAN](pdf/reference/contrib_barcode_RegisterEAN.pdf) -[barcode RegisterQR](pdf/reference/contrib_barcode_RegisterQR.pdf) -[barcode RegisterTwoOfFive](pdf/reference/contrib_barcode_RegisterTwoOfFive.pdf) -[httpimg Register](pdf/reference/contrib_httpimg_Register.pdf) - ##Nonstandard Fonts diff --git a/doc.go b/doc.go index b05ed8e..15bf40e 100644 --- a/doc.go +++ b/doc.go @@ -118,7 +118,7 @@ complete. Please note that these examples run in the context of a test. In order run an example as a standalone application, you'll need to examine fpdf_test.go for -some helper routines, for example exampleFilename and summary. +some helper routines, for example exampleFilename() and summary(). Example PDFs can be compared with reference copies in order to verify that they have been generated as expected. This comparison will be performed if a PDF diff --git a/mkdoc b/mkdoc index 213becc..71294d7 100755 --- a/mkdoc +++ b/mkdoc @@ -18,10 +18,5 @@ cat README.md | tr '\n' '\v' | sed \ -e 's/test.coverage.(\(https:\/\/blog\.golang\.org\/cover\))/[test coverage](\1)/g' \ -e 's/Pull.requests.(\(https:\/\/help\.github\.com\/articles\/using\-pull\-requests\/\))/[Pull requests](\1)/g' \ -e 's/Your change should\v/Your change should\v\v/g' \ - -e 's/##Nonstandard Fonts/__PDFS__\v\v##Nonstandard Fonts/g' \ | tr '\v' '\n' > _0 -sed -e '/__PDFS__/,$d' _0 > _1 -go run list/list.go >> _1 -sed -e '1,/__PDFS__/d' _0 >> _1 -rm _0 -mv _1 README.md +mv _0 README.md -- cgit v1.2.1-24-ge1ad