2014-08-11 09:11:24 +00:00
|
|
|
// Package datamatrix can create Datamatrix barcodes
|
|
|
|
package datamatrix
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
|
|
|
|
"github.com/boombuler/barcode"
|
|
|
|
)
|
|
|
|
|
2024-08-30 02:54:58 +00:00
|
|
|
// FNC1 is the codeword for the Function 1 Symbol Character to
|
|
|
|
// differentiate a GS1 DataMatrix from other Data Matrix symbols.
|
|
|
|
//
|
|
|
|
// It is used as both a start character and a separator of GS1 element
|
|
|
|
// strings.
|
|
|
|
const FNC1 byte = 232
|
|
|
|
|
2024-08-01 12:02:23 +00:00
|
|
|
// Encode returns a Datamatrix barcode for the given content and color scheme
|
2024-07-31 19:11:52 +00:00
|
|
|
func EncodeWithColor(content string, color barcode.ColorScheme) (barcode.Barcode, error) {
|
2014-08-11 09:11:24 +00:00
|
|
|
data := encodeText(content)
|
|
|
|
|
|
|
|
var size *dmCodeSize
|
|
|
|
for _, s := range codeSizes {
|
|
|
|
if s.DataCodewords() >= len(data) {
|
|
|
|
size = s
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if size == nil {
|
|
|
|
return nil, errors.New("to much data to encode")
|
|
|
|
}
|
|
|
|
data = addPadding(data, size.DataCodewords())
|
|
|
|
data = ec.calcECC(data, size)
|
2024-07-31 19:11:52 +00:00
|
|
|
code := render(data, size, color)
|
2014-08-11 09:11:24 +00:00
|
|
|
if code != nil {
|
|
|
|
code.content = content
|
|
|
|
return code, nil
|
|
|
|
}
|
|
|
|
return nil, errors.New("unable to render barcode")
|
|
|
|
}
|
|
|
|
|
2024-07-24 13:29:23 +00:00
|
|
|
// Encode returns a Datamatrix barcode for the given content
|
|
|
|
func Encode(content string) (barcode.Barcode, error) {
|
2024-07-31 19:11:52 +00:00
|
|
|
return EncodeWithColor(content, barcode.ColorScheme16)
|
2024-07-24 13:29:23 +00:00
|
|
|
}
|
|
|
|
|
2024-07-31 19:11:52 +00:00
|
|
|
func render(data []byte, size *dmCodeSize, color barcode.ColorScheme) *datamatrixCode {
|
|
|
|
cl := newCodeLayout(size, color)
|
2014-08-11 09:11:24 +00:00
|
|
|
|
2016-09-01 14:56:45 +00:00
|
|
|
cl.SetValues(data)
|
|
|
|
|
2014-08-11 09:11:24 +00:00
|
|
|
return cl.Merge()
|
|
|
|
}
|
|
|
|
|
|
|
|
func encodeText(content string) []byte {
|
|
|
|
var result []byte
|
|
|
|
input := []byte(content)
|
|
|
|
|
2024-08-30 02:54:58 +00:00
|
|
|
isGS1 := len(input) > 0 && input[0] == FNC1
|
|
|
|
|
2014-08-11 09:11:24 +00:00
|
|
|
for i := 0; i < len(input); {
|
|
|
|
c := input[i]
|
|
|
|
i++
|
|
|
|
|
|
|
|
if c >= '0' && c <= '9' && i < len(input) && input[i] >= '0' && input[i] <= '9' {
|
|
|
|
// two numbers...
|
|
|
|
c2 := input[i]
|
|
|
|
i++
|
|
|
|
cw := byte(((c-'0')*10 + (c2 - '0')) + 130)
|
|
|
|
result = append(result, cw)
|
2024-08-30 02:54:58 +00:00
|
|
|
} else if isGS1 && c == FNC1 {
|
|
|
|
result = append(result, c)
|
2014-08-11 09:11:24 +00:00
|
|
|
} else if c > 127 {
|
|
|
|
// not correct... needs to be redone later...
|
|
|
|
result = append(result, 235, c-127)
|
|
|
|
} else {
|
|
|
|
result = append(result, c+1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
func addPadding(data []byte, toCount int) []byte {
|
|
|
|
if len(data) < toCount {
|
|
|
|
data = append(data, 129)
|
|
|
|
}
|
|
|
|
for len(data) < toCount {
|
|
|
|
R := ((149 * (len(data) + 1)) % 253) + 1
|
2024-07-31 19:11:52 +00:00
|
|
|
tmp := 129 + R
|
|
|
|
if tmp > 254 {
|
2022-02-09 08:17:15 +00:00
|
|
|
tmp = tmp - 254
|
|
|
|
}
|
2024-07-31 19:11:52 +00:00
|
|
|
|
2022-02-09 08:17:15 +00:00
|
|
|
data = append(data, byte(tmp))
|
2014-08-11 09:11:24 +00:00
|
|
|
}
|
|
|
|
return data
|
|
|
|
}
|