From 0fb5126fefeb1a7be7ed1c4dac02539af931a237 Mon Sep 17 00:00:00 2001
From: Dave Barnes <phpdave11@gmail.com>
Date: Wed, 15 May 2019 10:45:22 -0500
Subject: Add support for imported objects and templates to version 1 of
 gofpdf.

---
 contrib/gofpdi/gofpdi.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 contrib/gofpdi/gofpdi.go

(limited to 'contrib')

diff --git a/contrib/gofpdi/gofpdi.go b/contrib/gofpdi/gofpdi.go
new file mode 100644
index 0000000..c1f3df8
--- /dev/null
+++ b/contrib/gofpdi/gofpdi.go
@@ -0,0 +1,62 @@
+package gofpdi
+
+import (
+	realgofpdi "github.com/phpdave11/gofpdi"
+)
+
+// Create new gofpdi instance
+var fpdi = realgofpdi.NewImporter()
+
+// gofpdiPdf is a partial interface that only implements the functions we need
+// from the PDF generator to put the imported PDF templates on the PDF.
+type gofpdiPdf interface {
+	ImportObjects(objs map[string][]byte)
+	ImportObjPos(objs map[string]map[int]string)
+	ImportTemplates(tpls map[string]string)
+	UseImportedTemplate(tplName string, x float64, y float64, w float64, h float64)
+	SetError(err error)
+}
+
+// Imports a page of a PDF file with the specified box (/MediaBox, /TrimBox, /ArtBox, /CropBox, or /BleedBox).
+// Returns a template id that can be used with UseImportedTemplate to draw the template onto the page.
+func ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
+	// Set source file for fpdi
+	fpdi.SetSourceFile(sourceFile)
+
+	// Import page
+	tpl := fpdi.ImportPage(pageno, box)
+
+	// Import objects into current pdf document
+	// Unordered means that the objects will be returned with a sha1 hash instead of an integer
+	// The objects themselves may have references to other hashes which will be replaced in ImportObjects()
+	tplObjIds := fpdi.PutFormXobjectsUnordered()
+
+	// Set template names and ids (hashes) in gofpdf
+	f.ImportTemplates(tplObjIds)
+
+	// Get a map[string]string of the imported objects.
+	// The map keys will be the ID of each object.
+	imported := fpdi.GetImportedObjectsUnordered()
+
+	// Import gofpdi objects into gofpdf
+	f.ImportObjects(imported)
+
+	// Get a map[string]map[int]string of the object hashes and their positions within each object, 
+	// to be replaced with object ids (integers).
+	importedObjPos := fpdi.GetImportedObjHashPos()
+
+	// Import gofpdi object hashes and their positions into gopdf
+	f.ImportObjPos(importedObjPos)
+
+	return tpl
+}
+
+// Draw the template onto the page at x,y
+// If w is 0, the template will be scaled to fit based on h
+// If h is 0, the template will be scaled to fit based on w
+func UseImportedTemplate(f gofpdiPdf, tplid int, x float64, y float64, w float64, h float64) {
+	// Get values from fpdi
+	tplName, scaleX, scaleY, tX, tY := fpdi.UseTemplate(tplid, x, y, w, h)
+
+	f.UseImportedTemplate(tplName, scaleX, scaleY, tX, tY)
+}
-- 
cgit v1.2.1-24-ge1ad


From ce8a12ff5655c57989b925abc0b8a3a1e6535d59 Mon Sep 17 00:00:00 2001
From: Dave Barnes <phpdave11@gmail.com>
Date: Wed, 15 May 2019 11:25:39 -0500
Subject: Clean up code based on jung-kurt's feedback.

---
 contrib/gofpdi/gofpdi.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'contrib')

diff --git a/contrib/gofpdi/gofpdi.go b/contrib/gofpdi/gofpdi.go
index c1f3df8..d1b98e9 100644
--- a/contrib/gofpdi/gofpdi.go
+++ b/contrib/gofpdi/gofpdi.go
@@ -29,10 +29,10 @@ func ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
 	// Import objects into current pdf document
 	// Unordered means that the objects will be returned with a sha1 hash instead of an integer
 	// The objects themselves may have references to other hashes which will be replaced in ImportObjects()
