mirror of
https://github.com/zxing/zxing.git
synced 2025-01-12 11:47:26 -08:00
Add codeset A support to Code 128 (#877)
* add support of Codeset A for Code 128 * simplification, everything from 0 to 127 is supported by Codeset A and B
This commit is contained in:
parent
437db89b45
commit
24f170efb3
|
@ -32,8 +32,10 @@ import java.util.Map;
|
|||
*/
|
||||
public final class Code128Writer extends OneDimensionalCodeWriter {
|
||||
|
||||
private static final int CODE_START_A = 103;
|
||||
private static final int CODE_START_B = 104;
|
||||
private static final int CODE_START_C = 105;
|
||||
private static final int CODE_CODE_A = 101;
|
||||
private static final int CODE_CODE_B = 100;
|
||||
private static final int CODE_CODE_C = 99;
|
||||
private static final int CODE_STOP = 106;
|
||||
|
@ -47,6 +49,7 @@ public final class Code128Writer extends OneDimensionalCodeWriter {
|
|||
private static final int CODE_FNC_1 = 102; // Code A, Code B, Code C
|
||||
private static final int CODE_FNC_2 = 97; // Code A, Code B
|
||||
private static final int CODE_FNC_3 = 96; // Code A, Code B
|
||||
private static final int CODE_FNC_4_A = 101; // Code A
|
||||
private static final int CODE_FNC_4_B = 100; // Code B
|
||||
|
||||
// Results of minimal lookahead for code C
|
||||
|
@ -80,16 +83,17 @@ public final class Code128Writer extends OneDimensionalCodeWriter {
|
|||
// Check content
|
||||
for (int i = 0; i < length; i++) {
|
||||
char c = contents.charAt(i);
|
||||
if (c < ' ' || c > '~') {
|
||||
switch (c) {
|
||||
case ESCAPE_FNC_1:
|
||||
case ESCAPE_FNC_2:
|
||||
case ESCAPE_FNC_3:
|
||||
case ESCAPE_FNC_4:
|
||||
break;
|
||||
default:
|
||||
switch (c) {
|
||||
case ESCAPE_FNC_1:
|
||||
case ESCAPE_FNC_2:
|
||||
case ESCAPE_FNC_3:
|
||||
case ESCAPE_FNC_4:
|
||||
break;
|
||||
default:
|
||||
if (c > 127) {
|
||||
// support for FNC4 isn't implemented, no full Latin-1 character set available at the moment
|
||||
throw new IllegalArgumentException("Bad character in input: " + c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,15 +123,30 @@ public final class Code128Writer extends OneDimensionalCodeWriter {
|
|||
patternIndex = CODE_FNC_3;
|
||||
break;
|
||||
case ESCAPE_FNC_4:
|
||||
patternIndex = CODE_FNC_4_B; // FIXME if this ever outputs Code A
|
||||
if (codeSet == CODE_CODE_A) {
|
||||
patternIndex = CODE_FNC_4_A;
|
||||
} else {
|
||||
patternIndex = CODE_FNC_4_B;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Then handle normal characters otherwise
|
||||
if (codeSet == CODE_CODE_B) {
|
||||
patternIndex = contents.charAt(position) - ' ';
|
||||
} else { // CODE_CODE_C
|
||||
patternIndex = Integer.parseInt(contents.substring(position, position + 2));
|
||||
position++; // Also incremented below
|
||||
switch (codeSet) {
|
||||
case CODE_CODE_A:
|
||||
patternIndex = contents.charAt(position) - ' ';
|
||||
if (patternIndex < 0) {
|
||||
// everything below a space character comes behind the underscore in the code patterns table
|
||||
patternIndex += '`';
|
||||
}
|
||||
break;
|
||||
case CODE_CODE_B:
|
||||
patternIndex = contents.charAt(position) - ' ';
|
||||
break;
|
||||
default:
|
||||
// CODE_CODE_C
|
||||
patternIndex = Integer.parseInt(contents.substring(position, position + 2));
|
||||
position++; // Also incremented below
|
||||
break;
|
||||
}
|
||||
}
|
||||
position++;
|
||||
|
@ -136,11 +155,16 @@ public final class Code128Writer extends OneDimensionalCodeWriter {
|
|||
// Do we have a code set?
|
||||
if (codeSet == 0) {
|
||||
// No, we don't have a code set
|
||||
if (newCodeSet == CODE_CODE_B) {
|
||||
patternIndex = CODE_START_B;
|
||||
} else {
|
||||
// CODE_CODE_C
|
||||
patternIndex = CODE_START_C;
|
||||
switch (newCodeSet) {
|
||||
case CODE_CODE_A:
|
||||
patternIndex = CODE_START_A;
|
||||
break;
|
||||
case CODE_CODE_B:
|
||||
patternIndex = CODE_START_B;
|
||||
break;
|
||||
default:
|
||||
patternIndex = CODE_START_C;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Yes, we have a code set
|
||||
|
@ -208,7 +232,17 @@ public final class Code128Writer extends OneDimensionalCodeWriter {
|
|||
|
||||
private static int chooseCode(CharSequence value, int start, int oldCode) {
|
||||
CType lookahead = findCType(value, start);
|
||||
if (lookahead == CType.UNCODABLE || lookahead == CType.ONE_DIGIT) {
|
||||
if (lookahead == CType.ONE_DIGIT) {
|
||||
return CODE_CODE_B;
|
||||
}
|
||||
if (lookahead == CType.UNCODABLE) {
|
||||
if (start < value.length()) {
|
||||
char c = value.charAt(start);
|
||||
if (c < ' ' || (oldCode == CODE_CODE_A && c < '`')) {
|
||||
// can continue in code A, encodes ASCII 0 to 95
|
||||
return CODE_CODE_A;
|
||||
}
|
||||
}
|
||||
return CODE_CODE_B; // no choice
|
||||
}
|
||||
if (oldCode == CODE_CODE_C) { // can continue in code C
|
||||
|
|
|
@ -34,8 +34,10 @@ public class Code128WriterTestCase extends Assert {
|
|||
private static final String FNC2 = "11110101000";
|
||||
private static final String FNC3 = "10111100010";
|
||||
private static final String FNC4 = "10111101110";
|
||||
private static final String START_CODE_A = "11010000100";
|
||||
private static final String START_CODE_B = "11010010000";
|
||||
private static final String START_CODE_C = "11010011100";
|
||||
private static final String SWITCH_CODE_A = "11101011110";
|
||||
private static final String SWITCH_CODE_B = "10111101110";
|
||||
private static final String QUIET_SPACE = "00000";
|
||||
private static final String STOP = "1100011101011";
|
||||
|
@ -108,6 +110,27 @@ public class Code128WriterTestCase extends Assert {
|
|||
String actual = BitMatrixTestCase.matrixToString(result);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeSwitchBetweenCodesetsAAndB() throws Exception {
|
||||
// start with A switch to B and back to A
|
||||
// "\0" "A" "B" Switch to B "a" "b" Switch to A "\u0010" check digit
|
||||
testEncode("\0ABab\u0010", QUIET_SPACE + START_CODE_A + "10100001100" + "10100011000" + "10001011000" + SWITCH_CODE_B + "10010110000" + "10010000110" + SWITCH_CODE_A + "10100111100" + "11001110100" + STOP + QUIET_SPACE);
|
||||
|
||||
// start with B switch to A and back to B
|
||||
// "a" "b" Switch to A "\0 "Switch to B" "a" "b" check digit
|
||||
testEncode("ab\0ab", QUIET_SPACE + START_CODE_B + "10010110000" + "10010000110" + SWITCH_CODE_A + "10100001100" + SWITCH_CODE_B + "10010110000" + "10010000110" + "11010001110" + STOP + QUIET_SPACE);
|
||||
}
|
||||
|
||||
private void testEncode(String toEncode, String expected) throws Exception {
|
||||
BitMatrix result = writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0);
|
||||
|
||||
String actual = BitMatrixTestCase.matrixToString(result);
|
||||
assertEquals(toEncode, expected, actual);
|
||||
|
||||
BitArray row = result.getRow(0, null);
|
||||
Result rtResult = reader.decodeRow(0, row, null);
|
||||
String actualRoundtripResultText = rtResult.getText();
|
||||
assertEquals(toEncode, actualRoundtripResultText);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue