pixelqr/internal/bytes_to_unicode.go

88 lines
1.4 KiB
Go

package internal
import (
"io"
"strings"
"github.com/fatih/color"
"github.com/qpliu/qrencode-go/qrencode"
)
const (
Upper byte = 1 << iota
Lower
)
var (
// Got the information from https://de.wikipedia.org/wiki/Unicodeblock_Blockelemente
byteMapping = map[byte]rune{
0: ' ',
Upper: '\u2580', // UPPER HALF BLOCK
Lower: '\u2584', // LOWER HALF BLOCK
Upper | Lower: '\u2588', // FULL BLOCK
}
)
func ConvertGridToUnicode(target io.Writer, source *qrencode.BitGrid) (err error) {
c := color.New(color.BgWhite)
c.Add(color.FgBlack)
writeSpaceLine := func() (n int, err error) {
n, err = c.Fprint(target, strings.Repeat(" ", source.Width()+2))
if err != nil {
return
}
m, err := target.Write([]byte{'\n'})
if err != nil {
return
}
n += m
return
}
if _, err = writeSpaceLine(); err != nil {
return
}
for y := 0; y < source.Height(); y += 2 {
// Go from left to right in both rows
line := " "
for x := 0; x < source.Width(); x++ {
var runeKey byte
// First row
if source.Get(x, y) {
runeKey |= Upper
}
if y+1 < source.Height() {
if source.Get(x, y+1) {
runeKey |= Lower
}
}
line += string(byteMapping[runeKey])
}
line += " "
_, err = c.Fprint(target, line)
if err != nil {
return
}
_, err = target.Write([]byte{'\n'})
if err != nil {
return
}
}
if err == io.EOF {
err = nil
}
_, err = writeSpaceLine()
return
}