-	tplObjIds := fpdi.PutFormXobjectsUnordered()
+	tplObjIDs := fpdi.PutFormXobjectsUnordered()
 
 	// Set template names and ids (hashes) in gofpdf
-	f.ImportTemplates(tplObjIds)
+	f.ImportTemplates(tplObjIDs)
 
 	// Get a map[string]string of the imported objects.
 	// The map keys will be the ID of each object.
@@ -41,7 +41,7 @@ func ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
 	// Import gofpdi objects into gofpdf
 	f.ImportObjects(imported)
 
-	// Get a map[string]map[int]string of the object hashes and their positions within each object, 
+	// Get a map[string]map[int]string of the object hashes and their positions within each object,
 	// to be replaced with object ids (integers).
 	importedObjPos := fpdi.GetImportedObjHashPos()
 
-- 
cgit v1.2.1-24-ge1ad


From 5f4e2f65402b9aa611f93b2fa14ea69bf7b26d2d Mon Sep 17 00:00:00 2001
From: Kurt <kurt.w.jung@gmail.com>
Date: Sat, 18 May 2019 08:08:21 -0400
Subject: Generalize awk script that produces doc.go

---
 contrib/gofpdi/gofpdi.go | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

(limited to 'contrib')

diff --git a/contrib/gofpdi/gofpdi.go b/contrib/gofpdi/gofpdi.go
index d1b98e9..b951ea3 100644
--- a/contrib/gofpdi/gofpdi.go
+++ b/contrib/gofpdi/gofpdi.go
@@ -17,8 +17,9 @@ type gofpdiPdf interface {
 	SetError(err error)
 }
 
-// Imports a page of a PDF file with the specified box (/MediaBox, /TrimBox, /ArtBox, /CropBox, or /BleedBox).
-// Returns a template id that can be used with UseImportedTemplate to draw the template onto the page.
+// ImportPage imports a page of a PDF file with the specified box (/MediaBox,
+// /TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id that can
+// be used with UseImportedTemplate to draw the template onto the page.
 func ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
 	// Set source file for fpdi
 	fpdi.SetSourceFile(sourceFile)
@@ -51,9 +52,9 @@ func ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
 	return tpl
 }
 
-// Draw the template onto the page at x,y
-// If w is 0, the template will be scaled to fit based on h
-// If h is 0, the template will be scaled to fit based on w
+// UseImportedTemplate draws the template onto the page at x,y. If w is 0, the
+// template will be scaled to fit based on h. If h is 0, the template will be
+// scaled to fit based on w.
 func UseImportedTemplate(f gofpdiPdf, tplid int, x float64, y float64, w float64, h float64) {
 	// Get values from fpdi
 	tplName, scaleX, scaleY, tX, tY := fpdi.UseTemplate(tplid, x, y, w, h)
-- 
cgit v1.2.1-24-ge1ad


From 290b8c334e0f9ce3f5fc95bb70002b13d3300bb5 Mon Sep 17 00:00:00 2001
From: Justin Schlechte <justin.schlechte@monsanto.com>
Date: Wed, 22 May 2019 11:24:02 -0500
Subject: maintain precision of desired w & h of barcodes

This fixes an issue with barcode scaling that limited
barcode sizes to integer multiples of the pdf's unit.
---
 contrib/barcode/barcode.go      | 10 +++++++---
 contrib/barcode/barcode_test.go | 21 +++++++++++++++++++++
 2 files changed, 28 insertions(+), 3 deletions(-)

(limited to 'contrib')

diff --git a/contrib/barcode/barcode.go b/contrib/barcode/barcode.go
index ad84fe5..7e0ac0d 100644
--- a/contrib/barcode/barcode.go
+++ b/contrib/barcode/barcode.go
@@ -93,13 +93,17 @@ func printBarcode(pdf barcodePdf, code string, x, y float64, w, h *float64, flow
 		}
 	}
 
