boombuler 12 лет назад
Родитель
Сommit
1af72b7408
2 измененных файлов с 150 добавлено и 0 удалено
  1. 39 0
      code39/code.go
  2. 111 0
      code39/encoder.go

+ 39 - 0
code39/code.go

@@ -0,0 +1,39 @@
+package code39
+
+import (
+	"github.com/boombuler/barcode"
+	"image"
+	"image/color"
+)
+
+type code struct {
+	*barcode.BitList
+	content string
+}
+
+func newCode() *code {
+	return &code{&barcode.BitList{}, ""}
+}
+
+func (c *code) Content() string {
+	return c.content
+}
+
+func (c *code) Metadata() barcode.Metadata {
+	return barcode.Metadata{"Code39", 1}
+}
+
+func (c *code) ColorModel() color.Model {
+	return color.Gray16Model
+}
+
+func (c *code) Bounds() image.Rectangle {
+	return image.Rect(0, 0, c.Len(), 1)
+}
+
+func (c *code) At(x, y int) color.Color {
+	if c.GetBit(x) {
+		return color.Black
+	}
+	return color.White
+}

+ 111 - 0
code39/encoder.go

@@ -0,0 +1,111 @@
+package code39
+
+import (
+	"errors"
+	"github.com/boombuler/barcode"
+	"strings"
+)
+
+type encodeInfo struct {
+	value int
+	data  []bool
+}
+
+var encodeTable map[rune]encodeInfo = map[rune]encodeInfo{
+	'0': encodeInfo{0, []bool{true, false, true, false, false, true, true, false, true, true, false, true}},
+	'1': encodeInfo{1, []bool{true, true, false, true, false, false, true, false, true, false, true, true}},
+	'2': encodeInfo{2, []bool{true, false, true, true, false, false, true, false, true, false, true, true}},
+	'3': encodeInfo{3, []bool{true, true, false, true, true, false, false, true, false, true, false, true}},
+	'4': encodeInfo{4, []bool{true, false, true, false, false, true, true, false, true, false, true, true}},
+	'5': encodeInfo{5, []bool{true, true, false, true, false, false, true, true, false, true, false, true}},
+	'6': encodeInfo{6, []bool{true, false, true, true, false, false, true, true, false, true, false, true}},
+	'7': encodeInfo{7, []bool{true, false, true, false, false, true, false, true, true, false, true, true}},
+	'8': encodeInfo{8, []bool{true, true, false, true, false, false, true, false, true, true, false, true}},
+	'9': encodeInfo{9, []bool{true, false, true, true, false, false, true, false, true, true, false, true}},
+	'A': encodeInfo{10, []bool{true, true, false, true, false, true, false, false, true, false, true, true}},
+	'B': encodeInfo{11, []bool{true, false, true, true, false, true, false, false, true, false, true, true}},
+	'C': encodeInfo{12, []bool{true, true, false, true, true, false, true, false, false, true, false, true}},
+	'D': encodeInfo{13, []bool{true, false, true, false, true, true, false, false, true, false, true, true}},
+	'E': encodeInfo{14, []bool{true, true, false, true, false, true, true, false, false, true, false, true}},
+	'F': encodeInfo{15, []bool{true, false, true, true, false, true, true, false, false, true, false, true}},
+	'G': encodeInfo{16, []bool{true, false, true, false, true, false, false, true, true, false, true, true}},
+	'H': encodeInfo{17, []bool{true, true, false, true, false, true, false, false, true, true, false, true}},
+	'I': encodeInfo{18, []bool{true, false, true, true, false, true, false, false, true, true, false, true}},
+	'J': encodeInfo{19, []bool{true, false, true, false, true, true, false, false, true, true, false, true}},
+	'K': encodeInfo{20, []bool{true, true, false, true, false, true, false, true, false, false, true, true}},
+	'L': encodeInfo{21, []bool{true, false, true, true, false, true, false, true, false, false, true, true}},
+	'M': encodeInfo{22, []bool{true, true, false, true, true, false, true, false, true, false, false, true}},
+	'N': encodeInfo{23, []bool{true, false, true, false, true, true, false, true, false, false, true, true}},
+	'O': encodeInfo{24, []bool{true, true, false, true, false, true, true, false, true, false, false, true}},
+	'P': encodeInfo{25, []bool{true, false, true, true, false, true, true, false, true, false, false, true}},
+	'Q': encodeInfo{26, []bool{true, false, true, false, true, false, true, true, false, false, true, true}},
+	'R': encodeInfo{27, []bool{true, true, false, true, false, true, false, true, true, false, false, true}},
+	'S': encodeInfo{28, []bool{true, false, true, true, false, true, false, true, true, false, false, true}},
+	'T': encodeInfo{29, []bool{true, false, true, false, true, true, false, true, true, false, false, true}},
+	'U': encodeInfo{30, []bool{true, true, false, false, true, false, true, false, true, false, true, true}},
+	'V': encodeInfo{31, []bool{true, false, false, true, true, false, true, false, true, false, true, true}},
+	'W': encodeInfo{32, []bool{true, true, false, false, true, true, false, true, false, true, false, true}},
+	'X': encodeInfo{33, []bool{true, false, false, true, false, true, true, false, true, false, true, true}},
+	'Y': encodeInfo{34, []bool{true, true, false, false, true, false, true, true, false, true, false, true}},
+	'Z': encodeInfo{35, []bool{true, false, false, true, true, false, true, true, false, true, false, true}},
+	'-': encodeInfo{36, []bool{true, false, false, true, false, true, false, true, true, false, true, true}},
+	'.': encodeInfo{37, []bool{true, true, false, false, true, false, true, false, true, true, false, true}},
+	' ': encodeInfo{38, []bool{true, false, false, true, true, false, true, false, true, true, false, true}},
+	'$': encodeInfo{39, []bool{true, false, false, true, false, false, true, false, false, true, false, true}},
+	'/': encodeInfo{40, []bool{true, false, false, true, false, false, true, false, true, false, false, true}},
+	'+': encodeInfo{41, []bool{true, false, false, true, false, true, false, false, true, false, false, true}},
+	'%': encodeInfo{42, []bool{true, false, true, false, false, true, false, false, true, false, false, true}},
+	'*': encodeInfo{-1, []bool{true, false, false, true, false, true, true, false, true, true, false, true}},
+}
+
+func getChecksum(content string) string {
+	sum := 0
+	for _, r := range content {
+		info, ok := encodeTable[r]
+		if !ok || info.value < 0 {
+			return "#"
+		}
+
+		sum += info.value
+	}
+
+	sum = sum % 43
+	for r, v := range encodeTable {
+		if v.value == sum {
+			return string(r)
+		}
+	}
+	return "#"
+}
+
+// encodes the given string as a code39 barcode
+// if includeChecksum is set to true, a checksum character is calculated and added to the content
+func Encode(content string, includeChecksum bool) (barcode.Barcode, error) {
+	if strings.ContainsRune(content, '*') {
+		return nil, errors.New("invalid data")
+	}
+
+	data := "*" + content
+	if includeChecksum {
+		data += getChecksum(content)
+	}
+	data += "*"
+
+	cd := newCode()
+
+	for i, r := range data {
+		if i != 0 {
+			cd.AddBit(false)
+		}
+
+		info, ok := encodeTable[r]
+		if !ok {
+			return nil, errors.New("invalid data")
+		}
+		for _, bit := range info.data {
+			cd.AddBit(bit)
+		}
+	}
+
+	return cd, nil
+}