Start to abstract
This commit is contained in:
92
main.go
92
main.go
@@ -2,35 +2,60 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
|
||||||
"codeberg.org/go-pdf/fpdf"
|
"codeberg.org/go-pdf/fpdf"
|
||||||
"github.com/yeqown/go-qrcode/v2"
|
"github.com/yeqown/go-qrcode/v2"
|
||||||
"github.com/yeqown/go-qrcode/writer/standard"
|
"github.com/yeqown/go-qrcode/writer/standard"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cols = 4
|
|
||||||
var rows = 4
|
|
||||||
var qrSize = 48.0
|
|
||||||
var fontSize = 25.0 // pts
|
|
||||||
var fontSizeMM = fontSize / 72 * 25.4
|
|
||||||
var text = "Á[Hjqy]|"
|
|
||||||
var font = "Courier"
|
|
||||||
|
|
||||||
var textTopPadding = 0.0 // typically none is required
|
var textTopPadding = 0.0 // typically none is required
|
||||||
var qrTopPadding = 5.0 // below the baseline of the text, remember the descenders like 'y', 'q'
|
var qrTopPadding = 5.0 // below the baseline of the text, remember the descenders like 'y', 'q'
|
||||||
|
|
||||||
var requiredCellPadding = 3.0 // half on each side, effectively
|
var requiredCellPadding = 3.0 // half on each side, effectively
|
||||||
|
|
||||||
// var probably some padding instead of offsets for qr/font placement
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
f, _ := os.Create("hello.pdf")
|
||||||
|
err := generatePage(f, PageOptions{
|
||||||
|
qrURL: "https://nanocat.net/dom/sdfih/dsifj/sidhof/sdifho/sdfiuoh/safiuho",
|
||||||
|
qrLabel: "Á[Hjqy]|",
|
||||||
|
qrSize: 54,
|
||||||
|
|
||||||
qrc, err := qrcode.New("https://nanocat.net/dom/sdfih/dsifj/sidhof/sdifho/sdfiuoh/safiuho")
|
font: "Helvetica",
|
||||||
|
fontStyle: "B",
|
||||||
|
fontSize: 34.0,
|
||||||
|
rows: 4,
|
||||||
|
cols: 3,
|
||||||
|
borders: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("could not generate pdf", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type PageOptions struct {
|
||||||
|
qrURL string
|
||||||
|
qrLabel string
|
||||||
|
qrSize float64
|
||||||
|
font string
|
||||||
|
fontStyle string
|
||||||
|
fontSize float64
|
||||||
|
rows int
|
||||||
|
cols int
|
||||||
|
borders bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func generatePage(w io.Writer, po PageOptions) error {
|
||||||
|
|
||||||
|
fontSizeMM := po.fontSize / 72 * 25.4
|
||||||
|
|
||||||
|
qrc, err := qrcode.New(po.qrURL)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("could not generate QRCode: %v", err)
|
return fmt.Errorf("could not generate QRCode: %v", err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b := newBWC()
|
b := newBWC()
|
||||||
@@ -78,65 +103,66 @@ func main() {
|
|||||||
AllowNegativePosition: false,
|
AllowNegativePosition: false,
|
||||||
}, b)
|
}, b)
|
||||||
|
|
||||||
// info := pdf.GetImageInfo("qr")
|
|
||||||
// panic(info.Height())
|
|
||||||
|
|
||||||
pdf.AddPage()
|
pdf.AddPage()
|
||||||
pdf.SetFont(font, "B", float64(fontSize))
|
pdf.SetFont(po.font, po.fontStyle, float64(po.fontSize))
|
||||||
|
|
||||||
textWidth := pdf.GetStringWidth(text)
|
textWidth := pdf.GetStringWidth(po.qrLabel)
|
||||||
|
|
||||||
colWidth := pageWidth / float64(cols)
|
colWidth := pageWidth / float64(po.cols)
|
||||||
rowHeight := pageHeight / float64(rows)
|
rowHeight := pageHeight / float64(po.rows)
|
||||||
|
|
||||||
cellHeight := textTopPadding + fontSizeMM + qrTopPadding + qrSize
|
cellHeight := textTopPadding + fontSizeMM + qrTopPadding + po.qrSize
|
||||||
cellWidth := qrSize
|
cellWidth := po.qrSize
|
||||||
|
|
||||||
if cellHeight > rowHeight-requiredCellPadding {
|
if cellHeight > rowHeight-requiredCellPadding {
|
||||||
|
|
||||||
slog.Warn("qr is too big for row", "cell_height", cellHeight, "row_height", rowHeight)
|
slog.Warn("qr is too big for row", "cell_height", cellHeight, "row_height", rowHeight)
|
||||||
|
return fmt.Errorf("qr is too big for row size")
|
||||||
}
|
}
|
||||||
|
|
||||||
slog.Info("check width", "cell_width", cellWidth, "col_width", colWidth)
|
// slog.Info("check width", "cell_width", cellWidth, "col_width", colWidth)
|
||||||
|
|
||||||
if cellWidth > colWidth-requiredCellPadding {
|
if cellWidth > colWidth-requiredCellPadding {
|
||||||
slog.Warn("qr is too big for column", "cell_width", cellWidth, "col_width", colWidth)
|
slog.Warn("qr is too big for column", "cell_width", cellWidth, "col_width", colWidth)
|
||||||
|
return fmt.Errorf("qr is too big for col size")
|
||||||
}
|
}
|
||||||
|
|
||||||
if textWidth > colWidth {
|
if textWidth > colWidth {
|
||||||
slog.Warn("text probably too wide")
|
slog.Warn("text probably too wide")
|
||||||
|
return fmt.Errorf("text is too wide for col size")
|
||||||
}
|
}
|
||||||
|
|
||||||
for rowIdx := range rows {
|
for rowIdx := range po.rows {
|
||||||
for colIdx := range cols {
|
for colIdx := range po.cols {
|
||||||
topLeftX := colWidth * float64(colIdx)
|
topLeftX := colWidth * float64(colIdx)
|
||||||
topLeftY := rowHeight * float64(rowIdx)
|
topLeftY := rowHeight * float64(rowIdx)
|
||||||
|
|
||||||
// draw box
|
// draw box
|
||||||
|
if po.borders {
|
||||||
pdf.SetDashPattern([]float64{1, 1}, 0)
|
pdf.SetDashPattern([]float64{1, 1}, 0)
|
||||||
pdf.Rect(topLeftX, topLeftY, colWidth, rowHeight, "D")
|
pdf.Rect(topLeftX, topLeftY, colWidth, rowHeight, "D")
|
||||||
pdf.SetDashPattern([]float64{}, 0)
|
pdf.SetDashPattern([]float64{}, 0)
|
||||||
|
}
|
||||||
|
|
||||||
// label at the top
|
// label at the top
|
||||||
pdf.Text(
|
pdf.Text(
|
||||||
topLeftX+colWidth/2-textWidth/2,
|
topLeftX+colWidth/2-textWidth/2,
|
||||||
topLeftY+fontSizeMM+textTopPadding,
|
topLeftY+fontSizeMM+textTopPadding,
|
||||||
text, // +fmt.Sprintf("%d/%d", rowIdx, colIdx)
|
po.qrLabel, // +fmt.Sprintf("%d/%d", rowIdx, colIdx)
|
||||||
)
|
)
|
||||||
|
|
||||||
// qr at the bottom
|
// qr at the bottom
|
||||||
pdf.ImageOptions("qr",
|
pdf.ImageOptions("qr",
|
||||||
topLeftX+colWidth/2-qrSize/2,
|
topLeftX+colWidth/2-po.qrSize/2,
|
||||||
topLeftY+textTopPadding+fontSizeMM+qrTopPadding,
|
topLeftY+textTopPadding+fontSizeMM+qrTopPadding,
|
||||||
qrSize, qrSize,
|
po.qrSize, po.qrSize,
|
||||||
false,
|
false,
|
||||||
fpdf.ImageOptions{AllowNegativePosition: true}, 0, "")
|
fpdf.ImageOptions{AllowNegativePosition: true}, 0, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pdf.OutputFileAndClose("hello.pdf")
|
err = pdf.Output(w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return fmt.Errorf("could not output PDF: %w", err)
|
||||||
}
|
}
|
||||||
fmt.Println(pageWidth, pageHeight)
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user