+	scaleToWidthF := float64(scaleToWidth)
+	scaleToHeightF := float64(scaleToHeight)
+
 	if w != nil {
-		scaleToWidth = int(*w)
+		scaleToWidthF = *w
 	}
 	if h != nil {
-		scaleToHeight = int(*h)
+		scaleToHeightF = *h
 	}
-	pdf.Image(bname, x, y, float64(scaleToWidth), float64(scaleToHeight), flow, "jpg", 0, "")
+
+	pdf.Image(bname, x, y, scaleToWidthF, scaleToHeightF, flow, "jpg", 0, "")
 
 }
 
diff --git a/contrib/barcode/barcode_test.go b/contrib/barcode/barcode_test.go
index 2b402a3..066ac41 100644
--- a/contrib/barcode/barcode_test.go
+++ b/contrib/barcode/barcode_test.go
@@ -199,3 +199,24 @@ func TestGetUnscaledBarcodeDimensions(t *testing.T) {
 	// Output:
 	// Successfully generated ../../pdf/contrib_barcode_GetBarcodeDimensions.pdf
 }
+
+// TestBarcodeNonIntegerScalingFactors shows that the barcode may be scaled to non-integer sizes
+func TestBarcodeNonIntegerScalingFactors(t *testing.T) {
+	pdf := gofpdf.New("L", "in", "A4", "")
+	pdf.SetFont("Helvetica", "", 12)
+	pdf.SetFillColor(200, 200, 220)
+	pdf.AddPage()
+
+	key := barcode.RegisterQR(pdf, "qrcode", qr.H, qr.Unicode)
+	var scale float64 = 1.5
+	barcode.BarcodeUnscalable(pdf, key, 0.5, 0.5, &scale, &scale, false)
+
+	pdf.SetDrawColor(255, 0, 0)
+	pdf.Line(0.5, 0.5, 0.5+scale, 0.5+scale)
+
+	fileStr := example.Filename("contrib_barcode_BarcodeScaling")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_BarcodeScaling.pdf
+}
-- 
cgit v1.2.1-24-ge1ad


From f3ee9b63d7affa5386053fe7c2b44c06ae4159d4 Mon Sep 17 00:00:00 2001
From: matthias <matthias@steuerbot.com>
Date: Fri, 9 Aug 2019 14:31:01 +0200
Subject: update contrib/gofpdi from v1.0.3 to v1.0.7 and expose new
 functionality

* imports pdf documents from any io.ReadSeeker
* exposes page sizes of imported pdf documents
---
 contrib/gofpdi/gofpdi.go | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

(limited to 'contrib')

diff --git a/contrib/gofpdi/gofpdi.go b/contrib/gofpdi/gofpdi.go
index b951ea3..58f8fae 100644
--- a/contrib/gofpdi/gofpdi.go
+++ b/contrib/gofpdi/gofpdi.go
@@ -2,6 +2,7 @@ package gofpdi
 
 import (
 	realgofpdi "github.com/phpdave11/gofpdi"
+	"io"
 )
 
 // Create new gofpdi instance
@@ -23,7 +24,21 @@ type gofpdiPdf interface {
 func ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
 	// Set source file for fpdi
 	fpdi.SetSourceFile(sourceFile)
+	// return template id
+	return getTemplateID(f, pageno, box)
+}
 
