clone

fifteen puzzle games for the terminal, with daily puzzles, weekly ladders and xp, built on bubble tea

chore/regenerate-vhs-gifs
puzzletea / shikaku / print_adapter.go
print_adapter.go 2.7K
1package shikaku23import (4 "strconv"5 "unicode/utf8"67 "codeberg.org/go-pdf/fpdf"8 "github.com/FelineStateMachine/puzzletea/pdfexport"9)1011type printAdapter struct{}1213var PDFPrintAdapter = printAdapter{}1415func (printAdapter) CanonicalGameType() string { return "Shikaku" }16func (printAdapter) Aliases() []string { return []string{"shikaku"} }1718func (printAdapter) BuildPDFPayload(save []byte) (any, error) {19 return pdfexport.ParseShikakuPrintData(save)20}2122func (printAdapter) RenderPDFBody(pdf *fpdf.Fpdf, payload any) error {23 switch data := payload.(type) {24 case *pdfexport.ShikakuData:25 renderShikakuPage(pdf, data)26 }27 return nil28}2930func renderShikakuPage(pdf *fpdf.Fpdf, data *pdfexport.ShikakuData) {31 if data == nil || data.Width <= 0 || data.Height <= 0 {32 return33 }3435 pageW, pageH := pdf.GetPageSize()36 pageNo := pdf.PageNo()37 body := pdfexport.PuzzleBodyRect(pageW, pageH, pageNo)38 rules := []string{"Partition into rectangles where each clue equals its rectangle area."}39 ruleLines := pdfexport.InstructionLineCount(pdf, body.W, rules)40 area := pdfexport.PuzzleBoardRect(pageW, pageH, pageNo, ruleLines)41 cellSize := pdfexport.FitCompactCellSize(data.Width, data.Height, area)42 if cellSize <= 0 {43 return44 }4546 blockW := float64(data.Width) * cellSize47 blockH := float64(data.Height) * cellSize48 startX, startY := pdfexport.CenteredOrigin(area, data.Width, data.Height, cellSize)4950 pdf.SetDrawColor(55, 55, 55)51 pdf.SetLineWidth(pdfexport.ThinGridLineMM)52 for y := 0; y < data.Height; y++ {53 for x := 0; x < data.Width; x++ {54 cellX := startX + float64(x)*cellSize55 cellY := startY + float64(y)*cellSize56 pdf.Rect(cellX, cellY, cellSize, cellSize, "D")5758 if y >= len(data.Clues) || x >= len(data.Clues[y]) || data.Clues[y][x] <= 0 {59 continue60 }61 drawShikakuClue(pdf, cellX, cellY, cellSize, data.Clues[y][x])62 }63 }6465 pdf.SetDrawColor(35, 35, 35)66 pdf.SetLineWidth(pdfexport.OuterBorderLineMM)67 pdf.Rect(startX, startY, blockW, blockH, "D")6869 ruleY := pdfexport.InstructionY(startY+blockH, pageH, ruleLines)70 pdfexport.RenderInstructions(pdf, body.X, ruleY, body.W, rules)71}7273func drawShikakuClue(pdf *fpdf.Fpdf, x, y, cellSize float64, value int) {74 text := strconv.Itoa(value)75 fontSize := pdfexport.StandardCellFontSize(cellSize, 0.58)76 runeCount := utf8.RuneCountInString(text)77 switch {78 case runeCount >= 3:79 fontSize *= 0.7280 case runeCount == 2:81 fontSize *= 0.8482 }83 fontSize = pdfexport.ClampStandardCellFontSize(fontSize)8485 pdf.SetTextColor(pdfexport.PrimaryTextGray, pdfexport.PrimaryTextGray, pdfexport.PrimaryTextGray)86 pdf.SetFont(pdfexport.SansFontFamily, "B", fontSize)87 lineH := fontSize * 0.9288 pdf.SetXY(x, y+(cellSize-lineH)/2)89 pdf.CellFormat(cellSize, lineH, text, "", 0, "C", false, 0, "")90}