diff --git a/code128/encode.go b/code128/encode.go
index e1dbae1..24981b7 100644
--- a/code128/encode.go
+++ b/code128/encode.go
@@ -43,6 +43,29 @@ func shouldUseCTable(nextRunes []rune, curEncoding byte) bool {
 	return true
 }
 
+func tableContainsRune(table string, r rune) bool {
+	return strings.ContainsRune(table, r) || r == FNC1 || r == FNC2 || r == FNC3 || r == FNC4
+}
+
+func shouldUseATable(nextRunes []rune, curEncoding byte) bool {
+	nextRune := nextRunes[0]
+	if !tableContainsRune(bTable, nextRune) || curEncoding == startASymbol {
+		return tableContainsRune(aTable, nextRune)
+	}
+	if curEncoding == 0 {
+		for _, r := range nextRunes {
+			if tableContainsRune(abTable, r) {
+				continue
+			}
+			if strings.ContainsRune(aOnlyTable, r) {
+				return true
+			}
+			break
+		}
+	}
+	return false
+}
+
 func getCodeIndexList(content []rune) *utils.BitList {
 	result := new(utils.BitList)
 	curEncoding := byte(0)
@@ -59,12 +82,42 @@ func getCodeIndexList(content []rune) *utils.BitList {
 			if content[i] == FNC1 {
 				result.AddByte(102)
 			} else {
-
 				idx := (content[i] - '0') * 10
 				i++
 				idx = idx + (content[i] - '0')
 				result.AddByte(byte(idx))
 			}
+		} else if shouldUseATable(content[i:], curEncoding) {
+			if curEncoding != startASymbol {
+				if curEncoding == byte(0) {
+					result.AddByte(startASymbol)
+				} else {
+					result.AddByte(codeASymbol)
+				}
+				curEncoding = startASymbol
+			}
+			var idx int
+			switch content[i] {
+			case FNC1:
+				idx = 102
+				break
+			case FNC2:
+				idx = 97
+				break
+			case FNC3:
+				idx = 96
+				break
+			case FNC4:
+				idx = 101
+				break
+			default:
+				idx = strings.IndexRune(aTable, content[i])
+				break
+			}
+			if idx < 0 {
+				return nil
+			}
+			result.AddByte(byte(idx))
 		} else {
 			if curEncoding != startBSymbol {
 				if curEncoding == byte(0) {
diff --git a/code128/encode_test.go b/code128/encode_test.go
index 411ea30..68b2c05 100644
--- a/code128/encode_test.go
+++ b/code128/encode_test.go
@@ -11,7 +11,7 @@ func testEncode(t *testing.T, txt, testResult string) {
 		t.Error(err)
 	} else {
 		if code.Bounds().Max.X != len(testResult) {
-			t.Errorf("%v: length missmatch", txt)
+			t.Errorf("%v: length missmatch. Got %d expected %d", txt, code.Bounds().Max.X, len(testResult))
 		} else {
 			encoded := ""
 			failed := false
@@ -88,3 +88,16 @@ func Test_shouldUseCTable(t *testing.T) {
 		t.Error("01[FNC1] failed")
 	}
 }
+
+func Test_Issue16(t *testing.T) {
+	if !shouldUseATable([]rune{'\r', 'A'}, 0) {
+		t.Error("Code should start with A-Table if the text start with \\r")
+	}
+	if !shouldUseATable([]rune{FNC1, '\r'}, 0) {
+		t.Error("Code should start with A-Table if the text start with <FNC1>\\r")
+	}
+	if shouldUseATable([]rune{FNC1, '1', '2', '3'}, 0) {
+		t.Error("Code should not start with A-Table if the text start with <FNC1>123")
+	}
+	testEncode(t, string(FNC3)+"$P\rI", "110100001001011110001010010001100111011101101111011101011000100010110001010001100011101011")
+}
diff --git a/code128/encodingtable.go b/code128/encodingtable.go
index 0ca3d49..8162a07 100644
--- a/code128/encodingtable.go
+++ b/code128/encodingtable.go
@@ -133,11 +133,11 @@ const (
 
 const abTable = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
 const bTable = abTable + "`abcdefghijklmnopqrstuvwxyz{|}~\u007F"
-const aTable = abTable +
-	"\u0000\u0001\u0002\u0003\u0004" + // NUL, SOH, STX, ETX, EOT
+const aOnlyTable = "\u0000\u0001\u0002\u0003\u0004" + // NUL, SOH, STX, ETX, EOT
 	"\u0005\u0006\u0007\u0008\u0009" + // ENQ, ACK, BEL, BS,  HT
 	"\u000A\u000B\u000C\u000D\u000E" + // LF,  VT,  FF,  CR,  SO
 	"\u000F\u0010\u0011\u0012\u0013" + // SI,  DLE, DC1, DC2, DC3
 	"\u0014\u0015\u0016\u0017\u0018" + // DC4, NAK, SYN, ETB, CAN
 	"\u0019\u001A\u001B\u001C\u001D" + // EM,  SUB, ESC, FS,  GS
 	"\u001E\u001F" // RS,  US
+const aTable = abTable + aOnlyTable