+// ImportPage imports a page of a PDF with the specified box (/MediaBox,
+// /TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id that can
+// be used with UseImportedTemplate to draw the template onto the page.
+func ImportPageFromStream(f gofpdiPdf, rs *io.ReadSeeker, pageno int, box string) int {
+	// Set source stream for fpdi
+	fpdi.SetSourceStream(rs)
+	// return template id
+	return getTemplateID(f, pageno, box)
+}
+
+func getTemplateID(f gofpdiPdf, pageno int, box string) int {
 	// Import page
 	tpl := fpdi.ImportPage(pageno, box)
 
@@ -61,3 +76,12 @@ func UseImportedTemplate(f gofpdiPdf, tplid int, x float64, y float64, w float64
 
 	f.UseImportedTemplate(tplName, scaleX, scaleY, tX, tY)
 }
+
+// GetPageSizes returns page dimensions for all pages of the imported pdf.
+// Result consists of map[<page number>]map[<box>]map[<dimension>]<value>.
+// <page number>: page number, note that page numbers start at 1
+// <box>: box identifier, e.g. "/MediaBox"
+// <dimension>: dimension string, either "w" or "h"
+func GetPageSizes() map[int]map[string]map[string]float64 {
+	return fpdi.GetPageSizes()
+}
-- 
cgit v1.2.1-24-ge1ad


From fdac35522f22a910970fc07bd6922f4f53ba6642 Mon Sep 17 00:00:00 2001
From: Kurt <kurt.w.jung@gmail.com>
Date: Mon, 12 Aug 2019 10:52:03 -0400
Subject: Corrected comment to match function name

---
 contrib/gofpdi/gofpdi.go | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

(limited to 'contrib')

diff --git a/contrib/gofpdi/gofpdi.go b/contrib/gofpdi/gofpdi.go
index 58f8fae..e600fb1 100644
--- a/contrib/gofpdi/gofpdi.go
+++ b/contrib/gofpdi/gofpdi.go
@@ -28,9 +28,10 @@ func ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
 	return getTemplateID(f, pageno, box)
 }
 
