org.krysalis.barcode4j.impl.code128.Code128LogicImpl Maven / Gradle / Ivy
Show all versions of barcode4j-fop-ext-0.20.5-complete Show documentation
/*
* Copyright 2002-2004 Jeremias Maerki.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.krysalis.barcode4j.impl.code128;
import org.krysalis.barcode4j.BarGroup;
import org.krysalis.barcode4j.ClassicBarcodeLogicHandler;
/**
* This class is an implementation of the Code 128 barcode.
*
* @author Jeremias Maerki
* @version $Id: Code128LogicImpl.java,v 1.3 2004/10/24 11:45:53 jmaerki Exp $
*/
public class Code128LogicImpl {
/** The function 1 command. ASCII: 0xF1 */
public static final char FNC_1 = 0xF1;
/** The function 2 command. ASCII: 0xF2 */
public static final char FNC_2 = 0xF2;
/** The function 3 command. ASCII: 0xF3 */
public static final char FNC_3 = 0xF3;
/** The function 4 command. ASCII: 0xF4 */
public static final char FNC_4 = 0xF4;
private static final byte[][] CHARSET =
{{2, 1, 2, 2, 2, 2}, //000, SP, #032
{2, 2, 2, 1, 2, 2},
{2, 2, 2, 2, 2, 1},
{1, 2, 1, 2, 2, 3},
{1, 2, 1, 3, 2, 2},
{1, 3, 1, 2, 2, 2},
{1, 2, 2, 2, 1, 3},
{1, 2, 2, 3, 1, 2},
{1, 3, 2, 2, 1, 2},
{2, 2, 1, 2, 1, 3},
{2, 2, 1, 3, 1, 2},
{2, 3, 1, 2, 1, 2},
{1, 1, 2, 2, 3, 2},
{1, 2, 2, 1, 3, 2},
{1, 2, 2, 2, 3, 1},
{1, 1, 3, 2, 2, 2},
{1, 2, 3, 1, 2, 2}, //016, '0', #048
{1, 2, 3, 2, 2, 1},
{2, 2, 3, 2, 1, 1},
{2, 2, 1, 1, 3, 2},
{2, 2, 1, 2, 3, 1},
{2, 1, 3, 2, 1, 2},
{2, 2, 3, 1, 1, 2},
{3, 1, 2, 1, 3, 1},
{3, 1, 1, 2, 2, 2},
{3, 2, 1, 1, 2, 2}, //025, '9', #057
{3, 2, 1, 2, 2, 1}, //026, ':', #058
{3, 1, 2, 2, 1, 2},
{3, 2, 2, 1, 1, 2},
{3, 2, 2, 2, 1, 1},
{2, 1, 2, 1, 2, 3},
{2, 1, 2, 3, 2, 1},
{2, 3, 2, 1, 2, 1},
{1, 1, 1, 3, 2, 3}, //033, 'A', #065
{1, 3, 1, 1, 2, 3},
{1, 3, 1, 3, 2, 1},
{1, 1, 2, 3, 1, 3},
{1, 3, 2, 1, 1, 3},
{1, 3, 2, 3, 1, 1},
{2, 1, 1, 3, 1, 3},
{2, 3, 1, 1, 1, 3},
{2, 3, 1, 3, 1, 1},
{1, 1, 2, 1, 3, 3},
{1, 1, 2, 3, 3, 1},
{1, 3, 2, 1, 3, 1},
{1, 1, 3, 1, 2, 3},
{1, 1, 3, 3, 2, 1},
{1, 3, 3, 1, 2, 1},
{3, 1, 3, 1, 2, 1},
{2, 1, 1, 3, 3, 1},
{2, 3, 1, 1, 3, 1},
{2, 1, 3, 1, 1, 3},
{2, 1, 3, 3, 1, 1},
{2, 1, 3, 1, 3, 1},
{3, 1, 1, 1, 2, 3},
{3, 1, 1, 3, 2, 1},
{3, 3, 1, 1, 2, 1},
{3, 1, 2, 1, 1, 3},
{3, 1, 2, 3, 1, 1}, //058, 'Z', #090
{3, 3, 2, 1, 1, 1}, //059, '[', #091
{3, 1, 4, 1, 1, 1},
{2, 2, 1, 4, 1, 1},
{4, 3, 1, 1, 1, 1},
{1, 1, 1, 2, 2, 4}, //063, '_', #095
{1, 1, 1, 4, 2, 2}, //064, A:NUL/B:'`', #000/#096
{1, 2, 1, 1, 2, 4}, //065, A:SOH/B:'a'. #001/#097
{1, 2, 1, 4, 2, 1},
{1, 4, 1, 1, 2, 2},
{1, 4, 1, 2, 2, 1},
{1, 1, 2, 2, 1, 4},
{1, 1, 2, 4, 1, 2},
{1, 2, 2, 1, 1, 4},
{1, 2, 2, 4, 1, 1},
{1, 4, 2, 1, 1, 2},
{1, 4, 2, 2, 1, 1},
{2, 4, 1, 2, 1, 1},
{2, 2, 1, 1, 1, 4},
{4, 1, 3, 1, 1, 1},
{2, 4, 1, 1, 1, 2},
{1, 3, 4, 1, 1, 1},
{1, 1, 1, 2, 4, 2},
{1, 2, 1, 1, 4, 2},
{1, 2, 1, 2, 4, 1},
{1, 1, 4, 2, 1, 2},
{1, 2, 4, 1, 1, 2},
{1, 2, 4, 2, 1, 1},
{4, 1, 1, 2, 1, 2},
{4, 2, 1, 1, 1, 2},
{4, 2, 1, 2, 1, 1},
{2, 1, 2, 1, 4, 1},
{2, 1, 4, 1, 2, 1}, //090, A:SUB/B:'z', #026/#122
{4, 1, 2, 1, 2, 1},
{1, 1, 1, 1, 4, 3},
{1, 1, 1, 3, 4, 1},
{1, 3, 1, 1, 4, 1}, //094, A:RS/B:tilde, #030/#126
{1, 1, 4, 1, 1, 3}, //095, A:US/B:DEL, #031/#127
{1, 1, 4, 3, 1, 1},
{4, 1, 1, 1, 1, 3},
{4, 1, 1, 3, 1, 1},
{1, 1, 3, 1, 4, 1},
{1, 1, 4, 1, 3, 1},
{3, 1, 1, 1, 4, 1},
{4, 1, 1, 1, 3, 1},
{2, 1, 1, 4, 1, 2}, //103, Start A
{2, 1, 1, 2, 1, 4}, //104, Start B
{2, 1, 1, 2, 3, 2}}; //105, Start C
private static final byte[] STOP = {2, 3, 3, 1, 1, 1, 2}; //106, STOP
/**
* Determines whether a character can be encoded in Code 128.
* @param ch the character to check
* @return true if it is a valid character
*/
public static boolean isValidChar(char ch) {
return (ch >= 0 && ch <= 127)
|| (ch >= FNC_1 && ch <= FNC_4);
}
/**
* Determines whether a character is defined in codeset A.
* @param ch the character to check
* @return true if it is found in codeset A
*/
public static boolean isInCodeSetA(char ch) {
return (ch >= 0 && ch <= 95)
|| (ch >= FNC_1 && ch <= FNC_4);
}
/**
* Determines whether a character is defined in codeset B.
* @param ch the character to check
* @return true if it is found in codeset B
*/
public static boolean isInCodeSetB(char ch) {
return (ch >= 32 && ch <= 127)
|| (ch >= FNC_1 && ch <= FNC_4);
}
/**
* Determines whether a character is a digit or a function 1 command.
* @param ch the character to check
* @param second true if checking the character for the second position in
* a duo.
* @return true if the above condition is met
*/
public static boolean canBeInCodeSetC(char ch, boolean second) {
if (second) {
return (ch >= '0' && ch <= '9');
} else {
return (ch >= '0' && ch <= '9') || (ch == FNC_1);
}
}
/**
* Converts a character set index to a String representation. This is
* primarily used for debugging purposes.
* @param index the character set index
* @return the String representation
*/
public static String symbolCharToString(int index) {
switch (index) {
case 96: return "FNC3/96";
case 97: return "FNC2/97";
case 98: return "Shift/98";
case 99: return "CodeC/99";
case 100: return "CodeB/FNC4";
case 101: return "CodeA/FNC4";
case 102: return "FNC1";
case 103: return "StartA";
case 104: return "StartB";
case 105: return "StartC";
default: return "idx" + Integer.toString(index);
}
}
/**
* Converts an encoded Code 128 message into a String for debugging
* purposes.
* @param encodedMsg the encoded message
* @return the String representation
*/
public static String toString(int[] encodedMsg) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < encodedMsg.length; i++) {
if (i > 0) {
sb.append("|");
}
sb.append(symbolCharToString(encodedMsg[i]));
}
return sb.toString();
}
/**
* Encodes a character.
* @param logic LogicHandler to send the barcode events to
* @param index index withing the character set of the character to encode
*/
protected void encodeChar(ClassicBarcodeLogicHandler logic, int index) {
logic.startBarGroup(BarGroup.MSG_CHARACTER, symbolCharToString(index));
for (byte i = 0; i < 6; i++) {
final int width = CHARSET[index][i];
final boolean black = ((i % 2) == 0);
logic.addBar(black, width);
}
logic.endBarGroup();
}
/**
* Encodes the special stop character.
* @param logic LogicHandler to send the barcode events to
*/
protected void encodeStop(ClassicBarcodeLogicHandler logic) {
logic.startBarGroup(BarGroup.STOP_CHARACTER, null);
for (byte i = 0; i < 7; i++) {
final int width = STOP[i];
final boolean black = ((i % 2) == 0);
logic.addBar(black, width);
}
logic.endBarGroup();
}
/**
* Returns the encoder to be used. The encoder is responsible for turning
* a String message into an array of character set indexes.
*
* Override this method to supply your own implementation.
* @return the requested encoder
*/
protected Code128Encoder getEncoder() {
return new DefaultCode128Encoder();
}
/**
* Encodes a message into an array of character set indexes.
* @param msg the message to encode
* @return the requested array of character set indexes
* @see #getEncoder()
*/
public int[] createEncodedMessage(String msg) {
return getEncoder().encode(msg);
}
/**
* Generates the barcode logic
* @param logic the logic handler to receive the generated events
* @param msg the message to encode
*/
public void generateBarcodeLogic(ClassicBarcodeLogicHandler logic, String msg) {
logic.startBarcode(msg, msg);
int[] encodedMsg = createEncodedMessage(msg);
for (int i = 0; i < encodedMsg.length; i++) {
encodeChar(logic, encodedMsg[i]);
}
//Calculate checksum
int checksum = encodedMsg[0];
for (int i = 1; i < encodedMsg.length; i++) {
checksum += i * encodedMsg[i];
}
checksum = checksum % 103;
encodeChar(logic, checksum);
encodeStop(logic);
logic.endBarcode();
}
}