mirror of
https://github.com/zxing/zxing.git
synced 2024-11-09 20:44:03 -08:00
Added option to force C40 encoding in data matrix (#1495)
* Added option FORCE_C40 * Restored original public API * Improved javadoc for EncodeHintType.FORCE_C40 * More javadoc fixes
This commit is contained in:
parent
39440b3015
commit
13465b3f1c
|
@ -45,7 +45,8 @@ public enum EncodeHintType {
|
||||||
DATA_MATRIX_SHAPE,
|
DATA_MATRIX_SHAPE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether to use compact mode for Data Matrix (type {@link Boolean}, or "true" or "false"
|
* Specifies whether to use compact mode for Data Matrix (type {@link Boolean}, or "true" or "false"
|
||||||
|
* {@link String } value).
|
||||||
* The compact encoding mode also supports the encoding of characters that are not in the ISO-8859-1
|
* The compact encoding mode also supports the encoding of characters that are not in the ISO-8859-1
|
||||||
* character set via ECIs.
|
* character set via ECIs.
|
||||||
* Please note that in that case, the most compact character encoding is chosen for characters in
|
* Please note that in that case, the most compact character encoding is chosen for characters in
|
||||||
|
@ -55,6 +56,7 @@ public enum EncodeHintType {
|
||||||
* Compact encoding also provides GS1-FNC1 support when {@link #GS1_FORMAT} is selected. In this case
|
* Compact encoding also provides GS1-FNC1 support when {@link #GS1_FORMAT} is selected. In this case
|
||||||
* group-separator character (ASCII 29 decimal) can be used to encode the positions of FNC1 codewords
|
* group-separator character (ASCII 29 decimal) can be used to encode the positions of FNC1 codewords
|
||||||
* for the purpose of delimiting AIs.
|
* for the purpose of delimiting AIs.
|
||||||
|
* This option and {@link #FORCE_C40} are mutually exclusive.
|
||||||
*/
|
*/
|
||||||
DATA_MATRIX_COMPACT,
|
DATA_MATRIX_COMPACT,
|
||||||
|
|
||||||
|
@ -127,6 +129,7 @@ public enum EncodeHintType {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether to use compact mode for QR code (type {@link Boolean}, or "true" or "false"
|
* Specifies whether to use compact mode for QR code (type {@link Boolean}, or "true" or "false"
|
||||||
|
* {@link String } value).
|
||||||
* Please note that when compaction is performed, the most compact character encoding is chosen
|
* Please note that when compaction is performed, the most compact character encoding is chosen
|
||||||
* for characters in the input that are not in the ISO-8859-1 character set. Based on experience,
|
* for characters in the input that are not in the ISO-8859-1 character set. Based on experience,
|
||||||
* some scanners do not support encodings like cp-1256 (Arabic). In such cases the encoding can
|
* some scanners do not support encodings like cp-1256 (Arabic). In such cases the encoding can
|
||||||
|
@ -143,13 +146,21 @@ public enum EncodeHintType {
|
||||||
/**
|
/**
|
||||||
* Forces which encoding will be used. Currently only used for Code-128 code sets (Type {@link String}).
|
* Forces which encoding will be used. Currently only used for Code-128 code sets (Type {@link String}).
|
||||||
* Valid values are "A", "B", "C".
|
* Valid values are "A", "B", "C".
|
||||||
|
* This option and {@link #CODE128_COMPACT} are mutually exclusive.
|
||||||
*/
|
*/
|
||||||
FORCE_CODE_SET,
|
FORCE_CODE_SET,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether to use compact mode for Code-128 code (type {@link Boolean}, or "true" or "false"
|
* Forces C40 encoding for data-matrix (type {@link Boolean}, or "true" or "false") {@link String } value). This
|
||||||
|
* option and {@link #DATA_MATRIX_COMPACT} are mutually exclusive.
|
||||||
|
*/
|
||||||
|
FORCE_C40,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether to use compact mode for Code-128 code (type {@link Boolean}, or "true" or "false"
|
||||||
|
* {@link String } value).
|
||||||
* This can yield slightly smaller bar codes. This option and {@link #FORCE_CODE_SET} are mutually
|
* This can yield slightly smaller bar codes. This option and {@link #FORCE_CODE_SET} are mutually
|
||||||
* exclusive options.
|
* exclusive.
|
||||||
*/
|
*/
|
||||||
CODE128_COMPACT,
|
CODE128_COMPACT,
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,9 @@ public final class DataMatrixWriter implements Writer {
|
||||||
}
|
}
|
||||||
encoded = MinimalEncoder.encodeHighLevel(contents, charset, hasGS1FormatHint ? 0x1D : -1, shape);
|
encoded = MinimalEncoder.encodeHighLevel(contents, charset, hasGS1FormatHint ? 0x1D : -1, shape);
|
||||||
} else {
|
} else {
|
||||||
encoded = HighLevelEncoder.encodeHighLevel(contents, shape, minSize, maxSize);
|
boolean hasForceC40Hint = hints != null && hints.containsKey(EncodeHintType.FORCE_C40) &&
|
||||||
|
Boolean.parseBoolean(hints.get(EncodeHintType.FORCE_C40).toString());
|
||||||
|
encoded = HighLevelEncoder.encodeHighLevel(contents, shape, minSize, maxSize, hasForceC40Hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolInfo symbolInfo = SymbolInfo.lookup(encoded.length(), shape, minSize, maxSize, true);
|
SymbolInfo symbolInfo = SymbolInfo.lookup(encoded.length(), shape, minSize, maxSize, true);
|
||||||
|
|
|
@ -23,6 +23,40 @@ class C40Encoder implements Encoder {
|
||||||
return HighLevelEncoder.C40_ENCODATION;
|
return HighLevelEncoder.C40_ENCODATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void encodeMaximal(EncoderContext context) {
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
int lastCharSize = 0;
|
||||||
|
int backtrackStartPosition = context.pos;
|
||||||
|
int backtrackBufferLength = 0;
|
||||||
|
while (context.hasMoreCharacters()) {
|
||||||
|
char c = context.getCurrentChar();
|
||||||
|
context.pos++;
|
||||||
|
lastCharSize = encodeChar(c, buffer);
|
||||||
|
if (buffer.length() % 3 == 0) {
|
||||||
|
backtrackStartPosition = context.pos;
|
||||||
|
backtrackBufferLength = buffer.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (backtrackBufferLength != buffer.length()) {
|
||||||
|
int unwritten = (buffer.length() / 3) * 2;
|
||||||
|
|
||||||
|
int curCodewordCount = context.getCodewordCount() + unwritten + 1; // +1 for the latch to C40
|
||||||
|
context.updateSymbolInfo(curCodewordCount);
|
||||||
|
int available = context.getSymbolInfo().getDataCapacity() - curCodewordCount;
|
||||||
|
int rest = buffer.length() % 3;
|
||||||
|
if ((rest == 2 && available != 2) ||
|
||||||
|
(rest == 1 && (lastCharSize > 3 || available != 1))) {
|
||||||
|
buffer.setLength(backtrackBufferLength);
|
||||||
|
context.pos = backtrackStartPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (buffer.length() > 0) {
|
||||||
|
context.writeCodeword(HighLevelEncoder.LATCH_TO_C40);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleEOD(context, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(EncoderContext context) {
|
public void encode(EncoderContext context) {
|
||||||
//step C
|
//step C
|
||||||
|
|
|
@ -125,7 +125,7 @@ public final class HighLevelEncoder {
|
||||||
* @return the encoded message (the char values range from 0 to 255)
|
* @return the encoded message (the char values range from 0 to 255)
|
||||||
*/
|
*/
|
||||||
public static String encodeHighLevel(String msg) {
|
public static String encodeHighLevel(String msg) {
|
||||||
return encodeHighLevel(msg, SymbolShapeHint.FORCE_NONE, null, null);
|
return encodeHighLevel(msg, SymbolShapeHint.FORCE_NONE, null, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,9 +143,29 @@ public final class HighLevelEncoder {
|
||||||
SymbolShapeHint shape,
|
SymbolShapeHint shape,
|
||||||
Dimension minSize,
|
Dimension minSize,
|
||||||
Dimension maxSize) {
|
Dimension maxSize) {
|
||||||
|
return encodeHighLevel(msg, shape, minSize, maxSize, false);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Performs message encoding of a DataMatrix message using the algorithm described in annex P
|
||||||
|
* of ISO/IEC 16022:2000(E).
|
||||||
|
*
|
||||||
|
* @param msg the message
|
||||||
|
* @param shape requested shape. May be {@code SymbolShapeHint.FORCE_NONE},
|
||||||
|
* {@code SymbolShapeHint.FORCE_SQUARE} or {@code SymbolShapeHint.FORCE_RECTANGLE}.
|
||||||
|
* @param minSize the minimum symbol size constraint or null for no constraint
|
||||||
|
* @param maxSize the maximum symbol size constraint or null for no constraint
|
||||||
|
* @param forceC40 enforce C40 encoding
|
||||||
|
* @return the encoded message (the char values range from 0 to 255)
|
||||||
|
*/
|
||||||
|
public static String encodeHighLevel(String msg,
|
||||||
|
SymbolShapeHint shape,
|
||||||
|
Dimension minSize,
|
||||||
|
Dimension maxSize,
|
||||||
|
boolean forceC40) {
|
||||||
//the codewords 0..255 are encoded as Unicode characters
|
//the codewords 0..255 are encoded as Unicode characters
|
||||||
|
C40Encoder c40Encoder = new C40Encoder();
|
||||||
Encoder[] encoders = {
|
Encoder[] encoders = {
|
||||||
new ASCIIEncoder(), new C40Encoder(), new TextEncoder(),
|
new ASCIIEncoder(), c40Encoder, new TextEncoder(),
|
||||||
new X12Encoder(), new EdifactEncoder(), new Base256Encoder()
|
new X12Encoder(), new EdifactEncoder(), new Base256Encoder()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -164,6 +184,13 @@ public final class HighLevelEncoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
int encodingMode = ASCII_ENCODATION; //Default mode
|
int encodingMode = ASCII_ENCODATION; //Default mode
|
||||||
|
|
||||||
|
if (forceC40) {
|
||||||
|
c40Encoder.encodeMaximal(context);
|
||||||
|
encodingMode = context.getNewEncoding();
|
||||||
|
context.resetEncoderSignal();
|
||||||
|
}
|
||||||
|
|
||||||
while (context.hasMoreCharacters()) {
|
while (context.hasMoreCharacters()) {
|
||||||
encoders[encodingMode].encode(context);
|
encoders[encodingMode].encode(context);
|
||||||
if (context.getNewEncoding() >= 0) {
|
if (context.getNewEncoding() >= 0) {
|
||||||
|
|
Loading…
Reference in a new issue