-// ImportPage imports a page of a PDF with the specified box (/MediaBox,
-// /TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id that can
-// be used with UseImportedTemplate to draw the template onto the page.
+// ImportPageFromStream imports a page of a PDF with the specified box
+// (/MediaBox, TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id
+// that can be used with UseImportedTemplate to draw the template onto the
+// page.
 func ImportPageFromStream(f gofpdiPdf, rs *io.ReadSeeker, pageno int, box string) int {
 	// Set source stream for fpdi
 	fpdi.SetSourceStream(rs)
-- 
cgit v1.2.1-24-ge1ad


From e697c5fb90d8afbc84be98bfec2154653e03382b Mon Sep 17 00:00:00 2001
From: matthias <matthias@steuerbot.com>
Date: Tue, 13 Aug 2019 14:03:28 +0200
Subject: wrap contrib/gofpdi:realgofpdi.Importer

* allow for multiple independent Importer instances
* keep a default Importer for backwards compatibility
* add package level comment
---
 contrib/gofpdi/gofpdi.go | 87 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 71 insertions(+), 16 deletions(-)

(limited to 'contrib')

diff --git a/contrib/gofpdi/gofpdi.go b/contrib/gofpdi/gofpdi.go
index e600fb1..7b9c822 100644
--- a/contrib/gofpdi/gofpdi.go
+++ b/contrib/gofpdi/gofpdi.go
@@ -1,3 +1,11 @@
+/*
+Package gofpdi wraps the gofpdi PDF library to import existing PDFs as templates. See github.com/phpdave11/gofpdi
+for further information and examples.
+
+Users should call NewImporter() to obtain their own Importer instance to work with.
+To retain backwards compatibility, the package offers a default Importer that may be used via global functions. Note
+however that use of the default Importer is not thread safe.
+*/
 package gofpdi
 
 import (
@@ -5,9 +13,6 @@ import (
 	"io"
 )
 
-// Create new gofpdi instance
-var fpdi = realgofpdi.NewImporter()
-
 // gofpdiPdf is a partial interface that only implements the functions we need
 // from the PDF generator to put the imported PDF templates on the PDF.
 type gofpdiPdf interface {
@@ -18,49 +23,61 @@ type gofpdiPdf interface {
 	SetError(err error)
 }
 
+// Importer wraps an Importer from the gofpdi library.
+type Importer struct {
+	fpdi *realgofpdi.Importer
+}
+
+// NewImporter creates a new Importer wrapping functionality from the gofpdi library.
+func NewImporter() *Importer {
+	return &Importer{
+		fpdi: realgofpdi.NewImporter(),
+	}
+}
+
 // ImportPage imports a page of a PDF file with the specified box (/MediaBox,
 // /TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id that can
 // be used with UseImportedTemplate to draw the template onto the page.
-func ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
+func (i *Importer) ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
 	// Set source file for fpdi
-	fpdi.SetSourceFile(sourceFile)
+	i.fpdi.SetSourceFile(sourceFile)
 	// return template id
-	return getTemplateID(f, pageno, box)
+	return i.getTemplateID(f, pageno, box)
 }
 
 // ImportPageFromStream imports a page of a PDF with the specified box
 // (/MediaBox, TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id
 // that can be used with UseImportedTemplate to draw the template onto the
 // page.
-func ImportPageFromStream(f gofpdiPdf, rs *io.ReadSeeker, pageno int, box string) int {
+func (i *Importer) ImportPageFromStream(f gofpdiPdf, rs *io.ReadSeeker, pageno int, box string) int {
 	// Set source stream for fpdi
-	fpdi.SetSourceStream(rs)
+	i.fpdi.SetSourceStream(rs)
 	// return template id
-	return getTemplateID(f, pageno, box)
+	return i.getTemplateID(f, pageno, box)
 }
 
-func getTemplateID(f gofpdiPdf, pageno int, box string) int {
+func (i *Importer) getTemplateID(f gofpdiPdf, pageno int, box string) int {
 	// Import page
-	tpl := fpdi.ImportPage(pageno, box)
+	tpl := i.fpdi.ImportPage(pageno, box)
 
 	// Import objects into current pdf document
 	// Unordered means that the objects will be returned with a sha1 hash instead of an integer
 	// The objects themselves may have references to other hashes which will be replaced in ImportObjects()
-	tplObjIDs := fpdi.PutFormXobjectsUnordered()
+	tplObjIDs := i.fpdi.PutFormXobjectsUnordered()
 
 	// Set template names and ids (hashes) in gofpdf
 	f.ImportTemplates(tplObjIDs)
 
 	// Get a map[string]string of the imported objects.
 	// The map keys will be the ID of each object.
-	imported := fpdi.GetImportedObjectsUnordered()
+	imported := i.fpdi.GetImportedObjectsUnordered()
 
 	// Import gofpdi objects into gofpdf
 	f.ImportObjects(imported)
 
 	// Get a map[string]map[int]string of the object hashes and their positions within each object,
 	// to be replaced with object ids (integers).
-	importedObjPos := fpdi.GetImportedObjHashPos()
+	importedObjPos := i.fpdi.GetImportedObjHashPos()
 
 	// Import gofpdi object hashes and their positions into gopdf
 	f.ImportObjPos(importedObjPos)
@@ -71,9 +88,9 @@ func getTemplateID(f gofpdiPdf, pageno int, box string) int {
 // UseImportedTemplate draws the template onto the page at x,y. If w is 0, the
 // template will be scaled to fit based on h. If h is 0, the template will be
 // scaled to fit based on w.
-func UseImportedTemplate(f gofpdiPdf, tplid int, x float64, y float64, w float64, h float64) {
+func (i *Importer) UseImportedTemplate(f gofpdiPdf, tplid int, x float64, y float64, w float64, h float64) {
 	// Get values from fpdi
-	tplName, scaleX, scaleY, tX, tY := fpdi.UseTemplate(tplid, x, y, w, h)
+	tplName, scaleX, scaleY, tX, tY := i.fpdi.UseTemplate(tplid, x, y, w, h)
 
 	f.UseImportedTemplate(tplName, scaleX, scaleY, tX, tY)
 }
@@ -83,6 +100,44 @@ func UseImportedTemplate(f gofpdiPdf, tplid int, x float64, y float64, w float64
 // <page number>: page number, note that page numbers start at 1
 // <box>: box identifier, e.g. "/MediaBox"
 // <dimension>: dimension string, either "w" or "h"
+func (i *Importer) GetPageSizes() map[int]map[string]map[string]float64 {
+	return i.fpdi.GetPageSizes()
+}
+
+// Default Importer used by global functions
+var fpdi = NewImporter()
+
+// ImportPage imports a page of a PDF file with the specified box (/MediaBox,
+// /TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id that can
+// be used with UseImportedTemplate to draw the template onto the page.
+// Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
+func ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
+	return fpdi.ImportPage(f, sourceFile, pageno, box)
+}
+
+// ImportPageFromStream imports a page of a PDF with the specified box
+// (/MediaBox, TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id
+// that can be used with UseImportedTemplate to draw the template onto the
+// page.
+// Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
+func ImportPageFromStream(f gofpdiPdf, rs *io.ReadSeeker, pageno int, box string) int {
+	return fpdi.ImportPageFromStream(f, rs, pageno, box)
+}
+
+// UseImportedTemplate draws the template onto the page at x,y. If w is 0, the
+// template will be scaled to fit based on h. If h is 0, the template will be
+// scaled to fit based on w.
+// Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
+func UseImportedTemplate(f gofpdiPdf, tplid int, x float64, y float64, w float64, h float64) {
+	fpdi.UseImportedTemplate(f, tplid, x, y, w, h)
+}
+
+// GetPageSizes returns page dimensions for all pages of the imported pdf.
+// Result consists of map[<page number>]map[<box>]map[<dimension>]<value>.
+// <page number>: page number, note that page numbers start at 1
+// <box>: box identifier, e.g. "/MediaBox"
+// <dimension>: dimension string, either "w" or "h"
+// Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
 func GetPageSizes() map[int]map[string]map[string]float64 {
 	return fpdi.GetPageSizes()
 }
-- 
cgit v1.2.1-24-ge1ad


From 03b1cc4baaf3f7c9ae441b711e18fdd5671a5dd4 Mon Sep 17 00:00:00 2001
From: matthias <matthias@steuerbot.com>
Date: Thu, 15 Aug 2019 17:27:56 +0200
Subject: add simple example

---
 contrib/gofpdi/gofpdi_test.go | 52 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 contrib/gofpdi/gofpdi_test.go

(limited to 'contrib')

diff --git a/contrib/gofpdi/gofpdi_test.go b/contrib/gofpdi/gofpdi_test.go
new file mode 100644
index 0000000..1ecc5ca
--- /dev/null
+++ b/contrib/gofpdi/gofpdi_test.go
@@ -0,0 +1,52 @@
+package gofpdi
+
+import (
+	"bytes"
+	"github.com/jung-kurt/gofpdf"
+	"github.com/jung-kurt/gofpdf/internal/example"
+	"io"
+)
+
+func ExampleGofpdiImporter() {
+	// create new pdf
+	pdf := gofpdf.New("P", "pt", "A4", "")
+
+	// for testing purposes, get an arbitrary template pdf as stream
+	rs, _ := getTemplatePdf()
+
+	// create a new Importer instance
+	imp := NewImporter()
+
+	// import first page and determine page sizes
+	tpl := imp.ImportPageFromStream(pdf, &rs, 1, "/MediaBox")
+	pageSizes := imp.GetPageSizes()
+	nrPages := len(imp.GetPageSizes())
+
+	// add all pages from template pdf
+	for i := 1; i <= nrPages; i++ {
+		pdf.AddPage()
+		if i > 1 {
+			tpl = imp.ImportPageFromStream(pdf, &rs, i, "/MediaBox")
+		}
+		imp.UseImportedTemplate(pdf, tpl, 0, 0, pageSizes[i]["/MediaBox"]["w"], pageSizes[i]["/MediaBox"]["h"])
+	}
+
+	// output
+	fileStr := example.Filename("contrib_gofpdi_Importer")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_gofpdi_Importer.pdf
+}
+
+func getTemplatePdf() (io.ReadSeeker, error) {
+	tpdf := gofpdf.New("P", "pt", "A4", "")
+	tpdf.AddPage()
+	tpdf.SetFont("Arial", "", 12)
+	tpdf.Text(20, 20, "Example Page 1")
+	tpdf.AddPage()
+	tpdf.Text(20, 20, "Example Page 2")
+	tbuf := bytes.Buffer{}
+	err := tpdf.Output(&tbuf)
+	return bytes.NewReader(tbuf.Bytes()), err
+}
-- 
cgit v1.2.1-24-ge1ad


From afaa377e877515c31a941b4c88953e20ead17255 Mon Sep 17 00:00:00 2001
From: matthias <matthias@steuerbot.com>
Date: Thu, 15 Aug 2019 17:33:26 +0200
Subject: add simple test for data race detection

---
 contrib/gofpdi/gofpdi_test.go | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

(limited to 'contrib')

diff --git a/contrib/gofpdi/gofpdi_test.go b/contrib/gofpdi/gofpdi_test.go
index 1ecc5ca..77db338 100644
--- a/contrib/gofpdi/gofpdi_test.go
+++ b/contrib/gofpdi/gofpdi_test.go
@@ -5,6 +5,8 @@ import (
 	"github.com/jung-kurt/gofpdf"
 	"github.com/jung-kurt/gofpdf/internal/example"
 	"io"
+	"sync"
+	"testing"
 )
 
 func ExampleGofpdiImporter() {
@@ -39,6 +41,29 @@ func ExampleGofpdiImporter() {
 	// Successfully generated ../../pdf/contrib_gofpdi_Importer.pdf
 }
 
+func TestGofpdiConcurrent(t *testing.T) {
+	wg := sync.WaitGroup{}
+	for i := 0; i < 100; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			pdf := gofpdf.New("P", "mm", "A4", "")
+			rs, _ := getTemplatePdf()
+			imp := NewImporter()
+			tpl := imp.ImportPageFromStream(pdf, &rs, 1, "/MediaBox")
+			pdf.AddPage()
+			tpl = imp.ImportPageFromStream(pdf, &rs, 1, "/MediaBox")
+			imp.UseImportedTemplate(pdf, tpl, 0, 0, 210.0, 297.0)
+			// write to bytes buffer
+			buf := bytes.Buffer{}
+			if err := pdf.Output(&buf); err != nil {
+				t.Fail()
+			}
+		}()
+	}
+	wg.Wait()
+}
+
 func getTemplatePdf() (io.ReadSeeker, error) {
 	tpdf := gofpdf.New("P", "pt", "A4", "")
 	tpdf.AddPage()
-- 
cgit v1.2.1-24-ge1ad


From dab6c0551d4d91973e1bb91341619885e48797a9 Mon Sep 17 00:00:00 2001
From: matthias <matthias@steuerbot.com>
Date: Thu, 15 Aug 2019 17:55:42 +0200
Subject: fix checks

---
 contrib/gofpdi/gofpdi_test.go | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

(limited to 'contrib')

diff --git a/contrib/gofpdi/gofpdi_test.go b/contrib/gofpdi/gofpdi_test.go
index 77db338..70ef6cc 100644
--- a/contrib/gofpdi/gofpdi_test.go
+++ b/contrib/gofpdi/gofpdi_test.go
@@ -9,7 +9,7 @@ import (
 	"testing"
 )
 
-func ExampleGofpdiImporter() {
+func ExampleNewImporter() {
 	// create new pdf
 	pdf := gofpdf.New("P", "pt", "A4", "")
 
@@ -48,11 +48,10 @@ func TestGofpdiConcurrent(t *testing.T) {
 		go func() {
 			defer wg.Done()
 			pdf := gofpdf.New("P", "mm", "A4", "")
+			pdf.AddPage()
 			rs, _ := getTemplatePdf()
 			imp := NewImporter()
 			tpl := imp.ImportPageFromStream(pdf, &rs, 1, "/MediaBox")
-			pdf.AddPage()
-			tpl = imp.ImportPageFromStream(pdf, &rs, 1, "/MediaBox")
 			imp.UseImportedTemplate(pdf, tpl, 0, 0, 210.0, 297.0)
 			// write to bytes buffer
 			buf := bytes.Buffer{}
-- 
cgit v1.2.1-24-ge1ad