package skibidi import ( "bytes" "strings" "github.com/fogleman/gg" ) type Theme struct { BG string KB_Any string KB_Not string KB_Maybe string KB_Good string KB_Txt string Any string Not string Maybe string Good string Txt string } type SubTheme struct { Round float64 Size float64 Empty_Filled bool KB_Round float64 KB_Size float64 } var keyboard = [][]rune{ []rune("QWERTYUIOP"), []rune("ASDFGHJKL"), []rune("ZXCVBNM"), } func kb_MaxLen() int { max := 0 for _, row := range keyboard { if len(row) > max { max = len(row) } } return max } const ( edge = 20 boxB = 40 boxMarginB = 4 fontB = 30 kb_boxB = 25 kb_boxMarginB = 2 kb_fontB = 15 ) // history format has to be like [X] (X) .X. func RenderWordle(history string, wordLen int, maxGuesses int, theme Theme, subTheme SubTheme) (img []byte, width int, height int, err error) { lines := strings.Split(history, "\n") wordLenF := float64(wordLen) //maxGuessesF := float64(maxGuesses) box := subTheme.Size * boxB boxMargin := subTheme.Size * boxMarginB font := subTheme.Size * fontB kb_box := subTheme.Size * kb_boxB kb_boxMargin := subTheme.Size * kb_boxMarginB //kb_font := subTheme.Size * kb_fontB wordSize := wordLenF*(box+boxMargin) - boxMargin widthF := 2*edge + max(wordSize, float64(kb_MaxLen())*(kb_box+kb_boxMargin)-kb_boxMargin) //heightF := 2*edge + maxGuessesF*(box+boxMargin) + float64(len(keyboard))*(kb_box+kb_boxMargin) width = int(widthF) height = int(height) wordPrePad := (widthF - wordSize) / 2.0 gc := gg.NewContext(width, height) gc.SetLineWidth(boxMargin / 2) if err := gc.LoadFontFace("./wordleimg/static/Roboto_Condensed-Regular.ttf", font); err != nil { return nil, 0, 0, err } for L := range maxGuesses { l := float64(L) line := "" if len(lines) >= L { line = lines[L] } boxY := edge + l*(box+boxMargin) for N := range wordLen { N3 := N * 3 n := float64(N) rn := []rune{' ', ' '} if len(line) >= N3+1 { rn = []rune(line)[N3 : N3+1] } boxX := wordPrePad + n*(box+boxMargin) gc.DrawRoundedRectangle(boxX, boxY, box, box, subTheme.Round) if rn[0] == ' ' { gc.SetHexColor(theme.Any) if subTheme.Empty_Filled { gc.Fill() } gc.Stroke() continue } switch rn[0] { case '.': gc.SetHexColor(theme.Not) case '(': gc.SetHexColor(theme.Maybe) case '[': gc.SetHexColor(theme.Good) } gc.Fill() gc.DrawString(string(rn[1]), boxX+box/2, boxY+box/2) } } var buf bytes.Buffer err = gc.EncodePNG(&buf) if err != nil { return nil, 0, 0, err } img = buf.Bytes() return }