From fdeef9c676bdb5f738d02c770b6312c0e2e12775 Mon Sep 17 00:00:00 2001 From: Aloidev Date: Wed, 19 Jul 2017 11:00:59 +0700 Subject: Issue #121 Add Last Page information FooterFnc --- def.go | 1 + fpdf.go | 27 +++++++++++++++++++++++--- fpdf_test.go | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/def.go b/def.go index c80eb37..ecc700b 100644 --- a/def.go +++ b/def.go @@ -221,6 +221,7 @@ type Fpdf struct { headerFnc func() // function provided by app and called to write header inFooter bool // flag set when processing footer footerFnc func() // function provided by app and called to write footer + footerFncLpi func(bool) // this same with footerFnc with additioanl info to indicates last page zoomMode string // zoom display mode layoutMode string // layout display mode title string // title diff --git a/fpdf.go b/fpdf.go index 9587e55..2c7e993 100644 --- a/fpdf.go +++ b/fpdf.go @@ -366,10 +366,17 @@ func (f *Fpdf) SetHeaderFunc(fnc func()) { // access to the Fpdf instance and other document generation variables. // // This method is demonstrated in the example for AddPage(). +// Deprecated: Use SetFooterFuncLpi instead. func (f *Fpdf) SetFooterFunc(fnc func()) { f.footerFnc = fnc } +// SetFooterFuncLpi work like SetFooterFnc it's just add Last Page information, +// true mean this is the last page. +func (f *Fpdf) SetFooterFuncLpi(fnc func(bool)) { + f.footerFncLpi = fnc +} + // SetTopMargin defines the top margin. The method can be called before // creating the first page. func (f *Fpdf) SetTopMargin(margin float64) { @@ -538,11 +545,19 @@ func (f *Fpdf) Close() { } } // Page footer - if f.footerFnc != nil { + if f.footerFnc != nil && f.footerFncLpi == nil { f.inFooter = true f.footerFnc() f.inFooter = false } + + // Page footer + if f.footerFncLpi != nil { + f.inFooter = true + f.footerFncLpi(true) // Last Page. + f.inFooter = false + } + // Close page f.endpage() // Close document @@ -592,11 +607,17 @@ func (f *Fpdf) AddPageFormat(orientationStr string, size SizeType) { tc := f.color.text cf := f.colorFlag if f.page > 0 { - // Page footer - if f.footerFnc != nil { + // Page footer avoid double call on footer. + if f.footerFnc != nil && f.footerFncLpi == nil { f.inFooter = true f.footerFnc() f.inFooter = false + + } + if f.footerFncLpi != nil { + f.inFooter = true + f.footerFncLpi(false) //not last page. + f.inFooter = false } // Close page f.endpage() diff --git a/fpdf_test.go b/fpdf_test.go index 7da45aa..f25866e 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -75,7 +75,70 @@ func TestIssue0116(t *testing.T) { if pdf.Error() == nil { t.Fatalf("expecting error when rendering text without having set font") } +} + +// Test to make sure the footer is not call twice and SetFooterFuncLpi can work +// without SetFooterFunc. +func TestFooterFuncLpi(t *testing.T) { + pdf := gofpdf.New("P", "mm", "A4", "") + var ( + oldFooterFnc = "oldFooterFnc" + bothPages = "bothPages" + firstPageOnly = "firstPageOnly" + lastPageOnly = "lastPageOnly" + ) + // This set just for testing, only set SetFooterFuncLpi. + pdf.SetFooterFunc(func() { + pdf.SetY(-15) + pdf.SetFont("Arial", "I", 8) + pdf.CellFormat(0, 10, oldFooterFnc, + "", 0, "C", false, 0, "") + }) + pdf.SetFooterFuncLpi(func(lastPage bool) { + pdf.SetY(-15) + pdf.SetFont("Arial", "I", 8) + pdf.CellFormat(0, 10, bothPages, "", 0, "L", false, 0, "") + if !lastPage { + pdf.CellFormat(0, 10, firstPageOnly, "", 0, "C", false, 0, "") + } else { + pdf.CellFormat(0, 10, lastPageOnly, "", 0, "C", false, 0, "") + } + }) + pdf.AddPage() + pdf.SetFont("Arial", "B", 16) + for j := 1; j <= 40; j++ { + pdf.CellFormat(0, 10, fmt.Sprintf("Printing line number %d", j), + "", 1, "", false, 0, "") + } + if pdf.Error() != nil { + t.Fatalf("not expecting error when rendering text") + } + w := &bytes.Buffer{} + if err := pdf.Output(w); err != nil { + t.Errorf("got err:%v want nil") + } + b := w.Bytes() + if bytes.Contains(b, []byte(oldFooterFnc)) { + t.Errorf("Not expecting %s render on pdf when FooterFncLpi is set", oldFooterFnc) + } + got := bytes.Count(b, []byte("bothPages")) + if got != 2 { + t.Errorf("footer %s should render on two page got:%d", bothPages, got) + } + got = bytes.Count(b, []byte(firstPageOnly)) + if got != 1 { + t.Errorf("footer %s should render only on first page got:%d", firstPageOnly, got) + } + got = bytes.Count(b, []byte(lastPageOnly)) + if got != 1 { + t.Errorf("footer %s should render only on first page got:%d", lastPageOnly, got) + } + f := bytes.Index(b, []byte(firstPageOnly)) + l := bytes.Index(b, []byte(lastPageOnly)) + if f > l { + t.Errorf("index %s : %d should less than indec of %s : %d", f, l) + } } type fontResourceType struct { -- cgit v1.2.1-24-ge1ad From 784ad190acab08c54aa4847f15207d5fa9c25ef0 Mon Sep 17 00:00:00 2001 From: Kurt Date: Wed, 19 Jul 2017 08:57:33 -0400 Subject: Tweak some last page expressions and comments --- def.go | 2 +- fpdf.go | 47 ++++++++++++++++++++++++----------------------- fpdf_test.go | 10 +++++----- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/def.go b/def.go index ecc700b..552415f 100644 --- a/def.go +++ b/def.go @@ -221,7 +221,7 @@ type Fpdf struct { headerFnc func() // function provided by app and called to write header inFooter bool // flag set when processing footer footerFnc func() // function provided by app and called to write footer - footerFncLpi func(bool) // this same with footerFnc with additioanl info to indicates last page + footerFncLpi func(bool) // function provided by app and called to write footer with last page flag zoomMode string // zoom display mode layoutMode string // layout display mode title string // title diff --git a/fpdf.go b/fpdf.go index 2c7e993..a8656dd 100644 --- a/fpdf.go +++ b/fpdf.go @@ -363,18 +363,27 @@ func (f *Fpdf) SetHeaderFunc(fnc func()) { // Close() and should not be called directly by the application. The // implementation in Fpdf is empty, so you have to provide an appropriate // function if you want page footers. fnc will typically be a closure that has -// access to the Fpdf instance and other document generation variables. +// access to the Fpdf instance and other document generation variables. See +// SetFooterFuncLpi for a similar function that passes a last page indicator. // // This method is demonstrated in the example for AddPage(). -// Deprecated: Use SetFooterFuncLpi instead. func (f *Fpdf) SetFooterFunc(fnc func()) { f.footerFnc = fnc + f.footerFncLpi = nil } -// SetFooterFuncLpi work like SetFooterFnc it's just add Last Page information, -// true mean this is the last page. -func (f *Fpdf) SetFooterFuncLpi(fnc func(bool)) { +// SetFooterFuncLpi sets the function that lets the application render the page +// footer. The specified function is automatically called by AddPage() and +// Close() and should not be called directly by the application. It is passed a +// boolean that is true if the last page of the document is being rendered. The +// implementation in Fpdf is empty, so you have to provide an appropriate +// function if you want page footers. fnc will typically be a closure that has +// access to the Fpdf instance and other document generation variables. +// +// This method is demonstrated in the example for AddPage(). +func (f *Fpdf) SetFooterFuncLpi(fnc func(lastPage bool)) { f.footerFncLpi = fnc + f.footerFnc = nil } // SetTopMargin defines the top margin. The method can be called before @@ -545,18 +554,13 @@ func (f *Fpdf) Close() { } } // Page footer - if f.footerFnc != nil && f.footerFncLpi == nil { - f.inFooter = true + f.inFooter = true + if f.footerFnc != nil { f.footerFnc() - f.inFooter = false - } - - // Page footer - if f.footerFncLpi != nil { - f.inFooter = true - f.footerFncLpi(true) // Last Page. - f.inFooter = false + } else if f.footerFncLpi != nil { + f.footerFncLpi(true) } + f.inFooter = false // Close page f.endpage() @@ -607,18 +611,15 @@ func (f *Fpdf) AddPageFormat(orientationStr string, size SizeType) { tc := f.color.text cf := f.colorFlag if f.page > 0 { + f.inFooter = true // Page footer avoid double call on footer. - if f.footerFnc != nil && f.footerFncLpi == nil { - f.inFooter = true + if f.footerFnc != nil { f.footerFnc() - f.inFooter = false + } else if f.footerFncLpi != nil { + f.footerFncLpi(false) // not last page. } - if f.footerFncLpi != nil { - f.inFooter = true - f.footerFncLpi(false) //not last page. - f.inFooter = false - } + f.inFooter = false // Close page f.endpage() } diff --git a/fpdf_test.go b/fpdf_test.go index f25866e..9b45486 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -116,11 +116,11 @@ func TestFooterFuncLpi(t *testing.T) { } w := &bytes.Buffer{} if err := pdf.Output(w); err != nil { - t.Errorf("got err:%v want nil") + t.Errorf("unexpected err: %s", err) } b := w.Bytes() if bytes.Contains(b, []byte(oldFooterFnc)) { - t.Errorf("Not expecting %s render on pdf when FooterFncLpi is set", oldFooterFnc) + t.Errorf("not expecting %s render on pdf when FooterFncLpi is set", oldFooterFnc) } got := bytes.Count(b, []byte("bothPages")) if got != 2 { @@ -128,16 +128,16 @@ func TestFooterFuncLpi(t *testing.T) { } got = bytes.Count(b, []byte(firstPageOnly)) if got != 1 { - t.Errorf("footer %s should render only on first page got:%d", firstPageOnly, got) + t.Errorf("footer %s should render only on first page got: %d", firstPageOnly, got) } got = bytes.Count(b, []byte(lastPageOnly)) if got != 1 { - t.Errorf("footer %s should render only on first page got:%d", lastPageOnly, got) + t.Errorf("footer %s should render only on first page got: %d", lastPageOnly, got) } f := bytes.Index(b, []byte(firstPageOnly)) l := bytes.Index(b, []byte(lastPageOnly)) if f > l { - t.Errorf("index %s : %d should less than indec of %s : %d", f, l) + t.Errorf("index %d (%s) should less than index %d (%s)", f, firstPageOnly, l, lastPageOnly) } } -- cgit v1.2.1-24-ge1ad