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