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 }