diff --git a/code128/encode.go b/code128/encode.go index 6c6a927..ff81fc5 100644 --- a/code128/encode.go +++ b/code128/encode.go @@ -43,7 +43,11 @@ func getCodeIndexList(content []rune) *utils.BitList { if shouldUseCTable(content[i:], curEncoding) { if curEncoding != startCSymbol { - result.AddByte(startCSymbol) + if curEncoding == byte(0) { + result.AddByte(startCSymbol) + } else { + result.AddByte(codeCSymbol) + } curEncoding = startCSymbol } idx := (content[i] - '0') * 10 @@ -53,24 +57,45 @@ func getCodeIndexList(content []rune) *utils.BitList { result.AddByte(byte(idx)) } else { if curEncoding != startBSymbol { - result.AddByte(startBSymbol) + if curEncoding == byte(0) { + result.AddByte(startBSymbol) + } else { + result.AddByte(codeBSymbol) + } curEncoding = startBSymbol } - idx := strings.IndexRune(bTable, content[i]) + var idx int + switch content[i] { + case FNC1: + idx = 102 + break + case FNC2: + idx = 97 + break + case FNC3: + idx = 96 + break + case FNC4: + idx = 100 + break + default: + idx = strings.IndexRune(bTable, content[i]) + break + } + if idx < 0 { return nil } result.AddByte(byte(idx)) } } - fmt.Println(result.GetBytes()) return result } // Encode creates a Code 128 barcode for the given content func Encode(content string) (barcode.Barcode, error) { contentRunes := strToRunes(content) - if len(contentRunes) < 0 || len(contentRunes) > 80 { + if len(contentRunes) <= 0 || len(contentRunes) > 80 { return nil, fmt.Errorf("content length should be between 1 and 80 runes but got %d", len(contentRunes)) } idxList := getCodeIndexList(contentRunes) diff --git a/code128/encode_test.go b/code128/encode_test.go new file mode 100644 index 0000000..a0e2a83 --- /dev/null +++ b/code128/encode_test.go @@ -0,0 +1,51 @@ +package code128 + +import ( + "image/color" + "testing" +) + +func testEncode(t *testing.T, txt, testResult string) { + code, err := Encode(txt) + if err != nil || code == nil { + t.Error(err) + } else { + if code.Bounds().Max.X != len(testResult) { + t.Errorf("%v: length missmatch", txt) + } else { + for i, r := range testResult { + if (code.At(i, 0) == color.Black) != (r == '1') { + t.Errorf("%v: code missmatch on position %d", txt, i) + } + } + } + } +} + +func Test_EncodeFunctionChars(t *testing.T) { + encFNC1 := "11110101110" + encFNC2 := "11110101000" + encFNC3 := "10111100010" + encFNC4 := "10111101110" + encStartB := "11010010000" + encStop := "1100011101011" + + testEncode(t, string(FNC1)+"123", encStartB+encFNC1+"10011100110"+"11001110010"+"11001011100"+"11001000010"+encStop) + testEncode(t, string(FNC2)+"123", encStartB+encFNC2+"10011100110"+"11001110010"+"11001011100"+"11100010110"+encStop) + testEncode(t, string(FNC3)+"123", encStartB+encFNC3+"10011100110"+"11001110010"+"11001011100"+"11101000110"+encStop) + testEncode(t, string(FNC4)+"123", encStartB+encFNC4+"10011100110"+"11001110010"+"11001011100"+"11100011010"+encStop) +} + +func Test_Unencodable(t *testing.T) { + if _, err := Encode(""); err == nil { + t.Fail() + } + if _, err := Encode("รค"); err == nil { + t.Fail() + } +} + +func Test_EncodeCTable(t *testing.T) { + testEncode(t, "HI345678H", "110100100001100010100011000100010101110111101000101100011100010110110000101001011110111011000101000111011000101100011101011") + testEncode(t, "334455", "11010011100101000110001000110111011101000110100100111101100011101011") +} diff --git a/code128/encodingtable.go b/code128/encodingtable.go index a102821..a32b31c 100644 --- a/code128/encodingtable.go +++ b/code128/encodingtable.go @@ -1,6 +1,6 @@ package code128 -var encodingTable [107][]bool = [107][]bool{ +var encodingTable = [107][]bool{ []bool{true, true, false, true, true, false, false, true, true, false, false}, []bool{true, true, false, false, true, true, false, true, true, false, false}, []bool{true, true, false, false, true, true, false, false, true, true, false}, @@ -110,9 +110,24 @@ var encodingTable [107][]bool = [107][]bool{ []bool{true, true, false, false, false, true, true, true, false, true, false, true, true}, } -const startASymbol byte = 103 +// const startASymbol byte = 103 const startBSymbol byte = 104 const startCSymbol byte = 105 + +const codeBSymbol byte = 100 +const codeCSymbol byte = 99 + const stopSymbol byte = 106 +const ( + // FNC1 - Special Function 1 + FNC1 = '\u00f1' + // FNC2 - Special Function 2 + FNC2 = '\u00f2' + // FNC3 - Special Function 3 + FNC3 = '\u00f3' + // FNC4 - Special Function 4 + FNC4 = '\u00f4' +) + const bTable = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"