Files
aistudio-wpf-diagram/Others/zxing.core/zxing.core/oned/Code93Writer.cs
2023-04-16 20:11:40 +08:00

222 lines
8.0 KiB
C#

/*
* Copyright 2015 ZXing authors
*
* 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.
*/
using System;
using System.Collections.Generic;
using ZXing.Common;
namespace ZXing.OneD
{
/// <summary>
/// This object renders a CODE93 code as a BitMatrix
/// </summary>
public class Code93Writer : OneDimensionalCodeWriter
{
private static readonly IList<BarcodeFormat> supportedWriteFormats = new List<BarcodeFormat> { BarcodeFormat.CODE_93 };
/// <summary>
/// returns supported formats
/// </summary>
protected override IList<BarcodeFormat> SupportedWriteFormats
{
get { return supportedWriteFormats; }
}
/// <summary>
/// </summary>
/// <param name="contents">barcode contents to encode.It should not be encoded for extended characters.</param>
/// <returns>a { @code bool[]} of horizontal pixels(false = white, true = black)</returns>
public override bool[] encode(String contents)
{
contents = convertToExtended(contents);
int length = contents.Length;
if (length > 80)
{
throw new ArgumentException(
"Requested contents should be less than 80 digits long after converting to extended encoding, but got " + length);
}
//length of code + 2 start/stop characters + 2 checksums, each of 9 bits, plus a termination bar
int codeWidth = (contents.Length + 2 + 2) * 9 + 1;
bool[] result = new bool[codeWidth];
//start character (*)
int pos = appendPattern(result, 0, Code93Reader.ASTERISK_ENCODING);
for (int i = 0; i < length; i++)
{
int indexInString = Code93Reader.ALPHABET_STRING.IndexOf(contents[i]);
pos += appendPattern(result, pos, Code93Reader.CHARACTER_ENCODINGS[indexInString]);
}
//add two checksums
int check1 = computeChecksumIndex(contents, 20);
pos += appendPattern(result, pos, Code93Reader.CHARACTER_ENCODINGS[check1]);
//append the contents to reflect the first checksum added
contents += Code93Reader.ALPHABET_STRING[check1];
int check2 = computeChecksumIndex(contents, 15);
pos += appendPattern(result, pos, Code93Reader.CHARACTER_ENCODINGS[check2]);
//end character (*)
pos += appendPattern(result, pos, Code93Reader.ASTERISK_ENCODING);
//termination bar (single black bar)
result[pos] = true;
return result;
}
/// <summary>
/// </summary>
/// <param name="target">output to append to</param>
/// <param name="pos">start position</param>
/// <param name="pattern">pattern to append</param>
/// <param name="startColor">unused</param>
/// <returns>9</returns>
[Obsolete("without replacement; intended as an internal-only method")]
protected new static int appendPattern(bool[] target, int pos, int[] pattern, bool startColor)
{
foreach (var bit in pattern)
{
target[pos++] = bit != 0;
}
return 9;
}
private static int appendPattern(bool[] target, int pos, int a)
{
for (int i = 0; i < 9; i++)
{
int temp = a & (1 << (8 - i));
target[pos + i] = temp != 0;
}
return 9;
}
private static int computeChecksumIndex(String contents, int maxWeight)
{
int weight = 1;
int total = 0;
for (int i = contents.Length - 1; i >= 0; i--)
{
int indexInString = Code93Reader.ALPHABET_STRING.IndexOf(contents[i]);
total += indexInString * weight;
if (++weight > maxWeight)
{
weight = 1;
}
}
return total % 47;
}
internal static String convertToExtended(String contents)
{
int length = contents.Length;
var extendedContent = new System.Text.StringBuilder(length * 2);
for (int i = 0; i < length; i++)
{
char character = contents[i];
// ($)=a, (%)=b, (/)=c, (+)=d. see Code93Reader.ALPHABET_STRING
if (character == 0)
{
// NUL: (%)U
extendedContent.Append("bU");
}
else if (character <= 26)
{
// SOH - SUB: ($)A - ($)Z
extendedContent.Append('a');
extendedContent.Append((char) ('A' + character - 1));
}
else if (character <= 31)
{
// ESC - US: (%)A - (%)E
extendedContent.Append('b');
extendedContent.Append((char) ('A' + character - 27));
}
else if (character == ' ' || character == '$' || character == '%' || character == '+')
{
// space $ % +
extendedContent.Append(character);
}
else if (character <= ',')
{
// ! " # & ' ( ) * ,: (/)A - (/)L
extendedContent.Append('c');
extendedContent.Append((char) ('A' + character - '!'));
}
else if (character <= '9')
{
extendedContent.Append(character);
}
else if (character == ':')
{
// :: (/)Z
extendedContent.Append("cZ");
}
else if (character <= '?')
{
// ; - ?: (%)F - (%)J
extendedContent.Append('b');
extendedContent.Append((char) ('F' + character - ';'));
}
else if (character == '@')
{
// @: (%)V
extendedContent.Append("bV");
}
else if (character <= 'Z')
{
// A - Z
extendedContent.Append(character);
}
else if (character <= '_')
{
// [ - _: (%)K - (%)O
extendedContent.Append('b');
extendedContent.Append((char) ('K' + character - '['));
}
else if (character == '`')
{
// `: (%)W
extendedContent.Append("bW");
}
else if (character <= 'z')
{
// a - z: (*)A - (*)Z
extendedContent.Append('d');
extendedContent.Append((char) ('A' + character - 'a'));
}
else if (character <= 127)
{
// { - DEL: (%)P - (%)T
extendedContent.Append('b');
extendedContent.Append((char) ('P' + character - '{'));
}
else
{
throw new ArgumentException(
"Requested content contains a non-encodable character: '" + character + "'");
}
}
return extendedContent.ToString();
}
}
}