github.com/hi-fi/sss/print@v0.0.0-20230212204231-b8661fcee5d7/pkg/pdf/leaflet.go (about)

     1  package pdf
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  
     8  	"github.com/hi-fi/sss/print/pkg/model"
     9  	"go.opentelemetry.io/otel"
    10  
    11  	"github.com/phpdave11/gofpdf"
    12  )
    13  
    14  var leafletTracer = otel.GetTracerProvider().Tracer("leaflet")
    15  
    16  func CreateLeaflet(ctx context.Context, data model.Model) bytes.Buffer {
    17  	spanCtx, span := leafletTracer.Start(ctx, "CreateLeaflet")
    18  	defer span.End()
    19  	pages := createLeafletPages(spanCtx, data)
    20  	switch style := data.Style; style {
    21  	case model.COLUMNS:
    22  	case model.LEAFLET, model.HIGH_LEAFLET:
    23  		pages, _ = makePrintableBooklet(spanCtx, &pages)
    24  	}
    25  	return pages
    26  }
    27  
    28  func createLeafletPages(ctx context.Context, data model.Model) (byteBuffer bytes.Buffer) {
    29  	_, span := leafletTracer.Start(ctx, "createLeafletPages")
    30  	defer span.End()
    31  	const (
    32  		margin = float64(10.0 * 2.835)
    33  		gutter = 8
    34  	)
    35  
    36  	var (
    37  		pageWd          = data.Page.Width
    38  		eventFontSize   = float64(data.FontSize) * 1.3
    39  		eventLineHeight = eventFontSize * 1.1
    40  		y0              = margin
    41  		crrntCol        int
    42  		colNum          = data.Columns
    43  		colWd           = float64((pageWd - 2.0*margin - float64((colNum-1)*gutter)) / float64(colNum))
    44  	)
    45  
    46  	init := &gofpdf.InitType{
    47  		OrientationStr: data.Page.Orientation,
    48  		UnitStr:        data.Page.Unit,
    49  		Size: gofpdf.SizeType{
    50  			Wd: data.Page.Width,
    51  			Ht: data.Page.Height,
    52  		},
    53  	}
    54  	pdf := initFPDF(init)
    55  
    56  	setCol := func(col int) {
    57  		crrntCol = col
    58  		x := margin + float64(col)*(colWd+gutter)
    59  		pdf.SetLeftMargin(x)
    60  		pdf.SetX(x)
    61  	}
    62  	pdf.SetAcceptPageBreakFunc(func() bool {
    63  		if crrntCol < colNum-1 {
    64  			setCol(crrntCol + 1)
    65  			pdf.SetY(y0)
    66  			// Start new column, not new page
    67  			return false
    68  		}
    69  		y0 = margin
    70  		setCol(0)
    71  		return true
    72  	})
    73  	_, _, _, bottomMargin := pdf.GetMargins()
    74  
    75  	// Front page at leaflets
    76  	titlePageColumnWidth := colWd
    77  	if data.Style != model.COLUMNS {
    78  		titlePageColumnWidth = pageWd - 2.0*margin
    79  	}
    80  	pdf.AddPage()
    81  	pdf.SetFont("dejavu", "B", eventFontSize)
    82  	pdf.MultiCell(titlePageColumnWidth, eventLineHeight, data.Event, "", "C", false)
    83  	if data.Style != model.COLUMNS && data.UseCoverImage && len(data.CoverImage) > 0 {
    84  		imageData, err := decodeBase64ToBytes(data.CoverImage)
    85  		if err != nil {
    86  			fmt.Printf("Error: %v", err)
    87  
    88  		} else {
    89  			getImageType(&imageData)
    90  			imageOptions := gofpdf.ImageOptions{
    91  				ImageType: imageData.Type,
    92  			}
    93  			pdf.RegisterImageOptionsReader("coverImage", imageOptions, bytes.NewReader(imageData.Data))
    94  			getImageSize(&imageData)
    95  			if data.SongsOnCover {
    96  				y := pdf.GetY() + (((pageWd-2.0*margin)/float64(imageData.Width))*float64(imageData.Height))/2.0
    97  				pdf.ImageOptions("coverImage", pdf.GetX(), y, pageWd-2.0*margin, 0, true, imageOptions, 0, "")
    98  			} else {
    99  				y := data.Page.Height/2 - (((pageWd-2.0*margin)/float64(imageData.Width))*float64(imageData.Height))/2.0
   100  				pdf.ImageOptions("coverImage", pdf.GetX(), y, pageWd-2.0*margin, 0, false, imageOptions, 0, "")
   101  				// Needs to add a bit more to needed size to prevent page change
   102  				pdf.SetY(-bottomMargin - getCellHeightNeeded(pdf, data.Description, colWd, eventLineHeight) - .01)
   103  			}
   104  
   105  		}
   106  	}
   107  	pdf.MultiCell(titlePageColumnWidth, eventLineHeight, data.Description, "", "C", false)
   108  	if data.SongsOnCover {
   109  		pdf.Ln(-1)
   110  		y0 = pdf.GetY()
   111  	}
   112  
   113  	// Songs at cover need also honor column setting like ones at later pages
   114  
   115  	// Actual content
   116  	if data.Style != model.COLUMNS && !data.SongsOnCover {
   117  		pdf.AddPage()
   118  	}
   119  	addSongs(data, pdf, bottomMargin, colWd)
   120  	if data.Style != model.COLUMNS && !data.SongsOnBack {
   121  		pdf.AddPage()
   122  	}
   123  	err := pdf.Output(&byteBuffer)
   124  	if err != nil {
   125  		fmt.Printf("error at Output %v\n", err)
   126  	}
   127  	return byteBuffer
   128  }