namespace GenCode128 { /// /// Static tools for determining codes for individual characters in the content /// public static class Code128Code { private const int CShift = 98; private const int CCodeA = 101; private const int CCodeB = 100; private const int CStartA = 103; private const int CStartB = 104; private const int CStop = 106; /// /// Indicates which code sets can represent a character -- CodeA, CodeB, or either /// public enum CodeSetAllowed { CodeA, CodeB, CodeAorB } /// /// Get the Code128 code value(s) to represent an ASCII character, with /// optional look-ahead for length optimization /// /// The ASCII value of the character to translate /// The next character in sequence (or -1 if none) /// The current codeset, that the returned codes need to follow; /// if the returned codes change that, then this value will be changed to reflect it /// An array of integers representing the codes that need to be output to produce the /// given character public static int[] CodesForChar(int charAscii, int lookAheadAscii, ref CodeSet currentCodeSet) { int[] result; var shifter = -1; if (!CharCompatibleWithCodeset(charAscii, currentCodeSet)) { // if we have a lookahead character AND if the next character is ALSO not compatible if ((lookAheadAscii != -1) && !CharCompatibleWithCodeset(lookAheadAscii, currentCodeSet)) { // we need to switch code sets switch (currentCodeSet) { case CodeSet.CodeA: shifter = CCodeB; currentCodeSet = CodeSet.CodeB; break; case CodeSet.CodeB: shifter = CCodeA; currentCodeSet = CodeSet.CodeA; break; } } else { // no need to switch code sets, a temporary SHIFT will suffice shifter = CShift; } } if (shifter != -1) { result = new int[2]; result[0] = shifter; result[1] = CodeValueForChar(charAscii); } else { result = new int[1]; result[0] = CodeValueForChar(charAscii); } return result; } /// /// Tells us which codesets a given character value is allowed in /// /// ASCII value of character to look at /// Which codeset(s) can be used to represent this character public static CodeSetAllowed CodesetAllowedForChar(int charAscii) { if (charAscii >= 32 && charAscii <= 95) { return CodeSetAllowed.CodeAorB; } else { return charAscii < 32 ? CodeSetAllowed.CodeA : CodeSetAllowed.CodeB; } } /// /// Determine if a character can be represented in a given codeset /// /// character to check for /// codeset context to test /// true if the codeset contains a representation for the ASCII character public static bool CharCompatibleWithCodeset(int charAscii, CodeSet currentCodeSet) { var csa = CodesetAllowedForChar(charAscii); return csa == CodeSetAllowed.CodeAorB || (csa == CodeSetAllowed.CodeA && currentCodeSet == CodeSet.CodeA) || (csa == CodeSetAllowed.CodeB && currentCodeSet == CodeSet.CodeB); } /// /// Gets the integer code128 code value for a character (assuming the appropriate code set) /// /// character to convert /// code128 symbol value for the character public static int CodeValueForChar(int charAscii) { return charAscii >= 32 ? charAscii - 32 : charAscii + 64; } /// /// Return the appropriate START code depending on the codeset we want to be in /// /// The codeset you want to start in /// The code128 code to start a barcode in that codeset public static int StartCodeForCodeSet(CodeSet cs) { return cs == CodeSet.CodeA ? CStartA : CStartB; } /// /// Return the Code128 stop code /// /// the stop code public static int StopCode() { return CStop; } } }