codeberg.org/go-pdf/fpdf@v0.11.1/contrib/gofpdi/gofpdi.go (about)

     1  /*
     2  Package gofpdi wraps the gofpdi PDF library to import existing PDFs as templates. See github.com/phpdave11/gofpdi
     3  for further information and examples.
     4  
     5  Users should call NewImporter() to obtain their own Importer instance to work with.
     6  To retain backwards compatibility, the package offers a default Importer that may be used via global functions. Note
     7  however that use of the default Importer is not thread safe.
     8  */
     9  package gofpdi
    10  
    11  import (
    12  	"io"
    13  
    14  	realgofpdi "github.com/phpdave11/gofpdi"
    15  )
    16  
    17  // gofpdiPdf is a partial interface that only implements the functions we need
    18  // from the PDF generator to put the imported PDF templates on the PDF.
    19  type gofpdiPdf interface {
    20  	ImportObjects(objs map[string][]byte)
    21  	ImportObjPos(objs map[string]map[int]string)
    22  	ImportTemplates(tpls map[string]string)
    23  	UseImportedTemplate(tplName string, x float64, y float64, w float64, h float64)
    24  	SetError(err error)
    25  }
    26  
    27  // Importer wraps an Importer from the gofpdi library.
    28  type Importer struct {
    29  	fpdi *realgofpdi.Importer
    30  }
    31  
    32  // NewImporter creates a new Importer wrapping functionality from the gofpdi library.
    33  func NewImporter() *Importer {
    34  	return &Importer{
    35  		fpdi: realgofpdi.NewImporter(),
    36  	}
    37  }
    38  
    39  // ImportPage imports a page of a PDF file with the specified box (/MediaBox,
    40  // /TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id that can
    41  // be used with UseImportedTemplate to draw the template onto the page.
    42  func (i *Importer) ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
    43  	// Set source file for fpdi
    44  	i.fpdi.SetSourceFile(sourceFile)
    45  	// return template id
    46  	return i.getTemplateID(f, pageno, box)
    47  }
    48  
    49  // ImportPageFromStream imports a page of a PDF with the specified box
    50  // (/MediaBox, TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id
    51  // that can be used with UseImportedTemplate to draw the template onto the
    52  // page.
    53  func (i *Importer) ImportPageFromStream(f gofpdiPdf, rs *io.ReadSeeker, pageno int, box string) int {
    54  	// Set source stream for fpdi
    55  	i.fpdi.SetSourceStream(rs)
    56  	// return template id
    57  	return i.getTemplateID(f, pageno, box)
    58  }
    59  
    60  func (i *Importer) getTemplateID(f gofpdiPdf, pageno int, box string) int {
    61  	// Import page
    62  	tpl := i.fpdi.ImportPage(pageno, box)
    63  
    64  	// Import objects into current pdf document
    65  	// Unordered means that the objects will be returned with a sha1 hash instead of an integer
    66  	// The objects themselves may have references to other hashes which will be replaced in ImportObjects()
    67  	tplObjIDs := i.fpdi.PutFormXobjectsUnordered()
    68  
    69  	// Set template names and ids (hashes) in gofpdf
    70  	f.ImportTemplates(tplObjIDs)
    71  
    72  	// Get a map[string]string of the imported objects.
    73  	// The map keys will be the ID of each object.
    74  	imported := i.fpdi.GetImportedObjectsUnordered()
    75  
    76  	// Import gofpdi objects into gofpdf
    77  	f.ImportObjects(imported)
    78  
    79  	// Get a map[string]map[int]string of the object hashes and their positions within each object,
    80  	// to be replaced with object ids (integers).
    81  	importedObjPos := i.fpdi.GetImportedObjHashPos()
    82  
    83  	// Import gofpdi object hashes and their positions into gopdf
    84  	f.ImportObjPos(importedObjPos)
    85  
    86  	return tpl
    87  }
    88  
    89  // UseImportedTemplate draws the template onto the page at x,y. If w is 0, the
    90  // template will be scaled to fit based on h. If h is 0, the template will be
    91  // scaled to fit based on w.
    92  func (i *Importer) UseImportedTemplate(f gofpdiPdf, tplid int, x float64, y float64, w float64, h float64) {
    93  	// Get values from fpdi
    94  	tplName, scaleX, scaleY, tX, tY := i.fpdi.UseTemplate(tplid, x, y, w, h)
    95  
    96  	f.UseImportedTemplate(tplName, scaleX, scaleY, tX, tY)
    97  }
    98  
    99  // GetPageSizes returns page dimensions for all pages of the imported pdf.
   100  // Result consists of map[<page number>]map[<box>]map[<dimension>]<value>.
   101  // <page number>: page number, note that page numbers start at 1
   102  // <box>: box identifier, e.g. "/MediaBox"
   103  // <dimension>: dimension string, either "w" or "h"
   104  func (i *Importer) GetPageSizes() map[int]map[string]map[string]float64 {
   105  	return i.fpdi.GetPageSizes()
   106  }
   107  
   108  // Default Importer used by global functions
   109  var fpdi = NewImporter()
   110  
   111  // ImportPage imports a page of a PDF file with the specified box (/MediaBox,
   112  // /TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id that can
   113  // be used with UseImportedTemplate to draw the template onto the page.
   114  // Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
   115  func ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
   116  	return fpdi.ImportPage(f, sourceFile, pageno, box)
   117  }
   118  
   119  // ImportPageFromStream imports a page of a PDF with the specified box
   120  // (/MediaBox, TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id
   121  // that can be used with UseImportedTemplate to draw the template onto the
   122  // page.
   123  // Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
   124  func ImportPageFromStream(f gofpdiPdf, rs *io.ReadSeeker, pageno int, box string) int {
   125  	return fpdi.ImportPageFromStream(f, rs, pageno, box)
   126  }
   127  
   128  // UseImportedTemplate draws the template onto the page at x,y. If w is 0, the
   129  // template will be scaled to fit based on h. If h is 0, the template will be
   130  // scaled to fit based on w.
   131  // Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
   132  func UseImportedTemplate(f gofpdiPdf, tplid int, x float64, y float64, w float64, h float64) {
   133  	fpdi.UseImportedTemplate(f, tplid, x, y, w, h)
   134  }
   135  
   136  // GetPageSizes returns page dimensions for all pages of the imported pdf.
   137  // Result consists of map[<page number>]map[<box>]map[<dimension>]<value>.
   138  // <page number>: page number, note that page numbers start at 1
   139  // <box>: box identifier, e.g. "/MediaBox"
   140  // <dimension>: dimension string, either "w" or "h"
   141  // Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
   142  func GetPageSizes() map[int]map[string]map[string]float64 {
   143  	return fpdi.GetPageSizes()
   144  }